You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by ak...@apache.org on 2017/04/28 04:59:51 UTC

[3/4] sentry git commit: SENTRY-1593: Implement client failover for Generic and NN clients (Kalyan Kalvagadda, reviewed by ALex Kolbasov)

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/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
index 075983e..b7ac640 100644
--- 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
@@ -6,9 +6,9 @@
  * 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
  * 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.
@@ -18,27 +18,18 @@
 package org.apache.sentry.provider.db.generic.service.thrift;
 
 import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.security.PrivilegedExceptionAction;
 import java.util.*;
 
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.Sasl;
-
-import com.google.common.collect.ImmutableMap;
 import org.apache.hadoop.conf.Configuration;
-import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION;
-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.core.common.exception.MissingConfigurationException;
+
+//import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION;
+
 import org.apache.sentry.core.common.exception.SentryUserException;
 import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.transport.SentryPolicyClientTransportConfig;
-import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.common.transport.SentryServiceClient;
+import org.apache.sentry.core.common.transport.SentryTransportFactory;
 import org.apache.sentry.core.model.db.AccessConstants;
 import org.apache.sentry.service.thrift.ServiceConstants;
 import org.apache.sentry.service.thrift.Status;
@@ -46,146 +37,76 @@ 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;
+/**
+ * Sentry Generic Service Client
+ * <p>
+ * The public implementation of SentryGenericServiceClient.
+ * TODO(kalyan) A Sentry Client in which all the operations are synchronized for thread safety
+ * Note: When using this client, if there is an exception in RPC, socket can get into an inconsistent state.
+ * So it is important to close and re-open the transportFactory so that new socket is used.
+ */
+
+public class SentryGenericServiceClientDefaultImpl implements SentryGenericServiceClient, SentryServiceClient {
   private SentryGenericPolicyService.Client client;
+  private SentryTransportFactory transportFactory;
   private TTransport transport;
-  private int connectionTimeout;
+  private Configuration conf;
   private static final Logger LOGGER = LoggerFactory
-                                       .getLogger(SentryGenericServiceClientDefaultImpl.class);
+    .getLogger(SentryGenericServiceClientDefaultImpl.class);
   private static final String THRIFT_EXCEPTION_MESSAGE = "Thrift exception occured ";
-  private final SentryPolicyClientTransportConfig transportConfig =  new SentryPolicyClientTransportConfig();
-
-  private static final ImmutableMap<String, String> SASL_PROPERTIES =
-    ImmutableMap.of(Sasl.SERVER_AUTH, "true", Sasl.QOP, "auth-conf");
 
-  /**
-   * 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, Configuration conf)
-        throws IOException {
-      super(mechanism, authorizationId, protocol, serverName, props, cbh,
-          transport);
-      if (wrapUgi) {
-       // If we don't set the configuration, the UGI will be created based on
-       // what's on the classpath, which may lack the kerberos changes we require
-        UserGroupInformation.setConfiguration(conf);
-        ugi = UserGroupInformation.getLoginUser();
-      }
-    }
+  public SentryGenericServiceClientDefaultImpl(Configuration conf, SentryPolicyClientTransportConfig transportConfig) throws IOException {
 
-    // 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.getMessage(), e);
-        } catch (InterruptedException e) {
-          throw new TTransportException(
-              "Interrupted while opening underlying transport: " + e.getMessage(), e);
-        }
-      }
-    }
-
-    private void baseOpen() throws TTransportException {
-      super.open();
-    }
+    //TODO(kalyan) need to find appropriate place to add it
+    // if (kerberos) {
+    //  // since the client uses hadoop-auth, we need to set kerberos in
+    //  // hadoop-auth if we plan to use kerberos
+    //  conf.set(HADOOP_SECURITY_AUTHENTICATION, SentryConstants.KERBEROS_MoODE);
+    // }
+    this.conf = conf;
+    transportFactory = new SentryTransportFactory(conf, transportConfig);
   }
 
-  public SentryGenericServiceClientDefaultImpl(Configuration conf) throws Exception {
-    // copy the configuration because we may make modifications to it.
-    this.conf = new Configuration(conf);
-
-      Preconditions.checkNotNull(this.conf, "Configuration object cannot be null");
-    try {
-      this.serverAddress = NetUtils.createSocketAddr(
-        transportConfig.getSentryServerRpcAddress(conf),
-        transportConfig.getServerRpcPort(conf));
-
-
-      this.connectionTimeout = transportConfig.getServerRpcConnTimeoutInMs(conf);
-      kerberos = transportConfig.isKerberosEnabled(conf);
-      transport = new TSocket(serverAddress.getHostName(),
-        serverAddress.getPort(), connectionTimeout);
-      if (kerberos) {
-        String serverPrincipal = transportConfig.getSentryPrincipal(conf);
-        // since the client uses hadoop-auth, we need to set kerberos in
-        // hadoop-auth if we plan to use kerberos
-        conf.set(HADOOP_SECURITY_AUTHENTICATION, SentryConstants.KERBEROS_MODE);
-
-        // 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 = transportConfig.useUserGroupInformation(conf);
-        transport = new UgiSaslClientTransport(AuthMethod.KERBEROS.getMechanismName(),
-          null, serverPrincipalParts[0], serverPrincipalParts[1],
-          SASL_PROPERTIES, null, transport, wrapUgi, conf);
-      } else {
-        serverPrincipalParts = null;
-      }
-      transport.open();
-    } catch (TTransportException e) {
-      throw new IOException("Transport exception while opening transport: " + e.getMessage(), e);
-    } catch (MissingConfigurationException e) {
-      throw new RuntimeException("Client Creation Failed: " + e.getMessage(), e);
+  /**
+   * Connect to the specified server configured
+   *
+   * @throws IOException
+   */
+  @Override
+  public synchronized void connect() throws IOException {
+    if (transport != null && transport.isOpen()) {
+      return;
     }
 
-    LOGGER.debug("Successfully opened transport: " + transport + " to " + serverAddress);
+    transport = transportFactory.getTransport();
+    TMultiplexedProtocol protocol = null;
     long maxMessageSize = conf.getLong(ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE,
-        ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE_DEFAULT);
-    TMultiplexedProtocol protocol = new TMultiplexedProtocol(
-        new TBinaryProtocol(transport, maxMessageSize, maxMessageSize, true, true),
-        SentryGenericPolicyProcessor.SENTRY_GENERIC_SERVICE_NAME);
+      ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE_DEFAULT);
+    protocol = new TMultiplexedProtocol(
+      new TBinaryProtocol(transport, maxMessageSize, maxMessageSize, true, true),
+      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
+   * @param roleName:          Name of the role
+   * @param component:         The request is issued to which component
    * @throws SentryUserException
    */
+  @Override
   public synchronized void createRole(String requestorUserName, String roleName, String component)
-  throws SentryUserException {
+    throws SentryUserException {
     TCreateSentryRoleRequest request = new TCreateSentryRoleRequest();
     request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
     request.setRequestorUserName(requestorUserName);
@@ -199,6 +120,7 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
     }
   }
 
+  @Override
   public void createRoleIfNotExist(String requestorUserName, String roleName, String component) throws SentryUserException {
     TCreateSentryRoleRequest request = new TCreateSentryRoleRequest();
     request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
@@ -219,26 +141,29 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
 
   /**
    * 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
+   * @param roleName:          Name of the role
+   * @param component:         The request is issued to which component
    * @throws SentryUserException
    */
+  @Override
   public void dropRole(String requestorUserName,
-      String roleName, String component)
-  throws SentryUserException {
+                       String roleName, String component)
+    throws SentryUserException {
     dropRole(requestorUserName, roleName, component, false);
   }
 
+  @Override
   public void dropRoleIfExists(String requestorUserName,
-      String roleName, String component)
-  throws SentryUserException {
+                               String roleName, String component)
+    throws SentryUserException {
     dropRole(requestorUserName, roleName, component, true);
   }
 
   private void dropRole(String requestorUserName,
-      String roleName, String component , boolean ifExists)
-  throws SentryUserException {
+                        String roleName, String component, boolean ifExists)
+    throws SentryUserException {
     TDropSentryRoleRequest request = new TDropSentryRoleRequest();
     request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
     request.setRequestorUserName(requestorUserName);
@@ -258,14 +183,16 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
 
   /**
    * 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
+   * @param roleName:          Name of the role
+   * @param component:         The request is issued to which component
+   * @param groups:            The name of groups
    * @throws SentryUserException
    */
+  @Override
   public void addRoleToGroups(String requestorUserName, String roleName,
-      String component, Set<String> groups) throws SentryUserException {
+                              String component, Set<String> groups) throws SentryUserException {
     TAlterSentryRoleAddGroupsRequest request = new TAlterSentryRoleAddGroupsRequest();
     request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
     request.setRequestorUserName(requestorUserName);
@@ -283,14 +210,16 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
 
   /**
    * 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
+   * @param roleName:          Name of the role
+   * @param component:         The request is issued to which component
+   * @param groups:            The name of groups
    * @throws SentryUserException
    */
+  @Override
   public void deleteRoleToGroups(String requestorUserName, String roleName,
-      String component, Set<String> groups) throws SentryUserException {
+                                 String component, Set<String> groups) throws SentryUserException {
     TAlterSentryRoleDeleteGroupsRequest request = new TAlterSentryRoleDeleteGroupsRequest();
     request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
     request.setRequestorUserName(requestorUserName);
@@ -308,14 +237,16 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
 
   /**
    * 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 roleName:          Name of the role
+   * @param component:         The request is issued to which component
    * @param privilege
    * @throws SentryUserException
    */
+  @Override
   public void grantPrivilege(String requestorUserName, String roleName,
-      String component, TSentryPrivilege privilege) throws SentryUserException {
+                             String component, TSentryPrivilege privilege) throws SentryUserException {
     TAlterSentryRoleGrantPrivilegeRequest request = new TAlterSentryRoleGrantPrivilegeRequest();
     request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
     request.setComponent(component);
@@ -333,14 +264,16 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
 
   /**
    * 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 roleName:          Name of the role
+   * @param component:         The request is issued to which component
    * @param privilege
    * @throws SentryUserException
    */
+  @Override
   public void revokePrivilege(String requestorUserName, String roleName,
-      String component, TSentryPrivilege privilege) throws SentryUserException {
+                              String component, TSentryPrivilege privilege) throws SentryUserException {
     TAlterSentryRoleRevokePrivilegeRequest request = new TAlterSentryRoleRevokePrivilegeRequest();
     request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
     request.setComponent(component);
@@ -358,13 +291,15 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
 
   /**
    * drop privilege
+   *
    * @param requestorUserName: user on whose behalf the request is issued
-   * @param component: The request is issued to which component
+   * @param component:         The request is issued to which component
    * @param privilege
    * @throws SentryUserException
    */
-  public void dropPrivilege(String requestorUserName,String component,
-      TSentryPrivilege privilege) throws SentryUserException {
+  @Override
+  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);
@@ -381,18 +316,20 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
 
   /**
    * 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 component:         The request is issued to which component
+   * @param serviceName:       The Authorizable belongs to which service
    * @param oldAuthorizables
    * @param newAuthorizables
    * @throws SentryUserException
    */
+  @Override
   public void renamePrivilege(String requestorUserName, String component,
-      String serviceName, List<? extends Authorizable> oldAuthorizables,
-      List<? extends Authorizable> newAuthorizables) throws SentryUserException {
+                              String serviceName, List<? extends Authorizable> oldAuthorizables,
+                              List<? extends Authorizable> newAuthorizables) throws SentryUserException {
     if (oldAuthorizables == null || oldAuthorizables.isEmpty()
-        || newAuthorizables == null || newAuthorizables.isEmpty()) {
+      || newAuthorizables == null || newAuthorizables.isEmpty()) {
       throw new SentryUserException("oldAuthorizables or newAuthorizables can not be null or empty");
     }
 
@@ -423,17 +360,19 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
 
   /**
    * 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
+   * @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
    */
+  @Override
   public synchronized Set<TSentryRole> listRolesByGroupName(
-      String requestorUserName,
-      String groupName,
-      String component)
-  throws SentryUserException {
+    String requestorUserName,
+    String groupName,
+    String component)
+    throws SentryUserException {
     TListSentryRolesRequest request = new TListSentryRolesRequest();
     request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
     request.setRequestorUserName(requestorUserName);
@@ -449,30 +388,34 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
     }
   }
 
+  @Override
   public Set<TSentryRole> listUserRoles(String requestorUserName, String component)
-      throws SentryUserException {
+    throws SentryUserException {
     return listRolesByGroupName(requestorUserName, AccessConstants.ALL, component);
   }
 
+  @Override
   public Set<TSentryRole> listAllRoles(String requestorUserName, String component)
-      throws SentryUserException {
+    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 component:         The request is issued to which component
    * @param serviceName
    * @param authorizables
    * @return
    * @throws SentryUserException
    */
+  @Override
   public Set<TSentryPrivilege> listPrivilegesByRoleName(
-      String requestorUserName, String roleName, String component,
-      String serviceName, List<? extends Authorizable> authorizables)
-      throws SentryUserException {
+    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);
@@ -497,25 +440,28 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
     return response.getPrivileges();
   }
 
+  @Override
   public Set<TSentryPrivilege> listPrivilegesByRoleName(
-      String requestorUserName, String roleName, String component,
-      String serviceName) throws SentryUserException {
+    String requestorUserName, String roleName, String component,
+    String serviceName) throws SentryUserException {
     return listPrivilegesByRoleName(requestorUserName, roleName, component, serviceName, null);
   }
 
   /**
    * get sentry permissions from provider as followings:
+   *
+   * @throws SentryUserException
    * @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
    */
+  @Override
   public Set<String> listPrivilegesForProvider(String component,
-      String serviceName, ActiveRoleSet roleSet, Set<String> groups,
-      List<? extends Authorizable> authorizables) throws SentryUserException {
+                                               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);
@@ -548,20 +494,20 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
    * Get sentry privileges based on valid active roles and the authorize objects. Note that
    * it is client responsibility to ensure the requestor username, etc. is not impersonated.
    *
-   * @param component: The request respond to which component.
-   * @param serviceName: The name of service.
+   * @param component:         The request respond to which component.
+   * @param serviceName:       The name of service.
    * @param requestorUserName: The requestor user name.
-   * @param authorizablesSet: The set of authorize objects. One authorize object is represented
-   *     as a string. e.g resourceType1=resourceName1->resourceType2=resourceName2->resourceType3=resourceName3.
-   * @param groups: The requested groups.
-   * @param roleSet: The active roles set.
-   *
-   * @returns The mapping of authorize objects and TSentryPrivilegeMap(<role, set<privileges>).
+   * @param authorizablesSet:  The set of authorize objects. One authorize object is represented
+   *                           as a string. e.g resourceType1=resourceName1->resourceType2=resourceName2->resourceType3=resourceName3.
+   * @param groups:            The requested groups.
+   * @param roleSet:           The active roles set.
    * @throws SentryUserException
+   * @returns The mapping of authorize objects and TSentryPrivilegeMap(<role, set<privileges>).
    */
+  @Override
   public Map<String, TSentryPrivilegeMap> listPrivilegsbyAuthorizable(String component,
-      String serviceName, String requestorUserName, Set<String> authorizablesSet,
-      Set<String> groups, ActiveRoleSet roleSet) throws SentryUserException {
+                                                                      String serviceName, String requestorUserName, Set<String> authorizablesSet,
+                                                                      Set<String> groups, ActiveRoleSet roleSet) throws SentryUserException {
 
     TListSentryPrivilegesByAuthRequest request = new TListSentryPrivilegesByAuthRequest();
 
@@ -591,10 +537,12 @@ public class SentryGenericServiceClientDefaultImpl implements SentryGenericServi
   }
 
   @Override
-  public void close() {
-    if (transport != null) {
-      transport.close();
-    }
+  public synchronized void close() {
+    transportFactory.close();
   }
 
+  @Override
+  public void disconnect() {
+    transportFactory.releaseTransport();
+  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/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
index 980d930..46ac4a3 100644
--- 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
@@ -6,9 +6,9 @@
  * 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
  * 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.
@@ -18,17 +18,27 @@
 package org.apache.sentry.provider.db.generic.service.thrift;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.common.transport.RetryClientInvocationHandler;
+import org.apache.sentry.core.common.transport.SentryPolicyClientTransportConfig;
+
+import java.lang.reflect.Proxy;
 
 /**
  * SentryGenericServiceClientFactory is a public class for the components which using Generic Model to create sentry client.
  */
 public final class SentryGenericServiceClientFactory {
+  private static final SentryPolicyClientTransportConfig transportConfig =
+          new SentryPolicyClientTransportConfig();
 
   private SentryGenericServiceClientFactory() {
   }
 
   public static SentryGenericServiceClient create(Configuration conf) throws Exception {
-      return new SentryGenericServiceClientDefaultImpl(conf);
+    return (SentryGenericServiceClient) Proxy
+      .newProxyInstance(SentryGenericServiceClientDefaultImpl.class.getClassLoader(),
+        SentryGenericServiceClientDefaultImpl.class.getInterfaces(),
+        new RetryClientInvocationHandler(conf,
+          new SentryGenericServiceClientDefaultImpl(conf, transportConfig), transportConfig));
   }
-    
+
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java
index f6bb8a5..09f7d13 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/log/entity/JsonLogEntityFactory.java
@@ -46,7 +46,7 @@ import org.apache.sentry.provider.db.service.thrift.TDropSentryRoleRequest;
 import org.apache.sentry.provider.db.service.thrift.TDropSentryRoleResponse;
 import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
 import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
-import org.apache.sentry.provider.db.service.thrift.ThriftUtil;
+import org.apache.sentry.core.common.utils.ThriftUtil;
 import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
 import org.apache.sentry.service.thrift.Status;
 import org.apache.sentry.service.thrift.TSentryResponseStatus;

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java
index d11d34f..795e2b0 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java
@@ -185,7 +185,7 @@ public class TransactionManager {
       } catch (Exception e) {
         retryNum++;
         if (retryNum >= transactionRetryMax) {
-          String message = "The transaction has reached max retry numbe, r"
+          String message = "The transaction has reached max retry number"
               + e.getMessage();
           LOGGER.error(message, e);
           throw new Exception(message, e);

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/PolicyStoreConstants.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/PolicyStoreConstants.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/PolicyStoreConstants.java
deleted file mode 100644
index 8cf1c1a..0000000
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/PolicyStoreConstants.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * 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.service.thrift;
-
-public final class PolicyStoreConstants {
-  public static final String SENTRY_GENERIC_POLICY_NOTIFICATION = "sentry.generic.policy.notification";
-  public static final String SENTRY_GENERIC_POLICY_STORE = "sentry.generic.policy.store";
-  public static final String SENTRY_GENERIC_POLICY_STORE_DEFAULT =
-      "org.apache.sentry.provider.db.generic.service.persistent.DelegateSentryStore";
-  public static class PolicyStoreServerConfig {
-    public static final String NOTIFICATION_HANDLERS = "sentry.policy.store.notification.handlers";
-  }
-  
-  private PolicyStoreConstants() {
-    // Make constructor private to avoid instantiation
-  }
-}