-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://reviews.apache.org/r/74106/
-----------------------------------------------------------
Review request for ranger, Madhan Neethiraj, Nikhil P, and Velmurugan Periasamy.
Bugs: RANGER-3898
https://issues.apache.org/jira/browse/RANGER-3898
Repository: ranger
Description
-------
Bug in Ranger Roles Cache
It seems Apache Ranger open source contains a bug where else block in the below
code will not be called at all
In the below code else block is a dead code
public RangerRoles getLatestRangerRoleOrCached(String serviceName, RoleDBStore
roleDBStore, Long lastKnownRoleVersion, Long rangerRoleVersionInDB) throws
Exception {
final RangerRoles ret;
if (lastKnownRoleVersion == null ||
!lastKnownRoleVersion.equals(rangerRoleVersionInDB)) {
roleCacheWrapper = new RangerRoleCacheWrapper();
ret = roleCacheWrapper.getLatestRangerRoles(serviceName,
roleDBStore, lastKnownRoleVersion, rangerRoleVersionInDB);
} else if (lastKnownRoleVersion.equals(rangerRoleVersionInDB)) {
ret = null;
} else {
ret = roleCacheWrapper.getRoles();
}
return ret;
}
The below behaviour also broken
when multiple threads are trying to access and one or more threads got timeout
while acquiring the lock,it will fetch the roles from cache but ,we are not
setting the roles in cache anywhere in our code
public RangerRoles getLatestRangerRoles(String serviceName, RoleDBStore
roleDBStore, Long lastKnownRoleVersion, Long rolesVersionInDB) throws Exception
{
RangerRoles ret = null;
boolean lockResult = false;
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerRoleCache.getLatestRangerRoles(ServiceName= " +
serviceName + " lastKnownRoleVersion= " + lastKnownRoleVersion + "
rolesVersionInDB= " + rolesVersionInDB + ")");
}
try {
lockResult = lock.tryLock(waitTimeInSeconds, TimeUnit.SECONDS);
if (lockResult) {
// We are getting all the Roles to be downloaded for now. Should do
downloades for each service based on what roles are there in the policies.
SearchFilter searchFilter = null;
final Set<RangerRole> rolesInDB = new
HashSet<>(roleDBStore.getRoles(searchFilter));
Date updateTime = new Date();
if (rolesInDB != null) {
ret = new RangerRoles();
ret.setRangerRoles(rolesInDB);
ret.setRoleUpdateTime(updateTime);
ret.setRoleVersion(rolesVersionInDB);
rolesVersion = rolesVersionInDB;
} else {
LOG.error("Could not get Ranger Roles from database ...");
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Could not get lock in [" + waitTimeInSeconds + "]
seconds, returning cached RangerRoles");
}
ret = getRoles();
}
} catch (InterruptedException exception) {
LOG.error("RangerRoleCache.getLatestRangerRoles:lock got interrupted..",
exception);
} finally {
if (lockResult) {
lock.unlock();
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerRoleCache.getLatestRangerRoles(ServiceName= " +
serviceName + " lastKnownRoleVersion= " + lastKnownRoleVersion + "
rolesVersionInDB= " + rolesVersionInDB + " RangerRoles= " + ret + ")");
}
return ret;
}
Diffs
-----
security-admin/src/main/java/org/apache/ranger/common/RangerRoleCache.java
d71e97034
Diff: https://reviews.apache.org/r/74106/diff/1/
Testing
-------
Tested the below Rest API's to make sure everything works fine
1.GET /service/roles/download/{serviceName}
2.GET /service/roles/secure/download/{serviceName}
Thanks,
Ramachandran Krishnan