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:49 UTC

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

Repository: sentry
Updated Branches:
  refs/heads/sentry-ha-redesign ec1e01d45 -> 14b3b904a


http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java
index 8bda2f8..834ed41 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/ServiceConstants.java
@@ -25,7 +25,6 @@ import javax.security.sasl.Sasl;
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableMap;
 import org.apache.sentry.provider.db.service.thrift.SentryMetrics;
-import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClientDefaultImpl;
 
 public class ServiceConstants {
 
@@ -119,6 +118,8 @@ public class ServiceConstants {
     public static final String SENTRY_STORE_LOCAL_GROUP_MAPPING = "org.apache.sentry.provider.file.LocalGroupMappingService";
     public static final String SENTRY_STORE_GROUP_MAPPING_DEFAULT = SENTRY_STORE_HADOOP_GROUP_MAPPING;
 
+    public static final String SENTRY_STORE_ORPHANED_PRIVILEGE_REMOVAL = "sentry.store.orphaned.privilege.removal";
+    public static final String SENTRY_STORE_ORPHANED_PRIVILEGE_REMOVAL_DEFAULT = "false";
     public static final String SENTRY_STORE_CLEAN_PERIOD_SECONDS =
         "sentry.store.clean.period.seconds";
     public static final long SENTRY_STORE_CLEAN_PERIOD_SECONDS_DEFAULT = 43200; // 12 hours.
@@ -225,12 +226,10 @@ public class ServiceConstants {
   }
 
   public static class ClientConfig {
-    public static final ImmutableMap<String, String> SASL_PROPERTIES = ServiceConstants.SASL_PROPERTIES;
     public static final String SERVER_RPC_PORT = "sentry.service.client.server.rpc-port";
     public static final int SERVER_RPC_PORT_DEFAULT = ServerConfig.RPC_PORT_DEFAULT;
     public static final String SERVER_RPC_ADDRESS = "sentry.service.client.server.rpc-address";
     public static final String SERVER_RPC_CONN_TIMEOUT = "sentry.service.client.server.rpc-connection-timeout";
-    public static final int SERVER_RPC_CONN_TIMEOUT_DEFAULT = 200000;
 
     // HA configuration
     public static final String SENTRY_HA_ENABLED = "sentry.ha.enabled";
@@ -254,20 +253,6 @@ public class ServiceConstants {
     public static final String SENTRY_POOL_RETRY_TOTAL = "sentry.service.client.connection.pool.retry-total";
     public static final int SENTRY_POOL_RETRY_TOTAL_DEFAULT = 3;
 
-    /**
-     * full retry num for getting the connection in non-pool model
-     * In a full retry, it will cycle through all available sentry servers
-     * {@link SentryPolicyServiceClientDefaultImpl#connectWithRetry()}
-     */
-    public static final String SENTRY_FULL_RETRY_TOTAL = "sentry.service.client.connection.full.retry-total";
-    public static final int SENTRY_FULL_RETRY_TOTAL_DEFAULT = 2;
-    /**
-     * max retry num for client rpc
-     * {@link RetryClientInvocationHandler#invokeImpl(Object, Method, Object[])}
-     */
-    public static final String SENTRY_RPC_RETRY_TOTAL = "sentry.service.client.rpc.retry-total";
-    public static final int SENTRY_RPC_RETRY_TOTAL_DEFAULT = 3;
-
     // max message size for thrift messages
     public static final String SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE = "sentry.policy.client.thrift.max.message.size";
     public static final long SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE_DEFAULT = 100 * 1024 * 1024;

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericPolicyProcessor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericPolicyProcessor.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericPolicyProcessor.java
index d4bf435..ac93e25 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericPolicyProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericPolicyProcessor.java
@@ -40,7 +40,7 @@ import org.apache.sentry.provider.db.generic.service.persistent.SentryStoreLayer
 import org.apache.sentry.provider.db.generic.service.persistent.PrivilegeObject.Builder;
 import org.apache.sentry.provider.db.service.model.MSentryGMPrivilege;
 import org.apache.sentry.provider.db.service.model.MSentryRole;
-import org.apache.sentry.provider.db.service.thrift.PolicyStoreConstants;
+import org.apache.sentry.core.common.utils.PolicyStoreConstants;
 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/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceClient.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceClient.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceClient.java
new file mode 100644
index 0000000..8959ad8
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceClient.java
@@ -0,0 +1,61 @@
+/**
+ * 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
+ * <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.
+ * 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.util.Set;
+
+import org.apache.sentry.service.thrift.SentryServiceFactory;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+
+public class TestSentryGenericServiceClient extends SentryGenericServiceIntegrationBase {
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    beforeSetup();
+    setupConf();
+    startSentryService();
+    afterSetup();
+    kerberos = false;
+  }
+
+  @Test
+  public void testConnectionWhenReconnect() throws Exception {
+    runTestAsSubject(new TestOperation() {
+      @Override
+      public void runTestAsSubject() throws Exception {
+        String requestorUserName = ADMIN_USER;
+        Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP);
+        String roleName = "admin_r";
+        setLocalGroupMapping(requestorUserName, requestorUserGroupNames);
+        writePolicyFile();
+
+        client.dropRoleIfExists(requestorUserName, roleName, "solr");
+        client.createRole(requestorUserName, roleName, "solr");
+        stopSentryService();
+        server = new SentryServiceFactory().create(conf);
+        startSentryService();
+        client.dropRole(requestorUserName, roleName, "solr");
+      }
+    });
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java
index 1ec8840..b1c2365 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactory.java
@@ -40,7 +40,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.PrivilegeScope;
 import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
 import org.apache.sentry.service.thrift.Status;

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactoryGM.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactoryGM.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactoryGM.java
index dfae5ab..4f35a44 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactoryGM.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/log/entity/TestJsonLogEntityFactoryGM.java
@@ -43,7 +43,7 @@ import org.apache.sentry.provider.db.generic.service.thrift.TDropSentryRoleReque
 import org.apache.sentry.provider.db.generic.service.thrift.TDropSentryRoleResponse;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
 import org.apache.sentry.provider.db.log.util.Constants;
-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.junit.BeforeClass;

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryPolicyServiceClient.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryPolicyServiceClient.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryPolicyServiceClient.java
new file mode 100644
index 0000000..3b3b30e
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryPolicyServiceClient.java
@@ -0,0 +1,64 @@
+/**
+ * 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
+ * <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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sentry.provider.db.service.thrift;
+
+import java.util.Set;
+
+import org.apache.sentry.service.thrift.SentryServiceFactory;
+import org.apache.sentry.service.thrift.SentryServiceIntegrationBase;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+
+public class TestSentryPolicyServiceClient extends SentryServiceIntegrationBase {
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    beforeSetup();
+    setupConf();
+    startSentryService();
+    afterSetup();
+    kerberos = false;
+  }
+
+  @Test
+  public void testConnectionWhenReconnect() throws Exception {
+    runTestAsSubject(new TestOperation() {
+      @Override
+      public void runTestAsSubject() throws Exception {
+        String requestorUserName = ADMIN_USER;
+        Set<String> requestorUserGroupNames = Sets.newHashSet(ADMIN_GROUP);
+        String roleName = "admin_r";
+        setLocalGroupMapping(requestorUserName, requestorUserGroupNames);
+        writePolicyFile();
+
+        client.dropRoleIfExists(requestorUserName, roleName);
+        client.createRole(requestorUserName, roleName);
+        client.listRoles(requestorUserName);
+        stopSentryService();
+        server = new SentryServiceFactory().create(conf);
+        startSentryService();
+        client.listRoles(requestorUserName);
+        client.dropRole(requestorUserName, roleName);
+      }
+    });
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryPolicyStoreProcessor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryPolicyStoreProcessor.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryPolicyStoreProcessor.java
index 04d92dd..58e2618 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryPolicyStoreProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryPolicyStoreProcessor.java
@@ -22,7 +22,7 @@ import org.junit.Assert;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.core.common.exception.SentryThriftAPIMismatchException;
-import org.apache.sentry.provider.db.service.thrift.PolicyStoreConstants.PolicyStoreServerConfig;
+import org.apache.sentry.core.common.utils.PolicyStoreConstants.PolicyStoreServerConfig;
 import org.apache.sentry.service.thrift.ServiceConstants;
 import org.junit.Before;
 import org.junit.Test;

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/TestPoolClientInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/TestPoolClientInvocationHandler.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/TestPoolClientInvocationHandler.java
index 7292387..a202775 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/TestPoolClientInvocationHandler.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/service/thrift/TestPoolClientInvocationHandler.java
@@ -19,7 +19,7 @@
 package org.apache.sentry.service.thrift;
 
 import com.google.common.net.HostAndPort;
-import org.apache.sentry.provider.db.service.thrift.ThriftUtil;
+import org.apache.sentry.core.common.utils.ThriftUtil;
 import org.junit.Assert;
 import org.junit.Test;
 import org.slf4j.Logger;


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

Posted by ak...@apache.org.
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
-  }
-}


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

Posted by ak...@apache.org.
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/SentryPolicyServiceClientDefaultImpl.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
index 4284b53..d1a4d99 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
@@ -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.
@@ -19,29 +19,18 @@
 package org.apache.sentry.provider.db.service.thrift;
 
 import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Collections;
 
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.Sasl;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.net.HostAndPort;
 import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.net.NetUtils;
-import org.apache.hadoop.security.SaslRpcServer;
-import org.apache.hadoop.security.SecurityUtil;
-import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.sentry.core.common.exception.MissingConfigurationException;
+
 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.SentryTransportFactory;
 import org.apache.sentry.core.model.db.AccessConstants;
 import org.apache.sentry.core.model.db.DBModelAuthorizable;
 import org.apache.sentry.core.common.utils.PolicyFileConstants;
@@ -53,228 +42,81 @@ import org.apache.sentry.service.thrift.Status;
 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.apache.sentry.core.common.transport.SentryServiceClient;
 import org.apache.sentry.core.common.transport.SentryPolicyClientTransportConfig;
+import org.apache.thrift.transport.TTransport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
-/*
- 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 recreate the client, which uses a new socket.
+/**
+ * Sentry Policy Service Client
+ * <p>
+ * The public implementation of SentryPolicyServiceClient.
+ * 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.
+ * When an class is instantiated, there will be transportFactory created connecting with first available
+ * server this is configured.
  */
-public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyServiceClient {
+public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyServiceClient, SentryServiceClient {
 
-  private final Configuration conf;
-  private final boolean kerberos;
-  private String[] serverPrincipalParts;
   private SentryPolicyService.Client client;
+  private SentryTransportFactory transportFactory;
   private TTransport transport;
-  private int connectionTimeout;
+  private Configuration conf;
+
   private static final Logger LOGGER = LoggerFactory
-                                       .getLogger(SentryPolicyServiceClient.class);
+    .getLogger(SentryPolicyServiceClient.class);
   private static final String THRIFT_EXCEPTION_MESSAGE = "Thrift exception occurred ";
-  // configs for connection retry
-  private int connectionFullRetryTotal;
-  private List<InetSocketAddress> endpoints;
-  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)
-        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 synchronized 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();
-    }
-  }
 
   /**
    * Initialize the sentry configurations.
    */
-  public SentryPolicyServiceClientDefaultImpl(Configuration conf)
+  public SentryPolicyServiceClientDefaultImpl(Configuration conf, SentryPolicyClientTransportConfig transportConfig)
     throws IOException {
+    transportFactory = new SentryTransportFactory(conf, transportConfig);
     this.conf = conf;
-    Preconditions.checkNotNull(this.conf, "Configuration object cannot be null");
-    try {
-      String hostsAndPortsStr;
-      this.connectionTimeout = transportConfig.getServerRpcConnTimeoutInMs(conf);
-      this.connectionFullRetryTotal = transportConfig.getSentryFullRetryTotal(conf);
-
-      this.kerberos = transportConfig.isKerberosEnabled(conf);
-      hostsAndPortsStr = transportConfig.getSentryServerRpcAddress(conf);
-
-      int serverPort = transportConfig.getServerRpcPort(conf);
-
-      String[] hostsAndPortsStrArr = hostsAndPortsStr.split(",");
-      HostAndPort[] hostsAndPorts = ThriftUtil.parseHostPortStrings(hostsAndPortsStrArr, serverPort);
-      this.endpoints = new ArrayList(hostsAndPortsStrArr.length);
-      for (int i = hostsAndPortsStrArr.length - 1; i >= 0; i--) {
-        this.endpoints.add(
-          new InetSocketAddress(hostsAndPorts[i].getHostText(), hostsAndPorts[i].getPort()));
-        LOGGER.debug("Added server endpoint: " + hostsAndPorts[i].toString());
-      }
-    } catch (MissingConfigurationException e) {
-      throw new RuntimeException("Client Creation Failed: " + e.getMessage(), e);
-    }
   }
 
   public SentryPolicyServiceClientDefaultImpl(String addr, int port,
                                               Configuration conf) throws IOException {
+    transportFactory = new SentryTransportFactory(addr, port, conf,
+      new SentryPolicyClientTransportConfig());
     this.conf = conf;
-    Preconditions.checkNotNull(this.conf, "Configuration object cannot be null");
-    try {
-      InetSocketAddress serverAddress = NetUtils.createSocketAddr(addr, port);
-      this.connectionTimeout = transportConfig.getServerRpcConnTimeoutInMs(conf);
-      this.kerberos = transportConfig.isKerberosEnabled(conf);
-      connect(serverAddress);
-    } catch (MissingConfigurationException e) {
-      throw new RuntimeException("Client Creation Failed: " + e.getMessage(), e);
-    }
-
+    connect();
   }
 
   /**
-   * This is a no-op when already connected.
-   * When there is a connection error, it will retry with another sentry server. It will
-   * first cycle through all the available sentry servers, and then retry the whole server
-   * list no more than connectionFullRetryTotal times. In this case, it won't introduce
-   * more latency when some server fails. Also to prevent all clients connecting to the
-   * same server, it will reorder the endpoints randomly after a full retry.
-   * <p>
-   * TODO: Have a small random sleep after a full retry to prevent all clients connecting to the same server.
-   * <p>
-   * TODO: Add metrics for the number of successful connects and errors per client, and total number of retries.
-   * @throws Exception if client fails to connect to all servers for a configured
-   * number of times
+   * Connect to the sentry server
+   *
+   * @throws IOException
    */
-  public synchronized void connectWithRetry() throws Exception {
-    if (isConnected()) {
+  @Override
+  public synchronized void connect() throws IOException {
+    if (transport != null && transport.isOpen()) {
       return;
     }
-    Exception currentException = null;
-    // Here for each full connectWithRetry it will cycle through all available sentry
-    // servers. Before each full connectWithRetry, it will shuffle the server list.
-    for (int retryCount = 0; retryCount < connectionFullRetryTotal; retryCount++) {
-      // Reorder endpoints randomly to prevent all clients connecting to the same endpoint
-      // at the same time after a node failure.
-      Collections.shuffle(endpoints);
-      for (InetSocketAddress addr : endpoints) {
-        try {
-          connect(addr);
-          LOGGER.info(String.format("Connected to SentryServer: %s", addr.toString()));
-          return;
-        } catch (Exception e) {
-          LOGGER.debug(String.format("Failed connection to %s: %s",
-              addr.toString(), e.getMessage()), e);
-          currentException = e;
-        }
-      }
-    }
-
-    // Throw exception as reaching the max full connectWithRetry number.
-    LOGGER.error(
-        String.format("Reach the max connection retry num %d ", connectionFullRetryTotal),
-        currentException);
-    throw currentException;
-  }
-
-  /**
-   * Connect to the specified socket address and throw Exception if failed.
-   */
-  private void connect(InetSocketAddress serverAddress) throws IOException {
-    transport = new TSocket(serverAddress.getHostName(),
-        serverAddress.getPort(), connectionTimeout);
-    try {
-      if (kerberos) {
-        String serverPrincipal = transportConfig.getSentryPrincipal(conf);
-
-        // 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 SentryPolicyServiceClientDefaultImpl.UgiSaslClientTransport(
-          SaslRpcServer.AuthMethod.KERBEROS.getMechanismName(),
-          null, serverPrincipalParts[0], serverPrincipalParts[1],
-          SASL_PROPERTIES, null, transport, wrapUgi);
-      } else {
-        serverPrincipalParts = null;
-      }
-
-      transport.open();
-    } catch (TTransportException e) {
-      throw new IOException("Transport exception while opening transport: " + e.getMessage(), e);
-    }
 
-    LOGGER.debug("Successfully opened transport: " + transport + " to " + serverAddress);
+    transport = transportFactory.getTransport();
     long maxMessageSize = conf.getLong(
-        ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE,
-        ServiceConstants.ClientConfig.SENTRY_POLICY_CLIENT_THRIFT_MAX_MESSAGE_SIZE_DEFAULT);
+      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),
-        SentryPolicyStoreProcessor.SENTRY_POLICY_SERVICE_NAME);
+      new TBinaryProtocol(transport, maxMessageSize, maxMessageSize, true, true),
+      SentryPolicyStoreProcessor.SENTRY_POLICY_SERVICE_NAME);
     client = new SentryPolicyService.Client(protocol);
     LOGGER.debug("Successfully created client");
   }
 
+  @Override
   public synchronized void createRole(String requestorUserName, String roleName)
-  throws SentryUserException {
+    throws SentryUserException {
     TCreateSentryRoleRequest request = new TCreateSentryRoleRequest();
     request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
     request.setRequestorUserName(requestorUserName);
@@ -287,21 +129,23 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
   }
 
+  @Override
   public synchronized void dropRole(String requestorUserName,
-      String roleName)
-  throws SentryUserException {
+                                    String roleName)
+    throws SentryUserException {
     dropRole(requestorUserName, roleName, false);
   }
 
+  @Override
   public synchronized void dropRoleIfExists(String requestorUserName,
-      String roleName)
-  throws SentryUserException {
+                                            String roleName)
+    throws SentryUserException {
     dropRole(requestorUserName, roleName, true);
   }
 
   private synchronized void dropRole(String requestorUserName,
-      String roleName, boolean ifExists)
-  throws SentryUserException {
+                                     String roleName, boolean ifExists)
+    throws SentryUserException {
     TDropSentryRoleRequest request = new TDropSentryRoleRequest();
     request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
     request.setRequestorUserName(requestorUserName);
@@ -320,15 +164,17 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
 
   /**
    * 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 all groups)
+   * @param groupName         : groupName to look up ( if null returns all roles for all groups)
    * @return Set of thrift sentry role objects
    * @throws SentryUserException
    */
+  @Override
   public synchronized Set<TSentryRole> listRolesByGroupName(
-      String requestorUserName,
-      String groupName)
-  throws SentryUserException {
+    String requestorUserName,
+    String groupName)
+    throws SentryUserException {
     TListSentryRolesRequest request = new TListSentryRolesRequest();
     request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
     request.setRequestorUserName(requestorUserName);
@@ -350,15 +196,14 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
   /**
    * Gets sentry role objects for a given userName using the Sentry service
    *
-   * @param requestorUserName
-   *        : user on whose behalf the request is issued
-   * @param userName
-   *        : userName to look up (can't be empty)
+   * @param requestorUserName : user on whose behalf the request is issued
+   * @param userName          : userName to look up (can't be empty)
    * @return Set of thrift sentry role objects
    * @throws SentryUserException
    */
+  @Override
   public Set<TSentryRole> listRolesByUserName(String requestorUserName, String userName)
-      throws SentryUserException {
+    throws SentryUserException {
     TListSentryRolesForUserRequest request = new TListSentryRolesForUserRequest();
     request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
     request.setRequestorUserName(requestorUserName);
@@ -373,23 +218,26 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
   }
 
+  @Override
   public synchronized Set<TSentryPrivilege> listAllPrivilegesByRoleName(String requestorUserName,
-      String roleName)
-                 throws SentryUserException {
+                                                                        String roleName)
+    throws SentryUserException {
     return listPrivilegesByRoleName(requestorUserName, roleName, null);
   }
 
   /**
    * Gets sentry privilege objects for a given roleName using the Sentry service
+   *
    * @param requestorUserName : user on whose behalf the request is issued
-   * @param roleName : roleName to look up
-   * @param authorizable : authorizable Hierarchy (server->db->table etc)
+   * @param roleName          : roleName to look up
+   * @param authorizable      : authorizable Hierarchy (server->db->table etc)
    * @return Set of thrift sentry privilege objects
    * @throws SentryUserException
    */
+  @Override
   public synchronized Set<TSentryPrivilege> listPrivilegesByRoleName(String requestorUserName,
-      String roleName, List<? extends Authorizable> authorizable)
-  throws SentryUserException {
+                                                                     String roleName, List<? extends Authorizable> authorizable)
+    throws SentryUserException {
     TListSentryPrivilegesRequest request = new TListSentryPrivilegesRequest();
     request.setProtocol_version(ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT);
     request.setRequestorUserName(requestorUserName);
@@ -408,36 +256,41 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
   }
 
+  @Override
   public synchronized Set<TSentryRole> listRoles(String requestorUserName)
-      throws SentryUserException {
+    throws SentryUserException {
     return listRolesByGroupName(requestorUserName, null);
   }
 
+  @Override
   public synchronized Set<TSentryRole> listUserRoles(String requestorUserName)
-      throws SentryUserException {
+    throws SentryUserException {
     Set<TSentryRole> tSentryRoles = Sets.newHashSet();
     tSentryRoles.addAll(listRolesByGroupName(requestorUserName, AccessConstants.ALL));
     tSentryRoles.addAll(listRolesByUserName(requestorUserName, requestorUserName));
     return tSentryRoles;
   }
 
+  @Override
   public synchronized TSentryPrivilege grantURIPrivilege(String requestorUserName,
-      String roleName, String server, String uri)
-  throws SentryUserException {
+                                                         String roleName, String server, String uri)
+    throws SentryUserException {
     return grantPrivilege(requestorUserName, roleName,
-        PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL);
+      PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL);
   }
 
+  @Override
   public synchronized TSentryPrivilege grantURIPrivilege(String requestorUserName,
-      String roleName, String server, String uri, Boolean grantOption)
-  throws SentryUserException {
+                                                         String roleName, String server, String uri, Boolean grantOption)
+    throws SentryUserException {
     return grantPrivilege(requestorUserName, roleName,
-        PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL, grantOption);
+      PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL, grantOption);
   }
 
+  @Override
   public synchronized void grantServerPrivilege(String requestorUserName,
-      String roleName, String server, String action)
-  throws SentryUserException {
+                                                String roleName, String server, String action)
+    throws SentryUserException {
 
     // "ALL" and "*" should be synonyms for action and need to be unified with grantServerPrivilege without
     // action explicitly specified.
@@ -446,7 +299,7 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
 
     grantPrivilege(requestorUserName, roleName,
-        PrivilegeScope.SERVER, server, null, null, null, null, action);
+      PrivilegeScope.SERVER, server, null, null, null, null, action);
   }
 
   @Deprecated
@@ -455,14 +308,15 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
    *  String roleName, String server, String action, Boolean grantOption)
    */
   public synchronized TSentryPrivilege grantServerPrivilege(String requestorUserName,
-      String roleName, String server, Boolean grantOption) throws SentryUserException {
+                                                            String roleName, String server, Boolean grantOption) throws SentryUserException {
     return grantServerPrivilege(requestorUserName, roleName, server,
-        AccessConstants.ALL, grantOption);
+      AccessConstants.ALL, grantOption);
   }
 
+  @Override
   public synchronized TSentryPrivilege grantServerPrivilege(String requestorUserName,
-      String roleName, String server, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                            String roleName, String server, String action, Boolean grantOption)
+    throws SentryUserException {
 
     // "ALL" and "*" should be synonyms for action and need to be unified with grantServerPrivilege without
     // action explicitly specified.
@@ -471,75 +325,85 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
 
     return grantPrivilege(requestorUserName, roleName,
-        PrivilegeScope.SERVER, server, null, null, null, null, action, grantOption);
+      PrivilegeScope.SERVER, server, null, null, null, null, action, grantOption);
   }
 
+  @Override
   public synchronized TSentryPrivilege grantDatabasePrivilege(String requestorUserName,
-      String roleName, String server, String db, String action)
-  throws SentryUserException {
+                                                              String roleName, String server, String db, String action)
+    throws SentryUserException {
     return grantPrivilege(requestorUserName, roleName,
-        PrivilegeScope.DATABASE, server, null, db, null, null, action);
+      PrivilegeScope.DATABASE, server, null, db, null, null, action);
   }
 
+  @Override
   public synchronized TSentryPrivilege grantDatabasePrivilege(String requestorUserName,
-      String roleName, String server, String db, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                              String roleName, String server, String db, String action, Boolean grantOption)
+    throws SentryUserException {
     return grantPrivilege(requestorUserName, roleName,
-        PrivilegeScope.DATABASE, server, null, db, null, null, action, grantOption);
+      PrivilegeScope.DATABASE, server, null, db, null, null, action, grantOption);
   }
 
+  @Override
   public synchronized TSentryPrivilege grantTablePrivilege(String requestorUserName,
-      String roleName, String server, String db, String table, String action)
-  throws SentryUserException {
+                                                           String roleName, String server, String db, String table, String action)
+    throws SentryUserException {
     return grantPrivilege(requestorUserName, roleName, PrivilegeScope.TABLE, server,
-        null,
-        db, table, null, action);
+      null,
+      db, table, null, action);
   }
 
+  @Override
   public synchronized TSentryPrivilege grantTablePrivilege(String requestorUserName,
-      String roleName, String server, String db, String table, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                           String roleName, String server, String db, String table, String action, Boolean grantOption)
+    throws SentryUserException {
     return grantPrivilege(requestorUserName, roleName, PrivilegeScope.TABLE, server,
-        null, db, table, null, action, grantOption);
+      null, db, table, null, action, grantOption);
   }
 
+  @Override
   public synchronized TSentryPrivilege grantColumnPrivilege(String requestorUserName,
-      String roleName, String server, String db, String table, String columnName, String action)
-  throws SentryUserException {
+                                                            String roleName, String server, String db, String table, String columnName, String action)
+    throws SentryUserException {
     return grantPrivilege(requestorUserName, roleName, PrivilegeScope.COLUMN, server,
-          null,
-          db, table, columnName, action);
+      null,
+      db, table, columnName, action);
   }
 
+  @Override
   public synchronized TSentryPrivilege grantColumnPrivilege(String requestorUserName,
-      String roleName, String server, String db, String table, String columnName, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                            String roleName, String server, String db, String table, String columnName, String action, Boolean grantOption)
+    throws SentryUserException {
     return grantPrivilege(requestorUserName, roleName, PrivilegeScope.COLUMN, server,
-          null, db, table, columnName, action, grantOption);
+      null, db, table, columnName, action, grantOption);
   }
 
+  @Override
   public synchronized Set<TSentryPrivilege> grantColumnsPrivileges(String requestorUserName,
-      String roleName, String server, String db, String table, List<String> columnNames, String action)
-  throws SentryUserException {
+                                                                   String roleName, String server, String db, String table, List<String> columnNames, String action)
+    throws SentryUserException {
     return grantPrivileges(requestorUserName, roleName, PrivilegeScope.COLUMN, server,
-            null,
-            db, table, columnNames, action);
+      null,
+      db, table, columnNames, action);
   }
 
+  @Override
   public synchronized Set<TSentryPrivilege> grantColumnsPrivileges(String requestorUserName,
-      String roleName, String server, String db, String table, List<String> columnNames, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                                   String roleName, String server, String db, String table, List<String> columnNames, String action, Boolean grantOption)
+    throws SentryUserException {
     return grantPrivileges(requestorUserName, roleName, PrivilegeScope.COLUMN,
-        server,
-        null, db, table, columnNames, action, grantOption);
+      server,
+      null, db, table, columnNames, action, grantOption);
   }
 
+  @Override
   public synchronized Set<TSentryPrivilege> grantPrivileges(
-      String requestorUserName, String roleName,
-      Set<TSentryPrivilege> privileges) throws SentryUserException {
+    String requestorUserName, String roleName,
+    Set<TSentryPrivilege> privileges) throws SentryUserException {
     return grantPrivilegesCore(requestorUserName, roleName, privileges);
   }
 
+  @Override
   public synchronized TSentryPrivilege grantPrivilege(String requestorUserName, String roleName,
                                                       TSentryPrivilege privilege) throws SentryUserException {
     return grantPrivilegeCore(requestorUserName, roleName, privilege);
@@ -548,7 +412,7 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
   private TSentryPrivilege grantPrivilegeCore(String requestorUserName, String roleName,
                                               TSentryPrivilege privilege) throws SentryUserException {
     Set<TSentryPrivilege> results =
-        grantPrivilegesCore(requestorUserName, roleName, ImmutableSet.of(privilege));
+      grantPrivilegesCore(requestorUserName, roleName, ImmutableSet.of(privilege));
     if (results != null && results.size() > 0) {
       return results.iterator().next();
     } else {
@@ -565,7 +429,7 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     request.setPrivileges(privileges);
     try {
       TAlterSentryRoleGrantPrivilegeResponse response =
-          client.alter_sentry_role_grant_privilege(request);
+        client.alter_sentry_role_grant_privilege(request);
       Status.throwIfNotOk(response.getStatus());
       return response.getPrivileges();
     } catch (TException e) {
@@ -575,24 +439,24 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
 
   @VisibleForTesting
   public static TSentryAuthorizable setupSentryAuthorizable(
-      List<? extends Authorizable> authorizable) {
+    List<? extends Authorizable> authorizable) {
     TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
 
     for (Authorizable authzble : authorizable) {
       if (authzble.getTypeName().equalsIgnoreCase(
-          DBModelAuthorizable.AuthorizableType.Server.toString())) {
+        DBModelAuthorizable.AuthorizableType.Server.toString())) {
         tSentryAuthorizable.setServer(authzble.getName());
       } else if (authzble.getTypeName().equalsIgnoreCase(
-          DBModelAuthorizable.AuthorizableType.URI.toString())) {
+        DBModelAuthorizable.AuthorizableType.URI.toString())) {
         tSentryAuthorizable.setUri(authzble.getName());
       } else if (authzble.getTypeName().equalsIgnoreCase(
-          DBModelAuthorizable.AuthorizableType.Db.toString())) {
+        DBModelAuthorizable.AuthorizableType.Db.toString())) {
         tSentryAuthorizable.setDb(authzble.getName());
       } else if (authzble.getTypeName().equalsIgnoreCase(
-          DBModelAuthorizable.AuthorizableType.Table.toString())) {
+        DBModelAuthorizable.AuthorizableType.Table.toString())) {
         tSentryAuthorizable.setTable(authzble.getName());
       } else if (authzble.getTypeName().equalsIgnoreCase(
-          DBModelAuthorizable.AuthorizableType.Column.toString())) {
+        DBModelAuthorizable.AuthorizableType.Column.toString())) {
         tSentryAuthorizable.setColumn(authzble.getName());
       }
     }
@@ -600,44 +464,48 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
   }
 
   private TSentryPrivilege grantPrivilege(String requestorUserName,
-      String roleName,
-      PrivilegeScope scope, String serverName, String uri, String db,
-      String table, String column, String action)  throws SentryUserException {
+                                          String roleName,
+                                          PrivilegeScope scope, String serverName, String uri, String db,
+                                          String table, String column, String action) throws SentryUserException {
     return grantPrivilege(requestorUserName, roleName, scope, serverName, uri,
-    db, table, column, action, false);
+      db, table, column, action, false);
   }
 
   private TSentryPrivilege grantPrivilege(String requestorUserName,
-      String roleName, PrivilegeScope scope, String serverName, String uri, String db, String table,
-      String column, String action, Boolean grantOption)
-  throws SentryUserException {
+
+                                          String roleName, PrivilegeScope scope, String serverName, String uri, String db, String table,
+                                          String column, String action, Boolean grantOption)
+    throws SentryUserException {
     TSentryPrivilege privilege =
-        convertToTSentryPrivilege(scope, serverName, uri, db, table, column, action, grantOption);
+      convertToTSentryPrivilege(scope, serverName, uri, db, table, column, action, grantOption);
     return grantPrivilegeCore(requestorUserName, roleName, privilege);
   }
 
   private Set<TSentryPrivilege> grantPrivileges(String requestorUserName,
-      String roleName,
-      PrivilegeScope scope, String serverName, String uri, String db,
-      String table, List<String> columns, String action)  throws SentryUserException {
+                                                String roleName,
+                                                PrivilegeScope scope, String serverName, String uri, String db,
+                                                String table, List<String> columns, String action) throws SentryUserException {
     return grantPrivileges(requestorUserName, roleName, scope, serverName, uri,
-    db, table, columns, action, false);
+      db, table, columns, action, false);
   }
 
   private Set<TSentryPrivilege> grantPrivileges(String requestorUserName,
-      String roleName, PrivilegeScope scope, String serverName, String uri, String db, String table,
-      List<String> columns, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                String roleName, PrivilegeScope scope, String serverName, String uri, String db, String
+                                                  table,
+                                                List<String> columns, String action, Boolean grantOption)
+    throws SentryUserException {
     Set<TSentryPrivilege> privileges = convertColumnPrivileges(scope,
-        serverName, uri, db, table, columns, action, grantOption);
+      serverName, uri, db, table, columns, action, grantOption);
     return grantPrivilegesCore(requestorUserName, roleName, privileges);
   }
 
-  public synchronized void revokePrivileges(String requestorUserName, String roleName, Set<TSentryPrivilege> privileges) throws  SentryUserException {
+  @Override
+  public synchronized void revokePrivileges(String requestorUserName, String roleName, Set<TSentryPrivilege> privileges) throws SentryUserException {
     this.revokePrivilegesCore(requestorUserName, roleName, privileges);
   }
 
-  public synchronized void revokePrivilege(String requestorUserName, String roleName, TSentryPrivilege privilege) throws  SentryUserException {
+  @Override
+  public synchronized void revokePrivilege(String requestorUserName, String roleName, TSentryPrivilege privilege) throws SentryUserException {
     this.revokePrivilegeCore(requestorUserName, roleName, privilege);
 
   }
@@ -654,30 +522,33 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     request.setPrivileges(privileges);
     try {
       TAlterSentryRoleRevokePrivilegeResponse response = client.alter_sentry_role_revoke_privilege(
-          request);
+        request);
       Status.throwIfNotOk(response.getStatus());
     } catch (TException e) {
       throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
     }
   }
 
+  @Override
   public synchronized void revokeURIPrivilege(String requestorUserName,
-      String roleName, String server, String uri)
-  throws SentryUserException {
+                                              String roleName, String server, String uri)
+    throws SentryUserException {
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL);
+      PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL);
   }
 
+  @Override
   public synchronized void revokeURIPrivilege(String requestorUserName,
-      String roleName, String server, String uri, Boolean grantOption)
-  throws SentryUserException {
+                                              String roleName, String server, String uri, Boolean grantOption)
+    throws SentryUserException {
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL, grantOption);
+      PrivilegeScope.URI, server, uri, null, null, null, AccessConstants.ALL, grantOption);
   }
 
+  @Override
   public synchronized void revokeServerPrivilege(String requestorUserName,
-      String roleName, String server, String action)
-  throws SentryUserException {
+                                                 String roleName, String server, String action)
+    throws SentryUserException {
 
     // "ALL" and "*" should be synonyms for action and need to be unified with revokeServerPrivilege without
     // action explicitly specified.
@@ -686,12 +557,12 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
 
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.SERVER, server, null, null, null, null, action);
+      PrivilegeScope.SERVER, server, null, null, null, null, action);
   }
 
   public synchronized void revokeServerPrivilege(String requestorUserName,
-      String roleName, String server, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                 String roleName, String server, String action, Boolean grantOption)
+    throws SentryUserException {
 
     // "ALL" and "*" should be synonyms for action and need to be unified with revokeServerPrivilege without
     // action explicitly specified.
@@ -700,7 +571,7 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
 
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.SERVER, server, null, null, null, null, action, grantOption);
+      PrivilegeScope.SERVER, server, null, null, null, null, action, grantOption);
   }
 
   @Deprecated
@@ -708,98 +579,108 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
    * Should use revokeServerPrivilege(String requestorUserName,
    *  String roleName, String server, String action, Boolean grantOption)
    */
+  @Override
   public synchronized void revokeServerPrivilege(String requestorUserName,
-      String roleName, String server, boolean grantOption)
-  throws SentryUserException {
+                                                 String roleName, String server, boolean grantOption)
+    throws SentryUserException {
     revokePrivilege(requestorUserName, roleName,
       PrivilegeScope.SERVER, server, null, null, null, null, AccessConstants.ALL, grantOption);
   }
 
+  @Override
   public synchronized void revokeDatabasePrivilege(String requestorUserName,
-      String roleName, String server, String db, String action)
-  throws SentryUserException {
+                                                   String roleName, String server, String db, String action)
+    throws SentryUserException {
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.DATABASE, server, null, db, null, null, action);
+      PrivilegeScope.DATABASE, server, null, db, null, null, action);
   }
 
+  @Override
   public synchronized void revokeDatabasePrivilege(String requestorUserName,
-      String roleName, String server, String db, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                   String roleName, String server, String db, String action, Boolean grantOption)
+    throws SentryUserException {
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.DATABASE, server, null, db, null, null, action, grantOption);
+      PrivilegeScope.DATABASE, server, null, db, null, null, action, grantOption);
   }
 
+  @Override
   public synchronized void revokeTablePrivilege(String requestorUserName,
-      String roleName, String server, String db, String table, String action)
-  throws SentryUserException {
+                                                String roleName, String server, String db, String table, String action)
+    throws SentryUserException {
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.TABLE, server, null,
-        db, table, null, action);
+      PrivilegeScope.TABLE, server, null,
+      db, table, null, action);
   }
 
+  @Override
   public synchronized void revokeTablePrivilege(String requestorUserName,
-      String roleName, String server, String db, String table, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                String roleName, String server, String db, String table, String action, Boolean grantOption)
+    throws SentryUserException {
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.TABLE, server, null,
-        db, table, null, action, grantOption);
+      PrivilegeScope.TABLE, server, null,
+      db, table, null, action, grantOption);
   }
 
+  @Override
   public synchronized void revokeColumnPrivilege(String requestorUserName, String roleName,
-      String server, String db, String table, String columnName, String action)
-  throws SentryUserException {
+                                                 String server, String db, String table, String columnName, String action)
+    throws SentryUserException {
     ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
     listBuilder.add(columnName);
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.COLUMN, server, null,
-        db, table, listBuilder.build(), action);
+      PrivilegeScope.COLUMN, server, null,
+      db, table, listBuilder.build(), action);
   }
 
+  @Override
   public synchronized void revokeColumnPrivilege(String requestorUserName, String roleName,
-      String server, String db, String table, String columnName, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                 String server, String db, String table, String columnName, String action, Boolean grantOption)
+    throws SentryUserException {
     ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
     listBuilder.add(columnName);
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.COLUMN, server, null,
-        db, table, listBuilder.build(), action, grantOption);
+      PrivilegeScope.COLUMN, server, null,
+      db, table, listBuilder.build(), action, grantOption);
   }
 
+  @Override
   public synchronized void revokeColumnsPrivilege(String requestorUserName, String roleName,
-      String server, String db, String table, List<String> columns, String action)
-  throws SentryUserException {
+                                                  String server, String db, String table, List<String> columns, String action)
+    throws SentryUserException {
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.COLUMN, server, null,
-        db, table, columns, action);
+      PrivilegeScope.COLUMN, server, null,
+      db, table, columns, action);
   }
 
+  @Override
   public synchronized void revokeColumnsPrivilege(String requestorUserName, String roleName,
-      String server, String db, String table, List<String> columns, String action, Boolean grantOption)
-  throws SentryUserException {
+                                                  String server, String db, String table, List<String> columns, String action, Boolean grantOption)
+    throws SentryUserException {
     revokePrivilege(requestorUserName, roleName,
-        PrivilegeScope.COLUMN, server, null,
-        db, table, columns, action, grantOption);
+      PrivilegeScope.COLUMN, server, null,
+      db, table, columns, action, grantOption);
   }
 
   private void revokePrivilege(String requestorUserName,
-      String roleName, PrivilegeScope scope, String serverName, String uri,
-      String db, String table, List<String> columns, String action)
-  throws SentryUserException {
+                               String roleName, PrivilegeScope scope, String serverName, String uri,
+                               String db, String table, List<String> columns, String action)
+    throws SentryUserException {
     this.revokePrivilege(requestorUserName, roleName, scope, serverName, uri, db, table, columns, action, false);
   }
 
   private void revokePrivilege(String requestorUserName, String roleName,
-      PrivilegeScope scope, String serverName, String uri, String db, String table, List<String> columns,
-      String action, Boolean grantOption)
-  throws SentryUserException {
+                               PrivilegeScope scope, String serverName, String uri, String db, String table, List<String> columns,
+                               String action, Boolean grantOption)
+    throws SentryUserException {
     Set<TSentryPrivilege> privileges = convertColumnPrivileges(scope,
-        serverName, uri, db, table, columns, action, grantOption);
+      serverName, uri, db, table, columns, action, grantOption);
     this.revokePrivilegesCore(requestorUserName, roleName, privileges);
   }
 
   private Set<TSentryPrivilege> convertColumnPrivileges(
-      PrivilegeScope scope, String serverName, String uri, String db, String table, List<String> columns,
-      String action, Boolean grantOption) {
+    PrivilegeScope scope, String serverName, String uri, String db, String
+    table, List<String> columns,
+    String action, Boolean grantOption) {
     ImmutableSet.Builder<TSentryPrivilege> setBuilder = ImmutableSet.builder();
     if (columns == null || columns.isEmpty()) {
       TSentryPrivilege privilege = new TSentryPrivilege();
@@ -832,8 +713,9 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
   }
 
   private TSentryPrivilege convertToTSentryPrivilege(
-      PrivilegeScope scope, String serverName, String uri, String db, String table, String column,
-      String action, Boolean grantOption) {
+    PrivilegeScope scope, String serverName, String uri, String db, String table, String
+    column,
+    String action, Boolean grantOption) {
     TSentryPrivilege privilege = new TSentryPrivilege();
     privilege.setPrivilegeScope(scope.toString());
     privilege.setServerName(serverName);
@@ -858,15 +740,17 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     return TSentryGrantOption.FALSE;
   }
 
-  public synchronized Set<String> listPrivilegesForProvider(Set<String> groups, Set<String> users,
-      ActiveRoleSet roleSet, Authorizable... authorizable) throws SentryUserException {
+  @Override
+  public synchronized Set<String> listPrivilegesForProvider
+    (Set<String> groups, Set<String> users,
+     ActiveRoleSet roleSet, Authorizable... authorizable) throws SentryUserException {
     TSentryActiveRoleSet thriftRoleSet = new TSentryActiveRoleSet(roleSet.isAll(), roleSet.getRoles());
     TListSentryPrivilegesForProviderRequest request =
-        new TListSentryPrivilegesForProviderRequest(ThriftConstants.
-            TSENTRY_SERVICE_VERSION_CURRENT, groups, thriftRoleSet);
+      new TListSentryPrivilegesForProviderRequest(ThriftConstants.
+        TSENTRY_SERVICE_VERSION_CURRENT, groups, thriftRoleSet);
     if (authorizable != null && authorizable.length > 0) {
       TSentryAuthorizable tSentryAuthorizable = setupSentryAuthorizable(Lists
-          .newArrayList(authorizable));
+        .newArrayList(authorizable));
       request.setAuthorizableHierarchy(tSentryAuthorizable);
     }
     if (users != null) {
@@ -883,25 +767,25 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
 
   @Override
   public synchronized void grantRoleToGroup(String requestorUserName,
-      String groupName, String roleName)
-  throws SentryUserException {
+                                            String groupName, String roleName)
+    throws SentryUserException {
     grantRoleToGroups(requestorUserName, roleName, Sets.newHashSet(groupName));
   }
 
   @Override
   public synchronized void revokeRoleFromGroup(String requestorUserName,
-      String groupName, String roleName)
-  throws SentryUserException {
+                                               String groupName, String roleName)
+    throws SentryUserException {
     revokeRoleFromGroups(requestorUserName, roleName, Sets.newHashSet(groupName));
   }
 
   @Override
   public synchronized void grantRoleToGroups(String requestorUserName,
-      String roleName, Set<String> groups)
-  throws SentryUserException {
+                                             String roleName, Set<String> groups)
+    throws SentryUserException {
     TAlterSentryRoleAddGroupsRequest request = new TAlterSentryRoleAddGroupsRequest(
-        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
-        roleName, convert2TGroups(groups));
+      ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
+      roleName, convert2TGroups(groups));
     try {
       TAlterSentryRoleAddGroupsResponse response = client.alter_sentry_role_add_groups(request);
       Status.throwIfNotOk(response.getStatus());
@@ -912,11 +796,11 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
 
   @Override
   public synchronized void revokeRoleFromGroups(String requestorUserName,
-      String roleName, Set<String> groups)
-  throws SentryUserException {
+                                                String roleName, Set<String> groups)
+    throws SentryUserException {
     TAlterSentryRoleDeleteGroupsRequest request = new TAlterSentryRoleDeleteGroupsRequest(
-        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
-        roleName, convert2TGroups(groups));
+      ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
+      roleName, convert2TGroups(groups));
     try {
       TAlterSentryRoleDeleteGroupsResponse response = client.alter_sentry_role_delete_groups(request);
       Status.throwIfNotOk(response.getStatus());
@@ -927,21 +811,21 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
 
   @Override
   public synchronized void grantRoleToUser(String requestorUserName, String userName,
-      String roleName) throws SentryUserException {
+                                           String roleName) throws SentryUserException {
     grantRoleToUsers(requestorUserName, roleName, Sets.newHashSet(userName));
   }
 
   @Override
   public synchronized void revokeRoleFromUser(String requestorUserName, String userName,
-      String roleName) throws SentryUserException {
+                                              String roleName) throws SentryUserException {
     revokeRoleFromUsers(requestorUserName, roleName, Sets.newHashSet(userName));
   }
 
   @Override
   public synchronized void grantRoleToUsers(String requestorUserName, String roleName,
-      Set<String> users) throws SentryUserException {
+                                            Set<String> users) throws SentryUserException {
     TAlterSentryRoleAddUsersRequest request = new TAlterSentryRoleAddUsersRequest(
-        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, roleName, users);
+      ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, roleName, users);
     try {
       TAlterSentryRoleAddUsersResponse response = client.alter_sentry_role_add_users(request);
       Status.throwIfNotOk(response.getStatus());
@@ -952,9 +836,9 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
 
   @Override
   public synchronized void revokeRoleFromUsers(String requestorUserName, String roleName,
-      Set<String> users) throws SentryUserException {
+                                               Set<String> users) throws SentryUserException {
     TAlterSentryRoleDeleteUsersRequest request = new TAlterSentryRoleDeleteUsersRequest(
-        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, roleName, users);
+      ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, roleName, users);
     try {
       TAlterSentryRoleDeleteUsersResponse response = client.alter_sentry_role_delete_users(request);
       Status.throwIfNotOk(response.getStatus());
@@ -973,14 +857,15 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     return tGroups;
   }
 
+  @Override
   public synchronized void dropPrivileges(String requestorUserName,
-      List<? extends Authorizable> authorizableObjects)
-      throws SentryUserException {
+                                          List<? extends Authorizable> authorizableObjects)
+    throws SentryUserException {
     TSentryAuthorizable tSentryAuthorizable = setupSentryAuthorizable(authorizableObjects);
 
     TDropPrivilegesRequest request = new TDropPrivilegesRequest(
-        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
-        tSentryAuthorizable);
+      ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
+      tSentryAuthorizable);
     try {
       TDropPrivilegesResponse response = client.drop_sentry_privilege(request);
       Status.throwIfNotOk(response.getStatus());
@@ -989,25 +874,28 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
   }
 
+  @Override
   public synchronized void renamePrivileges(String requestorUserName,
-      List<? extends Authorizable> oldAuthorizables,
-      List<? extends Authorizable> newAuthorizables) throws SentryUserException {
+                                            List<? extends Authorizable> oldAuthorizables,
+                                            List<? extends Authorizable> newAuthorizables) throws SentryUserException {
     TSentryAuthorizable tOldSentryAuthorizable = setupSentryAuthorizable(oldAuthorizables);
     TSentryAuthorizable tNewSentryAuthorizable = setupSentryAuthorizable(newAuthorizables);
 
     TRenamePrivilegesRequest request = new TRenamePrivilegesRequest(
-        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
-        tOldSentryAuthorizable, tNewSentryAuthorizable);
+      ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
+      tOldSentryAuthorizable, tNewSentryAuthorizable);
     try {
       TRenamePrivilegesResponse response = client
-          .rename_sentry_privilege(request);
+        .rename_sentry_privilege(request);
       Status.throwIfNotOk(response.getStatus());
     } catch (TException e) {
       throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
     }
   }
 
-  public synchronized Map<TSentryAuthorizable, TSentryPrivilegeMap> listPrivilegsbyAuthorizable(
+  @Override
+  public synchronized Map<TSentryAuthorizable, TSentryPrivilegeMap> listPrivilegsbyAuthorizable
+    (
       String requestorUserName,
       Set<List<? extends Authorizable>> authorizables, Set<String> groups,
       ActiveRoleSet roleSet) throws SentryUserException {
@@ -1017,8 +905,8 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
       authSet.add(setupSentryAuthorizable(authorizableHierarchy));
     }
     TListSentryPrivilegesByAuthRequest request = new TListSentryPrivilegesByAuthRequest(
-        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
-        authSet);
+      ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName,
+      authSet);
     if (groups != null) {
       request.setGroups(groups);
     }
@@ -1028,7 +916,7 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
 
     try {
       TListSentryPrivilegesByAuthResponse response = client
-          .list_sentry_privileges_by_authorizable(request);
+        .list_sentry_privileges_by_authorizable(request);
       Status.throwIfNotOk(response.getStatus());
       return response.getPrivilegesMapByAuth();
     } catch (TException e) {
@@ -1041,15 +929,18 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
    * propertyName, or if propertyName does not exist, the defaultValue.
    * There is no "requestorUserName" because this is regarded as an
    * internal interface.
+   *
    * @param propertyName Config attribute to search for
    * @param defaultValue String to return if not found
    * @return The value of the propertyName
    * @throws SentryUserException
    */
+
+  @Override
   public synchronized String getConfigValue(String propertyName, String defaultValue)
-          throws SentryUserException {
+    throws SentryUserException {
     TSentryConfigValueRequest request = new TSentryConfigValueRequest(
-            ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, propertyName);
+      ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, propertyName);
     if (defaultValue != null) {
       request.setDefaultValue(defaultValue);
     }
@@ -1062,44 +953,34 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
   }
 
-  public synchronized void close() {
-    if (isConnected()) {
-      transport.close();
-    }
-  }
-
-  private boolean isConnected() {
-    return transport != null && transport.isOpen();
-  }
-
   /**
    * Import the sentry mapping data, convert the mapping data from map structure to
    * TSentryMappingData, and call the import API.
-   * 
-   * @param policyFileMappingData
-   *        Include 2 maps to save the mapping data, the following is the example of the data
-   *        structure:
-   *        for the following mapping data:
-   *        group1=role1,role2
-   *        group2=role2,role3
-   *        role1=server=server1->db=db1
-   *        role2=server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2
-   *        role3=server=server1->url=hdfs://localhost/path
-   * 
-   *        The policyFileMappingData will be inputed as:
-   *        {
-   *          groups={[group1={role1, role2}], group2=[role2, role3]},
-   *          roles={role1=[server=server1->db=db1],
-   *                 role2=[server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2],
-   *                 role3=[server=server1->url=hdfs://localhost/path]
-   *                }
-   *        }
-   * @param requestorUserName
-   *        The name of the request user
+   *
+   * @param policyFileMappingData Include 2 maps to save the mapping data, the following is the example of the data
+   *                              structure:
+   *                              for the following mapping data:
+   *                              group1=role1,role2
+   *                              group2=role2,role3
+   *                              role1=server=server1->db=db1
+   *                              role2=server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2
+   *                              role3=server=server1->url=hdfs://localhost/path
+   *                              <p>
+   *                              The policyFileMappingData will be inputed as:
+   *                              {
+   *                              groups={[group1={role1, role2}], group2=[role2, role3]},
+   *                              roles={role1=[server=server1->db=db1],
+   *                              role2=[server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2],
+   *                              role3=[server=server1->url=hdfs://localhost/path]
+   *                              }
+   *                              }
+   * @param requestorUserName     The name of the request user
    */
-  public synchronized void importPolicy(Map<String, Map<String, Set<String>>> policyFileMappingData,
-      String requestorUserName, boolean isOverwriteRole)
-      throws SentryUserException {
+  @Override
+  public synchronized void importPolicy
+  (Map<String, Map<String, Set<String>>> policyFileMappingData,
+   String requestorUserName, boolean isOverwriteRole)
+    throws SentryUserException {
     try {
       TSentryMappingData tSentryMappingData = new TSentryMappingData();
       // convert the mapping data for [group,role] from map structure to
@@ -1109,11 +990,11 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
       // convert the mapping data for [role,privilege] from map structure to
       // TSentryMappingData.RolePrivilegesMap
       tSentryMappingData
-          .setRolePrivilegesMap(convertRolePrivilegesMapForSentryDB(policyFileMappingData
-              .get(PolicyFileConstants.ROLES)));
+        .setRolePrivilegesMap(convertRolePrivilegesMapForSentryDB(policyFileMappingData
+          .get(PolicyFileConstants.ROLES)));
       TSentryImportMappingDataRequest request = new TSentryImportMappingDataRequest(
-          ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, isOverwriteRole,
-          tSentryMappingData);
+        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, isOverwriteRole,
+        tSentryMappingData);
       TSentryImportMappingDataResponse response = client.import_sentry_mapping_data(request);
       Status.throwIfNotOk(response.getStatus());
     } catch (TException e) {
@@ -1124,7 +1005,7 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
   // convert the mapping data for [role,privilege] from map structure to
   // TSentryMappingData.RolePrivilegesMap
   private Map<String, Set<TSentryPrivilege>> convertRolePrivilegesMapForSentryDB(
-      Map<String, Set<String>> rolePrivilegesMap) {
+    Map<String, Set<String>> rolePrivilegesMap) {
     Map<String, Set<TSentryPrivilege>> rolePrivilegesMapResult = Maps.newHashMap();
     if (rolePrivilegesMap != null) {
       for (Map.Entry<String, Set<String>> entry : rolePrivilegesMap.entrySet()) {
@@ -1140,10 +1021,12 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
   }
 
   // export the sentry mapping data with map structure
-  public synchronized Map<String, Map<String, Set<String>>> exportPolicy(String requestorUserName,
-      String objectPath) throws SentryUserException {
+  @Override
+  public synchronized Map<String, Map<String, Set<String>>> exportPolicy(String
+                                                                           requestorUserName,
+                                                                         String objectPath) throws SentryUserException {
     TSentryExportMappingDataRequest request = new TSentryExportMappingDataRequest(
-        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName);
+      ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName);
     request.setObjectPath(objectPath);
     try {
       TSentryExportMappingDataResponse response = client.export_sentry_mapping_data(request);
@@ -1162,7 +1045,7 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
   // convert the mapping data for [roleName,privilege] from TSentryMappingData.RolePrivilegesMap to
   // map structure
   private Map<String, Set<String>> convertRolePrivilegesMapForPolicyFile(
-      Map<String, Set<TSentryPrivilege>> rolePrivilegesMap) {
+    Map<String, Set<TSentryPrivilege>> rolePrivilegesMap) {
     Map<String, Set<String>> rolePrivilegesMapForFile = Maps.newHashMap();
     if (rolePrivilegesMap != null) {
       for (Map.Entry<String, Set<TSentryPrivilege>> entry : rolePrivilegesMap.entrySet()) {
@@ -1180,4 +1063,14 @@ public class SentryPolicyServiceClientDefaultImpl implements SentryPolicyService
     }
     return rolePrivilegesMapForFile;
   }
+
+  @Override
+  public synchronized void close() {
+    transportFactory.close();
+  }
+
+  @Override
+  public void disconnect() {
+    transportFactory.releaseTransport();
+  }
 }
\ No newline at end of file

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/SentryPolicyStoreProcessor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
index 456dabc..d38b1eb 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
@@ -47,7 +47,7 @@ import org.apache.sentry.provider.db.log.entity.JsonLogEntity;
 import org.apache.sentry.provider.db.log.entity.JsonLogEntityFactory;
 import org.apache.sentry.provider.db.log.util.Constants;
 import org.apache.sentry.provider.db.service.persistent.SentryStore;
-import org.apache.sentry.provider.db.service.thrift.PolicyStoreConstants.PolicyStoreServerConfig;
+import org.apache.sentry.core.common.utils.PolicyStoreConstants.PolicyStoreServerConfig;
 import org.apache.sentry.provider.db.service.thrift.validator.GrantPrivilegeRequestValidator;
 import org.apache.sentry.provider.db.service.thrift.validator.RevokePrivilegeRequestValidator;
 import org.apache.sentry.service.thrift.SentryServiceUtil;

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/SentryProcessorWrapper.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryProcessorWrapper.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryProcessorWrapper.java
index a5f11a9..5e26486 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryProcessorWrapper.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryProcessorWrapper.java
@@ -18,6 +18,7 @@
 
 package org.apache.sentry.provider.db.service.thrift;
 
+import org.apache.sentry.core.common.utils.ThriftUtil;
 import org.apache.thrift.TException;
 import org.apache.thrift.protocol.TProtocol;
 

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/ThriftUtil.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/ThriftUtil.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/ThriftUtil.java
deleted file mode 100644
index 5fed04a..0000000
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/ThriftUtil.java
+++ /dev/null
@@ -1,127 +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;
-
-import com.google.common.net.HostAndPort;
-import org.apache.thrift.protocol.TProtocol;
-import org.apache.thrift.transport.TSaslClientTransport;
-import org.apache.thrift.transport.TSaslServerTransport;
-import org.apache.thrift.transport.TSocket;
-import org.apache.thrift.transport.TTransport;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-public final class ThriftUtil {
-
-  private static final Logger LOGGER = LoggerFactory.getLogger(ThriftUtil.class);
-
-  public static void setImpersonator(final TProtocol in) {
-    try {
-      TTransport transport = in.getTransport();
-      if (transport instanceof TSaslServerTransport) {
-        String impersonator = ((TSaslServerTransport) transport).getSaslServer()
-            .getAuthorizationID();
-        setImpersonator(impersonator);
-      }
-    } catch (Exception e) {
-      // If there has exception when get impersonator info, log the error information.
-      LOGGER.warn("There is an error when get the impersonator:" + e.getMessage());
-    }
-  }
-
-  public static void setIpAddress(final TProtocol in) {
-    try {
-      TTransport transport = in.getTransport();
-      TSocket tSocket = getUnderlyingSocketFromTransport(transport);
-      if (tSocket != null) {
-        setIpAddress(tSocket.getSocket().getInetAddress().toString());
-      } else {
-        LOGGER.warn("Unknown Transport, cannot determine ipAddress");
-      }
-    } catch (Exception e) {
-      // If there has exception when get impersonator info, log the error information.
-      LOGGER.warn("There is an error when get the client's ip address:" + e.getMessage());
-    }
-  }
-
-  /**
-   * Returns the underlying TSocket from the transport, or null of the transport type is unknown.
-   */
-  private static TSocket getUnderlyingSocketFromTransport(TTransport transport) {
-    Preconditions.checkNotNull(transport);
-    if (transport instanceof TSaslServerTransport) {
-      return (TSocket) ((TSaslServerTransport) transport).getUnderlyingTransport();
-    } else if (transport instanceof TSaslClientTransport) {
-      return (TSocket) ((TSaslClientTransport) transport).getUnderlyingTransport();
-    } else if (transport instanceof TSocket) {
-      return (TSocket) transport;
-    }
-    return null;
-  }
-
-  private static ThreadLocal<String> threadLocalIpAddress = new ThreadLocal<String>() {
-    @Override
-    protected synchronized String initialValue() {
-      return "";
-    }
-  };
-
-  public static void setIpAddress(String ipAddress) {
-    threadLocalIpAddress.set(ipAddress);
-  }
-
-  public static String getIpAddress() {
-    return threadLocalIpAddress.get();
-  }
-
-  private static ThreadLocal<String> threadLocalImpersonator = new ThreadLocal<String>() {
-    @Override
-    protected synchronized String initialValue() {
-      return "";
-    }
-  };
-
-  public static void setImpersonator(String impersonator) {
-    threadLocalImpersonator.set(impersonator);
-  }
-
-  public static String getImpersonator() {
-    return threadLocalImpersonator.get();
-  }
-  
-  private ThriftUtil() {
-    // Make constructor private to avoid instantiation
-  }
-
-  /**
-   * Utility function for parsing host and port strings. Expected form should be
-   * (host:port). The hostname could be in ipv6 style. If port is not specified,
-   * defaultPort will be used.
-   */
-  public static HostAndPort[] parseHostPortStrings(String[] hostsAndPortsArr, int defaultPort) {
-    HostAndPort[] hostsAndPorts = new HostAndPort[hostsAndPortsArr.length];
-    for (int i = 0; i < hostsAndPorts.length; i++) {
-     hostsAndPorts[i] =
-          HostAndPort.fromString(hostsAndPortsArr[i]).withDefaultPort(defaultPort);
-    }
-    return hostsAndPorts;
-  }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/PoolClientInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/PoolClientInvocationHandler.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/PoolClientInvocationHandler.java
index d5f4fcb..acf9b05 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/PoolClientInvocationHandler.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/PoolClientInvocationHandler.java
@@ -28,8 +28,9 @@ import org.apache.commons.pool2.impl.GenericObjectPool;
 import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.core.common.exception.SentryUserException;
+import org.apache.sentry.core.common.transport.SentryClientInvocationHandler;
 import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
-import org.apache.sentry.provider.db.service.thrift.ThriftUtil;
+import org.apache.sentry.core.common.utils.ThriftUtil;
 import org.apache.sentry.service.thrift.ServiceConstants.ClientConfig;
 import org.apache.thrift.transport.TTransportException;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/RetryClientInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/RetryClientInvocationHandler.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/RetryClientInvocationHandler.java
deleted file mode 100644
index 2f38198..0000000
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/RetryClientInvocationHandler.java
+++ /dev/null
@@ -1,146 +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.service.thrift;
-
-import com.google.common.base.Preconditions;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.sentry.core.common.exception.SentryUserException;
-import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClientDefaultImpl;
-import org.apache.thrift.transport.TTransportException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * The RetryClientInvocationHandler is a proxy class for handling thrift calls for non-pool
- * model. Currently only one client connection is allowed, and it's using lazy connection.
- * The client is not connected to the sentry server until there is any rpc call.
- * <p>
- * For every rpc call, if the client is not connected, it will first connect to a sentry
- * server, and then do the thrift call to the connected sentry server, which will execute
- * the requested method and return back the response. If it is failed with connection
- * problem, it will close the current connection and retry (reconnect and resend the
- * thrift call) no more than rpcRetryTotal times. If the client is already connected, it
- * will reuse the existing connection, and do the thrift call.
- * <p>
- * During reconnection, it will first cycle through all the available sentry servers, and
- * then retry the whole server list no more than connectionFullRetryTotal times. In this
- * case, it won't introduce more latency when some server fails. Also to prevent all
- * clients connecting to the same server, it will reorder the endpoints randomly after a
- * full retry.
- * <p>
- * TODO: allow multiple client connections
- */
-class RetryClientInvocationHandler extends SentryClientInvocationHandler{
-  private static final Logger LOGGER =
-      LoggerFactory.getLogger(RetryClientInvocationHandler.class);
-  private final Configuration conf;
-  private SentryPolicyServiceClientDefaultImpl client = null;
-  private final int rpcRetryTotal;
-
-  /**
-   * Initialize the sentry configurations, including rpc retry count and client connection
-   * configs for SentryPolicyServiceClientDefaultImpl
-   */
-  RetryClientInvocationHandler(Configuration conf) throws Exception {
-    this.conf = conf;
-    Preconditions.checkNotNull(this.conf, "Configuration object cannot be null");
-    this.rpcRetryTotal = conf.getInt(ServiceConstants.ClientConfig.SENTRY_RPC_RETRY_TOTAL,
-        ServiceConstants.ClientConfig.SENTRY_RPC_RETRY_TOTAL_DEFAULT);
-    client = new SentryPolicyServiceClientDefaultImpl(conf);
-  }
-
-  /**
-   * For every rpc call, if the client is not connected, it will first connect to a sentry
-   * server, and then do the thrift call to the connected sentry server, which will
-   * execute the requested method and return back the response. If it is failed with
-   * connection problem, it will close the current connection, and retry (reconnect and
-   * resend the thrift call) no more than rpcRetryTotal times. Throw SentryUserException
-   * if failed retry after rpcRetryTotal times.
-   * if it is failed with other exception, method would just re-throw the exception.
-   * Synchronized it for thread safety.
-   */
-  @Override
-  synchronized Object invokeImpl(Object proxy, Method method, Object[] args) throws Exception {
-    int retryCount = 0;
-    Exception lastExc = null;
-
-    while (retryCount < rpcRetryTotal) {
-      // Connect to a sentry server if not connected yet.
-      try {
-        client.connectWithRetry();
-      } catch (IOException e) {
-        // Increase the retry num
-        // Retry when the exception is caused by connection problem.
-        retryCount++;
-        lastExc = e;
-        close();
-        continue;
-      } catch (Exception e) {
-        close();
-        throw e;
-      }
-
-      // do the thrift call
-      try {
-        return method.invoke(client, args);
-      } catch (InvocationTargetException e) {
-        // Get the target exception, check if SentryUserException or TTransportException is wrapped.
-        // TTransportException means there has connection problem with the pool.
-        Throwable targetException = e.getCause();
-        if (targetException instanceof SentryUserException) {
-          Throwable sentryTargetException = targetException.getCause();
-          // If there has connection problem, eg, invalid connection if the service restarted,
-          // sentryTargetException instanceof TTransportException = true.
-          if (sentryTargetException instanceof TTransportException) {
-            // Retry when the exception is caused by connection problem.
-            lastExc = new TTransportException(sentryTargetException);
-            LOGGER.debug("Got TTransportException when do the thrift call ", lastExc);
-          } else {
-            // The exception is thrown by thrift call, eg, SentryAccessDeniedException.
-            // Do not need to reconnect to the sentry server.
-            throw (SentryUserException) targetException;
-          }
-        } else {
-          throw e;
-        }
-      }
-
-      // Increase the retry num
-      retryCount++;
-
-      // For connection problem, it will close the current connection, and reconnect to
-      // an available sentry server and redo the thrift call.
-      close();
-    }
-    // Throw the exception as reaching the max rpc retry num.
-    LOGGER.error(String.format("failed after %d retries ", rpcRetryTotal), lastExc);
-    throw new SentryUserException(
-        String.format("failed after %d retries ", rpcRetryTotal), lastExc);
-  }
-
-  @Override
-  public void close() {
-    client.close();
-    LOGGER.debug("Close the current client connection");
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryClientInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryClientInvocationHandler.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryClientInvocationHandler.java
deleted file mode 100644
index b8c7f23..0000000
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryClientInvocationHandler.java
+++ /dev/null
@@ -1,54 +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.service.thrift;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-
-/**
- * SentryClientInvocationHandler is the base interface for all the InvocationHandler in SENTRY
- */
-public abstract class SentryClientInvocationHandler implements InvocationHandler {
-
-  /**
-   * Close the InvocationHandler: An InvocationHandler may create some contexts,
-   * these contexts should be close when the method "close()" of client be called.
-   */
-  @Override
-  public final Object invoke(Object proxy, Method method, Object[] args) throws Exception {
-    // close() doesn't throw exception we supress that in case of connection
-    // loss. Changing SentryPolicyServiceClient#close() to throw an
-    // exception would be a backward incompatible change for Sentry clients.
-    if ("close".equals(method.getName()) && null == args) {
-      close();
-      return null;
-    }
-    return invokeImpl(proxy, method, args);
-  }
-
-  /**
-   * Subclass should implement this method for special function
-   */
-  abstract Object invokeImpl(Object proxy, Method method, Object[] args) throws Exception;
-
-  /**
-   * An abstract method "close", an invocationHandler should close its contexts at here.
-   */
-  public abstract void close();
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientFactory.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientFactory.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientFactory.java
index f822497..7db9310 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientFactory.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientFactory.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.
@@ -22,28 +22,33 @@ import java.lang.reflect.Proxy;
 
 import org.apache.hadoop.conf.Configuration;
 
+import org.apache.sentry.core.common.transport.RetryClientInvocationHandler;
+import org.apache.sentry.core.common.transport.SentryPolicyClientTransportConfig;
 import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
 import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClientDefaultImpl;
 import org.apache.sentry.service.thrift.ServiceConstants.ClientConfig;
 
 public final class SentryServiceClientFactory {
+  private static final SentryPolicyClientTransportConfig transportConfig =
+          new SentryPolicyClientTransportConfig();
 
   private SentryServiceClientFactory() {
   }
 
   public static SentryPolicyServiceClient create(Configuration conf) throws Exception {
     boolean pooled = conf.getBoolean(
-        ClientConfig.SENTRY_POOL_ENABLED, ClientConfig.SENTRY_POOL_ENABLED_DEFAULT);
+      ClientConfig.SENTRY_POOL_ENABLED, ClientConfig.SENTRY_POOL_ENABLED_DEFAULT);
     if (pooled) {
       return (SentryPolicyServiceClient) Proxy
-          .newProxyInstance(SentryPolicyServiceClientDefaultImpl.class.getClassLoader(),
-              SentryPolicyServiceClientDefaultImpl.class.getInterfaces(),
-              new PoolClientInvocationHandler(conf));
+        .newProxyInstance(SentryPolicyServiceClientDefaultImpl.class.getClassLoader(),
+          SentryPolicyServiceClientDefaultImpl.class.getInterfaces(),
+          new PoolClientInvocationHandler(conf));
     } else {
       return (SentryPolicyServiceClient) Proxy
-          .newProxyInstance(SentryPolicyServiceClientDefaultImpl.class.getClassLoader(),
-              SentryPolicyServiceClientDefaultImpl.class.getInterfaces(),
-              new RetryClientInvocationHandler(conf));
+        .newProxyInstance(SentryPolicyServiceClientDefaultImpl.class.getClassLoader(),
+          SentryPolicyServiceClientDefaultImpl.class.getInterfaces(),
+          new RetryClientInvocationHandler(conf,
+            new SentryPolicyServiceClientDefaultImpl(conf,transportConfig), transportConfig));
     }
   }
 }


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

Posted by ak...@apache.org.
SENTRY-1593: Implement client failover for Generic and NN clients (Kalyan Kalvagadda, reviewed by ALex Kolbasov)


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

Branch: refs/heads/sentry-ha-redesign
Commit: 14b3b904a83b3b4bb5c245bff9e839a7e40836f7
Parents: ec1e01d
Author: Alexander Kolbasov <ak...@cloudera.com>
Authored: Thu Apr 27 21:59:00 2017 -0700
Committer: Alexander Kolbasov <ak...@cloudera.com>
Committed: Thu Apr 27 21:59:00 2017 -0700

----------------------------------------------------------------------
 sentry-core/sentry-core-common/pom.xml          |   4 +
 .../exception/SentryHdfsServiceException.java   |  33 +
 .../transport/RetryClientInvocationHandler.java | 147 ++++
 .../SentryClientInvocationHandler.java          |  54 ++
 .../SentryClientTransportConfigInterface.java   |   7 +
 .../SentryClientTransportConstants.java         |   1 +
 .../SentryHDFSClientTransportConfig.java        |   5 +
 .../SentryPolicyClientTransportConfig.java      |   5 +
 .../common/transport/SentryServiceClient.java   |  43 ++
 .../transport/SentryTransportFactory.java       | 309 ++++++++
 .../core/common/utils/PolicyStoreConstants.java |  32 +
 .../sentry/core/common/utils/ThriftUtil.java    | 127 ++++
 .../apache/sentry/hdfs/ServiceConstants.java    |   5 +-
 sentry-hdfs/sentry-hdfs-dist/pom.xml            |   4 +
 .../sentry/hdfs/SentryHDFSServiceClient.java    |   2 +
 .../SentryHDFSServiceClientDefaultImpl.java     | 182 ++---
 .../hdfs/SentryHDFSServiceClientFactory.java    |  25 +-
 .../hdfs/SentryHDFSServiceProcessorFactory.java |   2 +-
 .../sentry/hdfs/SentryHdfsServiceException.java |  33 -
 .../thrift/SentryGenericPolicyProcessor.java    |   2 +-
 .../SentryGenericPolicyProcessorWrapper.java    |   2 +-
 .../SentryGenericServiceClientDefaultImpl.java  | 330 ++++----
 .../SentryGenericServiceClientFactory.java      |  20 +-
 .../db/log/entity/JsonLogEntityFactory.java     |   2 +-
 .../service/persistent/TransactionManager.java  |   2 +-
 .../db/service/thrift/PolicyStoreConstants.java |  32 -
 .../SentryPolicyServiceClientDefaultImpl.java   | 747 ++++++++-----------
 .../thrift/SentryPolicyStoreProcessor.java      |   2 +-
 .../service/thrift/SentryProcessorWrapper.java  |   1 +
 .../provider/db/service/thrift/ThriftUtil.java  | 127 ----
 .../thrift/PoolClientInvocationHandler.java     |   3 +-
 .../thrift/RetryClientInvocationHandler.java    | 146 ----
 .../thrift/SentryClientInvocationHandler.java   |  54 --
 .../thrift/SentryServiceClientFactory.java      |  25 +-
 .../sentry/service/thrift/ServiceConstants.java |  19 +-
 .../TestSentryGenericPolicyProcessor.java       |   2 +-
 .../thrift/TestSentryGenericServiceClient.java  |  61 ++
 .../db/log/entity/TestJsonLogEntityFactory.java |   2 +-
 .../log/entity/TestJsonLogEntityFactoryGM.java  |   2 +-
 .../thrift/TestSentryPolicyServiceClient.java   |  64 ++
 .../thrift/TestSentryPolicyStoreProcessor.java  |   2 +-
 .../thrift/TestPoolClientInvocationHandler.java |   2 +-
 42 files changed, 1474 insertions(+), 1195 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/pom.xml b/sentry-core/sentry-core-common/pom.xml
index 9d18063..e1be256 100644
--- a/sentry-core/sentry-core-common/pom.xml
+++ b/sentry-core/sentry-core-common/pom.xml
@@ -62,6 +62,10 @@ limitations under the License.
       <artifactId>hadoop-common</artifactId>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libthrift</artifactId>
+    </dependency>
   </dependencies>
 
   <build>

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/exception/SentryHdfsServiceException.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/exception/SentryHdfsServiceException.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/exception/SentryHdfsServiceException.java
new file mode 100644
index 0000000..6b09dc2
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/exception/SentryHdfsServiceException.java
@@ -0,0 +1,33 @@
+/**
+ * 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.core.common.exception;
+
+public class SentryHdfsServiceException extends RuntimeException {
+  private static final long serialVersionUID = 1511645864949767378L;
+
+  public SentryHdfsServiceException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public SentryHdfsServiceException(String message) {
+    super(message);
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/RetryClientInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/RetryClientInvocationHandler.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/RetryClientInvocationHandler.java
new file mode 100644
index 0000000..34a594e
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/RetryClientInvocationHandler.java
@@ -0,0 +1,147 @@
+/**
+ * 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
+ * <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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.core.common.transport;
+
+import com.google.common.base.Preconditions;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.common.exception.SentryUserException;
+import org.apache.sentry.core.common.exception.SentryHdfsServiceException;
+import org.apache.thrift.transport.TTransportException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * The RetryClientInvocationHandler is a proxy class for handling thrift calls for non-pool
+ * model. Currently only one client connection is allowed.
+ * <p>
+ * For every rpc call, if the client is not connected, it will first connect to one of the
+ * sentry servers, and then do the thrift call to the connected sentry server, which will
+ * execute the requested method and return back the response. If it is failed with connection
+ * problem, it will close the current connection and retry (reconnect and resend the
+ * thrift call) no more than rpcRetryTotal times. If the client is already connected, it
+ * will reuse the existing connection, and do the thrift call.
+ * <p>
+ * During reconnection, invocatiaon handler will first cycle through all the configured sentry servers, and
+ * then retry the whole server list no more than connectionFullRetryTotal times. In this
+ * case, it won't introduce more latency when some server fails.
+ * <p>
+ */
+
+public class RetryClientInvocationHandler extends SentryClientInvocationHandler {
+  private static final Logger LOGGER =
+    LoggerFactory.getLogger(RetryClientInvocationHandler.class);
+  private SentryServiceClient client = null;
+  private final int maxRetryCount;
+
+  /**
+   * Initialize the sentry configurations, including rpc retry count and client connection
+   * configs for SentryPolicyServiceClientDefaultImpl
+   */
+  public RetryClientInvocationHandler(Configuration conf, SentryServiceClient clientObject,
+                                      SentryClientTransportConfigInterface transportConfig) {
+    Preconditions.checkNotNull(conf, "Configuration object cannot be null");
+    Preconditions.checkNotNull(clientObject, "Client Object cannot be null");
+    client = clientObject;
+    maxRetryCount = transportConfig.getSentryRpcRetryTotal(conf);
+  }
+
+  /**
+   * For every rpc call, if the client is not connected, it will first connect to a sentry
+   * server, and then do the thrift call to the connected sentry server, which will
+   * execute the requested method and return back the response. If it is failed with
+   * connection problem, it will close the current connection, and retry (reconnect and
+   * resend the thrift call) no more than rpcRetryTotal times. Throw SentryUserException
+   * if failed retry after rpcRetryTotal times.
+   * if it is failed with other exception, method would just re-throw the exception.
+   * Synchronized it for thread safety.
+   */
+  @Override
+  public synchronized Object invokeImpl(Object proxy, Method method, Object[] args) throws Exception {
+    int retryCount = 0;
+    Exception lastExc = null;
+
+    while (retryCount < maxRetryCount) {
+      // Connect to a sentry server if not connected yet.
+      try {
+        client.connect();
+      } catch (IOException e) {
+        // Increase the retry num
+        // Retry when the exception is caused by connection problem.
+        retryCount++;
+        lastExc = e;
+        close();
+        continue;
+      }
+
+      // do the thrift call
+      try {
+        return method.invoke(client, args);
+      } catch (InvocationTargetException e) {
+        // Get the target exception, check if SentryUserException or TTransportException is wrapped.
+        // TTransportException means there is a connection problem.
+        Throwable targetException = e.getCause();
+        if (targetException instanceof SentryUserException ||
+          targetException instanceof SentryHdfsServiceException) {
+          Throwable sentryTargetException = targetException.getCause();
+          // If there has connection problem, eg, invalid connection if the service restarted,
+          // sentryTargetException instanceof TTransportException will be true.
+          if (sentryTargetException instanceof TTransportException) {
+            // Retry when the exception is caused by connection problem.
+            lastExc = new TTransportException(sentryTargetException);
+            LOGGER.error("Thrift call failed with TTransportException", lastExc);
+            // Closing the thrift client on TTransportException. New client object is
+            // created using new socket when an attempt to reconnect is made.
+            close();
+          } else {
+            // The exception is thrown by thrift call, eg, SentryAccessDeniedException.
+            // Do not need to reconnect to the sentry server.
+            if (targetException instanceof SentryUserException) {
+              throw (SentryUserException) targetException;
+            } else {
+              throw (SentryHdfsServiceException) targetException;
+            }
+          }
+        } else {
+          throw e;
+        }
+      }
+
+      // Increase the retry num
+      retryCount++;
+    }
+
+    // Throw the exception as reaching the max rpc retry num.
+    String error = String.format("Request failed, %d retries attempted ", maxRetryCount);
+    LOGGER.error(error, lastExc);
+    throw new SentryUserException(error, lastExc);
+  }
+
+  @Override
+  public synchronized void close() {
+    try {
+      LOGGER.debug("Releasing the current client connection");
+      client.disconnect();
+    } catch (Exception e) {
+      LOGGER.error("Encountered failure while closing the connection");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientInvocationHandler.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientInvocationHandler.java
new file mode 100644
index 0000000..bf33fda
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientInvocationHandler.java
@@ -0,0 +1,54 @@
+/**
+ * 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.core.common.transport;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * SentryClientInvocationHandler is the base interface for all the InvocationHandler in SENTRY
+ */
+public abstract class SentryClientInvocationHandler implements InvocationHandler {
+
+  /**
+   * Close the InvocationHandler: An InvocationHandler may create some contexts,
+   * these contexts should be close when the method "close()" of client be called.
+   */
+  @Override
+  public final Object invoke(Object proxy, Method method, Object[] args) throws Exception {
+    // close() doesn't throw exception we supress that in case of connection
+    // loss. Changing SentryPolicyServiceClient#close() to throw an
+    // exception would be a backward incompatible change for Sentry clients.
+    if ("close".equals(method.getName()) && null == args) {
+      close();
+      return null;
+    }
+    return invokeImpl(proxy, method, args);
+  }
+
+  /**
+   * Subclass should implement this method for special function
+   */
+  abstract public Object invokeImpl(Object proxy, Method method, Object[] args) throws Exception;
+
+  /**
+   * An abstract method "close", an invocationHandler should close its contexts at here.
+   */
+  public abstract void close();
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConfigInterface.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConfigInterface.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConfigInterface.java
index 6cea596..24192fd 100644
--- a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConfigInterface.java
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConfigInterface.java
@@ -40,6 +40,13 @@ interface SentryClientTransportConfigInterface {
 
   /**
    * @param conf configuration
+   * @return number of times should client re-create the transport and try to connect
+   * before finally giving up.
+   */
+  int getSentryRpcRetryTotal(Configuration conf);
+
+  /**
+   * @param conf configuration
    * @return True, if kerberos should be enabled.
    * False, Iff kerberos is enabled.
    * @throws MissingConfigurationException if property is mandatory and is missing in

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConstants.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConstants.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConstants.java
index 636de40..4af7d1f 100644
--- a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConstants.java
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryClientTransportConstants.java
@@ -28,6 +28,7 @@ package org.apache.sentry.core.common.transport;
  * <code>SentryClientTransportConfigInterface</code>.
  */
 class SentryClientTransportConstants {
+
   /**
    * max retry num for client rpc
    * {link RetryClientInvocationHandler#invokeImpl(Object, Method, Object[])}

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryHDFSClientTransportConfig.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryHDFSClientTransportConfig.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryHDFSClientTransportConfig.java
index 12175f7..64cdd46 100644
--- a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryHDFSClientTransportConfig.java
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryHDFSClientTransportConfig.java
@@ -46,6 +46,11 @@ public final class SentryHDFSClientTransportConfig
   }
 
   @Override
+  public int getSentryRpcRetryTotal(Configuration conf) {
+    return conf.getInt(SENTRY_RPC_RETRY_TOTAL, SENTRY_RPC_RETRY_TOTAL_DEFAULT);
+  }
+
+  @Override
   public boolean useUserGroupInformation(Configuration conf)
     throws MissingConfigurationException {
     return Boolean.valueOf(conf.get(SECURITY_USE_UGI_TRANSPORT, "true"));

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryPolicyClientTransportConfig.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryPolicyClientTransportConfig.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryPolicyClientTransportConfig.java
index 038bca7..396a7f6 100644
--- a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryPolicyClientTransportConfig.java
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryPolicyClientTransportConfig.java
@@ -46,6 +46,11 @@ public final class SentryPolicyClientTransportConfig
   }
 
   @Override
+  public int getSentryRpcRetryTotal(Configuration conf) {
+    return conf.getInt(SENTRY_RPC_RETRY_TOTAL, SENTRY_RPC_RETRY_TOTAL_DEFAULT);
+  }
+
+  @Override
   public boolean useUserGroupInformation(Configuration conf)
     throws MissingConfigurationException {
     return Boolean.valueOf(conf.get(SECURITY_USE_UGI_TRANSPORT, "true"));

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryServiceClient.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryServiceClient.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryServiceClient.java
new file mode 100644
index 0000000..9a10ca5
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryServiceClient.java
@@ -0,0 +1,43 @@
+/**
+ * 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
+ * <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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.core.common.transport;
+
+/**
+ * Client interface for Proxy Invocation handlers
+ * <p>
+ * Defines interface that Sentry client's should expose to the Invocation handlers like
+ * <code>RetryClientInvocationHandler</code> used to proxy the method invocation on sentry
+ * client instances .
+ * <p>
+ * All the sentry clients that need retrying and failover capabilities should implement
+ * this interface.
+ */
+public interface SentryServiceClient {
+  /**
+   * Connect to Sentry server.
+   * Either creates a new connection or reuses an existing one.
+   * @throws Exception on failure to acquire a transport towards server.
+   */
+  void connect() throws Exception;
+
+  /**
+   * Disconnect from the server. May close connection or return it to a
+   * pool for reuse.
+   */
+  void disconnect();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryTransportFactory.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryTransportFactory.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryTransportFactory.java
new file mode 100644
index 0000000..9ddb400
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/transport/SentryTransportFactory.java
@@ -0,0 +1,309 @@
+/**
+ * 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
+ * <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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sentry.core.common.transport;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.net.HostAndPort;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.net.NetUtils;
+import org.apache.hadoop.security.SaslRpcServer;
+import org.apache.hadoop.security.SecurityUtil;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.sentry.core.common.exception.MissingConfigurationException;
+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.apache.sentry.core.common.utils.ThriftUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Create Thrift transports suitable for talking to Sentry
+ */
+
+public class SentryTransportFactory {
+  protected final Configuration conf;
+  private String[] serverPrincipalParts;
+  protected TTransport thriftTransport;
+  private final int connectionTimeout;
+  private static final Logger LOGGER = LoggerFactory.getLogger(SentryTransportFactory.class);
+  // configs for connection retry
+  private final int connectionFullRetryTotal;
+  private final ArrayList<InetSocketAddress> endpoints;
+  private final SentryClientTransportConfigInterface transportConfig;
+  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 {
+    UserGroupInformation ugi = null;
+
+    public UgiSaslClientTransport(String mechanism, String protocol,
+                                  String serverName, TTransport transport,
+                                  boolean wrapUgi, Configuration conf)
+      throws IOException, SaslException {
+      super(mechanism, null, protocol, serverName, SASL_PROPERTIES, null,
+        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();
+      }
+    }
+
+    // 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();
+    }
+  }
+
+  /**
+   * Initialize the object based on the sentry configuration provided.
+   * List of configured servers are reordered randomly preventing all
+   * clients connecting to the same server.
+   *
+   * @param conf            Sentry configuration
+   * @param transportConfig transport configuration to use
+   */
+  public SentryTransportFactory(Configuration conf,
+                                SentryClientTransportConfigInterface transportConfig) throws IOException {
+
+    this.conf = conf;
+    Preconditions.checkNotNull(this.conf, "Configuration object cannot be null");
+    serverPrincipalParts = null;
+    this.transportConfig = transportConfig;
+
+    try {
+      String hostsAndPortsStr;
+      this.connectionTimeout = transportConfig.getServerRpcConnTimeoutInMs(conf);
+      this.connectionFullRetryTotal = transportConfig.getSentryFullRetryTotal(conf);
+
+      hostsAndPortsStr = transportConfig.getSentryServerRpcAddress(conf);
+
+      int serverPort = transportConfig.getServerRpcPort(conf);
+
+      String[] hostsAndPortsStrArr = hostsAndPortsStr.split(",");
+      HostAndPort[] hostsAndPorts = ThriftUtil.parseHostPortStrings(hostsAndPortsStrArr, serverPort);
+
+      this.endpoints = new ArrayList(hostsAndPortsStrArr.length);
+      for (HostAndPort endpoint : hostsAndPorts) {
+        this.endpoints.add(
+          new InetSocketAddress(endpoint.getHostText(), endpoint.getPort()));
+        LOGGER.debug("Added server endpoint: " + endpoint.toString());
+      }
+
+      // Reorder endpoints randomly to prevent all clients connecting to the same endpoint
+      // at the same time after a node failure.
+      Collections.shuffle(endpoints);
+    } catch (MissingConfigurationException e) {
+      throw new RuntimeException("Sentry Thrift Client Creation Failed: " + e.getMessage(), e);
+    }
+  }
+
+  /**
+   * Initialize object based on the parameters provided provided.
+   *
+   * @param addr            Host address which the client needs to connect
+   * @param port            Host Port which the client needs to connect
+   * @param conf            Sentry configuration
+   * @param transportConfig transport configuration to use
+   */
+  public SentryTransportFactory(String addr, int port, Configuration conf,
+                                SentryClientTransportConfigInterface transportConfig) throws IOException {
+    // copy the configuration because we may make modifications to it.
+    this.conf = new Configuration(conf);
+    serverPrincipalParts = null;
+    Preconditions.checkNotNull(this.conf, "Configuration object cannot be null");
+    this.transportConfig = transportConfig;
+
+    try {
+      this.endpoints = new ArrayList(1);
+      this.endpoints.add(NetUtils.createSocketAddr(addr, port));
+      this.connectionTimeout = transportConfig.getServerRpcConnTimeoutInMs(conf);
+      this.connectionFullRetryTotal = transportConfig.getSentryFullRetryTotal(conf);
+    } catch (MissingConfigurationException e) {
+      throw new RuntimeException("Sentry Thrift Client Creation Failed: " + e.getMessage(), e);
+    }
+  }
+
+
+  /**
+   * On connection error, Iterates through all the configured servers and tries to connect.
+   * On successful connection, control returns
+   * On connection failure, continues iterating through all the configured sentry servers,
+   * and then retries the whole server list no more than connectionFullRetryTotal times.
+   * In this case, it won't introduce more latency when some server fails.
+   * <p>
+   * TODO: Add metrics for the number of successful connects and errors per client, and total number of retries.
+   */
+  public TTransport getTransport() throws IOException {
+    IOException currentException = null;
+    for (int retryCount = 0; retryCount < connectionFullRetryTotal; retryCount++) {
+      try {
+        return connectToAvailableServer();
+      } catch (IOException e) {
+        currentException = e;
+        LOGGER.error(
+          String.format("Failed to connect to all the configured sentry servers, " +
+            "Retrying again"));
+      }
+    }
+    // Throws exception on reaching the connectionFullRetryTotal.
+    LOGGER.error(
+      String.format("Reach the max connection retry num %d ", connectionFullRetryTotal),
+      currentException);
+    throw currentException;
+  }
+
+  /**
+   * Iterates through all the configured servers and tries to connect.
+   * On connection error, tries to connect to next server.
+   * Control returns on successful connection OR it's done trying to all the
+   * configured servers.
+   *
+   * @throws IOException
+   */
+  private TTransport connectToAvailableServer() throws IOException {
+    IOException currentException = null;
+    for (InetSocketAddress addr : endpoints) {
+      try {
+        return connectToServer(addr);
+      } catch (IOException e) {
+        LOGGER.error(String.format("Failed connection to %s: %s",
+          addr.toString(), e.getMessage()), e);
+        currentException = e;
+      }
+    }
+    throw currentException;
+  }
+
+  /**
+   * Connect to the specified socket address and throw IOException if failed.
+   *
+   * @param serverAddress Address client needs to connect
+   * @throws Exception if there is failure in establishing the connection.
+   */
+  private TTransport connectToServer(InetSocketAddress serverAddress) throws IOException {
+    try {
+      thriftTransport = createTransport(serverAddress);
+      thriftTransport.open();
+    } catch (TTransportException e) {
+      throw new IOException("Failed to open transport: " + e.getMessage(), e);
+    } catch (MissingConfigurationException e) {
+      throw new RuntimeException(e.getMessage(), e);
+    }
+
+    LOGGER.debug("Successfully opened transport: " + thriftTransport + " to " + serverAddress);
+    return thriftTransport;
+  }
+
+  /**
+   * New socket is is created
+   *
+   * @param serverAddress
+   * @return
+   * @throws TTransportException
+   * @throws MissingConfigurationException
+   * @throws IOException
+   */
+  private TTransport createTransport(InetSocketAddress serverAddress)
+    throws TTransportException, MissingConfigurationException, IOException {
+    TTransport socket = new TSocket(serverAddress.getHostName(),
+      serverAddress.getPort(), connectionTimeout);
+
+    if (!transportConfig.isKerberosEnabled(conf)) {
+      return socket;
+    } else {
+      String serverPrincipal = transportConfig.getSentryPrincipal(conf);
+      serverPrincipal = SecurityUtil.getServerPrincipal(serverPrincipal, serverAddress.getAddress());
+      LOGGER.debug("Using server kerberos principal: " + serverPrincipal);
+      if (serverPrincipalParts == null) {
+        serverPrincipalParts = SaslRpcServer.splitKerberosName(serverPrincipal);
+        Preconditions.checkArgument(serverPrincipalParts.length == 3,
+          "Kerberos principal should have 3 parts: " + serverPrincipal);
+      }
+
+      boolean wrapUgi = transportConfig.useUserGroupInformation(conf);
+      return new UgiSaslClientTransport(SaslRpcServer.AuthMethod.KERBEROS.getMechanismName(),
+        serverPrincipalParts[0], serverPrincipalParts[1],
+        socket, wrapUgi, conf);
+    }
+  }
+
+  private boolean isConnected() {
+    return thriftTransport != null && thriftTransport.isOpen();
+  }
+
+  /**
+   * Method currently closes the transport
+   * TODO (Kalyan) Plan is to hold the transport and resuse it accross multiple client's
+   * That way, new connection need not be created for each new client
+   */
+  public void releaseTransport() {
+    close();
+  }
+
+  /**
+   * Method closes the transport
+   */
+  public void close() {
+    if (isConnected()) {
+      thriftTransport.close();
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/PolicyStoreConstants.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/PolicyStoreConstants.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/PolicyStoreConstants.java
new file mode 100644
index 0000000..97604de
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/PolicyStoreConstants.java
@@ -0,0 +1,32 @@
+/**
+ * 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.core.common.utils;
+
+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
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/ThriftUtil.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/ThriftUtil.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/ThriftUtil.java
new file mode 100644
index 0000000..d9fab86
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/ThriftUtil.java
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sentry.core.common.utils;
+
+import com.google.common.net.HostAndPort;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TSaslClientTransport;
+import org.apache.thrift.transport.TSaslServerTransport;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+public final class ThriftUtil {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(ThriftUtil.class);
+
+  public static void setImpersonator(final TProtocol in) {
+    try {
+      TTransport transport = in.getTransport();
+      if (transport instanceof TSaslServerTransport) {
+        String impersonator = ((TSaslServerTransport) transport).getSaslServer()
+            .getAuthorizationID();
+        setImpersonator(impersonator);
+      }
+    } catch (Exception e) {
+      // If there has exception when get impersonator info, log the error information.
+      LOGGER.warn("There is an error when get the impersonator:" + e.getMessage());
+    }
+  }
+
+  public static void setIpAddress(final TProtocol in) {
+    try {
+      TTransport transport = in.getTransport();
+      TSocket tSocket = getUnderlyingSocketFromTransport(transport);
+      if (tSocket != null) {
+        setIpAddress(tSocket.getSocket().getInetAddress().toString());
+      } else {
+        LOGGER.warn("Unknown Transport, cannot determine ipAddress");
+      }
+    } catch (Exception e) {
+      // If there has exception when get impersonator info, log the error information.
+      LOGGER.warn("There is an error when get the client's ip address:" + e.getMessage());
+    }
+  }
+
+  /**
+   * Returns the underlying TSocket from the transport, or null of the transport type is unknown.
+   */
+  private static TSocket getUnderlyingSocketFromTransport(TTransport transport) {
+    Preconditions.checkNotNull(transport);
+    if (transport instanceof TSaslServerTransport) {
+      return (TSocket) ((TSaslServerTransport) transport).getUnderlyingTransport();
+    } else if (transport instanceof TSaslClientTransport) {
+      return (TSocket) ((TSaslClientTransport) transport).getUnderlyingTransport();
+    } else if (transport instanceof TSocket) {
+      return (TSocket) transport;
+    }
+    return null;
+  }
+
+  private static ThreadLocal<String> threadLocalIpAddress = new ThreadLocal<String>() {
+    @Override
+    protected synchronized String initialValue() {
+      return "";
+    }
+  };
+
+  public static void setIpAddress(String ipAddress) {
+    threadLocalIpAddress.set(ipAddress);
+  }
+
+  public static String getIpAddress() {
+    return threadLocalIpAddress.get();
+  }
+
+  private static ThreadLocal<String> threadLocalImpersonator = new ThreadLocal<String>() {
+    @Override
+    protected synchronized String initialValue() {
+      return "";
+    }
+  };
+
+  public static void setImpersonator(String impersonator) {
+    threadLocalImpersonator.set(impersonator);
+  }
+
+  public static String getImpersonator() {
+    return threadLocalImpersonator.get();
+  }
+  
+  private ThriftUtil() {
+    // Make constructor private to avoid instantiation
+  }
+
+  /**
+   * Utility function for parsing host and port strings. Expected form should be
+   * (host:port). The hostname could be in ipv6 style. If port is not specified,
+   * defaultPort will be used.
+   */
+  public static HostAndPort[] parseHostPortStrings(String[] hostsAndPortsArr, int defaultPort) {
+    HostAndPort[] hostsAndPorts = new HostAndPort[hostsAndPortsArr.length];
+    for (int i = 0; i < hostsAndPorts.length; i++) {
+     hostsAndPorts[i] =
+          HostAndPort.fromString(hostsAndPortsArr[i]).withDefaultPort(defaultPort);
+    }
+    return hostsAndPorts;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java
index 48e2e49..0741ebc 100644
--- a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java
+++ b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/ServiceConstants.java
@@ -77,12 +77,9 @@ public class ServiceConstants {
     public static final String PRINCIPAL = "sentry.hdfs.service.server.principal";
 
     public static final String SERVER_RPC_PORT = "sentry.hdfs.service.client.server.rpc-port";
-    public static final int SERVER_RPC_PORT_DEFAULT = 8038;
-
+  
     public static final String SERVER_RPC_ADDRESS = "sentry.hdfs.service.client.server.rpc-address";
 
-    public static final String SERVER_RPC_CONN_TIMEOUT = "sentry.hdfs.service.client.server.rpc-connection-timeout";
-    public static final int SERVER_RPC_CONN_TIMEOUT_DEFAULT = 200000;
     public static final String USE_COMPACT_TRANSPORT = "sentry.hdfs.service.client.compact.transport";
     public static final boolean USE_COMPACT_TRANSPORT_DEFAULT = false;
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-hdfs/sentry-hdfs-dist/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-hdfs/sentry-hdfs-dist/pom.xml b/sentry-hdfs/sentry-hdfs-dist/pom.xml
index e828d5e..dd2d847 100644
--- a/sentry-hdfs/sentry-hdfs-dist/pom.xml
+++ b/sentry-hdfs/sentry-hdfs-dist/pom.xml
@@ -49,6 +49,10 @@ limitations under the License.
       <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-core-common</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-core-common</artifactId>
+    </dependency>
   </dependencies>
 
   <build>

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClient.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClient.java b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClient.java
index ab12bf4..11f6894 100644
--- a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClient.java
+++ b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClient.java
@@ -17,6 +17,8 @@
  */
 package org.apache.sentry.hdfs;
 
+import org.apache.sentry.core.common.exception.SentryHdfsServiceException;
+
 public interface SentryHDFSServiceClient {
   String SENTRY_HDFS_SERVICE_NAME = "SentryHDFSService";
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.java b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.java
index 28b1224..798bbef 100644
--- a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.java
+++ b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientDefaultImpl.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,162 +18,80 @@
 package org.apache.sentry.hdfs;
 
 import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.security.PrivilegedExceptionAction;
 import java.util.LinkedList;
-import java.util.Map;
 
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.Sasl;
-
-import com.google.common.collect.ImmutableMap;
 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.core.common.exception.MissingConfigurationException;
+import org.apache.sentry.core.common.exception.SentryHdfsServiceException;
+import org.apache.sentry.core.common.transport.SentryHDFSClientTransportConfig;
+import org.apache.sentry.core.common.transport.SentryServiceClient;
+import org.apache.sentry.core.common.transport.SentryTransportFactory;
 import org.apache.sentry.hdfs.service.thrift.SentryHDFSService;
 import org.apache.sentry.hdfs.service.thrift.SentryHDFSService.Client;
 import org.apache.sentry.hdfs.service.thrift.TAuthzUpdateResponse;
 import org.apache.sentry.hdfs.service.thrift.TPathsUpdate;
 import org.apache.sentry.hdfs.service.thrift.TPermissionsUpdate;
-import org.apache.sentry.hdfs.ServiceConstants.ClientConfig;
-import org.apache.sentry.core.common.transport.SentryHDFSClientTransportConfig;
 import org.apache.thrift.protocol.TBinaryProtocol;
 import org.apache.thrift.protocol.TCompactProtocol;
 import org.apache.thrift.protocol.TMultiplexedProtocol;
 import org.apache.thrift.protocol.TProtocol;
-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;
+/**
+ * Sentry HDFS Service Client
+ * <p>
+ * The public implementation of SentryHDFSServiceClient.
+ * 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 transport so that new socket is used.
+ */
 
-public class SentryHDFSServiceClientDefaultImpl implements SentryHDFSServiceClient {
+public class SentryHDFSServiceClientDefaultImpl implements SentryHDFSServiceClient, SentryServiceClient {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(SentryHDFSServiceClientDefaultImpl.class);
-
-  /**
-   * 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 {
-          // ensure that the ticket is valid before connecting to service. Note that
-          // checkTGTAndReloginFromKeytab() renew the ticket only when more than 80%
-          // of ticket lifetime has passed. 
-          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();
-    }
-  }
-
-  private final Configuration conf;
-  private final InetSocketAddress serverAddress;
-  private final int connectionTimeout;
-  private boolean kerberos;
-  private TTransport transport;
-
-  private String[] serverPrincipalParts;
   private Client client;
-  private final SentryHDFSClientTransportConfig transportConfig = new SentryHDFSClientTransportConfig();
-  private static final ImmutableMap<String, String> SASL_PROPERTIES =
-    ImmutableMap.of(Sasl.SERVER_AUTH, "true", Sasl.QOP, "auth-conf");
+  private SentryTransportFactory transportFactory;
+  private TTransport transport;
+  private Configuration conf;
 
-  public SentryHDFSServiceClientDefaultImpl(Configuration conf) throws IOException {
+  public SentryHDFSServiceClientDefaultImpl(Configuration conf, SentryHDFSClientTransportConfig transportConfig) throws IOException {
+    transportFactory = new SentryTransportFactory(conf, transportConfig);
     this.conf = 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);
-        // Resolve server host in the same way as we are doing on server side
-        serverPrincipal = SecurityUtil.getServerPrincipal(serverPrincipal, serverAddress.getAddress());
-        LOGGER.info("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);
-      } 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 sentry server
+   *
+   * @throws IOException
+   */
+  @Override
+  public synchronized void connect() throws IOException {
+    if (transport != null && transport.isOpen()) {
+      return;
     }
-    LOGGER.info("Successfully opened transport: " + transport + " to " + serverAddress);
+
+    transport = transportFactory.getTransport();
     TProtocol tProtocol = null;
     long maxMessageSize = conf.getLong(ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE,
-        ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT);
-    if (conf.getBoolean(ClientConfig.USE_COMPACT_TRANSPORT,
-        ClientConfig.USE_COMPACT_TRANSPORT_DEFAULT)) {
+            ServiceConstants.ClientConfig.SENTRY_HDFS_THRIFT_MAX_MESSAGE_SIZE_DEFAULT);
+    if (conf.getBoolean(ServiceConstants.ClientConfig.USE_COMPACT_TRANSPORT,
+            ServiceConstants.ClientConfig.USE_COMPACT_TRANSPORT_DEFAULT)) {
       tProtocol = new TCompactProtocol(transport, maxMessageSize, maxMessageSize);
     } else {
       tProtocol = new TBinaryProtocol(transport, maxMessageSize, maxMessageSize, true, true);
     }
     TMultiplexedProtocol protocol = new TMultiplexedProtocol(
-      tProtocol, SentryHDFSServiceClient.SENTRY_HDFS_SERVICE_NAME);
+            tProtocol, SentryHDFSServiceClient.SENTRY_HDFS_SERVICE_NAME);
+
     client = new SentryHDFSService.Client(protocol);
     LOGGER.info("Successfully created client");
   }
 
+  @Override
   public synchronized void notifyHMSUpdate(PathsUpdate update)
-      throws SentryHdfsServiceException {
+          throws SentryHdfsServiceException {
     try {
       client.handle_hms_notification(update.toThrift());
     } catch (Exception e) {
@@ -181,8 +99,9 @@ public class SentryHDFSServiceClientDefaultImpl implements SentryHDFSServiceClie
     }
   }
 
+  @Override
   public synchronized long getLastSeenHMSPathSeqNum()
-      throws SentryHdfsServiceException {
+          throws SentryHdfsServiceException {
     try {
       return client.check_hms_seq_num(-1);
     } catch (Exception e) {
@@ -190,8 +109,9 @@ public class SentryHDFSServiceClientDefaultImpl implements SentryHDFSServiceClie
     }
   }
 
+  @Override
   public synchronized SentryAuthzUpdate getAllUpdatesFrom(long permSeqNum, long pathSeqNum)
- throws SentryHdfsServiceException {
+          throws SentryHdfsServiceException {
     SentryAuthzUpdate retVal = new SentryAuthzUpdate(new LinkedList<PermissionsUpdate>(), new LinkedList<PathsUpdate>());
     try {
       TAuthzUpdateResponse sentryUpdates = client.get_all_authz_updates_from(permSeqNum, pathSeqNum);
@@ -211,9 +131,13 @@ public class SentryHDFSServiceClientDefaultImpl implements SentryHDFSServiceClie
     return retVal;
   }
 
-  public void close() {
-    if (transport != null) {
-      transport.close();
-    }
+  @Override
+  public synchronized void close() {
+    transportFactory.close();
+  }
+
+  @Override
+  public void disconnect() {
+    transportFactory.releaseTransport();
   }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientFactory.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientFactory.java b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientFactory.java
index 2a18b15..e350103 100644
--- a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientFactory.java
+++ b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceClientFactory.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.
@@ -17,20 +17,29 @@
  */
 package org.apache.sentry.hdfs;
 
+import java.lang.reflect.Proxy;
+
 import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.common.transport.RetryClientInvocationHandler;
+import org.apache.sentry.core.common.transport.SentryHDFSClientTransportConfig;
 
 /**
  * Client factory to create normal client or proxy with HA invocation handler
  */
 public class SentryHDFSServiceClientFactory {
-    
+  private final static SentryHDFSClientTransportConfig transportConfig =
+          new SentryHDFSClientTransportConfig();
+
   private SentryHDFSServiceClientFactory() {
     // Make constructor private to avoid instantiation
   }
-  
+
   public static SentryHDFSServiceClient create(Configuration conf)
-      throws Exception {
-    return new SentryHDFSServiceClientDefaultImpl(conf);
+    throws Exception {
+    return (SentryHDFSServiceClient) Proxy
+      .newProxyInstance(SentryHDFSServiceClientDefaultImpl.class.getClassLoader(),
+        SentryHDFSServiceClientDefaultImpl.class.getInterfaces(),
+        new RetryClientInvocationHandler(conf,
+          new SentryHDFSServiceClientDefaultImpl(conf, transportConfig), transportConfig));
   }
-
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java
index 4dc99a2..1ad9a02 100644
--- a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java
+++ b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java
@@ -22,7 +22,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.hdfs.service.thrift.SentryHDFSService;
 import org.apache.sentry.hdfs.service.thrift.SentryHDFSService.Iface;
 import org.apache.sentry.provider.db.service.persistent.SentryStore;
-import org.apache.sentry.provider.db.service.thrift.ThriftUtil;
+import org.apache.sentry.core.common.utils.ThriftUtil;
 import org.apache.sentry.service.thrift.ProcessorFactory;
 import org.apache.thrift.TException;
 import org.apache.thrift.TMultiplexedProcessor;

http://git-wip-us.apache.org/repos/asf/sentry/blob/14b3b904/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHdfsServiceException.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHdfsServiceException.java b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHdfsServiceException.java
deleted file mode 100644
index 307d8c3..0000000
--- a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHdfsServiceException.java
+++ /dev/null
@@ -1,33 +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.hdfs;
-
-public class SentryHdfsServiceException extends RuntimeException {
-  private static final long serialVersionUID = 1511645864949767378L;
-
-  public SentryHdfsServiceException(String message, Throwable cause) {
-    super(message, cause);
-  }
-
-  public SentryHdfsServiceException(String message) {
-    super(message);
-  }
-
-
-}

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/SentryGenericPolicyProcessor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
index 919b81b..0c51cc6 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
@@ -46,7 +46,7 @@ import org.apache.sentry.provider.db.log.entity.JsonLogEntityFactory;
 import org.apache.sentry.provider.db.log.util.Constants;
 import org.apache.sentry.provider.db.service.model.MSentryGMPrivilege;
 import org.apache.sentry.provider.db.service.model.MSentryRole;
-import org.apache.sentry.provider.db.service.thrift.PolicyStoreConstants;
+import org.apache.sentry.core.common.utils.PolicyStoreConstants;
 import org.apache.sentry.provider.db.service.thrift.SentryPolicyStoreProcessor;
 import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
 import org.apache.sentry.service.thrift.ServiceConstants.ThriftConstants;

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/SentryGenericPolicyProcessorWrapper.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessorWrapper.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessorWrapper.java
index d320d0f..a0fc2cc 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessorWrapper.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessorWrapper.java
@@ -18,7 +18,7 @@
 
 package org.apache.sentry.provider.db.generic.service.thrift;
 
-import org.apache.sentry.provider.db.service.thrift.ThriftUtil;
+import org.apache.sentry.core.common.utils.ThriftUtil;
 import org.apache.thrift.TException;
 import org.apache.thrift.protocol.TProtocol;