http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/bf3eb482/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
new file mode 100644
index 0000000..d6600a0
--- /dev/null
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
@@ -0,0 +1,549 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.provider.db.generic.service.thrift;
+
+import static 
org.apache.sentry.provider.common.ProviderConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.provider.common.ProviderConstants.KV_JOINER;
+
+import java.lang.reflect.Constructor;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.SentryUserException;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
+import org.apache.sentry.provider.db.SentryAlreadyExistsException;
+import org.apache.sentry.provider.db.SentryInvalidInputException;
+import org.apache.sentry.provider.db.SentryNoSuchObjectException;
+import 
org.apache.sentry.provider.db.generic.service.persistent.PrivilegeObject;
+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.persistent.CommitContext;
+import org.apache.sentry.provider.db.service.thrift.PolicyStoreConstants;
+import 
org.apache.sentry.provider.db.service.thrift.SentryConfigurationException;
+import org.apache.sentry.provider.db.service.thrift.SentryPolicyStoreProcessor;
+import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
+import org.apache.sentry.service.thrift.Status;
+import org.apache.sentry.service.thrift.TSentryResponseStatus;
+import org.apache.thrift.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+public class SentryGenericPolicyProcessor implements 
SentryGenericPolicyService.Iface {
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(SentryGenericPolicyProcessor.class);
+  private final Configuration conf;
+  private final ImmutableSet<String> adminGroups;
+  private final SentryStoreLayer store;
+  private final NotificationHandlerInvoker handerInvoker;
+
+  public static final String SENTRY_GENERIC_SERVICE_NAME = 
"SentryGenericPolicyService";
+
+  public SentryGenericPolicyProcessor(Configuration conf) throws Exception {
+    this.store = createStore(conf);
+    this.handerInvoker = new NotificationHandlerInvoker(createHandlers(conf));
+    this.conf = conf;
+    adminGroups = 
ImmutableSet.copyOf(toTrimedLower(Sets.newHashSet(conf.getStrings(
+        ServerConfig.ADMIN_GROUPS, new String[]{}))));
+  }
+
+  @VisibleForTesting
+  public SentryGenericPolicyProcessor(Configuration conf, SentryStoreLayer 
store) throws Exception {
+    this.store = store;
+    this.handerInvoker = new NotificationHandlerInvoker(createHandlers(conf));
+    this.conf = conf;
+    adminGroups = 
ImmutableSet.copyOf(toTrimedLower(Sets.newHashSet(conf.getStrings(
+        ServerConfig.ADMIN_GROUPS, new String[]{}))));
+  }
+
+  private void authorize(String requestorUser, Set<String> requestorGroups)
+  throws SentryAccessDeniedException {
+    if (!inAdminGroups(requestorGroups)) {
+      String msg = "User: " + requestorUser + " is part of " + requestorGroups 
+
+          " which does not, intersect admin groups " + adminGroups;
+      LOGGER.warn(msg);
+      throw new SentryAccessDeniedException("Access denied to " + 
requestorUser);
+    }
+  }
+
+  private Set<String> toTrimedLower(Set<String> s) {
+    if (null == s) return new HashSet<String>();
+    Set<String> result = Sets.newHashSet();
+    for (String v : s) {
+      result.add(v.trim().toLowerCase());
+    }
+    return result;
+  }
+
+  private String toTrimedLower(String s) {
+    if (Strings.isNullOrEmpty(s)){
+      return "";
+    }
+    return s.trim().toLowerCase();
+  }
+
+  public static Set<String> getRequestorGroups(Configuration conf, String 
userName) throws SentryUserException {
+    return SentryPolicyStoreProcessor.getGroupsFromUserName(conf, userName);
+  }
+
+  private boolean inAdminGroups(Set<String> requestorGroups) {
+    requestorGroups = toTrimedLower(requestorGroups);
+    if (Sets.intersection(adminGroups, requestorGroups).isEmpty()) {
+      return false;
+    } else return true;
+  }
+
+  public static SentryStoreLayer createStore(Configuration conf) throws 
SentryConfigurationException {
+    SentryStoreLayer storeLayer = null;
+    String Store = conf.get(PolicyStoreConstants.SENTRY_GENERIC_POLICY_STORE,
+        PolicyStoreConstants.SENTRY_GENERIC_POLICY_STORE_DEFAULT);
+
+    if (Strings.isNullOrEmpty(Store)) {
+      throw new SentryConfigurationException("the parameter configuration for 
sentry.generic.policy.store can't be empty");
+    }
+    try {
+      storeLayer = createInstance(Store, conf, SentryStoreLayer.class);
+    } catch (Exception e) {
+      throw new SentryConfigurationException("Create sentryStore error: " + 
e.getMessage(), e);
+    }
+    return storeLayer;
+  }
+
+  public static List<NotificationHandler> createHandlers(Configuration conf) 
throws SentryConfigurationException {
+
+    List<NotificationHandler> handlers = Lists.newArrayList();
+    Iterable<String> notificationHandlers = 
Splitter.onPattern("[\\s,]").trimResults()
+        
.omitEmptyStrings().split(conf.get(PolicyStoreConstants.SENTRY_GENERIC_POLICY_NOTIFICATION,
 ""));
+    try {
+      for (String notificationHandler : notificationHandlers) {
+        handlers.add(createInstance(notificationHandler, conf, 
NotificationHandler.class));
+      }
+    } catch (Exception e) {
+      throw new SentryConfigurationException("Create notificationHandlers 
error: " + e.getMessage(), e);
+    }
+    return handlers;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> T createInstance(String className, Configuration conf, 
Class<T> iface) throws Exception {
+    T result;
+    try {
+      Class clazz = Class.forName(className);
+      if (!iface.isAssignableFrom(clazz)) {
+        throw new IllegalArgumentException("Class " + clazz + " is not a " +
+                                                 iface.getName());
+      }
+      Constructor<T> meth = 
(Constructor<T>)clazz.getDeclaredConstructor(Configuration.class);
+      meth.setAccessible(true);
+      result = meth.newInstance(new Object[]{conf});
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+    return result;
+  }
+
+  private <T> Response<T> requestHandle(RequestHandler<T> handler) {
+    Response<T> response = new Response<T>();
+    try {
+      response = handler.handle();
+    } catch (SentryAccessDeniedException e) {
+      LOGGER.error(e.getMessage(), e);
+      response.status = Status.AccessDenied(e.getMessage(), e);
+    } catch (SentryAlreadyExistsException e) {
+      LOGGER.error(e.getMessage(), e);
+      response.status = Status.AlreadyExists(e.getMessage(), e);
+    } catch (SentryNoSuchObjectException e) {
+      LOGGER.error(e.getMessage(), e);
+      response.status = Status.NoSuchObject(e.getMessage(), e);
+    } catch (SentryInvalidInputException e) {
+      String msg = "Invalid input privilege object";
+      LOGGER.error(msg, e);
+      response.status = Status.InvalidInput(msg, e);
+    } catch (Exception e) {
+      String msg = "Unknown error:" + e.getMessage();
+      LOGGER.error(msg, e);
+      response.status = Status.RuntimeError(msg, e);
+    }
+    return response;
+  }
+
+  private PrivilegeObject toPrivilegeObject(TSentryPrivilege tSentryPrivilege) 
{
+    Boolean grantOption;
+    if (tSentryPrivilege.getGrantOption().equals(TSentryGrantOption.TRUE)) {
+      grantOption = true;
+    } else if 
(tSentryPrivilege.getGrantOption().equals(TSentryGrantOption.FALSE)) {
+      grantOption = false;
+    } else {
+      grantOption = null;
+    }
+    return new Builder().setComponent(tSentryPrivilege.getComponent())
+                                             
.setService(tSentryPrivilege.getServiceName())
+                                             
.setAuthorizables(toAuthorizables(tSentryPrivilege.getAuthorizables()))
+                                             
.setAction(tSentryPrivilege.getAction())
+                                             .withGrantOption(grantOption)
+                                             .build();
+  }
+
+  private TSentryPrivilege fromPrivilegeObject(PrivilegeObject privilege) {
+
+    TSentryPrivilege tPrivilege = new 
TSentryPrivilege(privilege.getComponent(), privilege.getService(),
+                                                       
fromAuthorizable(privilege.getAuthorizables()),
+                                                       privilege.getAction());
+    if (privilege.getGrantOption() == null) {
+      tPrivilege.setGrantOption(TSentryGrantOption.UNSET);
+    } else if (privilege.getGrantOption()) {
+      tPrivilege.setGrantOption(TSentryGrantOption.TRUE);
+    } else {
+      tPrivilege.setGrantOption(TSentryGrantOption.FALSE);
+    }
+    return tPrivilege;
+  }
+
+  private List<TAuthorizable> fromAuthorizable(List<? extends Authorizable> 
authorizables) {
+    List<TAuthorizable> tAuthorizables = Lists.newArrayList();
+    for (Authorizable authorizable : authorizables) {
+      tAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), 
authorizable.getName()));
+    }
+    return tAuthorizables;
+  }
+
+  private List<? extends Authorizable> toAuthorizables(List<TAuthorizable> 
tAuthorizables) {
+    List<Authorizable> authorizables = Lists.newArrayList();
+    if (tAuthorizables == null) {
+      return authorizables;
+    }
+    for (final TAuthorizable tAuthorizable : tAuthorizables) {
+      authorizables.add(new Authorizable() {
+        @Override
+        public String getTypeName() {
+          return tAuthorizable.getType();
+        }
+        @Override
+        public String getName() {
+          return tAuthorizable.getName();
+        }
+      });
+    }
+    return authorizables;
+  }
+
+  private Set<String> buildPermissions(Set<PrivilegeObject> privileges) {
+    Set<String> permissions = Sets.newHashSet();
+    for (PrivilegeObject privilege : privileges) {
+      List<String> hierarchy = Lists.newArrayList();
+      for (Authorizable authorizable : privilege.getAuthorizables()) {
+        
hierarchy.add(KV_JOINER.join(authorizable.getTypeName(),authorizable.getName()));
+      }
+      hierarchy.add(KV_JOINER.join("action", privilege.getAction()));
+      permissions.add(AUTHORIZABLE_JOINER.join(hierarchy));
+    }
+    return permissions;
+  }
+
+  @Override
+  public TCreateSentryRoleResponse create_sentry_role(
+      final TCreateSentryRoleRequest request) throws TException {
+    Response<Void> respose = requestHandle(new RequestHandler<Void>() {
+      @Override
+      public Response<Void> handle() throws Exception {
+        authorize(request.getRequestorUserName(),
+            getRequestorGroups(conf, request.getRequestorUserName()));
+        CommitContext context = store.createRole(request.getComponent(), 
request.getRoleName(), request.getRequestorUserName());
+        return new Response<Void>(Status.OK(), context);
+      }
+    });
+
+    TCreateSentryRoleResponse tResponse = new 
TCreateSentryRoleResponse(respose.status);
+    if (Status.OK.getCode() == respose.status.getValue()) {
+      handerInvoker.create_sentry_role(respose.context, request, tResponse);
+    }
+    return tResponse;
+  }
+
+  @Override
+  public TDropSentryRoleResponse drop_sentry_role(final TDropSentryRoleRequest 
request)
+      throws TException {
+    Response<Void> respose = requestHandle(new RequestHandler<Void>() {
+      @Override
+      public Response<Void> handle() throws Exception {
+        authorize(request.getRequestorUserName(),
+            getRequestorGroups(conf, request.getRequestorUserName()));
+        CommitContext context = store.dropRole(request.getComponent(), 
request.getRoleName(), request.getRequestorUserName());
+        return new Response<Void>(Status.OK(), context);
+      }
+    });
+
+    TDropSentryRoleResponse tResponse = new 
TDropSentryRoleResponse(respose.status);
+    if (Status.OK.getCode() == respose.status.getValue()) {
+      handerInvoker.drop_sentry_role(respose.context, request, tResponse);
+    }
+    return tResponse;
+  }
+
+  @Override
+  public TAlterSentryRoleGrantPrivilegeResponse 
alter_sentry_role_grant_privilege(
+      final TAlterSentryRoleGrantPrivilegeRequest request) throws TException {
+    Response<Void> respose = requestHandle(new RequestHandler<Void>() {
+      @Override
+      public Response<Void> handle() throws Exception {
+        CommitContext context = 
store.alterRoleGrantPrivilege(request.getComponent(), request.getRoleName(),
+                                           
toPrivilegeObject(request.getPrivilege()),
+                                           request.getRequestorUserName());
+       return new Response<Void>(Status.OK(), context);
+      }
+    });
+
+    TAlterSentryRoleGrantPrivilegeResponse tResponse = new 
TAlterSentryRoleGrantPrivilegeResponse(respose.status);
+    if (Status.OK.getCode() == respose.status.getValue()) {
+      handerInvoker.alter_sentry_role_grant_privilege(respose.context, 
request, tResponse);
+    }
+    return tResponse;
+  }
+
+  @Override
+  public TAlterSentryRoleRevokePrivilegeResponse 
alter_sentry_role_revoke_privilege(
+      final TAlterSentryRoleRevokePrivilegeRequest request) throws TException {
+    Response<Void> respose = requestHandle(new RequestHandler<Void>() {
+      @Override
+      public Response<Void> handle() throws Exception {
+        CommitContext context = 
store.alterRoleRevokePrivilege(request.getComponent(), request.getRoleName(),
+                                           
toPrivilegeObject(request.getPrivilege()),
+                                           request.getRequestorUserName());
+       return new Response<Void>(Status.OK(), context);
+      }
+    });
+
+    TAlterSentryRoleRevokePrivilegeResponse tResponse = new 
TAlterSentryRoleRevokePrivilegeResponse(respose.status);
+    if (Status.OK.getCode() == respose.status.getValue()) {
+      handerInvoker.alter_sentry_role_revoke_privilege(respose.context, 
request, tResponse);
+    }
+    return tResponse;
+  }
+
+  @Override
+  public TAlterSentryRoleAddGroupsResponse alter_sentry_role_add_groups(
+      final TAlterSentryRoleAddGroupsRequest request) throws TException {
+    Response<Void> respose = requestHandle(new RequestHandler<Void>() {
+      @Override
+      public Response<Void> handle() throws Exception {
+        authorize(request.getRequestorUserName(),
+            getRequestorGroups(conf, request.getRequestorUserName()));
+        CommitContext context = store.alterRoleAddGroups(
+            request.getComponent(), request.getRoleName(), request.getGroups(),
+            request.getRequestorUserName());
+        return new Response<Void>(Status.OK(), context);
+      }
+    });
+
+    TAlterSentryRoleAddGroupsResponse tResponse = new 
TAlterSentryRoleAddGroupsResponse(respose.status);
+    if (Status.OK.getCode() == respose.status.getValue()) {
+      handerInvoker.alter_sentry_role_add_groups(respose.context, request, 
tResponse);
+    }
+    return tResponse;
+  }
+
+  @Override
+  public TAlterSentryRoleDeleteGroupsResponse alter_sentry_role_delete_groups(
+      final TAlterSentryRoleDeleteGroupsRequest request) throws TException {
+    Response<Void> respose = requestHandle(new RequestHandler<Void>() {
+      @Override
+      public Response<Void> handle() throws Exception {
+        authorize(request.getRequestorUserName(),
+            getRequestorGroups(conf, request.getRequestorUserName()));
+        CommitContext context = store.alterRoleDeleteGroups(
+            request.getComponent(), request.getRoleName(), request.getGroups(),
+            request.getRequestorUserName());
+        return new Response<Void>(Status.OK(), context);
+      }
+    });
+
+    TAlterSentryRoleDeleteGroupsResponse tResponse = new 
TAlterSentryRoleDeleteGroupsResponse(respose.status);
+    if (Status.OK.getCode() == respose.status.getValue()) {
+      handerInvoker.alter_sentry_role_delete_groups(respose.context, request, 
tResponse);
+    }
+    return tResponse;
+  }
+
+  @Override
+  public TListSentryRolesResponse list_sentry_roles_by_group(
+      final TListSentryRolesRequest request) throws TException {
+    Response<Set<TSentryRole>> respose = requestHandle(new 
RequestHandler<Set<TSentryRole>>() {
+      @Override
+      public Response<Set<TSentryRole>> handle() throws Exception {
+        Set<String> groups = getRequestorGroups(conf, 
request.getRequestorUserName());
+        if (AccessConstants.ALL.equalsIgnoreCase(request.getGroupName())) {
+          //check all groups which requestorUserName belongs to
+        } else {
+          boolean admin = inAdminGroups(groups);
+          //Only admin users can list all roles in the system ( groupname = 
null)
+          //Non admin users are only allowed to list only groups which they 
belong to
+          if(!admin && (request.getGroupName() == null || 
!groups.contains(request.getGroupName()))) {
+            throw new SentryAccessDeniedException("Access denied to " + 
request.getRequestorUserName());
+          }
+          groups.clear();
+          groups.add(request.getGroupName());
+        }
+
+        Set<String> roleNames = store.getRolesByGroups(request.getComponent(), 
groups);
+        Set<TSentryRole> tSentryRoles = Sets.newHashSet();
+        for (String roleName : roleNames) {
+          Set<String> groupsForRoleName = 
store.getGroupsByRoles(request.getComponent(), Sets.newHashSet(roleName));
+          tSentryRoles.add(new TSentryRole(roleName, groupsForRoleName));
+        }
+        return new Response<Set<TSentryRole>>(Status.OK(), tSentryRoles);
+      }
+    });
+    TListSentryRolesResponse tResponse = new TListSentryRolesResponse();
+    tResponse.setStatus(respose.status);
+    tResponse.setRoles(respose.content);
+    return tResponse;
+  }
+
+  @Override
+  public TListSentryPrivilegesResponse list_sentry_privileges_by_role(
+      final TListSentryPrivilegesRequest request) throws TException {
+    Response<Set<TSentryPrivilege>> respose = requestHandle(new 
RequestHandler<Set<TSentryPrivilege>>() {
+      @Override
+      public Response<Set<TSentryPrivilege>> handle() throws Exception {
+        Set<String> groups = getRequestorGroups(conf, 
request.getRequestorUserName());
+        if (!inAdminGroups(groups)) {
+          Set<String> roleNamesForGroups = 
toTrimedLower(store.getRolesByGroups(request.getComponent(), groups));
+          if 
(!roleNamesForGroups.contains(toTrimedLower(request.getRoleName()))) {
+            throw new SentryAccessDeniedException("Access denied to " + 
request.getRequestorUserName());
+          }
+        }
+        Set<PrivilegeObject> privileges = 
store.getPrivilegesByProvider(request.getComponent(),
+                                                                        
request.getServiceName(),
+                                                                        
Sets.newHashSet(request.getRoleName()),
+                                                                        null,
+                                                                        
toAuthorizables(request.getAuthorizables()));
+        Set<TSentryPrivilege> tSentryPrivileges = Sets.newHashSet();
+        for (PrivilegeObject privilege : privileges) {
+          tSentryPrivileges.add(fromPrivilegeObject(privilege));
+        }
+        return new Response<Set<TSentryPrivilege>>(Status.OK(), 
tSentryPrivileges);
+      }
+    });
+    TListSentryPrivilegesResponse tResponse = new 
TListSentryPrivilegesResponse();
+    tResponse.setStatus(respose.status);
+    tResponse.setPrivileges(respose.content);
+    return tResponse;
+  }
+
+  @Override
+  public TListSentryPrivilegesForProviderResponse 
list_sentry_privileges_for_provider(
+      final TListSentryPrivilegesForProviderRequest request) throws TException 
{
+    Response<Set<String>> respose = requestHandle(new 
RequestHandler<Set<String>>() {
+      @Override
+      public Response<Set<String>> handle() throws Exception {
+        Set<String> activeRoleNames = 
toTrimedLower(request.getRoleSet().getRoles());
+        Set<String> roleNamesForGroups = 
store.getRolesByGroups(request.getComponent(), request.getGroups());
+        Set<String> rolesToQuery = request.getRoleSet().isAll() ? 
roleNamesForGroups : Sets.intersection(activeRoleNames, roleNamesForGroups);
+        Set<PrivilegeObject> privileges = 
store.getPrivilegesByProvider(request.getComponent(),
+                                                                       
request.getServiceName(),
+                                                                       
rolesToQuery, null,
+                                                                       
toAuthorizables(request.getAuthorizables()));
+        return new Response<Set<String>>(Status.OK(), 
buildPermissions(privileges));
+      }
+    });
+    TListSentryPrivilegesForProviderResponse tResponse = new 
TListSentryPrivilegesForProviderResponse();
+    tResponse.setStatus(respose.status);
+    tResponse.setPrivileges(respose.content);
+    return tResponse;
+  }
+
+  @Override
+  public TDropPrivilegesResponse drop_sentry_privilege(
+      final TDropPrivilegesRequest request) throws TException {
+    Response<Void> respose = requestHandle(new RequestHandler<Void>() {
+      @Override
+      public Response<Void> handle() throws Exception {
+        authorize(request.getRequestorUserName(),
+            getRequestorGroups(conf, request.getRequestorUserName()));
+        CommitContext context = store.dropPrivilege(request.getComponent(),
+            toPrivilegeObject(request.getPrivilege()),
+            request.getRequestorUserName());
+        return new Response<Void>(Status.OK(), context);
+      }
+    });
+
+    TDropPrivilegesResponse tResponse = new 
TDropPrivilegesResponse(respose.status);
+    if (Status.OK.getCode() == respose.status.getValue()) {
+      handerInvoker.drop_sentry_privilege(respose.context, request, tResponse);
+    }
+    return tResponse;
+  }
+
+  @Override
+  public TRenamePrivilegesResponse rename_sentry_privilege(
+      final TRenamePrivilegesRequest request) throws TException {
+    Response<Void> respose = requestHandle(new RequestHandler<Void>() {
+      @Override
+      public Response<Void> handle() throws Exception {
+        authorize(request.getRequestorUserName(),
+            getRequestorGroups(conf, request.getRequestorUserName()));
+        CommitContext context = store.renamePrivilege(request.getComponent(), 
request.getServiceName(),
+                                    
toAuthorizables(request.getOldAuthorizables()),
+                                    
toAuthorizables(request.getNewAuthorizables()),
+                                    request.getRequestorUserName());
+        return new Response<Void>(Status.OK(),context);
+      }
+    });
+
+    TRenamePrivilegesResponse tResponse = new 
TRenamePrivilegesResponse(respose.status);
+    if (Status.OK.getCode() == respose.status.getValue()) {
+      handerInvoker.rename_sentry_privilege(respose.context, request, 
tResponse);
+    }
+    return tResponse;
+  }
+
+  private static class Response<T> {
+    TSentryResponseStatus status;
+    CommitContext context;
+    T content;
+
+    Response() {
+    }
+
+    Response(TSentryResponseStatus status, CommitContext context) {
+      this(status,context,null);
+    }
+
+    Response(TSentryResponseStatus status, T content) {
+      this(status,null,content);
+    }
+
+    Response(TSentryResponseStatus status, CommitContext context, T content) {
+      this.status = status;
+      this.context = context;
+      this.content = content;
+    }
+  }
+  private interface RequestHandler <T>{
+    public Response<T> handle() throws Exception ;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/bf3eb482/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessorFactory.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessorFactory.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessorFactory.java
new file mode 100644
index 0000000..71ce579
--- /dev/null
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessorFactory.java
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sentry.provider.db.generic.service.thrift;
+
+import org.apache.hadoop.conf.Configuration;
+import 
org.apache.sentry.provider.db.generic.service.thrift.SentryGenericPolicyService;
+import 
org.apache.sentry.provider.db.service.thrift.PolicyStoreConstants.PolicyStoreServerConfig;
+import org.apache.sentry.service.thrift.ProcessorFactory;
+import org.apache.thrift.TMultiplexedProcessor;
+import org.apache.thrift.TProcessor;
+
+public class SentryGenericPolicyProcessorFactory extends ProcessorFactory {
+
+  public SentryGenericPolicyProcessorFactory(Configuration conf) {
+    super(conf);
+  }
+
+  @Override
+  public boolean register(TMultiplexedProcessor multiplexedProcessor) throws 
Exception {
+    SentryGenericPolicyProcessor processHandler = new 
SentryGenericPolicyProcessor(conf);
+    TProcessor processor = new 
SentryGenericPolicyService.Processor<SentryGenericPolicyService.Iface>(processHandler);
+    
multiplexedProcessor.registerProcessor(SentryGenericPolicyProcessor.SENTRY_GENERIC_SERVICE_NAME,
 processor);
+    return true;
+  }
+
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/bf3eb482/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryGMPrivilege.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryGMPrivilege.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryGMPrivilege.java
new file mode 100644
index 0000000..266f349
--- /dev/null
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryGMPrivilege.java
@@ -0,0 +1,484 @@
+/**
+vim  * 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.model;
+
+import static 
org.apache.sentry.provider.common.ProviderConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.provider.common.ProviderConstants.KV_JOINER;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.jdo.annotations.PersistenceCapable;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.model.db.AccessConstants;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+
+/**
+ * Database backed Sentry Generic Privilege for new authorization Model
+ * Any changes to this object
+ * require re-running the maven build so DN an re-enhance.
+ */
+@PersistenceCapable
+public class MSentryGMPrivilege {
+  private static final String PREFIX_RESOURCE_NAME = "resourceName";
+  private static final String PREFIX_RESOURCE_TYPE = "resourceType";
+  private static final String NULL_COL = "__NULL__";
+  private static final String SERVICE_SCOPE = "Server";
+  private static final int AUTHORIZABLE_LEVEL = 4;
+  /**
+   * The authorizable List has been stored into resourceName and resourceField 
columns
+   * We assume that the generic model privilege for any component(hive/impala 
or solr) doesn't exceed four level.
+   * This generic model privilege currently can support maximum 4 level.
+   **/
+  private String resourceName0 = NULL_COL;
+  private String resourceType0 = NULL_COL;
+  private String resourceName1 = NULL_COL;
+  private String resourceType1 = NULL_COL;
+  private String resourceName2 = NULL_COL;
+  private String resourceType2 = NULL_COL;
+  private String resourceName3 = NULL_COL;
+  private String resourceType3 = NULL_COL;
+
+  private String serviceName;
+  private String componentName;
+  private String action;
+  private String scope;
+
+  private Boolean grantOption = false;
+  // roles this privilege is a part of
+  private Set<MSentryRole> roles;
+  private long createTime;
+
+  public MSentryGMPrivilege() {
+    this.roles = new HashSet<MSentryRole>();
+  }
+
+  public MSentryGMPrivilege(String componentName, String serviceName,
+                                 List<? extends Authorizable> authorizables,
+                                 String action, Boolean grantOption) {
+    this.componentName = componentName;
+    this.serviceName = serviceName;
+    this.action = action;
+    this.grantOption = grantOption;
+    this.roles = new HashSet<MSentryRole>();
+    this.createTime = System.currentTimeMillis();
+    setAuthorizables(authorizables);
+  }
+
+  public MSentryGMPrivilege(MSentryGMPrivilege copy) {
+    this.action = copy.action;
+    this.componentName = copy.componentName;
+    this.serviceName = copy.serviceName;
+    this.grantOption = copy.grantOption;
+    this.scope = copy.scope;
+    this.createTime = copy.createTime;
+    setAuthorizables(copy.getAuthorizables());
+    this.roles = new HashSet<MSentryRole>();
+    for (MSentryRole role : copy.roles) {
+      roles.add(role);
+    }
+  }
+
+  public String getServiceName() {
+    return serviceName;
+  }
+
+  public void setServiceName(String serviceName) {
+    this.serviceName = serviceName;
+  }
+
+  public String getComponentName() {
+    return componentName;
+  }
+
+  public void setComponentName(String componentName) {
+    this.componentName = componentName;
+  }
+
+  public String getAction() {
+    return action;
+  }
+
+  public void setAction(String action) {
+    this.action = action;
+  }
+
+  public Boolean getGrantOption() {
+    return grantOption;
+  }
+
+  public void setGrantOption(Boolean grantOption) {
+    this.grantOption = grantOption;
+  }
+
+  public Set<MSentryRole> getRoles() {
+    return roles;
+  }
+
+  public void setRoles(Set<MSentryRole> roles) {
+    this.roles = roles;
+  }
+
+  public long getCreateTime() {
+    return createTime;
+  }
+
+  public void setCreateTime(long createTime) {
+    this.createTime = createTime;
+  }
+
+  public String getScope() {
+    return scope;
+  }
+
+  public List<? extends Authorizable> getAuthorizables() {
+    List<Authorizable> authorizables = Lists.newArrayList();
+    //construct atuhorizable lists
+    for (int i = 0; i < AUTHORIZABLE_LEVEL; i++) {
+      final String resourceName = (String) getField(this, PREFIX_RESOURCE_NAME 
+ String.valueOf(i));
+      final String resourceTYpe = (String) getField(this, PREFIX_RESOURCE_TYPE 
+ String.valueOf(i));
+
+      if (notNULL(resourceName) && notNULL(resourceTYpe)) {
+        authorizables.add(new Authorizable() {
+          @Override
+          public String getTypeName() {
+            return resourceTYpe;
+          }
+          @Override
+          public String getName() {
+            return resourceName;
+          }
+        });
+      }
+    }
+    return authorizables;
+  }
+
+  /**
+   * Only allow strict hierarchies. That is, can level =1 be not null when 
level = 0 is null
+   * @param authorizables
+   */
+  public void setAuthorizables(List<? extends Authorizable> authorizables) {
+    if ((authorizables == null) || (authorizables.isEmpty())) {
+      //service scope
+      scope = SERVICE_SCOPE;
+      return;
+    }
+    if (authorizables.size() > AUTHORIZABLE_LEVEL) {
+      throw new IllegalStateException("This generic privilege model only 
supports maximum 4 level.");
+    }
+
+    for (int i = 0; i < authorizables.size(); i++) {
+      Authorizable authorizable = authorizables.get(i);
+      if (authorizable == null) {
+        String msg = String.format("The authorizable can't be null. Please 
check authorizables[%d]:", i);
+        throw new IllegalStateException(msg);
+      }
+      String resourceName = authorizable.getName();
+      String resourceTYpe = authorizable.getTypeName();
+      if (isNULL(resourceName) || isNULL(resourceTYpe)) {
+        String msg = String.format("The name and type of authorizable can't be 
empty or null.Please check authorizables[%d]", i);
+        throw new IllegalStateException(msg);
+      }
+      setField(this, PREFIX_RESOURCE_NAME + String.valueOf(i), 
toNULLCol(resourceName));
+      setField(this, PREFIX_RESOURCE_TYPE + String.valueOf(i), 
toNULLCol(resourceTYpe));
+      scope = resourceTYpe;
+    }
+  }
+
+  public void appendRole(MSentryRole role) {
+    if (roles.add(role)) {
+      role.appendGMPrivilege(this);
+    }
+  }
+
+  public void removeRole(MSentryRole role) {
+    if(roles.remove(role)) {
+      role.removeGMPrivilege(this);
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((action == null) ? 0 : action.hashCode());
+    result = prime * result + ((componentName == null) ? 0 : 
componentName.hashCode());
+    result = prime * result + ((serviceName == null) ? 0 : 
serviceName.hashCode());
+    result = prime * result + ((grantOption == null) ? 0 : 
grantOption.hashCode());
+    result = prime * result + ((scope == null) ? 0 : scope.hashCode());
+
+    for (Authorizable authorizable : getAuthorizables()) {
+      result = prime * result + authorizable.getName().hashCode();
+      result = prime * result + authorizable.getTypeName().hashCode();
+    }
+
+    return result;
+  }
+
+  @Override
+  public String toString() {
+    List<String> unifiedNames = Lists.newArrayList();
+    for (Authorizable auth : getAuthorizables()) {
+      unifiedNames.add(KV_JOINER.join(auth.getTypeName(),auth.getName()));
+    }
+
+    return "MSentryGMPrivilege ["
+        + "serverName=" + serviceName + ", componentName=" + componentName
+        + ", authorizables=" + AUTHORIZABLE_JOINER.join(unifiedNames)+ ", 
scope=" + scope
+        + ", action=" + action + ", roles=[...]"  + ", createTime="
+        + createTime + ", grantOption=" + grantOption +"]";
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+      if (this == obj)
+          return true;
+      if (obj == null)
+          return false;
+      if (getClass() != obj.getClass())
+          return false;
+      MSentryGMPrivilege other = (MSentryGMPrivilege) obj;
+      if (action == null) {
+          if (other.action != null)
+              return false;
+      } else if (!action.equalsIgnoreCase(other.action))
+          return false;
+      if (scope == null) {
+        if (other.scope != null)
+            return false;
+      } else if (!scope.equals(other.scope))
+        return false;
+      if (serviceName == null) {
+          if (other.serviceName != null)
+              return false;
+      } else if (!serviceName.equals(other.serviceName))
+          return false;
+      if (componentName == null) {
+          if (other.componentName != null)
+              return false;
+      } else if (!componentName.equals(other.componentName))
+          return false;
+      if (grantOption == null) {
+        if (other.grantOption != null)
+          return false;
+      } else if (!grantOption.equals(other.grantOption))
+        return false;
+
+      List<? extends Authorizable> authorizables = getAuthorizables();
+      List<? extends Authorizable> other_authorizables = 
other.getAuthorizables();
+
+      if (authorizables.size() != other_authorizables.size()) {
+        return false;
+      }
+      for (int i = 0; i < authorizables.size(); i++) {
+        String o1 = KV_JOINER.join(authorizables.get(i).getTypeName(),
+                                         authorizables.get(i).getName());
+        String o2 = KV_JOINER.join(other_authorizables.get(i).getTypeName(),
+            other_authorizables.get(i).getName());
+        if (!o1.equals(o2)) {
+          return false;
+        }
+      }
+      return true;
+  }
+
+  /**
+   * Return true if this privilege implies request privilege
+   * Otherwise, return false
+   * @param other, other privilege
+   */
+  public boolean implies(MSentryGMPrivilege request) {
+    //component check
+    if (!componentName.equals(request.getComponentName())) {
+      return false;
+    }
+    //service check
+    if (!serviceName.equals(request.getServiceName())) {
+      return false;
+    }
+    // check action implies
+    if (!action.equalsIgnoreCase(AccessConstants.ALL)
+        && !action.equalsIgnoreCase(request.getAction())
+        && !action.equalsIgnoreCase(AccessConstants.ACTION_ALL)) {
+      return false;
+    }
+    //check authorizable list implies
+    Iterator<? extends Authorizable> existIterator = 
getAuthorizables().iterator();
+    Iterator<? extends Authorizable> requestIterator = 
request.getAuthorizables().iterator();
+    while (existIterator.hasNext() && requestIterator.hasNext()) {
+      Authorizable existAuth = existIterator.next();
+      Authorizable requestAuth = requestIterator.next();
+      //check authorizable type
+      if (!existAuth.getTypeName().equals(requestAuth.getTypeName())) {
+        return false;
+      }
+      //check authorizable name
+      if (!existAuth.getName().equals(requestAuth.getName())) {
+        /**The persistent authorizable isn't equal the request authorizable
+        * but the following situations are pass check
+        * The name of persistent authorizable is ALL or "*"
+        */
+        if (existAuth.getName().equalsIgnoreCase(AccessConstants.ACTION_ALL)
+            || existAuth.getName().equalsIgnoreCase(AccessConstants.ALL)) {
+          continue;
+        } else {
+          return false;
+        }
+      }
+    }
+
+    if ( (!existIterator.hasNext()) && (!requestIterator.hasNext()) ){
+      /**
+       * The persistent privilege has the same authorizables size as the 
requested privilege
+       * The check is pass
+       */
+      return true;
+
+    } else if (existIterator.hasNext()) {
+      /**
+       * The persistent privilege has much more authorizables than request 
privilege,so its scope is less
+       * than the requested privilege.
+       * There is a situation that the check is pass, the name of the 
exceeding authorizables is ALL or "*".
+       * Take the Solr for example,the exist privilege is 
collection=c1->field=*->action=query
+       * the request privilege is collection=c1->action=query, the check is 
pass
+       */
+      while (existIterator.hasNext()) {
+        Authorizable existAuthorizable = existIterator.next();
+        if (existAuthorizable.getName().equalsIgnoreCase(AccessConstants.ALL)
+            || 
existAuthorizable.getName().equalsIgnoreCase(AccessConstants.ACTION_ALL)) {
+          continue;
+        } else {
+          return false;
+        }
+      }
+    } else {
+      /**
+       * The requested privilege has much more authorizables than persistent 
privilege, so its scope is less
+       * than the persistent privilege
+       * The check is pass
+       */
+      return true;
+    }
+
+    return true;
+  }
+
+  public static String toNULLCol(String col) {
+    return Strings.isNullOrEmpty(col) ? NULL_COL : col;
+  }
+
+  public static boolean notNULL(String s) {
+    return !(Strings.isNullOrEmpty(s) || NULL_COL.equals(s));
+  }
+
+  public static boolean isNULL(String s) {
+    return !notNULL(s);
+  }
+
+  public static <T> void setField(Object obj, String fieldName, T fieldValue) {
+    try {
+      Class<?> clazz = obj.getClass();
+      Field field=clazz.getDeclaredField(fieldName);
+      field.setAccessible(true);
+      field.set(obj, fieldValue);
+    } catch (Exception e) {
+      throw new RuntimeException("setField error: " + e.getMessage(), e);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T> T getField(Object obj, String fieldName) {
+    try {
+      Class<?> clazz = obj.getClass();
+      Field field=clazz.getDeclaredField(fieldName);
+      field.setAccessible(true);
+      return (T)field.get(obj);
+    } catch (Exception e) {
+      throw new RuntimeException("getField error: " + e.getMessage(), e);
+    }
+  }
+
+  /**
+   * return the query to execute in JDO for search the given privilege
+   * @param privilege
+   * @return query
+   */
+  public static String toQuery(MSentryGMPrivilege privilege) {
+    StringBuilder query = new StringBuilder();
+    query.append("serviceName == \"" + toNULLCol(privilege.getServiceName()) + 
"\" ");
+    query.append("&& componentName == \"" + 
toNULLCol(privilege.getComponentName()) + "\" ");
+    query.append("&& scope == \"" + toNULLCol(privilege.getScope()) + "\" ");
+    query.append("&& action == \"" + toNULLCol(privilege.getAction()) + "\"");
+    if (privilege.getGrantOption() == null) {
+      query.append("&& this.grantOption == null ");
+    } else if (privilege.getGrantOption()) {
+      query.append("&& grantOption ");
+    } else {
+      query.append("&& !grantOption ");
+    }
+    List<? extends Authorizable> authorizables = privilege.getAuthorizables();
+    for (int i = 0; i < AUTHORIZABLE_LEVEL; i++) {
+      String resourceName = PREFIX_RESOURCE_NAME + String.valueOf(i);
+      String resourceType = PREFIX_RESOURCE_TYPE + String.valueOf(i);
+
+      if (i >= authorizables.size()) {
+        query.append("&& " + resourceName + " == \"" + NULL_COL + "\" ");
+        query.append("&& " + resourceType + " == \"" + NULL_COL + "\" ");
+      } else {
+        query.append("&& " + resourceName + " == \"" + 
authorizables.get(i).getName() + "\" ");
+        query.append("&& " + resourceType + " == \"" + 
authorizables.get(i).getTypeName() + "\" ");
+      }
+    }
+    return query.toString();
+  }
+
+  /**
+   * Get the query to execute in the JDO deducing privileges include the scope 
of according to the given privilege
+   * The query was used in three privilege operations:
+   * 1.revoking privilege
+   * 2.renaming privilege
+   * 3.dropping privilege
+   * Take the Solr for example, if there exists three privileges such as 
p1:Collection=c1->action=query,
+   * p2:Collection=c1->Field=f1->action=query and 
p3:Collection=c1->Field=f2->action=query.
+   * When the revoking operation happens, the request privilege is 
p4:Collection=c1->action=query.
+   * The result is that not only p1 should be revoked, but also p2 and p3 
should be revoked together.
+   * So the populateIncludePrivilegesQuery should be Collection=c1
+   * @param privilege
+   * @return query
+   */
+  public static String populateIncludePrivilegesQuery(MSentryGMPrivilege 
privilege) {
+    StringBuilder query = new StringBuilder();
+    query.append("serviceName == \"" + toNULLCol(privilege.getServiceName()) + 
"\" ");
+    query.append("&& componentName == \"" + 
toNULLCol(privilege.getComponentName()) + "\" ");
+    List<? extends Authorizable> authorizables = privilege.getAuthorizables();
+    for (int i= 0 ; i < authorizables.size(); i++) {
+      String resourceName = PREFIX_RESOURCE_NAME + String.valueOf(i);
+      String resourceType = PREFIX_RESOURCE_TYPE + String.valueOf(i);
+      query.append("&& " + resourceName + " == \"" + 
authorizables.get(i).getName() + "\" ");
+      query.append("&& " + resourceType + " == \"" + 
authorizables.get(i).getTypeName() + "\" ");
+    }
+    return query.toString();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/bf3eb482/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryRole.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryRole.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryRole.java
index bca9fb9..0076753 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryRole.java
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryRole.java
@@ -36,6 +36,9 @@ public class MSentryRole {
   private String roleName;
   // set of privileges granted to this role
   private Set<MSentryPrivilege> privileges;
+  // set of generic model privileges grant ro this role
+  private Set<MSentryGMPrivilege> gmPrivileges;
+
   // set of groups this role belongs to
   private Set<MSentryGroup> groups;
   private long createTime;
@@ -44,6 +47,7 @@ public class MSentryRole {
     this.roleName = roleName;
     this.createTime = createTime;
     privileges = new HashSet<MSentryPrivilege>();
+    gmPrivileges = new HashSet<MSentryGMPrivilege>();
     groups = new HashSet<MSentryGroup>();
   }
 
@@ -71,6 +75,14 @@ public class MSentryRole {
     return privileges;
   }
 
+  public Set<MSentryGMPrivilege> getGmPrivileges() {
+    return gmPrivileges;
+  }
+
+  public void setGmPrivileges(Set<MSentryGMPrivilege> gmPrivileges) {
+    this.gmPrivileges = gmPrivileges;
+  }
+
   public void setGroups(Set<MSentryGroup> groups) {
     this.groups = groups;
   }
@@ -95,6 +107,25 @@ public class MSentryRole {
     }
   }
 
+  public void removeGMPrivilege(MSentryGMPrivilege gmPrivilege) {
+    if (gmPrivileges.remove(gmPrivilege)) {
+      gmPrivilege.removeRole(this);
+    }
+  }
+
+  public void appendGMPrivilege(MSentryGMPrivilege gmPrivilege) {
+    if (gmPrivileges.add(gmPrivilege)) {
+      gmPrivilege.appendRole(this);
+    }
+  }
+
+  public void removeGMPrivileges() {
+    for (MSentryGMPrivilege privilege : ImmutableSet.copyOf(gmPrivileges)) {
+      privilege.removeRole(this);
+    }
+    Preconditions.checkState(gmPrivileges.isEmpty(), "gmPrivileges should be 
empty: " + gmPrivileges);
+  }
+
   public void appendGroups(Set<MSentryGroup> groups) {
     this.groups.addAll(groups);
   }
@@ -121,7 +152,7 @@ public class MSentryRole {
 
   @Override
   public String toString() {
-    return "MSentryRole [roleName=" + roleName + ", privileges=[..]"
+    return "MSentryRole [roleName=" + roleName + ", privileges=[..]" + ", 
gmPrivileges=[..]"
         + ", groups=[...]" + ", createTime=" + createTime + "]";
   }
 
@@ -149,4 +180,5 @@ public class MSentryRole {
       return false;
     return true;
   }
-}
\ No newline at end of file
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/bf3eb482/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/package.jdo
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/package.jdo
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/package.jdo
index 594201f..d8f69b5 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/package.jdo
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/package.jdo
@@ -64,8 +64,18 @@
             <element>
                 <column name="DB_PRIVILEGE_ID"/>
             </element>
-      </field>  
-      
+      </field>
+
+      <field name = "gmPrivileges" table="SENTRY_ROLE_GM_PRIVILEGE_MAP" 
default-fetch-group="true">
+        <collection 
element-type="org.apache.sentry.provider.db.service.model.MSentryGMPrivilege"/>
+            <join>
+                <column name="ROLE_ID"/>
+            </join>
+            <element>
+                <column name="GM_PRIVILEGE_ID"/>
+            </element>
+      </field>
+
       <field name = "groups" table="SENTRY_ROLE_GROUP_MAP" >
         <collection 
element-type="org.apache.sentry.provider.db.service.model.MSentryGroup"/>
             <join>
@@ -74,10 +84,10 @@
             <element>
                 <column name="GROUP_ID"/>
             </element>
-      </field>  
+      </field>
     </class>
-    
-    <class name="MSentryPrivilege" identity-type="datastore" 
table="SENTRY_DB_PRIVILEGE" detachable="true">  
+
+    <class name="MSentryPrivilege" identity-type="datastore" 
table="SENTRY_DB_PRIVILEGE" detachable="true">
       <datastore-identity>
         <column name="DB_PRIVILEGE_ID"/>
       </datastore-identity>
@@ -119,8 +129,74 @@
       </field>
       <field name="roles" mapped-by="privileges">
          <collection 
element-type="org.apache.sentry.provider.db.service.model.MSentryRole"/>
-      </field>  
+      </field>
     </class>
+
+    <class name="MSentryGMPrivilege" identity-type="datastore" 
table="SENTRY_GM_PRIVILEGE" detachable="true">
+      <datastore-identity>
+        <column name="GM_PRIVILEGE_ID"/>
+      </datastore-identity>
+    <index name="GM_PRIVILEGE_INDEX" unique="true">
+        <field name="componentName"/>
+        <field name="serviceName"/>
+        <field name="resourceName0"/>
+        <field name="resourceType0"/>
+        <field name="resourceName1"/>
+        <field name="resourceType1"/>
+        <field name="resourceName2"/>
+        <field name="resourceType2"/>
+        <field name="resourceName3"/>
+        <field name="resourceType3"/>
+        <field name="action"/>
+        <field name="grantOption"/>
+         </index>
+      <field name="componentName">
+        <column name="COMPONENT_NAME" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="serviceName">
+        <column name="SERVICE_NAME" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="resourceName0">
+        <column name="RESOURCE_NAME_0" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="resourceType0">
+        <column name="RESOURCE_TYPE_0" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="resourceName1">
+        <column name="RESOURCE_NAME_1" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="resourceType1">
+        <column name="RESOURCE_TYPE_1" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="resourceName2">
+        <column name="RESOURCE_NAME_2" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="resourceType2">
+        <column name="RESOURCE_TYPE_2" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="resourceName3">
+        <column name="RESOURCE_NAME_3" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="resourceType3">
+        <column name="RESOURCE_TYPE_3" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="action">
+        <column name="ACTION" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name="scope">
+        <column name="SCOPE" length="100" jdbc-type="VARCHAR"/>
+      </field>
+      <field name = "createTime">
+        <column name = "CREATE_TIME" jdbc-type="BIGINT"/>
+      </field>
+      <field name="grantOption">
+        <column name="WITH_GRANT_OPTION" length="1" jdbc-type="CHAR"/>
+      </field>
+      <field name="roles" mapped-by="gmPrivileges">
+        <collection 
element-type="org.apache.sentry.provider.db.service.model.MSentryRole"/>
+      </field>
+    </class>
+
     <class name="MSentryVersion" table="SENTRY_VERSION" 
identity-type="datastore" detachable="true">
       <datastore-identity>
         <column name="VER_ID"/>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/bf3eb482/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
index f98e853..136dab6 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
@@ -219,7 +219,7 @@ public class SentryStore {
    *
    * Synchronized because we obtain persistence manager
    */
-  private synchronized PersistenceManager openTransaction() {
+  public synchronized PersistenceManager openTransaction() {
     PersistenceManager pm = pmf.getPersistenceManager();
     Transaction currentTransaction = pm.currentTransaction();
     currentTransaction.begin();
@@ -229,7 +229,7 @@ public class SentryStore {
   /**
    * Synchronized due to sequence id generation
    */
-  private synchronized CommitContext 
commitUpdateTransaction(PersistenceManager pm) {
+  public synchronized CommitContext commitUpdateTransaction(PersistenceManager 
pm) {
     commitTransaction(pm);
     return new CommitContext(SERVER_UUID, incrementGetSequenceId());
   }
@@ -244,7 +244,7 @@ public class SentryStore {
     return ++commitSequenceId;
   }
 
-  private void commitTransaction(PersistenceManager pm) {
+  public void commitTransaction(PersistenceManager pm) {
     Transaction currentTransaction = pm.currentTransaction();
     try {
       Preconditions.checkState(currentTransaction.isActive(), "Transaction is 
not active");
@@ -254,7 +254,7 @@ public class SentryStore {
     }
   }
 
-  private void rollbackTransaction(PersistenceManager pm) {
+  public void rollbackTransaction(PersistenceManager pm) {
     if (pm == null || pm.isClosed()) {
       return;
     }
@@ -271,7 +271,7 @@ public class SentryStore {
   Get the MSentry object from roleName
   Note: Should be called inside a transaction
    */
-  private MSentryRole getMSentryRole(PersistenceManager pm, String roleName) {
+  public MSentryRole getMSentryRole(PersistenceManager pm, String roleName) {
     Query query = pm.newQuery(MSentryRole.class);
     query.setFilter("this.roleName == t");
     query.declareParameters("java.lang.String t");
@@ -744,6 +744,8 @@ public class SentryStore {
         pm.retrieve(sentryRole);
         int numPrivs = sentryRole.getPrivileges().size();
         sentryRole.removePrivileges();
+        //with SENTRY-398 generic model
+        sentryRole.removeGMPrivileges();
         privCleaner.incPrivRemoval(numPrivs);
         pm.deletePersistent(sentryRole);
       }
@@ -1171,7 +1173,7 @@ public class SentryStore {
     }
   }
 
-  private Set<MSentryRole> getRolesForGroups(PersistenceManager pm, 
Set<String> groups) {
+  public Set<MSentryRole> getRolesForGroups(PersistenceManager pm, Set<String> 
groups) {
     Set<MSentryRole> result = new HashSet<MSentryRole>();
     Query query = pm.newQuery(MSentryGroup.class);
     query.setFilter("this.groupName == t");

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/bf3eb482/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
index 34bec93..1a1c0b7 100644
--- 
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
@@ -18,7 +18,10 @@
 package org.apache.sentry.provider.db.service.thrift;
 
 public 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";
   }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/bf3eb482/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 56e0ce4..47794bc 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
@@ -67,7 +67,7 @@ public class ServiceConstants {
     public static final String RPC_MIN_THREADS = 
"sentry.service.server-min-threads";
     public static final int RPC_MIN_THREADS_DEFAULT = 10;
     public static final String ALLOW_CONNECT = "sentry.service.allow.connect";
-    
+
     public static final String SENTRY_POLICY_STORE_PLUGINS = 
"sentry.policy.store.plugins";
     public static final String SENTRY_POLICY_STORE_PLUGINS_DEFAULT = "";
 
@@ -76,7 +76,8 @@ public class ServiceConstants {
 
     public static final String PROCESSOR_FACTORIES = 
"sentry.service.processor.factories";
     public static final String PROCESSOR_FACTORIES_DEFAULT =
-        
"org.apache.sentry.provider.db.service.thrift.SentryPolicyStoreProcessorFactory";
+        
"org.apache.sentry.provider.db.service.thrift.SentryPolicyStoreProcessorFactory"
 +
+        
",org.apache.sentry.provider.db.generic.service.thrift.SentryGenericPolicyProcessorFactory";
     public static final String SENTRY_STORE_JDBC_URL = "sentry.store.jdbc.url";
     public static final String SENTRY_STORE_JDBC_USER = 
"sentry.store.jdbc.user";
     public static final String SENTRY_STORE_JDBC_USER_DEFAULT = "Sentry";

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/bf3eb482/sentry-provider/sentry-provider-db/src/main/resources/sentry_common_service.thrift
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/resources/sentry_common_service.thrift
 
b/sentry-provider/sentry-provider-db/src/main/resources/sentry_common_service.thrift
index 9456274..956dabe 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/resources/sentry_common_service.thrift
+++ 
b/sentry-provider/sentry-provider-db/src/main/resources/sentry_common_service.thrift
@@ -25,6 +25,7 @@ namespace php sentry.service.thrift
 namespace cpp Apache.Sentry.Service.Thrift
 
 const i32 TSENTRY_SERVICE_V1 = 1;
+const i32 TSENTRY_SERVICE_V2 = 1;
 
 const i32 TSENTRY_STATUS_OK = 0;
 const i32 TSENTRY_STATUS_ALREADY_EXISTS = 1;

Reply via email to