sentry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From co...@apache.org
Subject [1/6] sentry git commit: SENTRY-1288: Create sentry-service-client module(Colin Ma, reviewed by Dapeng Sun)
Date Mon, 27 Jun 2016 01:27:23 GMT
Repository: sentry
Updated Branches:
  refs/heads/SENTRY-1205 e72e6eacf -> 018750927


http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java
new file mode 100644
index 0000000..2d2dcb5
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java
@@ -0,0 +1,117 @@
+/**
+ * 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.tools.command.hive;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.PolicyFileConstants;
+import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.service.thrift.ServiceConstants;
+
+public final class CommandUtil {
+
+  public static final String SPLIT_CHAR = ",";
+  
+  private CommandUtil() {
+    // Make constructor private to avoid instantiation
+  }
+
+  // parse the privilege in String and get the TSentryPrivilege as result
+  public static TSentryPrivilege convertToTSentryPrivilege(String privilegeStr) throws Exception {
+    TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
+    for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
+      KeyValue tempKV = new KeyValue(authorizable);
+      String key = tempKV.getKey();
+      String value = tempKV.getValue();
+
+      if (PolicyFileConstants.PRIVILEGE_SERVER_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setServerName(value);
+      } else if (PolicyFileConstants.PRIVILEGE_DATABASE_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setDbName(value);
+      } else if (PolicyFileConstants.PRIVILEGE_TABLE_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setTableName(value);
+      } else if (PolicyFileConstants.PRIVILEGE_COLUMN_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setColumnName(value);
+      } else if (PolicyFileConstants.PRIVILEGE_URI_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setURI(value);
+      } else if (PolicyFileConstants.PRIVILEGE_ACTION_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setAction(value);
+      } else if (PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME.equalsIgnoreCase(key)) {
+        TSentryGrantOption grantOption = "true".equalsIgnoreCase(value) ? TSentryGrantOption.TRUE
+                : TSentryGrantOption.FALSE;
+        tSentryPrivilege.setGrantOption(grantOption);
+      }
+    }
+    tSentryPrivilege.setPrivilegeScope(getPrivilegeScope(tSentryPrivilege));
+    validatePrivilegeHierarchy(tSentryPrivilege);
+    return tSentryPrivilege;
+  }
+
+  // for the different hierarchy for hive:
+  // 1: server->url
+  // 2: server->database->table->column
+  // if both of them are found in the privilege string, the privilege scope will be set as
+  // PrivilegeScope.URI
+  private static String getPrivilegeScope(TSentryPrivilege tSentryPrivilege) {
+    ServiceConstants.PrivilegeScope privilegeScope = ServiceConstants.PrivilegeScope.SERVER;
+    if (!StringUtils.isEmpty(tSentryPrivilege.getURI())) {
+      privilegeScope = ServiceConstants.PrivilegeScope.URI;
+    } else if (!StringUtils.isEmpty(tSentryPrivilege.getColumnName())) {
+      privilegeScope = ServiceConstants.PrivilegeScope.COLUMN;
+    } else if (!StringUtils.isEmpty(tSentryPrivilege.getTableName())) {
+      privilegeScope = ServiceConstants.PrivilegeScope.TABLE;
+    } else if (!StringUtils.isEmpty(tSentryPrivilege.getDbName())) {
+      privilegeScope = ServiceConstants.PrivilegeScope.DATABASE;
+    }
+    return privilegeScope.toString();
+  }
+
+  // check the privilege value for the specific privilege scope
+  // eg, for the table scope, server and database can't be empty
+  private static void validatePrivilegeHierarchy(TSentryPrivilege tSentryPrivilege) throws Exception {
+    String serverName = tSentryPrivilege.getServerName();
+    String dbName = tSentryPrivilege.getDbName();
+    String tableName = tSentryPrivilege.getTableName();
+    String columnName = tSentryPrivilege.getColumnName();
+    String uri = tSentryPrivilege.getURI();
+    if (ServiceConstants.PrivilegeScope.SERVER.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      if (StringUtils.isEmpty(serverName)) {
+        throw new IllegalArgumentException("The hierarchy of privilege is not correct.");
+      }
+    } else if (ServiceConstants.PrivilegeScope.URI.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      if (StringUtils.isEmpty(serverName) || StringUtils.isEmpty(uri)) {
+        throw new IllegalArgumentException("The hierarchy of privilege is not correct.");
+      }
+    } else if (ServiceConstants.PrivilegeScope.DATABASE.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      if (StringUtils.isEmpty(serverName) || StringUtils.isEmpty(dbName)) {
+        throw new IllegalArgumentException("The hierarchy of privilege is not correct.");
+      }
+    } else if (ServiceConstants.PrivilegeScope.TABLE.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      if (StringUtils.isEmpty(serverName) || StringUtils.isEmpty(dbName)
+              || StringUtils.isEmpty(tableName)) {
+        throw new IllegalArgumentException("The hierarchy of privilege is not correct.");
+      }
+    } else if (ServiceConstants.PrivilegeScope.COLUMN.toString().equals(tSentryPrivilege.getPrivilegeScope())
+      && (StringUtils.isEmpty(serverName) || StringUtils.isEmpty(dbName)
+              || StringUtils.isEmpty(tableName) || StringUtils.isEmpty(columnName))) {
+        throw new IllegalArgumentException("The hierarchy of privilege is not correct.");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CreateRoleCmd.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CreateRoleCmd.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CreateRoleCmd.java
new file mode 100644
index 0000000..5a4834a
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CreateRoleCmd.java
@@ -0,0 +1,37 @@
+/**
+ * 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.tools.command.hive;
+
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
+
+/**
+ * The class for admin command to create role.
+ */
+public class CreateRoleCmd implements Command {
+
+  private String roleName;
+
+  public CreateRoleCmd(String roleName) {
+    this.roleName = roleName;
+  }
+
+  @Override
+  public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception {
+    client.createRole(requestorName, roleName);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/DropRoleCmd.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/DropRoleCmd.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/DropRoleCmd.java
new file mode 100644
index 0000000..facec0e
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/DropRoleCmd.java
@@ -0,0 +1,37 @@
+/**
+ * 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.tools.command.hive;
+
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
+
+/**
+ * The class for admin command to drop role.
+ */
+public class DropRoleCmd implements Command {
+
+  private String roleName;
+
+  public DropRoleCmd(String roleName) {
+    this.roleName = roleName;
+  }
+
+  @Override
+  public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception {
+    client.dropRole(requestorName, roleName);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantPrivilegeToRoleCmd.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantPrivilegeToRoleCmd.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantPrivilegeToRoleCmd.java
new file mode 100644
index 0000000..a1ef2f9
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantPrivilegeToRoleCmd.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
+ *
+ *     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.tools.command.hive;
+
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
+import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.service.thrift.ServiceConstants;
+
+/**
+ * The class for admin command to grant privilege to role.
+ */
+public class GrantPrivilegeToRoleCmd implements Command {
+
+  private String roleName;
+  private String privilegeStr;
+
+  public GrantPrivilegeToRoleCmd(String roleName, String privilegeStr) {
+    this.roleName = roleName;
+    this.privilegeStr = privilegeStr;
+  }
+
+  @Override
+  public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception {
+    TSentryPrivilege tSentryPrivilege = CommandUtil.convertToTSentryPrivilege(privilegeStr);
+    boolean grantOption = tSentryPrivilege.getGrantOption().equals(TSentryGrantOption.TRUE) ? true : false;
+    if (ServiceConstants.PrivilegeScope.SERVER.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.grantServerPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              tSentryPrivilege.getAction(), grantOption);
+    } else if (ServiceConstants.PrivilegeScope.DATABASE.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.grantDatabasePrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              tSentryPrivilege.getDbName(), tSentryPrivilege.getAction(), grantOption);
+    } else if (ServiceConstants.PrivilegeScope.TABLE.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.grantTablePrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              tSentryPrivilege.getDbName(), tSentryPrivilege.getTableName(),
+              tSentryPrivilege.getAction(), grantOption);
+    } else if (ServiceConstants.PrivilegeScope.COLUMN.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.grantColumnPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              tSentryPrivilege.getDbName(), tSentryPrivilege.getTableName(),
+              tSentryPrivilege.getColumnName(), tSentryPrivilege.getAction(), grantOption);
+    } else if (ServiceConstants.PrivilegeScope.URI.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.grantURIPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              tSentryPrivilege.getURI(), grantOption);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantRoleToGroupsCmd.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantRoleToGroupsCmd.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantRoleToGroupsCmd.java
new file mode 100644
index 0000000..07a3de4
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/GrantRoleToGroupsCmd.java
@@ -0,0 +1,44 @@
+/**
+ * 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.tools.command.hive;
+
+import com.google.common.collect.Sets;
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
+import org.apache.sentry.provider.db.tools.SentryShellCommon;
+
+import java.util.Set;
+
+/**
+ * The class for admin command to grant role to group.
+ */
+public class GrantRoleToGroupsCmd implements Command {
+
+  private String roleName;
+  private String groupNamesStr;
+
+  public GrantRoleToGroupsCmd(String roleName, String groupNamesStr) {
+    this.roleName = roleName;
+    this.groupNamesStr = groupNamesStr;
+  }
+
+  @Override
+  public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception {
+    Set<String> groups = Sets.newHashSet(groupNamesStr.split(SentryShellCommon.GROUP_SPLIT_CHAR));
+    client.grantRoleToGroups(requestorName, roleName, groups);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java
new file mode 100644
index 0000000..5f3e9fb
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java
@@ -0,0 +1,97 @@
+/**
+ * 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.tools.command.hive;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.lang.StringUtils;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.common.utils.PolicyFileConstants;
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
+import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * The class for admin command to list privileges.
+ */
+public class ListPrivilegesCmd implements Command {
+
+  private String roleName;
+
+  public ListPrivilegesCmd(String roleName) {
+    this.roleName = roleName;
+  }
+
+  @Override
+  public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception {
+    Set<TSentryPrivilege> privileges = client
+            .listAllPrivilegesByRoleName(requestorName, roleName);
+    if (privileges != null) {
+      for (TSentryPrivilege privilege : privileges) {
+        String privilegeStr = convertToPrivilegeStr(privilege);
+        System.out.println(privilegeStr);
+      }
+    }
+  }
+
+  // convert TSentryPrivilege to privilege in string
+  private String convertToPrivilegeStr(TSentryPrivilege tSentryPrivilege) {
+    List<String> privileges = Lists.newArrayList();
+    if (tSentryPrivilege != null) {
+      String serverName = tSentryPrivilege.getServerName();
+      String dbName = tSentryPrivilege.getDbName();
+      String tableName = tSentryPrivilege.getTableName();
+      String columnName = tSentryPrivilege.getColumnName();
+      String uri = tSentryPrivilege.getURI();
+      String action = tSentryPrivilege.getAction();
+      String grantOption = (tSentryPrivilege.getGrantOption() == TSentryGrantOption.TRUE ? "true"
+              : "false");
+      if (!StringUtils.isEmpty(serverName)) {
+        privileges.add(SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_SERVER_NAME,
+                serverName));
+        if (!StringUtils.isEmpty(uri)) {
+          privileges.add(SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_URI_NAME,
+                  uri));
+        } else if (!StringUtils.isEmpty(dbName)) {
+          privileges.add(SentryConstants.KV_JOINER.join(
+                  PolicyFileConstants.PRIVILEGE_DATABASE_NAME, dbName));
+          if (!StringUtils.isEmpty(tableName)) {
+            privileges.add(SentryConstants.KV_JOINER.join(
+                    PolicyFileConstants.PRIVILEGE_TABLE_NAME, tableName));
+            if (!StringUtils.isEmpty(columnName)) {
+              privileges.add(SentryConstants.KV_JOINER.join(
+                      PolicyFileConstants.PRIVILEGE_COLUMN_NAME, columnName));
+            }
+          }
+        }
+        if (!StringUtils.isEmpty(action)) {
+          privileges.add(SentryConstants.KV_JOINER.join(
+                  PolicyFileConstants.PRIVILEGE_ACTION_NAME, action));
+        }
+      }
+      // only append the grant option to privilege string if it's true
+      if ("true".equals(grantOption)) {
+        privileges.add(SentryConstants.KV_JOINER.join(
+                PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME, grantOption));
+      }
+    }
+    return SentryConstants.AUTHORIZABLE_JOINER.join(privileges);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListRolesCmd.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListRolesCmd.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListRolesCmd.java
new file mode 100644
index 0000000..283f2c0
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListRolesCmd.java
@@ -0,0 +1,51 @@
+/**
+ * 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.tools.command.hive;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
+import org.apache.sentry.provider.db.service.thrift.TSentryRole;
+
+import java.util.Set;
+
+/**
+ * The class for admin command to list roles.
+ */
+public class ListRolesCmd implements Command {
+
+  private String groupName;
+
+  public ListRolesCmd(String groupName) {
+    this.groupName = groupName;
+  }
+
+  @Override
+  public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception {
+    Set<TSentryRole> roles;
+    if (StringUtils.isEmpty(groupName)) {
+      roles = client.listRoles(requestorName);
+    } else {
+      roles = client.listRolesByGroupName(requestorName, groupName);
+    }
+    if (roles != null) {
+      for (TSentryRole role : roles) {
+        System.out.println(role.getRoleName());
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokePrivilegeFromRoleCmd.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokePrivilegeFromRoleCmd.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokePrivilegeFromRoleCmd.java
new file mode 100644
index 0000000..f3da6c4
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokePrivilegeFromRoleCmd.java
@@ -0,0 +1,62 @@
+/**
+ * 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.tools.command.hive;
+
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
+import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.service.thrift.ServiceConstants;
+
+/**
+ * The class for admin command to revoke privileges from role.
+ */
+public class RevokePrivilegeFromRoleCmd implements Command {
+
+  private String roleName;
+  private String privilegeStr;
+
+  public RevokePrivilegeFromRoleCmd(String roleName, String privilegeStr) {
+    this.roleName = roleName;
+    this.privilegeStr = privilegeStr;
+  }
+
+  @Override
+  public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception {
+    TSentryPrivilege tSentryPrivilege = CommandUtil.convertToTSentryPrivilege(privilegeStr);
+    boolean grantOption = tSentryPrivilege.getGrantOption().equals(TSentryGrantOption.TRUE) ? true : false;
+    if (ServiceConstants.PrivilegeScope.SERVER.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.revokeServerPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              grantOption);
+    } else if (ServiceConstants.PrivilegeScope.DATABASE.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.revokeDatabasePrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              tSentryPrivilege.getDbName(), tSentryPrivilege.getAction(), grantOption);
+    } else if (ServiceConstants.PrivilegeScope.TABLE.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.revokeTablePrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              tSentryPrivilege.getDbName(), tSentryPrivilege.getTableName(),
+              tSentryPrivilege.getAction(), grantOption);
+    } else if (ServiceConstants.PrivilegeScope.COLUMN.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.revokeColumnPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              tSentryPrivilege.getDbName(), tSentryPrivilege.getTableName(),
+              tSentryPrivilege.getColumnName(), tSentryPrivilege.getAction(), grantOption);
+    } else if (ServiceConstants.PrivilegeScope.URI.toString().equals(tSentryPrivilege.getPrivilegeScope())) {
+      client.revokeURIPrivilege(requestorName, roleName, tSentryPrivilege.getServerName(),
+              tSentryPrivilege.getURI(), grantOption);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokeRoleFromGroupsCmd.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokeRoleFromGroupsCmd.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokeRoleFromGroupsCmd.java
new file mode 100644
index 0000000..86773ca
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/provider/db/tools/command/hive/RevokeRoleFromGroupsCmd.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
+ *
+ *     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.tools.command.hive;
+
+import com.google.common.collect.Sets;
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
+
+import java.util.Set;
+
+/**
+ * The class for admin command to revoke role from group.
+ */
+public class RevokeRoleFromGroupsCmd implements Command {
+
+  private String roleName;
+  private String groupNamesStr;
+
+  public RevokeRoleFromGroupsCmd(String roleName, String groupNamesStr) {
+    this.roleName = roleName;
+    this.groupNamesStr = groupNamesStr;
+  }
+
+  @Override
+  public void execute(SentryPolicyServiceClient client, String requestorName) throws Exception {
+    Set<String> groups = Sets.newHashSet(groupNamesStr.split(CommandUtil.SPLIT_CHAR));
+    client.revokeRoleFromGroups(requestorName, roleName, groups);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/HAClientInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/HAClientInvocationHandler.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/HAClientInvocationHandler.java
new file mode 100644
index 0000000..d97a07e
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/HAClientInvocationHandler.java
@@ -0,0 +1,139 @@
+/**
+ * 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.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.SecurityUtil;
+import org.apache.curator.x.discovery.ServiceInstance;
+import org.apache.sentry.core.common.exception.SentryUserException;
+import org.apache.sentry.provider.db.service.persistent.HAContext;
+import org.apache.sentry.provider.db.service.persistent.ServiceManager;
+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.ServerConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+public class HAClientInvocationHandler extends SentryClientInvocationHandler {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(HAClientInvocationHandler.class);
+
+  private final Configuration conf;
+  private ServiceManager manager;
+  private ServiceInstance<Void> currentServiceInstance;
+  private SentryPolicyServiceClient client = null;
+
+  private static final String THRIFT_EXCEPTION_MESSAGE = "Thrift exception occured ";
+  public static final String SENTRY_HA_ERROR_MESSAGE = "No Sentry server available. Please ensure that at least one Sentry server is online";
+
+  public HAClientInvocationHandler(Configuration conf) throws Exception {
+    this.conf = conf;
+    checkClientConf();
+  }
+
+  @Override
+  public Object invokeImpl(Object proxy, Method method, Object[] args) throws
+      SentryUserException {
+    Object result = null;
+    try {
+      if (!method.isAccessible()) {
+        method.setAccessible(true);
+      }
+      // The client is initialized in the first call instead of constructor.
+      // This way we can propagate the connection exception to caller cleanly
+      if (client == null) {
+        renewSentryClient();
+      }
+      result = method.invoke(client, args);
+    } catch (IllegalAccessException e) {
+      throw new SentryUserException(e.getMessage(), e.getCause());
+    } catch (InvocationTargetException e) {
+      if (e.getTargetException() instanceof SentryUserException) {
+        throw (SentryUserException)e.getTargetException();
+      } else {
+        LOGGER.warn(THRIFT_EXCEPTION_MESSAGE + ": Error in connect current" +
+            " service, will retry other service.", e);
+        if (client != null) {
+          client.close();
+          client = null;
+        }
+      }
+    } catch (IOException e1) {
+      throw new SentryUserException("Error connecting to sentry service "
+          + e1.getMessage(), e1);
+    }
+    return result;
+  }
+
+  // Retrieve the new connection endpoint from ZK and connect to new server
+  private void renewSentryClient() throws IOException {
+    try {
+      manager = new ServiceManager(HAContext.getHAContext(conf));
+    } catch (Exception e1) {
+      throw new IOException("Failed to extract Sentry node info from zookeeper", e1);
+    }
+
+    try {
+      while (true) {
+        currentServiceInstance = manager.getServiceInstance();
+        if (currentServiceInstance == null) {
+          throw new IOException(SENTRY_HA_ERROR_MESSAGE);
+        }
+        InetSocketAddress serverAddress =
+            ServiceManager.convertServiceInstance(currentServiceInstance);
+        conf.set(ServiceConstants.ClientConfig.SERVER_RPC_ADDRESS, serverAddress.getHostName());
+        conf.setInt(ServiceConstants.ClientConfig.SERVER_RPC_PORT, serverAddress.getPort());
+        try {
+          client = new SentryPolicyServiceClientDefaultImpl(conf);
+          LOGGER.info("Sentry Client using server " + serverAddress.getHostName() +
+              ":" + serverAddress.getPort());
+          break;
+        } catch (IOException e) {
+          manager.reportError(currentServiceInstance);
+          LOGGER.info("Transport exception while opening transport:", e, e.getMessage());
+        }
+      }
+    } finally {
+      manager.close();
+    }
+  }
+
+  private void checkClientConf() {
+    if (conf.getBoolean(ServerConfig.SENTRY_HA_ZOOKEEPER_SECURITY,
+        ServerConfig.SENTRY_HA_ZOOKEEPER_SECURITY_DEFAULT)) {
+      String serverPrincipal = Preconditions.checkNotNull(conf.get(ServerConfig.PRINCIPAL),
+          ServerConfig.PRINCIPAL + " is required");
+      Preconditions.checkArgument(serverPrincipal.contains(SecurityUtil.HOSTNAME_PATTERN),
+          ServerConfig.PRINCIPAL + " : " + serverPrincipal + " should contain " + SecurityUtil.HOSTNAME_PATTERN);
+    }
+  }
+
+  @Override
+  public void close() {
+    if (client != null) {
+      client.close();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/PoolClientInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/PoolClientInvocationHandler.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/PoolClientInvocationHandler.java
new file mode 100644
index 0000000..a35bf1d
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/PoolClientInvocationHandler.java
@@ -0,0 +1,154 @@
+/**
+ * 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.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.commons.pool2.PooledObjectFactory;
+import org.apache.commons.pool2.impl.AbandonedConfig;
+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.provider.db.service.thrift.SentryPolicyServiceClient;
+import org.apache.sentry.service.thrift.ServiceConstants.ClientConfig;
+import org.apache.thrift.transport.TTransportException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The PoolClientInvocationHandler is a proxy class for handling thrift call. For every thrift call,
+ * get the instance of SentryPolicyServiceBaseClient from the commons-pool, and return the instance
+ * to the commons-pool after complete the call. For any exception with the call, discard the
+ * instance and create a new one added to the commons-pool. Then, get the instance and do the call
+ * again. For the thread safe, the commons-pool will manage the connection pool, and every thread
+ * can get the connection by borrowObject() and return the connection to the pool by returnObject().
+ */
+
+public class PoolClientInvocationHandler extends SentryClientInvocationHandler {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(PoolClientInvocationHandler.class);
+
+  private final Configuration conf;
+  private PooledObjectFactory<SentryPolicyServiceClient> poolFactory;
+  private GenericObjectPool<SentryPolicyServiceClient> pool;
+  private GenericObjectPoolConfig poolConfig;
+  private int connectionRetryTotal;
+
+  private static final String POOL_EXCEPTION_MESSAGE = "Pool exception occured ";
+
+  public PoolClientInvocationHandler(Configuration conf) throws Exception {
+    this.conf = conf;
+    readConfiguration();
+    poolFactory = new SentryServiceClientPoolFactory(conf);
+    pool = new GenericObjectPool<SentryPolicyServiceClient>(poolFactory, poolConfig, new AbandonedConfig());
+  }
+
+  @Override
+  public Object invokeImpl(Object proxy, Method method, Object[] args) throws Exception {
+    int retryCount = 0;
+    Object result = null;
+    while (retryCount < connectionRetryTotal) {
+      try {
+        // The wapper here is for the retry of thrift call, the default retry number is 3.
+        result = invokeFromPool(method, args);
+        break;
+      } catch (TTransportException e) {
+        // TTransportException means there has connection problem, create a new connection and try
+        // again. Get the lock of pool and add new connection.
+        synchronized (pool) {
+          // If there has room, create new instance and add it to the commons-pool, this instance
+          // will be back first from the commons-pool because the configuration is LIFO.
+          if (pool.getNumIdle() + pool.getNumActive() < pool.getMaxTotal()) {
+            pool.addObject();
+          }
+        }
+        // Increase the retry num, and throw the exception if can't retry again.
+        retryCount++;
+        if (retryCount == connectionRetryTotal) {
+          throw new SentryUserException(e.getMessage(), e);
+        }
+      }
+    }
+    return result;
+  }
+
+  private Object invokeFromPool(Method method, Object[] args) throws Exception {
+    Object result = null;
+    SentryPolicyServiceClient client;
+    try {
+      // get the connection from the pool, don't know if the connection is broken.
+      client = pool.borrowObject();
+    } catch (Exception e) {
+      LOGGER.debug(POOL_EXCEPTION_MESSAGE, e);
+      throw new SentryUserException(e.getMessage(), e);
+    }
+    try {
+      // do the thrift call
+      result = 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) {
+          // If the exception is caused by connection problem, destroy the instance and
+          // remove it from the commons-pool. Throw the TTransportException for reconnect.
+          pool.invalidateObject(client);
+          throw new TTransportException(sentryTargetException);
+        }
+        // The exception is thrown by thrift call, eg, SentryAccessDeniedException.
+        throw (SentryUserException) targetException;
+      }
+      throw e;
+    } finally{
+      try {
+        // return the instance to commons-pool
+        pool.returnObject(client);
+      } catch (Exception e) {
+        LOGGER.error(POOL_EXCEPTION_MESSAGE, e);
+        throw e;
+      }
+    }
+    return result;
+  }
+
+  @Override
+  public void close() {
+    try {
+      pool.close();
+    } catch (Exception e) {
+      LOGGER.debug(POOL_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  private void readConfiguration() {
+    poolConfig = new GenericObjectPoolConfig();
+    // config the pool size for commons-pool
+    poolConfig.setMaxTotal(conf.getInt(ClientConfig.SENTRY_POOL_MAX_TOTAL, ClientConfig.SENTRY_POOL_MAX_TOTAL_DEFAULT));
+    poolConfig.setMinIdle(conf.getInt(ClientConfig.SENTRY_POOL_MIN_IDLE, ClientConfig.SENTRY_POOL_MIN_IDLE_DEFAULT));
+    poolConfig.setMaxIdle(conf.getInt(ClientConfig.SENTRY_POOL_MAX_IDLE, ClientConfig.SENTRY_POOL_MAX_IDLE_DEFAULT));
+    // get the retry number for reconnecting service
+    connectionRetryTotal = conf.getInt(ClientConfig.SENTRY_POOL_RETRY_TOTAL,
+        ClientConfig.SENTRY_POOL_RETRY_TOTAL_DEFAULT);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryClientInvocationHandler.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryClientInvocationHandler.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryClientInvocationHandler.java
new file mode 100644
index 0000000..a41be7f
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/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.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
+   */
+  public 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/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientFactory.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientFactory.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientFactory.java
new file mode 100644
index 0000000..48ee66a
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientFactory.java
@@ -0,0 +1,52 @@
+/**
+ * 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.Proxy;
+
+import org.apache.hadoop.conf.Configuration;
+
+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 SentryServiceClientFactory() {
+  }
+
+  public static SentryPolicyServiceClient create(Configuration conf) throws Exception {
+    boolean haEnabled = conf.getBoolean(ClientConfig.SERVER_HA_ENABLED, false);
+    boolean pooled = conf.getBoolean(ClientConfig.SENTRY_POOL_ENABLED, false);
+    if (pooled) {
+      return (SentryPolicyServiceClient) Proxy
+          .newProxyInstance(SentryPolicyServiceClientDefaultImpl.class.getClassLoader(),
+              SentryPolicyServiceClientDefaultImpl.class.getInterfaces(),
+              new PoolClientInvocationHandler(conf));
+    } else if (haEnabled) {
+      return (SentryPolicyServiceClient) Proxy
+          .newProxyInstance(SentryPolicyServiceClientDefaultImpl.class.getClassLoader(),
+              SentryPolicyServiceClientDefaultImpl.class.getInterfaces(),
+              new HAClientInvocationHandler(conf));
+    } else {
+      return new SentryPolicyServiceClientDefaultImpl(conf);
+    }
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientPoolFactory.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientPoolFactory.java b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientPoolFactory.java
new file mode 100644
index 0000000..3a38b24
--- /dev/null
+++ b/sentry-service/sentry-service-client/src/main/java/org/apache/sentry/service/thrift/SentryServiceClientPoolFactory.java
@@ -0,0 +1,78 @@
+/**
+ * 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.Proxy;
+
+import org.apache.commons.pool2.BasePooledObjectFactory;
+import org.apache.commons.pool2.PooledObject;
+import org.apache.commons.pool2.impl.DefaultPooledObject;
+import org.apache.hadoop.conf.Configuration;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SentryServiceClientPoolFactory is for connection pool to manage the object. Implement the related
+ * method to create object, destroy object and wrap object.
+ */
+
+public class SentryServiceClientPoolFactory extends BasePooledObjectFactory<SentryPolicyServiceClient> {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(SentryServiceClientPoolFactory.class);
+
+  private Configuration conf;
+
+  public SentryServiceClientPoolFactory(Configuration conf) {
+    this.conf = conf;
+  }
+
+  @Override
+  public SentryPolicyServiceClient create() throws Exception {
+    LOGGER.debug("Creating Sentry Service Client...");
+    boolean haEnabled = conf.getBoolean(ClientConfig.SERVER_HA_ENABLED, false);
+    if (haEnabled) {
+      return (SentryPolicyServiceClient) Proxy
+          .newProxyInstance(SentryPolicyServiceClientDefaultImpl.class.getClassLoader(),
+              SentryPolicyServiceClientDefaultImpl.class.getInterfaces(),
+              new HAClientInvocationHandler(conf));
+    } else {
+      return new SentryPolicyServiceClientDefaultImpl(conf);
+    }
+  }
+
+  @Override
+  public PooledObject<SentryPolicyServiceClient> wrap(SentryPolicyServiceClient client) {
+    return new DefaultPooledObject<SentryPolicyServiceClient>(client);
+  }
+
+  @Override
+  public void destroyObject(PooledObject<SentryPolicyServiceClient> pooledObject) {
+    SentryPolicyServiceClient client = pooledObject.getObject();
+    LOGGER.debug("Destroying Sentry Service Client: " + client);
+    if (client != null) {
+      // The close() of TSocket or TSaslClientTransport is called actually, and there has no
+      // exception even there has some problems, eg, the client is closed already.
+      // The close here is just try to close the socket and the client will be destroyed soon.
+      client.close();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/01875092/sentry-service/sentry-service-server/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/pom.xml b/sentry-service/sentry-service-server/pom.xml
index d327bf6..6cfd982 100644
--- a/sentry-service/sentry-service-server/pom.xml
+++ b/sentry-service/sentry-service-server/pom.xml
@@ -33,6 +33,10 @@ limitations under the License.
       <artifactId>commons-lang</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.derby</groupId>
+      <artifactId>derby</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
     </dependency>
@@ -54,7 +58,7 @@ limitations under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-service-common</artifactId>
+      <artifactId>sentry-service-client</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
@@ -112,10 +116,6 @@ limitations under the License.
       <artifactId>jetty-servlet</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-db</artifactId>
-    </dependency>
-    <dependency>
       <groupId>org.apache.hive</groupId>
       <artifactId>hive-beeline</artifactId>
     </dependency>


Mime
View raw message