Repository: sentry Updated Branches: refs/heads/sentry-ha-redesign cb0f10036 -> 79cbd178a
SENTRY-1594: TransactionBlock should become generic (Alexander Kolbasov, Reviewed by: Hao Hao) Change-Id: Ie5c7d2b89feb3b003d6d06fac6ca8020406fcb24 Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/79cbd178 Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/79cbd178 Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/79cbd178 Branch: refs/heads/sentry-ha-redesign Commit: 79cbd178a8fbd6d742294a79236dec3b27811585 Parents: cb0f100 Author: hahao <hao....@cloudera.com> Authored: Tue Jan 17 11:35:58 2017 -0800 Committer: hahao <hao....@cloudera.com> Committed: Tue Jan 17 11:35:58 2017 -0800 ---------------------------------------------------------------------- .../service/persistent/DelegateSentryStore.java | 184 ++++---- .../db/service/persistent/SentryStore.java | 423 ++++++++++--------- .../db/service/persistent/TransactionBlock.java | 17 +- .../service/persistent/TransactionManager.java | 32 +- 4 files changed, 331 insertions(+), 325 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/79cbd178/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/DelegateSentryStore.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/DelegateSentryStore.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/DelegateSentryStore.java index ece6831..8e2a6d5 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/DelegateSentryStore.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/DelegateSentryStore.java @@ -63,7 +63,7 @@ public class DelegateSentryStore implements SentryStoreLayer { private Set<String> adminGroups; private PrivilegeOperatePersistence privilegeOperator; - public DelegateSentryStore(Configuration conf) throws Exception { + DelegateSentryStore(Configuration conf) throws Exception { this.privilegeOperator = new PrivilegeOperatePersistence(conf); // The generic model doesn't turn on the thread that cleans hive privileges conf.set(ServerConfig.SENTRY_STORE_ORPHANED_PRIVILEGE_REMOVAL,"false"); @@ -128,7 +128,7 @@ public class DelegateSentryStore implements SentryStoreLayer { if (mRole == null) { throw new SentryNoSuchObjectException("Role: " + trimmedRole + " doesn't exist"); } - /** + /* * check with grant option */ grantOptionCheck(privilege, grantorPrincipal, pm); @@ -152,7 +152,7 @@ public class DelegateSentryStore implements SentryStoreLayer { if (mRole == null) { throw new SentryNoSuchObjectException("Role: " + trimmedRole + " doesn't exist"); } - /** + /* * check with grant option */ grantOptionCheck(privilege, grantorPrincipal, pm); @@ -209,12 +209,10 @@ public class DelegateSentryStore implements SentryStoreLayer { /** * Grant option check - * @param component - * @param pm - * @param privilegeReader * @throws SentryUserException */ - private void grantOptionCheck(PrivilegeObject requestPrivilege, String grantorPrincipal,PersistenceManager pm) + private void grantOptionCheck(PrivilegeObject requestPrivilege, + String grantorPrincipal,PersistenceManager pm) throws SentryUserException { if (Strings.isNullOrEmpty(grantorPrincipal)) { @@ -259,30 +257,30 @@ public class DelegateSentryStore implements SentryStoreLayer { return groupNames; } - return (Set<String>) delegate.getTransactionManager().executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - //get groups by roles - Query query = pm.newQuery(MSentryGroup.class); - StringBuilder filters = new StringBuilder(); - query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role"); - List<String> rolesFiler = new LinkedList<String>(); - for (String role : trimmedRoles) { - rolesFiler.add("role.roleName == \"" + role + "\" "); - } - filters.append("roles.contains(role) " + "&& (" + Joiner.on(" || ").join(rolesFiler) + ")"); - query.setFilter(filters.toString()); - - List<MSentryGroup> groups = (List<MSentryGroup>)query.execute(); - if (groups == null) { - return groupNames; - } - for (MSentryGroup group : groups) { - groupNames.add(group.getGroupName()); - } + return delegate.getTransactionManager().executeTransaction( + new TransactionBlock<Set<String>>() { + public Set<String> execute(PersistenceManager pm) throws Exception { + //get groups by roles + Query query = pm.newQuery(MSentryGroup.class); + StringBuilder filters = new StringBuilder(); + query.declareVariables("MSentryRole role"); + List<String> rolesFiler = new LinkedList<String>(); + for (String role : trimmedRoles) { + rolesFiler.add("role.roleName == \"" + role + "\" "); + } + filters.append("roles.contains(role) " + "&& (" + Joiner.on(" || ").join(rolesFiler) + ")"); + query.setFilter(filters.toString()); + @SuppressWarnings("unchecked") + List<MSentryGroup> groups = (List<MSentryGroup>)query.execute(); + if (groups == null) { return groupNames; } - }); + for (MSentryGroup group : groups) { + groupNames.add(group.getGroupName()); + } + return groupNames; + } + }); } @Override @@ -294,20 +292,20 @@ public class DelegateSentryStore implements SentryStoreLayer { return privileges; } - return (Set<PrivilegeObject>) delegate.getTransactionManager().executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - Set<MSentryRole> mRoles = Sets.newHashSet(); - for (String role : roles) { - MSentryRole mRole = getRole(toTrimmedLower(role), pm); - if (mRole != null) { - mRoles.add(mRole); - } + return delegate.getTransactionManager().executeTransaction( + new TransactionBlock<Set<PrivilegeObject>>() { + public Set<PrivilegeObject> execute(PersistenceManager pm) throws Exception { + Set<MSentryRole> mRoles = Sets.newHashSet(); + for (String role : roles) { + MSentryRole mRole = getRole(toTrimmedLower(role), pm); + if (mRole != null) { + mRoles.add(mRole); } - privileges.addAll(privilegeOperator.getPrivilegesByRole(mRoles, pm)); - return privileges; } - }); + privileges.addAll(privilegeOperator.getPrivilegesByRole(mRoles, pm)); + return privileges; + } + }); } @Override @@ -317,37 +315,38 @@ public class DelegateSentryStore implements SentryStoreLayer { Preconditions.checkNotNull(component); Preconditions.checkNotNull(service); - return (Set<PrivilegeObject>) delegate.getTransactionManager().executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - String trimmedComponent = toTrimmedLower(component); - String trimmedService = toTrimmedLower(service); - Set<PrivilegeObject> privileges = Sets.newHashSet(); - //CaseInsensitive roleNames - Set<String> trimmedRoles = toTrimmedLower(roles); - - if (groups != null) { - trimmedRoles.addAll(delegate.getRoleNamesForGroups(groups)); - } + return delegate.getTransactionManager().executeTransaction( + new TransactionBlock<Set<PrivilegeObject>>() { + public Set<PrivilegeObject> execute(PersistenceManager pm) throws Exception { + String trimmedComponent = toTrimmedLower(component); + String trimmedService = toTrimmedLower(service); - if (trimmedRoles.size() == 0) { - return privileges; - } + Set<PrivilegeObject> privileges = Sets.newHashSet(); + //CaseInsensitive roleNames + Set<String> trimmedRoles = toTrimmedLower(roles); - Set<MSentryRole> mRoles = Sets.newHashSet(); - for (String role : trimmedRoles) { - MSentryRole mRole = getRole(role, pm); - if (mRole != null) { - mRoles.add(mRole); - } - } - //get the privileges - privileges.addAll(privilegeOperator.getPrivilegesByProvider(trimmedComponent, - trimmedService, mRoles, authorizables, pm)); + if (groups != null) { + trimmedRoles.addAll(delegate.getRoleNamesForGroups(groups)); + } + if (trimmedRoles.size() == 0) { return privileges; } - }); + + Set<MSentryRole> mRoles = Sets.newHashSet(); + for (String role : trimmedRoles) { + MSentryRole mRole = getRole(role, pm); + if (mRole != null) { + mRoles.add(mRole); + } + } + //get the privileges + privileges.addAll(privilegeOperator. + getPrivilegesByProvider(trimmedComponent, + trimmedService, mRoles, authorizables, pm)); + return privileges; + } + }); } @Override @@ -363,36 +362,35 @@ public class DelegateSentryStore implements SentryStoreLayer { return privileges; } - return (Set<MSentryGMPrivilege>) delegate.getTransactionManager().executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - String lComponent = toTrimmedLower(component); - String lService = toTrimmedLower(service); - - Set<MSentryRole> mRoles = Sets.newHashSet(); - for (String role : validActiveRoles) { - MSentryRole mRole = getRole(role, pm); - if (mRole != null) { - mRoles.add(mRole); - } + return delegate.getTransactionManager().executeTransaction( + new TransactionBlock<Set<MSentryGMPrivilege>>() { + public Set<MSentryGMPrivilege> execute(PersistenceManager pm) throws Exception { + String lComponent = toTrimmedLower(component); + String lService = toTrimmedLower(service); + Set<MSentryRole> mRoles = Sets.newHashSet(); + for (String role : validActiveRoles) { + MSentryRole mRole = getRole(role, pm); + if (mRole != null) { + mRoles.add(mRole); } + } - //get the privileges - Set<MSentryGMPrivilege> mSentryGMPrivileges = - privilegeOperator.getPrivilegesByAuthorizable(lComponent, lService, mRoles, authorizables, pm); - - for (MSentryGMPrivilege mSentryGMPrivilege : mSentryGMPrivileges) { - /** - * force to load all roles related this privilege - * avoid the lazy-loading - */ - pm.retrieve(mSentryGMPrivilege); - privileges.add(mSentryGMPrivilege); - } + //get the privileges + Set<MSentryGMPrivilege> mSentryGMPrivileges = + privilegeOperator.getPrivilegesByAuthorizable(lComponent, lService, + mRoles, authorizables, pm); - return privileges; + for (MSentryGMPrivilege mSentryGMPrivilege : mSentryGMPrivileges) { + /* + * force to load all roles related this privilege + * avoid the lazy-loading + */ + pm.retrieve(mSentryGMPrivilege); + privileges.add(mSentryGMPrivilege); } - }); + return privileges; + } + }); } @Override http://git-wip-us.apache.org/repos/asf/sentry/blob/79cbd178/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 5226b86..0712e2c 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 @@ -303,6 +303,7 @@ public class SentryStore { private String trimAndLower(String input) { return input.trim().toLowerCase(); } + /** * Create a sentry role and persist it. Role name is the primary key for the * role, so an attempt to create a role which exists fails with JDO exception. @@ -333,9 +334,9 @@ public class SentryStore { */ private <T> Long getCount(final Class<T> tClass) { try { - return (Long) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + return tm.executeTransaction( + new TransactionBlock<Long>() { + public Long execute(PersistenceManager pm) throws Exception { Query query = pm.newQuery(); query.setClass(tClass); query.setResult("count(this)"); @@ -386,7 +387,7 @@ public class SentryStore { /** * @return Number of users */ - public Gauge<Long> getUserCountGauge() { + Gauge<Long> getUserCountGauge() { return new Gauge<Long>() { @Override public Long getValue() { @@ -431,7 +432,7 @@ public class SentryStore { * @param privilege Privilege to grant * @throws Exception */ - public void alterSentryRoleGrantPrivilege(String grantorPrincipal, + void alterSentryRoleGrantPrivilege(String grantorPrincipal, String roleName, TSentryPrivilege privilege) throws Exception { alterSentryRoleGrantPrivileges(grantorPrincipal, roleName, Sets.newHashSet(privilege)); @@ -521,7 +522,7 @@ public class SentryStore { return mPrivilege; } - public void alterSentryRoleRevokePrivilege(String grantorPrincipal, + void alterSentryRoleRevokePrivilege(String grantorPrincipal, String roleName, TSentryPrivilege tPrivilege) throws Exception { alterSentryRoleRevokePrivileges(grantorPrincipal, roleName, Sets.newHashSet(tPrivilege)); @@ -693,7 +694,6 @@ public class SentryStore { } } - @SuppressWarnings("unchecked") private Set<MSentryPrivilege> getChildPrivileges(PersistenceManager pm, Set<String> roleNames, MSentryPrivilege parent) throws SentryInvalidInputException { // Column and URI do not have children @@ -947,9 +947,9 @@ public class SentryStore { @VisibleForTesting MSentryRole getMSentryRoleByName(final String roleName) throws Exception { - return (MSentryRole)tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + return tm.executeTransaction( + new TransactionBlock<MSentryRole>() { + public MSentryRole execute(PersistenceManager pm) throws Exception { String trimmedRoleName = trimAndLower(roleName); MSentryRole sentryRole = getRole(pm, trimmedRoleName); if (sentryRole == null) { @@ -964,9 +964,9 @@ public class SentryStore { if (roleNames == null || roleNames.isEmpty()) { return false; } - return (Boolean) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + return tm.executeTransaction( + new TransactionBlock<Boolean>() { + public Boolean execute(PersistenceManager pm) throws Exception { Query query = pm.newQuery(MSentryPrivilege.class); QueryParamBuilder paramBuilder = addRolesFilter(query,null, roleNames); paramBuilder.add(SERVER_NAME, serverName); @@ -978,68 +978,73 @@ public class SentryStore { }); } - @SuppressWarnings("unchecked") private List<MSentryPrivilege> getMSentryPrivileges(final Set<String> roleNames, - final TSentryAuthorizable authHierarchy) throws Exception { - List<MSentryPrivilege> result = new ArrayList<MSentryPrivilege>(); + final TSentryAuthorizable + authHierarchy) + throws Exception { if (roleNames == null || roleNames.isEmpty()) { - return result; + return new ArrayList<>(); } - return (List<MSentryPrivilege>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - Query query = pm.newQuery(MSentryPrivilege.class); - QueryParamBuilder paramBuilder = addRolesFilter(query, null, roleNames); - - if (authHierarchy != null && authHierarchy.getServer() != null) { - paramBuilder.add(SERVER_NAME, authHierarchy.getServer()); - if (authHierarchy.getDb() != null) { - paramBuilder.addNull(URI) - .newChild() - .add(DB_NAME, authHierarchy.getDb()) - .addNull(DB_NAME); - if (authHierarchy.getTable() != null - && !AccessConstants.ALL.equalsIgnoreCase(authHierarchy.getTable())) { - if (!AccessConstants.SOME.equalsIgnoreCase(authHierarchy.getTable())) { - paramBuilder.addNull(URI) - .newChild() - .add(TABLE_NAME, authHierarchy.getTable()) - .addNull(TABLE_NAME); - } - if (authHierarchy.getColumn() != null - && !AccessConstants.ALL.equalsIgnoreCase(authHierarchy.getColumn()) - && !AccessConstants.SOME.equalsIgnoreCase(authHierarchy.getColumn())) { - paramBuilder.addNull(URI) - .newChild() - .add(COLUMN_NAME, authHierarchy.getColumn()) - .addNull(COLUMN_NAME); - } + return tm.executeTransaction( + new TransactionBlock<List<MSentryPrivilege>>() { + public List<MSentryPrivilege> execute(PersistenceManager pm) + throws Exception { + Query query = pm.newQuery(MSentryPrivilege.class); + QueryParamBuilder paramBuilder = addRolesFilter(query, null, roleNames); + + if (authHierarchy != null && authHierarchy.getServer() != null) { + paramBuilder.add(SERVER_NAME, authHierarchy.getServer()); + if (authHierarchy.getDb() != null) { + paramBuilder.addNull(URI) + .newChild() + .add(DB_NAME, authHierarchy.getDb()) + .addNull(DB_NAME); + if (authHierarchy.getTable() != null + && !AccessConstants.ALL.equalsIgnoreCase(authHierarchy.getTable())) { + if (!AccessConstants.SOME.equalsIgnoreCase(authHierarchy.getTable())) { + paramBuilder.addNull(URI) + .newChild() + .add(TABLE_NAME, authHierarchy.getTable()) + .addNull(TABLE_NAME); } - } - if (authHierarchy.getUri() != null) { - paramBuilder.addNull(DB_NAME) - .newChild() - .addNull(URI) + if (authHierarchy.getColumn() != null + && !AccessConstants.ALL.equalsIgnoreCase(authHierarchy.getColumn()) + && !AccessConstants.SOME.equalsIgnoreCase(authHierarchy.getColumn())) { + paramBuilder.addNull(URI) .newChild() - .addNotNull(URI) - .addCustomParam("\"" + authHierarchy.getUri() + - "\".startsWith(:URI)", URI, authHierarchy.getUri()); + .add(COLUMN_NAME, authHierarchy.getColumn()) + .addNull(COLUMN_NAME); + } } } - LOGGER.debug("getMSentryPrivileges1() Query: " + paramBuilder.toString()); - query.setFilter(paramBuilder.toString()); - return query.executeWithMap(paramBuilder.getArguments()); + if (authHierarchy.getUri() != null) { + paramBuilder.addNull(DB_NAME) + .newChild() + .addNull(URI) + .newChild() + .addNotNull(URI) + .addCustomParam("\"" + authHierarchy.getUri() + + "\".startsWith(:URI)", URI, authHierarchy.getUri()); + } } - }); + LOGGER.debug("getMSentryPrivileges1() Query: " + paramBuilder.toString()); + query.setFilter(paramBuilder.toString()); + @SuppressWarnings("unchecked") + List<MSentryPrivilege> result = + (List<MSentryPrivilege>) + query.executeWithMap(paramBuilder.getArguments()); + return result; + } + }); } - @SuppressWarnings("unchecked") - List<MSentryPrivilege> getMSentryPrivilegesByAuth(final Set<String> roleNames, - final TSentryAuthorizable authHierarchy) throws Exception { - return (List<MSentryPrivilege>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + private List<MSentryPrivilege> getMSentryPrivilegesByAuth(final Set<String> roleNames, + final TSentryAuthorizable + authHierarchy) throws Exception { + return tm.executeTransaction( + new TransactionBlock<List<MSentryPrivilege>>() { + public List<MSentryPrivilege> execute(PersistenceManager pm) throws Exception { Query query = pm.newQuery(MSentryPrivilege.class); QueryParamBuilder paramBuilder = new QueryParamBuilder(); if (roleNames == null || roleNames.isEmpty()) { @@ -1071,9 +1076,11 @@ public class SentryStore { FetchGroup grp = pm.getFetchGroup(MSentryPrivilege.class, "fetchRole"); grp.addMember("roles"); pm.getFetchPlan().addGroup("fetchRole"); - // LOGGER.debug("XXX: " + paramBuilder.toString()); query.setFilter(paramBuilder.toString()); - return query.executeWithMap(paramBuilder.getArguments()); + @SuppressWarnings("unchecked") + List<MSentryPrivilege> result = (List<MSentryPrivilege>)query. + executeWithMap(paramBuilder.getArguments()); + return result; } }); } @@ -1158,17 +1165,16 @@ public class SentryStore { return convertToTSentryPrivileges(getMSentryPrivileges(roleNames, authHierarchy)); } - @SuppressWarnings("unchecked") private Set<MSentryRole> getMSentryRolesByGroupName(final String groupName) throws Exception { - return (Set<MSentryRole>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + return tm.executeTransaction( + new TransactionBlock<Set<MSentryRole>>() { + public Set<MSentryRole> execute(PersistenceManager pm) throws Exception { Set<MSentryRole> roles; //If no group name was specified, return all roles if (groupName == null) { - roles = new HashSet<MSentryRole>(getAllRoles(pm)); + roles = new HashSet<>(getAllRoles(pm)); } else { String trimmedGroupName = groupName.trim(); MSentryGroup sentryGroup = getGroup(pm, trimmedGroupName); @@ -1187,7 +1193,8 @@ public class SentryStore { /** * Gets sentry role objects for a given groupName from the persistence layer - * @param groupNames : set of groupNames to look up ( if null returns all roles for all groups) + * @param groupNames : set of groupNames to look up (if null returns all + * roles for all groups) * @return : Set of thrift sentry role objects * @throws SentryNoSuchObjectException */ @@ -1207,15 +1214,14 @@ public class SentryStore { return convertToTSentryRoles(roleSet); } - @SuppressWarnings("unchecked") public Set<String> getRoleNamesForGroups(final Set<String> groups) throws Exception { if (groups == null || groups.isEmpty()) { return ImmutableSet.of(); } - return (Set<String>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + return tm.executeTransaction( + new TransactionBlock<Set<String>>() { + public Set<String>execute(PersistenceManager pm) throws Exception { return getRoleNamesForGroupsCore(pm, groups); } }); @@ -1225,15 +1231,14 @@ public class SentryStore { return convertToRoleNameSet(getRolesForGroups(pm, groups)); } - @SuppressWarnings("unchecked") public Set<String> getRoleNamesForUsers(final Set<String> users) throws Exception { if (users == null || users.isEmpty()) { return ImmutableSet.of(); } - return (Set<String>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + return tm.executeTransaction( + new TransactionBlock<Set<String>>() { + public Set<String> execute(PersistenceManager pm) throws Exception { return getRoleNamesForUsersCore(pm,users); } }); @@ -1243,17 +1248,17 @@ public class SentryStore { return convertToRoleNameSet(getRolesForUsers(pm, users)); } - @SuppressWarnings("unchecked") - public Set<TSentryRole> getTSentryRolesByUserNames(final Set<String> users) throws Exception { - return (Set<TSentryRole>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - Set<MSentryRole> mSentryRoles = getRolesForUsers(pm, users); - // Since {@link MSentryRole#getGroups()} is lazy-loading, the converting should be call - // before transaction committed. - return convertToTSentryRoles(mSentryRoles); - } - }); + public Set<TSentryRole> getTSentryRolesByUserNames(final Set<String> users) + throws Exception { + return tm.executeTransaction( + new TransactionBlock<Set<TSentryRole>>() { + public Set<TSentryRole> execute(PersistenceManager pm) throws Exception { + Set<MSentryRole> mSentryRoles = getRolesForUsers(pm, users); + // Since {@link MSentryRole#getGroups()} is lazy-loading, + // the conversion should be done before transaction is committed. + return convertToTSentryRoles(mSentryRoles); + } + }); } public Set<MSentryRole> getRolesForGroups(PersistenceManager pm, Set<String> groups) { @@ -1310,21 +1315,20 @@ public class SentryStore { return hasAnyServerPrivileges(rolesToQuery, server); } - @SuppressWarnings("unchecked") private Set<String> getRolesToQuery(final Set<String> groups, final Set<String> users, final TSentryActiveRoleSet roleSet) throws Exception { - return (Set<String>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - Set<String> activeRoleNames = toTrimedLower(roleSet.getRoles()); - - Set<String> roleNames = Sets.newHashSet(); - roleNames.addAll(toTrimedLower(getRoleNamesForGroupsCore(pm, groups))); - roleNames.addAll(toTrimedLower(getRoleNamesForUsersCore(pm, users))); - return roleSet.isAll() ? roleNames : Sets.intersection(activeRoleNames, - roleNames); - } - }); + return tm.executeTransaction( + new TransactionBlock<Set<String>>() { + public Set<String> execute(PersistenceManager pm) throws Exception { + Set<String> activeRoleNames = toTrimedLower(roleSet.getRoles()); + + Set<String> roleNames = Sets.newHashSet(); + roleNames.addAll(toTrimedLower(getRoleNamesForGroupsCore(pm, groups))); + roleNames.addAll(toTrimedLower(getRoleNamesForUsersCore(pm, users))); + return roleSet.isAll() ? roleNames : Sets.intersection(activeRoleNames, + roleNames); + } + }); } @VisibleForTesting @@ -1510,34 +1514,34 @@ public class SentryStore { }); } - @SuppressWarnings("unchecked") private MSentryVersion getMSentryVersion() throws Exception { - return (MSentryVersion) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - try { - Query query = pm.newQuery(MSentryVersion.class); - List<MSentryVersion> mSentryVersions = (List<MSentryVersion>) query - .execute(); - pm.retrieveAll(mSentryVersions); - if (mSentryVersions.isEmpty()) { - throw new SentryNoSuchObjectException("No matching version found"); - } - if (mSentryVersions.size() > 1) { - throw new SentryAccessDeniedException( - "Metastore contains multiple versions"); - } - return mSentryVersions.get(0); - } catch (JDODataStoreException e) { - if (e.getCause() instanceof MissingTableException) { - throw new SentryAccessDeniedException("Version table not found. " - + "The sentry store is not set or corrupt "); - } else { - throw e; - } + return tm.executeTransaction( + new TransactionBlock<MSentryVersion>() { + public MSentryVersion execute(PersistenceManager pm) throws Exception { + try { + Query query = pm.newQuery(MSentryVersion.class); + @SuppressWarnings("unchecked") + List<MSentryVersion> mSentryVersions = (List<MSentryVersion>) query + .execute(); + pm.retrieveAll(mSentryVersions); + if (mSentryVersions.isEmpty()) { + throw new SentryNoSuchObjectException("No matching version found"); + } + if (mSentryVersions.size() > 1) { + throw new SentryAccessDeniedException( + "Metastore contains multiple versions"); + } + return mSentryVersions.get(0); + } catch (JDODataStoreException e) { + if (e.getCause() instanceof MissingTableException) { + throw new SentryAccessDeniedException("Version table not found. " + + "The sentry store is not set or corrupt "); + } else { + throw e; } } - }); + } + }); } /** @@ -1816,12 +1820,12 @@ public class SentryStore { ServerConfig.ADMIN_GROUPS, new String[]{})); } - @SuppressWarnings("unchecked") public Map<String, HashMap<String, String>> retrieveFullPrivilegeImage() throws Exception { Map<String, HashMap<String, String>> result = new HashMap<>(); - return (Map<String, HashMap<String, String>>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + return tm.executeTransaction( + new TransactionBlock<Map<String, HashMap<String, String>>>() { + public Map<String, HashMap<String, String>> execute(PersistenceManager pm) + throws Exception { Map<String, HashMap<String, String>> retVal = new HashMap<>(); Query query = pm.newQuery(MSentryPrivilege.class); QueryParamBuilder paramBuilder = new QueryParamBuilder(); @@ -1832,6 +1836,7 @@ public class SentryStore { query.setFilter(paramBuilder.toString()); query.setOrdering("serverName ascending, dbName ascending, tableName ascending"); + @SuppressWarnings("unchecked") List<MSentryPrivilege> privileges = (List<MSentryPrivilege>) query.executeWithMap(paramBuilder.getArguments()); for (MSentryPrivilege mPriv : privileges) { @@ -1862,14 +1867,14 @@ public class SentryStore { /** * @return Mapping of Role -> [Groups] */ - @SuppressWarnings("unchecked") public Map<String, LinkedList<String>> retrieveFullRoleImage() throws Exception { Map<String, LinkedList<String>> result = new HashMap<>(); - return (Map<String, LinkedList<String>>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + return tm.executeTransaction( + new TransactionBlock<Map<String, LinkedList<String>>>() { + public Map<String, LinkedList<String>> execute(PersistenceManager pm) throws Exception { Map<String, LinkedList<String>> retVal = new HashMap<>(); Query query = pm.newQuery(MSentryGroup.class); + @SuppressWarnings("unchecked") List<MSentryGroup> groups = (List<MSentryGroup>) query.execute(); for (MSentryGroup mGroup : groups) { for (MSentryRole role : mGroup.getRoles()) { @@ -2140,32 +2145,31 @@ public class SentryStore { } } - // get mapping datas for [group,role], [user,role] with the specific roles + /** get mapping datas for [group,role], [user,role] with the specific roles */ @SuppressWarnings("unchecked") public List<Map<String, Set<String>>> getGroupUserRoleMapList(final Set<String> roleNames) throws Exception { - List<Map<String, Set<String>>> result = new ArrayList<>(); - return (List<Map<String, Set<String>>>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - Query query = pm.newQuery(MSentryRole.class); - List<MSentryRole> mSentryRoles; - if (roleNames == null || roleNames.isEmpty()) { - mSentryRoles = (List<MSentryRole>)query.execute(); - } else { - QueryParamBuilder paramBuilder = new QueryParamBuilder(QueryParamBuilder.Op.OR); - paramBuilder.addSet("roleName == ", roleNames); - query.setFilter(paramBuilder.toString()); - mSentryRoles = - (List<MSentryRole>) query.executeWithMap(paramBuilder.getArguments()); - } - Map<String, Set<String>> groupRolesMap = getGroupRolesMap(mSentryRoles); - Map<String, Set<String>> userRolesMap = getUserRolesMap(mSentryRoles); - List<Map<String, Set<String>>> mapsList = new ArrayList<>(); - mapsList.add(INDEX_GROUP_ROLES_MAP, groupRolesMap); - mapsList.add(INDEX_USER_ROLES_MAP, userRolesMap); - return mapsList; + return tm.executeTransaction( + new TransactionBlock<List<Map<String, Set<String>>>>() { + public List<Map<String, Set<String>>> execute(PersistenceManager pm) throws Exception { + Query query = pm.newQuery(MSentryRole.class); + List<MSentryRole> mSentryRoles; + if (roleNames == null || roleNames.isEmpty()) { + mSentryRoles = (List<MSentryRole>)query.execute(); + } else { + QueryParamBuilder paramBuilder = new QueryParamBuilder(QueryParamBuilder.Op.OR); + paramBuilder.addSet("roleName == ", roleNames); + query.setFilter(paramBuilder.toString()); + mSentryRoles = + (List<MSentryRole>) query.executeWithMap(paramBuilder.getArguments()); } - }); + Map<String, Set<String>> groupRolesMap = getGroupRolesMap(mSentryRoles); + Map<String, Set<String>> userRolesMap = getUserRolesMap(mSentryRoles); + List<Map<String, Set<String>>> mapsList = new ArrayList<>(); + mapsList.add(INDEX_GROUP_ROLES_MAP, groupRolesMap); + mapsList.add(INDEX_USER_ROLES_MAP, userRolesMap); + return mapsList; + } + }); } private Map<String, Set<String>> getGroupRolesMap(List<MSentryRole> mSentryRoles) { @@ -2218,27 +2222,29 @@ public class SentryStore { /** * @return mapping data for [role,privilege] with the specific auth object */ - @SuppressWarnings("unchecked") public Map<String, Set<TSentryPrivilege>> getRoleNameTPrivilegesMap(final String dbName, final String tableName) throws Exception { - return (Map<String, Set<TSentryPrivilege>>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - Query query = pm.newQuery(MSentryPrivilege.class); - QueryParamBuilder paramBuilder = new QueryParamBuilder(); + return tm.executeTransaction( + new TransactionBlock<Map<String, Set<TSentryPrivilege>>>() { + public Map<String, Set<TSentryPrivilege>> execute(PersistenceManager pm) + throws Exception { + Query query = pm.newQuery(MSentryPrivilege.class); + QueryParamBuilder paramBuilder = new QueryParamBuilder(); - if (!StringUtils.isEmpty(dbName)) { - paramBuilder.add(DB_NAME, dbName); - } - if (!StringUtils.isEmpty(tableName)) { - paramBuilder.add(TABLE_NAME, tableName); - } - query.setFilter(paramBuilder.toString()); - List<MSentryPrivilege> mSentryPrivileges = - (List<MSentryPrivilege>) query.executeWithMap(paramBuilder.getArguments()); - return getRolePrivilegesMap(mSentryPrivileges); + if (!StringUtils.isEmpty(dbName)) { + paramBuilder.add(DB_NAME, dbName); } - }); + if (!StringUtils.isEmpty(tableName)) { + paramBuilder.add(TABLE_NAME, tableName); + } + query.setFilter(paramBuilder.toString()); + @SuppressWarnings("unchecked") + List<MSentryPrivilege> mSentryPrivileges = + (List<MSentryPrivilege>) query. + executeWithMap(paramBuilder.getArguments()); + return getRolePrivilegesMap(mSentryPrivileges); + } + }); } private Map<String, Set<TSentryPrivilege>> getRolePrivilegesMap( @@ -2266,11 +2272,10 @@ public class SentryStore { /** * @return Set of all role names, or an empty set if no roles are defined */ - @SuppressWarnings("unchecked") public Set<String> getAllRoleNames() throws Exception { - return (Set<String>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + return tm.executeTransaction( + new TransactionBlock<Set<String>>() { + public Set<String> execute(PersistenceManager pm) throws Exception { return getAllRoleNamesCore(pm); } }); @@ -2298,9 +2303,9 @@ public class SentryStore { * @param pm PersistenceManager instance * @return map of group names to group data for each group */ - @SuppressWarnings("unchecked") private Map<String, MSentryGroup> getGroupNameTGroupMap(PersistenceManager pm) { Query query = pm.newQuery(MSentryGroup.class); + @SuppressWarnings("unchecked") List<MSentryGroup> mSentryGroups = (List<MSentryGroup>) query.execute(); Map<String, MSentryGroup> existGroupsMap = Maps.newHashMap(); if (mSentryGroups != null) { @@ -2317,10 +2322,9 @@ public class SentryStore { * @param pm PersistenceManager instance * @return map of user names to user data for each user */ - // get the all exist users - @SuppressWarnings("unchecked") private Map<String, MSentryUser> getUserNameToUserMap(PersistenceManager pm) { Query query = pm.newQuery(MSentryUser.class); + @SuppressWarnings("unchecked") List<MSentryUser> users = (List<MSentryUser>) query.execute(); Map<String, MSentryUser> existUsersMap = Maps.newHashMap(); if (users != null) { @@ -2337,9 +2341,9 @@ public class SentryStore { * @param pm PersistenceManager instance * @return List of all privileges */ - @SuppressWarnings("unchecked") private List<MSentryPrivilege> getPrivilegesList(PersistenceManager pm) { Query query = pm.newQuery(MSentryPrivilege.class); + @SuppressWarnings("unchecked") List<MSentryPrivilege> resultList = (List<MSentryPrivilege>) query.execute(); if (resultList == null) { resultList = Lists.newArrayList(); @@ -2348,11 +2352,10 @@ public class SentryStore { } @VisibleForTesting - @SuppressWarnings("unchecked") - protected Map<String, MSentryRole> getRolesMap() throws Exception { - return (Map<String, MSentryRole>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + Map<String, MSentryRole> getRolesMap() throws Exception { + return tm.executeTransaction( + new TransactionBlock<Map<String, MSentryRole>>() { + public Map<String, MSentryRole> execute(PersistenceManager pm) throws Exception { List<MSentryRole> mSentryRoles = getAllRoles(pm); Map<String, MSentryRole> existRolesMap = Maps.newHashMap(); if (mSentryRoles != null) { @@ -2368,36 +2371,34 @@ public class SentryStore { } @VisibleForTesting - @SuppressWarnings("unchecked") - protected Map<String, MSentryGroup> getGroupNameToGroupMap() throws Exception { - return (Map<String, MSentryGroup>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - return getGroupNameTGroupMap(pm); - } - }); + Map<String, MSentryGroup> getGroupNameToGroupMap() throws Exception { + return tm.executeTransaction( + new TransactionBlock<Map<String, MSentryGroup>>() { + public Map<String, MSentryGroup> execute(PersistenceManager pm) throws Exception { + return getGroupNameTGroupMap(pm); + } + }); } @VisibleForTesting - @SuppressWarnings("unchecked") - protected Map<String, MSentryUser> getUserNameToUserMap() throws Exception { - return (Map<String, MSentryUser>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { + Map<String, MSentryUser> getUserNameToUserMap() throws Exception { + return tm.executeTransaction( + new TransactionBlock<Map<String, MSentryUser>>() { + public Map<String, MSentryUser> execute(PersistenceManager pm) throws Exception { return getUserNameToUserMap(pm); } }); } @VisibleForTesting - @SuppressWarnings("unchecked") - protected List<MSentryPrivilege> getPrivilegesList() throws Exception { - return (List<MSentryPrivilege>) tm.executeTransaction( - new TransactionBlock() { - public Object execute(PersistenceManager pm) throws Exception { - return getPrivilegesList(pm); - } - }); + List<MSentryPrivilege> getPrivilegesList() throws Exception { + return tm.executeTransaction( + new TransactionBlock<List<MSentryPrivilege>>() { + public List<MSentryPrivilege> execute(PersistenceManager pm) + throws Exception { + return getPrivilegesList(pm); + } + }); } /** http://git-wip-us.apache.org/repos/asf/sentry/blob/79cbd178/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionBlock.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionBlock.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionBlock.java index 76d004b..c7b19ce 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionBlock.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionBlock.java @@ -1,4 +1,4 @@ -/** +/* * 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 @@ -22,16 +22,17 @@ import javax.jdo.PersistenceManager; /** * TransactionBlock wraps the code that is executed inside a single - * transaction + * transaction. The {@link #execute(PersistenceManager)} method returns the + * result of the transaction. */ -public interface TransactionBlock { +public interface TransactionBlock<T> { /** - * Execute some code as a single transaction, the code should not start new transaction - * or manipulate transactions with the PersistenceManager. TransactionManager is responsible to - * handle the transaction management. + * Execute some code as a single transaction, the code should not start new + * transaction or manipulate transactions with the PersistenceManager. + * * @param pm PersistenceManager for the current transaction * @return Object with the result of execute() * @throws Exception */ - Object execute(PersistenceManager pm) throws Exception; -} + T execute(PersistenceManager pm) throws Exception; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/sentry/blob/79cbd178/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java ---------------------------------------------------------------------- diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java index 1581f39..ec365bf 100644 --- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java +++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/TransactionManager.java @@ -1,4 +1,4 @@ -/** +/* * 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 @@ -38,13 +38,16 @@ import org.apache.sentry.provider.db.service.thrift.SentryMetrics; /** * TransactionManager is used for executing the database transaction, it supports * the transaction with retry mechanism for the unexpected exceptions, - * except SentryUserExceptions, eg, SentryNoSuchObjectException, - * SentryAlreadyExistsException etc. - * <p> - * The purpose of the class is to separate all transaction houskeeping (opening + * except <em>SentryUserExceptions</em>, eg, <em>SentryNoSuchObjectException</em>, + * <em>SentryAlreadyExistsException</em> etc. <p> + * + * The purpose of the class is to separate all transaction housekeeping (opening * transaction, rolling back failed transactions) from the actual transaction - * business logic. - * <p> + * business logic.<p> + * + * TransactionManager creates an instance of PersistenceManager for each + * transaction.<p> + * * TransactionManager exposes several metrics: * <ul> * <li>Timer metric for all transactions</li> @@ -54,7 +57,8 @@ import org.apache.sentry.provider.db.service.thrift.SentryMetrics; */ public class TransactionManager { - private static final Logger LOGGER = LoggerFactory.getLogger(TransactionManager.class); + private static final Logger LOGGER = + LoggerFactory.getLogger(TransactionManager.class); private final PersistenceManagerFactory pmf; @@ -92,19 +96,20 @@ public class TransactionManager { /** - * Execute some code as a single transaction, the code in tb.execute() should not start new - * transaction or manipulate transactions with the PersistenceManager. + * Execute some code as a single transaction, the code in tb.execute() + * should not start new transaction or manipulate transactions with the + * PersistenceManager. * @param tb transaction block with code to execute * @return Object with the result of tb.execute() */ - public Object executeTransaction(TransactionBlock tb) throws Exception { + public <T> T executeTransaction(TransactionBlock<T> tb) throws Exception { final Timer.Context context = transactionTimer.time(); try (CloseablePersistenceManager cpm = new CloseablePersistenceManager(pmf.getPersistenceManager())) { Transaction transaction = cpm.pm.currentTransaction(); transaction.begin(); try { - Object result = tb.execute(cpm.pm); + T result = tb.execute(cpm.pm); transaction.commit(); return result; } catch (Exception e) { @@ -129,7 +134,8 @@ public class TransactionManager { * @param tb transaction block with code to execute * @return Object with the result of tb.execute() */ - public Object executeTransactionWithRetry(TransactionBlock tb) throws Exception { + public <T> T executeTransactionWithRetry(TransactionBlock<T> tb) + throws Exception { int retryNum = 0; while (retryNum < transactionRetryMax) { try {