This is an automated email from the ASF dual-hosted git repository.
abhay pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new b69c2df RANGER-3192: Use read-write locks for managing access to
policy-engine and tag-repository
b69c2df is described below
commit b69c2df7625696b3d38cf1cfbbcf1db4d634c7b0
Author: Abhay Kulkarni <[email protected]>
AuthorDate: Sat Feb 27 07:08:47 2021 -0800
RANGER-3192: Use read-write locks for managing access to policy-engine and
tag-repository
---
.../ranger/admin/client/RangerAdminRESTClient.java | 18 +-
.../plugin/contextenricher/RangerTagEnricher.java | 151 +++++---
.../ranger/plugin/policyengine/PolicyEngine.java | 259 +++++++++-----
.../policyengine/RangerPolicyEngineImpl.java | 397 ++++++++++++++-------
.../policyengine/RangerPolicyRepository.java | 263 ++++++++------
.../org/apache/ranger/plugin/store/TagStore.java | 2 +
.../ranger/plugin/util/RangerCommonConstants.java | 24 +-
.../ranger/plugin/util/RangerReadWriteLock.java | 98 +++++
.../admin/client/RangerAdminJersey2RESTClient.java | 18 +-
.../apache/ranger/biz/RangerPolicyAdminCache.java | 4 +-
.../apache/ranger/biz/RangerPolicyAdminImpl.java | 250 +++++++++----
.../java/org/apache/ranger/biz/ServiceDBStore.java | 9 +-
.../java/org/apache/ranger/biz/TagDBStore.java | 24 +-
.../ranger/common/RangerAdminTagEnricher.java | 12 +
14 files changed, 1044 insertions(+), 485 deletions(-)
diff --git
a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
index 9d527bf..e0d7a9b 100644
---
a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
+++
b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
@@ -53,8 +53,8 @@ public class RangerAdminRESTClient extends
AbstractRangerAdminClient {
private String clusterName;
private RangerRESTClient restClient;
private RangerRESTUtils restUtils = new RangerRESTUtils();
- private String supportsPolicyDeltas;
- private String supportsTagDeltas;
+ private boolean supportsPolicyDeltas;
+ private boolean supportsTagDeltas;
private final String pluginCapabilities = Long.toHexString(new
RangerPluginCapability().getPluginCapabilities());
public static <T> GenericType<List<T>> getGenericType(final T clazz) {
@@ -97,8 +97,8 @@ public class RangerAdminRESTClient extends
AbstractRangerAdminClient {
}
int restClientConnTimeOutMs =
config.getInt(propertyPrefix + ".policy.rest.client.connection.timeoutMs", 120
* 1000);
int restClientReadTimeOutMs =
config.getInt(propertyPrefix + ".policy.rest.client.read.timeoutMs", 30 * 1000);
- supportsPolicyDeltas = config.get(propertyPrefix +
".policy.rest.supports.policy.deltas", "false");
- supportsTagDeltas = config.get(propertyPrefix +
".tag.rest.supports.tag.deltas", "false");
+ supportsPolicyDeltas =
config.getBoolean(propertyPrefix +
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA,
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA_DEFAULT);
+ supportsTagDeltas =
config.getBoolean(propertyPrefix +
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA,
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA_DEFAULT);
if (!StringUtil.isEmpty(tmpUrl)) {
url = tmpUrl.trim();
@@ -106,12 +106,6 @@ public class RangerAdminRESTClient extends
AbstractRangerAdminClient {
if (url.endsWith("/")) {
url = url.substring(0, url.length() - 1);
}
- if (!"true".equalsIgnoreCase(supportsPolicyDeltas)) {
- supportsPolicyDeltas = "false";
- }
- if (!"true".equalsIgnoreCase(supportsTagDeltas)) {
- supportsTagDeltas = "false";
- }
init(url, sslConfigFileName, restClientConnTimeOutMs ,
restClientReadTimeOutMs, config);
@@ -140,7 +134,7 @@ public class RangerAdminRESTClient extends
AbstractRangerAdminClient {
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_ACTIVATION_TIME,
Long.toString(lastActivationTimeInMillis));
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
queryParams.put(RangerRESTUtils.REST_PARAM_CLUSTER_NAME,
clusterName);
-
queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_POLICY_DELTAS,
supportsPolicyDeltas);
+
queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_POLICY_DELTAS,
Boolean.toString(supportsPolicyDeltas));
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES,
pluginCapabilities);
if (isSecureMode) {
@@ -799,7 +793,7 @@ public class RangerAdminRESTClient extends
AbstractRangerAdminClient {
queryParams.put(RangerRESTUtils.LAST_KNOWN_TAG_VERSION_PARAM,
Long.toString(lastKnownVersion));
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_ACTIVATION_TIME,
Long.toString(lastActivationTimeInMillis));
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
- queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS,
supportsTagDeltas);
+ queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS,
Boolean.toString(supportsTagDeltas));
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES,
pluginCapabilities);
if (isSecureMode) {
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
index 97b9e2c..f457460 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
@@ -26,6 +26,7 @@ import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceResource;
@@ -42,7 +43,9 @@ import org.apache.ranger.plugin.util.DownloadTrigger;
import org.apache.ranger.plugin.util.DownloaderTask;
import org.apache.ranger.plugin.service.RangerAuthContext;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.RangerPerfTracer;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.RangerServiceNotFoundException;
import org.apache.ranger.plugin.util.RangerServiceTagsDeltaUtil;
import org.apache.ranger.plugin.util.ServiceTags;
@@ -87,6 +90,7 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
private Timer tagDownloadTimer;
private RangerServiceDefHelper serviceDefHelper;
+ private RangerReadWriteLock lock = new
RangerReadWriteLock(false);
@Override
public void init() {
@@ -132,6 +136,9 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
cacheFilename =
cacheFilename.replace(File.pathSeparatorChar, '_');
String cacheFile = cacheDir == null ? null :
(cacheDir + File.separator + cacheFilename);
+
+ createLock();
+
tagRetriever.setServiceName(serviceName);
tagRetriever.setServiceDef(serviceDef);
tagRetriever.setAppId(appId);
@@ -189,21 +196,33 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerTagEnricher.enrich(" + request +
") with dataStore:[" + dataStore + "]");
}
- final EnrichedServiceTags enrichedServiceTags;
- if (dataStore instanceof EnrichedServiceTags) {
- enrichedServiceTags = (EnrichedServiceTags) dataStore;
- } else {
- enrichedServiceTags = this.enrichedServiceTags;
+ final Set<RangerTagForEval> matchedTags;
+
+ try (RangerReadWriteLock.RangerLock readLock =
this.lock.getReadLock()) {
- if (dataStore != null) {
- LOG.warn("Incorrect type of dataStore :[" +
dataStore.getClass().getName() + "], falling back to original enrich");
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
}
- }
- final Set<RangerTagForEval> matchedTags = enrichedServiceTags
== null ? null : findMatchingTags(request, enrichedServiceTags);
+ final EnrichedServiceTags enrichedServiceTags;
-
RangerAccessRequestUtil.setRequestTagsInContext(request.getContext(),
matchedTags);
+ if (dataStore instanceof EnrichedServiceTags) {
+ enrichedServiceTags = (EnrichedServiceTags)
dataStore;
+ } else {
+ enrichedServiceTags = this.enrichedServiceTags;
+
+ if (dataStore != null) {
+ LOG.warn("Incorrect type of dataStore
:[" + dataStore.getClass().getName() + "], falling back to original enrich");
+ }
+ }
+
+ matchedTags = enrichedServiceTags == null ? null :
findMatchingTags(request, enrichedServiceTags);
+
+
RangerAccessRequestUtil.setRequestTagsInContext(request.getContext(),
matchedTags);
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerTagEnricher.enrich(" + request +
") with dataStore:[" + dataStore + "]): tags count=" + (matchedTags == null ? 0
: matchedTags.size()));
@@ -266,48 +285,64 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
LOG.debug("==>
RangerTagEnricher.setServiceTags(serviceTags=" + serviceTags + ",
rebuildOnlyIndex=" + rebuildOnlyIndex + ")");
}
- if (serviceTags == null) {
- LOG.info("ServiceTags is null for service " +
serviceName);
- enrichedServiceTags = null;
- } else {
+ try (RangerReadWriteLock.RangerLock writeLock =
this.lock.getWriteLock()) {
+
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
writeLock);
+ }
+ }
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_SET_SERVICETAGS_LOG)) {
perf =
RangerPerfTracer.getPerfTracer(PERF_SET_SERVICETAGS_LOG,
"RangerTagEnricher.setServiceTags(newTagVersion=" + serviceTags.getTagVersion()
+ ",isDelta=" + serviceTags.getIsDelta() + ")");
}
- if (!serviceTags.getIsDelta()) {
- processServiceTags(serviceTags);
+ if (serviceTags == null) {
+ LOG.info("ServiceTags is null for service " +
serviceName);
+ enrichedServiceTags = null;
} else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Received service-tag
deltas:" + serviceTags);
- }
-
- ServiceTags oldServiceTags =
enrichedServiceTags != null ? enrichedServiceTags.getServiceTags() : new
ServiceTags();
- ServiceTags allServiceTags = rebuildOnlyIndex ?
oldServiceTags : RangerServiceTagsDeltaUtil.applyDelta(oldServiceTags,
serviceTags);
-
- if (serviceTags.getTagsChangeExtent() ==
ServiceTags.TagsChangeExtent.NONE) {
+ if (!serviceTags.getIsDelta()) {
+ processServiceTags(serviceTags);
+ } else {
if (LOG.isDebugEnabled()) {
- LOG.debug("No change to
service-tags other than version change");
+ LOG.debug("Received service-tag
deltas:" + serviceTags);
}
- } else {
- if (serviceTags.getTagsChangeExtent()
!= ServiceTags.TagsChangeExtent.TAGS) {
-
processServiceTagDeltas(serviceTags, allServiceTags);
- } else {
+ ServiceTags oldServiceTags =
enrichedServiceTags != null ? enrichedServiceTags.getServiceTags() : new
ServiceTags();
+ ServiceTags allServiceTags =
rebuildOnlyIndex ? oldServiceTags :
RangerServiceTagsDeltaUtil.applyDelta(oldServiceTags, serviceTags);
+
+ if (serviceTags.getTagsChangeExtent()
== ServiceTags.TagsChangeExtent.NONE) {
if (LOG.isDebugEnabled()) {
- LOG.debug("Delta
contains only tag attribute changes");
+ LOG.debug("No change to
service-tags other than version change");
+ }
+ } else {
+ if
(serviceTags.getTagsChangeExtent() != ServiceTags.TagsChangeExtent.TAGS) {
+ Map<String,
RangerResourceTrie<RangerServiceResourceMatcher>> trieMap;
+
+ if (enrichedServiceTags
== null) {
+ trieMap = new
HashMap<>();
+ } else {
+ trieMap =
writeLock.isLockingEnabled() ? enrichedServiceTags.getServiceResourceTrie() :
copyServiceResourceTrie();
+ }
+
+
processServiceTagDeltas(serviceTags, allServiceTags, trieMap);
+ } else {
+ if
(LOG.isDebugEnabled()) {
+
LOG.debug("Delta contains only tag attribute changes");
+ }
+
List<RangerServiceResourceMatcher> resourceMatchers = enrichedServiceTags !=
null ? enrichedServiceTags.getServiceResourceMatchers() : new ArrayList<>();
+ Map<String,
RangerResourceTrie<RangerServiceResourceMatcher>> serviceResourceTrie =
enrichedServiceTags != null ? enrichedServiceTags.getServiceResourceTrie() :
new HashMap<>();
+ enrichedServiceTags =
new EnrichedServiceTags(allServiceTags, resourceMatchers, serviceResourceTrie);
}
-
List<RangerServiceResourceMatcher> resourceMatchers
= enrichedServiceTags != null ?
enrichedServiceTags.getServiceResourceMatchers() : new ArrayList<>();
- Map<String,
RangerResourceTrie<RangerServiceResourceMatcher>> serviceResourceTrie =
enrichedServiceTags != null ? enrichedServiceTags.getServiceResourceTrie() :
new HashMap<>();
- enrichedServiceTags = new
EnrichedServiceTags(allServiceTags, resourceMatchers, serviceResourceTrie);
}
}
+
}
+ setEnrichedServiceTagsInPlugin();
+
RangerPerfTracer.logAlways(perf);
}
- setEnrichedServiceTagsInPlugin();
-
if (LOG.isDebugEnabled()) {
LOG.debug("<==
RangerTagEnricher.setServiceTags(serviceTags=" + serviceTags + ",
rebuildOnlyIndex=" + rebuildOnlyIndex + ")");
}
@@ -315,11 +350,13 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
}
protected Long getServiceTagsVersion() {
- return enrichedServiceTags != null ?
enrichedServiceTags.getServiceTags().getTagVersion() : -1L;
+ EnrichedServiceTags localEnrichedServiceTags =
enrichedServiceTags;
+ return localEnrichedServiceTags != null ?
localEnrichedServiceTags.getServiceTags().getTagVersion() : -1L;
}
protected Long getResourceTrieVersion() {
- return enrichedServiceTags != null ?
enrichedServiceTags.getResourceTrieVersion() : -1L;
+ EnrichedServiceTags localEnrichedServiceTags =
enrichedServiceTags;
+ return localEnrichedServiceTags != null ?
localEnrichedServiceTags.getResourceTrieVersion() : -1L;
}
@Override
@@ -359,6 +396,18 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
return enrichedServiceTags;
}
+ protected RangerReadWriteLock createLock() {
+ String propertyPrefix = "ranger.plugin." +
serviceDef.getName();
+ RangerPluginConfig config = getPluginConfig();
+ boolean deltasEnabled = config != null &&
config.getBoolean(propertyPrefix +
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA,
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA_DEFAULT);
+ boolean inPlaceUpdatesEnabled = config != null &&
config.getBoolean(propertyPrefix +
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_IN_PLACE_TAG_UPDATES,
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_IN_PLACE_TAG_UPDATES_DEFAULT);
+ boolean useReadWriteLock = deltasEnabled &&
inPlaceUpdatesEnabled;
+
+ LOG.info("Policy-Engine will" + (useReadWriteLock ? " " : " not
") + "use read-write locking to update tags in place when tag-deltas are
provided");
+
+ return new RangerReadWriteLock(useReadWriteLock);
+
+ }
private void processServiceTags(ServiceTags serviceTags) {
if (LOG.isDebugEnabled()) {
LOG.debug("Processing all service-tags");
@@ -405,24 +454,18 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
}
}
- private void processServiceTagDeltas(ServiceTags deltas, ServiceTags
allServiceTags) {
+ private void processServiceTagDeltas(ServiceTags deltas, ServiceTags
allServiceTags, Map<String, RangerResourceTrie<RangerServiceResourceMatcher>>
serviceResourceTrie) {
if (LOG.isDebugEnabled()) {
LOG.debug("Delta contains changes other than tag
attribute changes, [" + deltas.getTagsChangeExtent() + "]");
}
- boolean isInError = false;
-
- ResourceHierarchies hierarchies = new
ResourceHierarchies();
+ boolean isInError = false;
- List<RangerServiceResourceMatcher>
resourceMatchers = new ArrayList<>();
- Map<String, RangerResourceTrie<RangerServiceResourceMatcher>>
serviceResourceTrie = new HashMap<>();
+ ResourceHierarchies hierarchies = new
ResourceHierarchies();
+ List<RangerServiceResourceMatcher> resourceMatchers = new
ArrayList<>();
if (enrichedServiceTags != null) {
resourceMatchers.addAll(enrichedServiceTags.getServiceResourceMatchers());
- for (Map.Entry<String,
RangerResourceTrie<RangerServiceResourceMatcher>> entry :
enrichedServiceTags.getServiceResourceTrie().entrySet()) {
-
RangerResourceTrie<RangerServiceResourceMatcher> resourceTrie = new
RangerResourceTrie<>(entry.getValue());
- serviceResourceTrie.put(entry.getKey(),
resourceTrie);
- }
}
List<RangerServiceResource> changedServiceResources =
deltas.getServiceResources();
@@ -810,6 +853,18 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
return ret;
}
+ private Map<String, RangerResourceTrie<RangerServiceResourceMatcher>>
copyServiceResourceTrie() {
+ Map<String, RangerResourceTrie<RangerServiceResourceMatcher>>
ret = new HashMap<>();
+
+ if (enrichedServiceTags != null) {
+ for (Map.Entry<String,
RangerResourceTrie<RangerServiceResourceMatcher>> entry :
enrichedServiceTags.getServiceResourceTrie().entrySet()) {
+
RangerResourceTrie<RangerServiceResourceMatcher> resourceTrie = new
RangerResourceTrie<>(entry.getValue());
+ ret.put(entry.getKey(), resourceTrie);
+ }
+ }
+ return ret;
+ }
+
static public final class EnrichedServiceTags {
final private ServiceTags
serviceTags;
final private List<RangerServiceResourceMatcher>
serviceResourceMatchers;
@@ -896,7 +951,7 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
RangerPerfTracer.log(perf);
} catch (InterruptedException excp) {
- LOG.debug("RangerTagRefresher(" +
getName() + ").run(): Interrupted! Exiting thread", excp);
+ LOG.info("RangerTagRefresher(" +
getName() + ").run(): Interrupted! Exiting thread", excp);
break;
} finally {
if (trigger != null) {
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
index 1909ad4..9d79520 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
@@ -46,6 +46,7 @@ import org.apache.ranger.plugin.service.RangerAuthContext;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.apache.ranger.plugin.util.RangerPolicyDeltaUtil;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.RangerRoles;
import org.apache.ranger.plugin.util.ServicePolicies;
import org.apache.ranger.plugin.util.StringTokenReplacer;
@@ -67,6 +68,16 @@ public class PolicyEngine {
private String[] trustedProxyAddresses;
private final Map<String, StringTokenReplacer> tokenReplacers = new
HashMap<>();
+ private final RangerReadWriteLock lock;
+
+ public RangerReadWriteLock.RangerLock getReadLock() {
+ return lock.getReadLock();
+ }
+
+ public RangerReadWriteLock.RangerLock getWriteLock() {
+ return lock.getWriteLock();
+ }
+
public boolean getUseForwardedIPAddress() {
return useForwardedIPAddress;
}
@@ -152,6 +163,8 @@ public class PolicyEngine {
}
sb.append("} ");
+ sb.append(lock.toString());
+
sb.append("}");
return sb;
@@ -167,7 +180,7 @@ public class PolicyEngine {
return resourceZoneTrie;
}
- public PolicyEngine(ServicePolicies servicePolicies,
RangerPluginContext pluginContext, RangerRoles roles) {
+ public PolicyEngine(ServicePolicies servicePolicies, RangerPluginContext
pluginContext, RangerRoles roles, boolean isUseReadWriteLock) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> PolicyEngine(" + ", " + servicePolicies + ", " +
pluginContext + ")");
}
@@ -184,6 +197,9 @@ public class PolicyEngine {
}
this.pluginContext = pluginContext;
+ this.lock = new RangerReadWriteLock(isUseReadWriteLock);
+
+ LOG.info("Policy engine will" + (isUseReadWriteLock ? " " : " not ") +
"perform in place update while processing policy-deltas.");
this.pluginContext.setAuthContext(new RangerAuthContext(null, roles));
@@ -200,8 +216,7 @@ public class PolicyEngine {
if (!options.disableTagPolicyEvaluation
&& tagPolicies != null
&& !StringUtils.isEmpty(tagPolicies.getServiceName())
- && tagPolicies.getServiceDef() != null
- && !CollectionUtils.isEmpty(tagPolicies.getPolicies())) {
+ && tagPolicies.getServiceDef() != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("PolicyEngine : Building tag-policy-repository for
tag-service " + tagPolicies.getServiceName());
}
@@ -281,33 +296,46 @@ public class PolicyEngine {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_INIT_LOG,
"RangerPolicyEngine.cloneWithDelta()");
}
- RangerServiceDef serviceDef = this.getServiceDef();
- String serviceType = (serviceDef != null) ?
serviceDef.getName() : "";
- boolean isValidDeltas = false;
+ try (RangerReadWriteLock.RangerLock writeLock = getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + writeLock);
+ }
+ }
- if (CollectionUtils.isNotEmpty(servicePolicies.getPolicyDeltas()) ||
MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
- isValidDeltas =
CollectionUtils.isEmpty(servicePolicies.getPolicyDeltas()) ||
RangerPolicyDeltaUtil.isValidDeltas(servicePolicies.getPolicyDeltas(),
serviceType);
+ RangerServiceDef serviceDef = this.getServiceDef();
+ String serviceType = (serviceDef != null) ? serviceDef.getName() :
"";
+ boolean isValidDeltas = false;
- if (isValidDeltas) {
- if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
- for (Map.Entry<String, ServicePolicies.SecurityZoneInfo>
entry : servicePolicies.getSecurityZones().entrySet()) {
- if
(!RangerPolicyDeltaUtil.isValidDeltas(entry.getValue().getPolicyDeltas(),
serviceType)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Invalid policy-deltas for security
zone:[" + entry.getKey() + "]");
- }
+ if (CollectionUtils.isNotEmpty(servicePolicies.getPolicyDeltas())
|| MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
+ isValidDeltas =
CollectionUtils.isEmpty(servicePolicies.getPolicyDeltas()) ||
RangerPolicyDeltaUtil.isValidDeltas(servicePolicies.getPolicyDeltas(),
serviceType);
+
+ if (isValidDeltas) {
+ if
(MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
+ for (Map.Entry<String,
ServicePolicies.SecurityZoneInfo> entry :
servicePolicies.getSecurityZones().entrySet()) {
+ if
(!RangerPolicyDeltaUtil.isValidDeltas(entry.getValue().getPolicyDeltas(),
serviceType)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Invalid policy-deltas for
security zone:[" + entry.getKey() + "]");
+ }
- isValidDeltas = false;
- break;
+ isValidDeltas = false;
+ break;
+ }
}
}
}
}
- }
- if (isValidDeltas) {
- ret = new PolicyEngine(this, servicePolicies);
- } else {
- ret = null;
+ if (isValidDeltas) {
+ if (writeLock.isLockingEnabled()) {
+ updatePolicyEngine(servicePolicies);
+ ret = this;
+ } else {
+ ret = new PolicyEngine(this, servicePolicies);
+ }
+ } else {
+ ret = null;
+ }
}
RangerPerfTracer.log(perf);
@@ -556,83 +584,17 @@ public class PolicyEngine {
return ret;
}
-
private PolicyEngine(final PolicyEngine other, ServicePolicies
servicePolicies) {
this.useForwardedIPAddress = other.useForwardedIPAddress;
this.trustedProxyAddresses = other.trustedProxyAddresses;
this.pluginContext = other.pluginContext;
+ this.lock = other.lock;
long policyVersion =
servicePolicies.getPolicyVersion() != null ? servicePolicies.getPolicyVersion()
: -1L;
List<RangerPolicyDelta> defaultZoneDeltas = new
ArrayList<>();
List<RangerPolicyDelta> defaultZoneDeltasForTagPolicies = new
ArrayList<>();
- if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
- buildZoneTrie(servicePolicies);
-
- Map<String, List<RangerPolicyDelta>> zoneDeltasMap = new
HashMap<>();
-
- for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> zone :
servicePolicies.getSecurityZones().entrySet()) {
- List<RangerPolicyDelta> deltas =
zone.getValue().getPolicyDeltas();
-
- for (RangerPolicyDelta delta : deltas) {
- String zoneName = delta.getZoneName();
-
- if (StringUtils.isNotEmpty(zoneName)) {
- List<RangerPolicyDelta> zoneDeltas =
zoneDeltasMap.get(zoneName);
-
- if (zoneDeltas == null) {
- zoneDeltas = new ArrayList<>();
- zoneDeltasMap.put(zoneName, zoneDeltas);
- }
-
- zoneDeltas.add(delta);
- } else {
- LOG.warn("policyDelta : [" + delta + "] does not
belong to any zone. Should not have come here.");
- }
- }
- }
-
- for (Map.Entry<String, List<RangerPolicyDelta>> entry :
zoneDeltasMap.entrySet()) {
- final String zoneName = entry.getKey();
- final List<RangerPolicyDelta> zoneDeltas =
entry.getValue();
- final RangerPolicyRepository otherRepository =
other.zonePolicyRepositories.get(zoneName);
- final RangerPolicyRepository policyRepository;
-
- if (CollectionUtils.isNotEmpty(zoneDeltas)) {
- if (otherRepository == null) {
- List<RangerPolicy> policies = new ArrayList<>();
-
- for (RangerPolicyDelta delta : zoneDeltas) {
- if (delta.getChangeType() ==
RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE) {
- policies.add(delta.getPolicy());
- } else {
- LOG.warn("Expected changeType:[" +
RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE + "], found policy-change-delta:["
+ delta +"]");
- }
- }
-
-
servicePolicies.getSecurityZones().get(zoneName).setPolicies(policies);
-
- policyRepository = new
RangerPolicyRepository(servicePolicies, this.pluginContext, zoneName);
- } else {
- policyRepository = new
RangerPolicyRepository(otherRepository, zoneDeltas, policyVersion);
- }
- } else {
- policyRepository = shareWith(otherRepository);
- }
-
- zonePolicyRepositories.put(zoneName, policyRepository);
- }
- }
-
- List<RangerPolicyDelta> unzonedDeltas =
servicePolicies.getPolicyDeltas();
-
- for (RangerPolicyDelta delta : unzonedDeltas) {
- if
(servicePolicies.getServiceDef().getName().equals(delta.getServiceType())) {
- defaultZoneDeltas.add(delta);
- } else {
- defaultZoneDeltasForTagPolicies.add(delta);
- }
- }
+ getDeltasSortedByZones(servicePolicies, defaultZoneDeltas,
defaultZoneDeltasForTagPolicies);
if (other.policyRepository != null &&
CollectionUtils.isNotEmpty(defaultZoneDeltas)) {
this.policyRepository = new
RangerPolicyRepository(other.policyRepository, defaultZoneDeltas,
policyVersion);
@@ -813,5 +775,122 @@ public class PolicyEngine {
LOG.debug("<== PolicyEngine.cleanup()");
}
}
+
+ void updatePolicyEngine(ServicePolicies servicePolicies) {
+
+ long policyVersion =
servicePolicies.getPolicyVersion() != null ? servicePolicies.getPolicyVersion()
: -1L;
+ List<RangerPolicyDelta> defaultZoneDeltas = new
ArrayList<>();
+ List<RangerPolicyDelta> defaultZoneDeltasForTagPolicies = new
ArrayList<>();
+
+ getDeltasSortedByZones(servicePolicies, defaultZoneDeltas,
defaultZoneDeltasForTagPolicies);
+
+ if (this.policyRepository != null &&
CollectionUtils.isNotEmpty(defaultZoneDeltas)) {
+ this.policyRepository.reinit(defaultZoneDeltas, policyVersion);
+ }
+
+ if (servicePolicies.getTagPolicies() != null &&
CollectionUtils.isNotEmpty(defaultZoneDeltasForTagPolicies)) {
+ if (this.tagPolicyRepository != null) {
+
this.tagPolicyRepository.reinit(defaultZoneDeltasForTagPolicies, policyVersion);
+ } else {
+ LOG.error("No previous tagPolicyRepository to update! Should
not have come here!!");
+ }
+ }
+
+ // Set all repositories to shared
+ if (policyRepository != null) {
+ policyRepository.setShared();
+ }
+ for (RangerPolicyRepository zoneRepository :
zonePolicyRepositories.values()) {
+ if (zoneRepository != null) {
+ zoneRepository.setShared();
+ }
+ }
+ if (tagPolicyRepository != null) {
+ tagPolicyRepository.setShared();
+ }
+
+ reorderPolicyEvaluators();
+ }
+
+ private void getDeltasSortedByZones(ServicePolicies servicePolicies,
List<RangerPolicyDelta> defaultZoneDeltas, List<RangerPolicyDelta>
defaultZoneDeltasForTagPolicies) {
+ long policyVersion =
servicePolicies.getPolicyVersion() != null ? servicePolicies.getPolicyVersion()
: -1L;
+
+ if (CollectionUtils.isNotEmpty(defaultZoneDeltas)) {
+ LOG.warn("Emptying out defaultZoneDeltas!");
+ defaultZoneDeltas.clear();
+ }
+ if (CollectionUtils.isNotEmpty(defaultZoneDeltasForTagPolicies)) {
+ LOG.warn("Emptying out defaultZoneDeltasForTagPolicies!");
+ defaultZoneDeltasForTagPolicies.clear();
+ }
+
+ if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
+ buildZoneTrie(servicePolicies);
+
+ Map<String, List<RangerPolicyDelta>> zoneDeltasMap = new
HashMap<>();
+
+ for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> zone :
servicePolicies.getSecurityZones().entrySet()) {
+ List<RangerPolicyDelta> deltas =
zone.getValue().getPolicyDeltas();
+
+ for (RangerPolicyDelta delta : deltas) {
+ String zoneName = delta.getZoneName();
+
+ if (StringUtils.isNotEmpty(zoneName)) {
+ List<RangerPolicyDelta> zoneDeltas =
zoneDeltasMap.get(zoneName);
+
+ if (zoneDeltas == null) {
+ zoneDeltas = new ArrayList<>();
+ zoneDeltasMap.put(zoneName, zoneDeltas);
+ }
+
+ zoneDeltas.add(delta);
+ } else {
+ LOG.warn("policyDelta : [" + delta + "] does not
belong to any zone. Should not have come here.");
+ }
+ }
+ }
+
+ for (Map.Entry<String, List<RangerPolicyDelta>> entry :
zoneDeltasMap.entrySet()) {
+ final String zoneName = entry.getKey();
+ final List<RangerPolicyDelta> zoneDeltas =
entry.getValue();
+ final RangerPolicyRepository otherRepository =
this.zonePolicyRepositories.get(zoneName);
+ final RangerPolicyRepository policyRepository;
+
+ if (CollectionUtils.isNotEmpty(zoneDeltas)) {
+ if (otherRepository == null) {
+ List<RangerPolicy> policies = new ArrayList<>();
+
+ for (RangerPolicyDelta delta : zoneDeltas) {
+ if (delta.getChangeType() ==
RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE) {
+ policies.add(delta.getPolicy());
+ } else {
+ LOG.warn("Expected changeType:[" +
RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE + "], found policy-change-delta:["
+ delta +"]");
+ }
+ }
+
+
servicePolicies.getSecurityZones().get(zoneName).setPolicies(policies);
+
+ policyRepository = new
RangerPolicyRepository(servicePolicies, this.pluginContext, zoneName);
+ } else {
+ policyRepository = new
RangerPolicyRepository(otherRepository, zoneDeltas, policyVersion);
+ }
+ } else {
+ policyRepository = shareWith(otherRepository);
+ }
+
+ zonePolicyRepositories.put(zoneName, policyRepository);
+ }
+ }
+
+ List<RangerPolicyDelta> unzonedDeltas =
servicePolicies.getPolicyDeltas();
+
+ for (RangerPolicyDelta delta : unzonedDeltas) {
+ if
(servicePolicies.getServiceDef().getName().equals(delta.getServiceType())) {
+ defaultZoneDeltas.add(delta);
+ } else {
+ defaultZoneDeltasForTagPolicies.add(delta);
+ }
+ }
+ }
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index 4e0c98e..75811b8 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -25,6 +25,7 @@ import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
import org.apache.ranger.authorization.utils.StringUtil;
import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
@@ -36,7 +37,9 @@ import
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatche
import org.apache.ranger.plugin.service.RangerDefaultRequestProcessor;
import org.apache.ranger.plugin.util.GrantRevokeRequest;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.RangerPerfTracer;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.RangerRoles;
import org.apache.ranger.plugin.util.ServicePolicies;
@@ -71,7 +74,11 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
PolicyEngine policyEngine =
other.policyEngine.cloneWithDelta(servicePolicies);
if (policyEngine != null) {
- ret = new RangerPolicyEngineImpl(policyEngine,
other);
+ if (policyEngine == other.policyEngine) {
+ ret = other;
+ } else {
+ ret = new
RangerPolicyEngineImpl(policyEngine, other);
+ }
}
}
@@ -79,7 +86,18 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
}
public RangerPolicyEngineImpl(ServicePolicies servicePolicies,
RangerPluginContext pluginContext, RangerRoles roles) {
- policyEngine = new PolicyEngine(servicePolicies,
pluginContext, roles);
+ final boolean isUseReadWriteLock;
+
+ Configuration config = pluginContext != null ?
pluginContext.getConfig() : null;
+
+ if (config != null) {
+ boolean isDeltasSupported =
config.getBoolean(pluginContext.getConfig().getPropertyPrefix() +
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA,
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA_DEFAULT);
+ isUseReadWriteLock = isDeltasSupported &&
config.getBoolean(pluginContext.getConfig().getPropertyPrefix() +
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_IN_PLACE_POLICY_UPDATES,
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_IN_PLACE_POLICY_UPDATES_DEFAULT);
+ } else {
+ isUseReadWriteLock = false;
+ }
+
+ policyEngine = new PolicyEngine(servicePolicies,
pluginContext, roles, isUseReadWriteLock);
serviceConfig = new
ServiceConfig(servicePolicies.getServiceConfig());
requestProcessor = new
RangerDefaultRequestProcessor(policyEngine);
}
@@ -105,22 +123,32 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
LOG.info("RangerPolicyEngineImpl.evaluatePolicies(" +
requestHashCode + ", " + request + ")");
}
- requestProcessor.preProcess(request);
+ RangerAccessResult ret;
- RangerAccessResult ret =
zoneAwareAccessEvaluationWithNoAudit(request, policyType);
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
- if (resultProcessor != null) {
- RangerPerfTracer perfAuditTracer = null;
+ requestProcessor.preProcess(request);
-
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_AUDIT_LOG)) {
- String requestHashCode =
Integer.toHexString(System.identityHashCode(request)) + "_" + policyType;
+ ret = zoneAwareAccessEvaluationWithNoAudit(request,
policyType);
- perfAuditTracer =
RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_AUDIT_LOG,
"RangerPolicyEngine.processAudit(requestHashCode=" + requestHashCode + ")");
- }
+ if (resultProcessor != null) {
+ RangerPerfTracer perfAuditTracer = null;
- resultProcessor.processResult(ret);
+ if
(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_AUDIT_LOG)) {
+ String requestHashCode =
Integer.toHexString(System.identityHashCode(request)) + "_" + policyType;
- RangerPerfTracer.log(perfAuditTracer);
+ perfAuditTracer =
RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_AUDIT_LOG,
"RangerPolicyEngine.processAudit(requestHashCode=" + requestHashCode + ")");
+ }
+
+ resultProcessor.processResult(ret);
+
+ RangerPerfTracer.log(perfAuditTracer);
+ }
}
RangerPerfTracer.log(perf);
@@ -140,18 +168,25 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
Collection<RangerAccessResult> ret = new ArrayList<>();
- if (requests != null) {
- for (RangerAccessRequest request : requests) {
- requestProcessor.preProcess(request);
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
+ if (requests != null) {
+ for (RangerAccessRequest request : requests) {
+ requestProcessor.preProcess(request);
- RangerAccessResult result =
zoneAwareAccessEvaluationWithNoAudit(request, policyType);
+ RangerAccessResult result =
zoneAwareAccessEvaluationWithNoAudit(request, policyType);
- ret.add(result);
+ ret.add(result);
+ }
}
- }
- if (resultProcessor != null) {
- resultProcessor.processResults(ret);
+ if (resultProcessor != null) {
+ resultProcessor.processResults(ret);
+ }
}
if (LOG.isDebugEnabled()) {
@@ -167,27 +202,35 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
LOG.debug("==>
RangerPolicyEngineImpl.evaluateAuditPolicies(result=" + result + ")");
}
- RangerPolicyRepository tagPolicyRepository =
policyEngine.getTagPolicyRepository();
- RangerPolicyRepository policyRepository =
policyEngine.getPolicyRepository();
- RangerAccessRequest request =
result.getAccessRequest();
- boolean savedIsAuditedDetermined =
result.getIsAuditedDetermined();
- boolean savedIsAudited =
result.getIsAudited();
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
- result.setIsAudited(false);
- result.setIsAuditedDetermined(false);
+ RangerPolicyRepository tagPolicyRepository =
policyEngine.getTagPolicyRepository();
+ RangerPolicyRepository policyRepository =
policyEngine.getPolicyRepository();
+ RangerAccessRequest request = result.getAccessRequest();
+ boolean savedIsAuditedDetermined =
result.getIsAuditedDetermined();
+ boolean savedIsAudited = result.getIsAudited();
- try {
- if (tagPolicyRepository != null) {
- evaluateTagAuditPolicies(request, result,
tagPolicyRepository);
- }
+ result.setIsAudited(false);
+ result.setIsAuditedDetermined(false);
- if (!result.getIsAuditedDetermined() &&
policyRepository != null) {
- evaluateResourceAuditPolicies(request, result,
policyRepository);
- }
- } finally {
- if (!result.getIsAuditedDetermined()) {
- result.setIsAudited(savedIsAudited);
-
result.setIsAuditedDetermined(savedIsAuditedDetermined);
+ try {
+ if (tagPolicyRepository != null) {
+ evaluateTagAuditPolicies(request,
result, tagPolicyRepository);
+ }
+
+ if (!result.getIsAuditedDetermined() &&
policyRepository != null) {
+ evaluateResourceAuditPolicies(request,
result, policyRepository);
+ }
+ } finally {
+ if (!result.getIsAuditedDetermined()) {
+ result.setIsAudited(savedIsAudited);
+
result.setIsAuditedDetermined(savedIsAuditedDetermined);
+ }
}
}
@@ -209,122 +252,130 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
perf =
RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_GET_ACLS_LOG,
"RangerPolicyEngine.getResourceACLs(requestHashCode=" +
request.getResource().getAsString() + ")");
}
- requestProcessor.preProcess(request);
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
- String zoneName =
policyEngine.getUniquelyMatchedZoneName(request.getResource().getAsMap());
+ requestProcessor.preProcess(request);
- if (LOG.isDebugEnabled()) {
- LOG.debug("zoneName:[" + zoneName + "]");
- }
- List<RangerPolicyEvaluator> allEvaluators
= new ArrayList<>();
- Map<Long, RangerPolicyResourceMatcher.MatchType>
tagMatchTypeMap = new HashMap<>();
- Set<Long>
policyIdForTemporalTags = new HashSet<>();
+ String zoneName =
policyEngine.getUniquelyMatchedZoneName(request.getResource().getAsMap());
- getResourceACLEvaluatorsForZone(request, zoneName,
allEvaluators, tagMatchTypeMap, policyIdForTemporalTags);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("zoneName:[" + zoneName + "]");
+ }
+ List<RangerPolicyEvaluator> allEvaluators = new
ArrayList<>();
+ Map<Long, RangerPolicyResourceMatcher.MatchType>
tagMatchTypeMap = new HashMap<>();
+ Set<Long> policyIdForTemporalTags = new HashSet<>();
- allEvaluators.sort(RangerPolicyEvaluator.EVAL_ORDER_COMPARATOR);
+ getResourceACLEvaluatorsForZone(request, zoneName,
allEvaluators, tagMatchTypeMap, policyIdForTemporalTags);
- if (CollectionUtils.isNotEmpty(allEvaluators)) {
- Integer policyPriority = null;
+
allEvaluators.sort(RangerPolicyEvaluator.EVAL_ORDER_COMPARATOR);
- for (RangerPolicyEvaluator evaluator : allEvaluators) {
- if (policyPriority == null) {
- policyPriority =
evaluator.getPolicyPriority();
- }
+ if (CollectionUtils.isNotEmpty(allEvaluators)) {
+ Integer policyPriority = null;
- if (policyPriority !=
evaluator.getPolicyPriority()) {
- ret.finalizeAcls();
+ for (RangerPolicyEvaluator evaluator :
allEvaluators) {
+ if (policyPriority == null) {
+ policyPriority =
evaluator.getPolicyPriority();
+ }
- policyPriority =
evaluator.getPolicyPriority();
- }
+ if (policyPriority !=
evaluator.getPolicyPriority()) {
+ ret.finalizeAcls();
- RangerPolicyResourceMatcher.MatchType matchType
= tagMatchTypeMap.get(evaluator.getId());
+ policyPriority =
evaluator.getPolicyPriority();
+ }
- if (matchType == null) {
- matchType =
evaluator.getPolicyResourceMatcher().getMatchType(request.getResource(),
request.getContext());
- }
+ RangerPolicyResourceMatcher.MatchType
matchType = tagMatchTypeMap.get(evaluator.getId());
- final boolean isMatched;
+ if (matchType == null) {
+ matchType =
evaluator.getPolicyResourceMatcher().getMatchType(request.getResource(),
request.getContext());
+ }
- if (request.getResourceMatchingScope() ==
RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
- isMatched = matchType !=
RangerPolicyResourceMatcher.MatchType.NONE;
- } else {
- isMatched = matchType ==
RangerPolicyResourceMatcher.MatchType.SELF || matchType ==
RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
- }
+ final boolean isMatched;
- if (!isMatched) {
- continue;
- }
+ if (request.getResourceMatchingScope()
== RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+ isMatched = matchType !=
RangerPolicyResourceMatcher.MatchType.NONE;
+ } else {
+ isMatched = matchType ==
RangerPolicyResourceMatcher.MatchType.SELF || matchType ==
RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
+ }
- PolicyACLSummary aclSummary =
evaluator.getPolicyACLSummary();
+ if (!isMatched) {
+ continue;
+ }
- if (aclSummary != null) {
- boolean isConditional =
policyIdForTemporalTags.contains(evaluator.getId()) ||
evaluator.getValidityScheduleEvaluatorsCount() != 0;
- Integer accessResult;
+ PolicyACLSummary aclSummary =
evaluator.getPolicyACLSummary();
- for (Map.Entry<String, Map<String,
PolicyACLSummary.AccessResult>> userAccessInfo :
aclSummary.getUsersAccessInfo().entrySet()) {
- final String userName =
userAccessInfo.getKey();
+ if (aclSummary != null) {
+ boolean isConditional =
policyIdForTemporalTags.contains(evaluator.getId()) ||
evaluator.getValidityScheduleEvaluatorsCount() != 0;
+ Integer accessResult;
- for (Map.Entry<String,
PolicyACLSummary.AccessResult> accessInfo :
userAccessInfo.getValue().entrySet()) {
- if (isConditional) {
- accessResult =
ACCESS_CONDITIONAL;
- } else {
- accessResult =
accessInfo.getValue().getResult();
+ for (Map.Entry<String,
Map<String, PolicyACLSummary.AccessResult>> userAccessInfo :
aclSummary.getUsersAccessInfo().entrySet()) {
+ final String userName =
userAccessInfo.getKey();
+
+ for (Map.Entry<String,
PolicyACLSummary.AccessResult> accessInfo :
userAccessInfo.getValue().entrySet()) {
+ if
(isConditional) {
+
accessResult = ACCESS_CONDITIONAL;
+ } else {
+
accessResult = accessInfo.getValue().getResult();
- if
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
-
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ if
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ }
}
- }
- RangerPolicy policy =
evaluator.getPolicy();
+ RangerPolicy
policy = evaluator.getPolicy();
-
ret.setUserAccessInfo(userName, accessInfo.getKey(), accessResult, policy);
+
ret.setUserAccessInfo(userName, accessInfo.getKey(), accessResult, policy);
+ }
}
- }
- for (Map.Entry<String, Map<String,
PolicyACLSummary.AccessResult>> groupAccessInfo :
aclSummary.getGroupsAccessInfo().entrySet()) {
- final String groupName =
groupAccessInfo.getKey();
+ for (Map.Entry<String,
Map<String, PolicyACLSummary.AccessResult>> groupAccessInfo :
aclSummary.getGroupsAccessInfo().entrySet()) {
+ final String groupName
= groupAccessInfo.getKey();
- for (Map.Entry<String,
PolicyACLSummary.AccessResult> accessInfo :
groupAccessInfo.getValue().entrySet()) {
- if (isConditional) {
- accessResult =
ACCESS_CONDITIONAL;
- } else {
- accessResult =
accessInfo.getValue().getResult();
+ for (Map.Entry<String,
PolicyACLSummary.AccessResult> accessInfo :
groupAccessInfo.getValue().entrySet()) {
+ if
(isConditional) {
+
accessResult = ACCESS_CONDITIONAL;
+ } else {
+
accessResult = accessInfo.getValue().getResult();
- if
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
-
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ if
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ }
}
- }
- RangerPolicy policy =
evaluator.getPolicy();
+ RangerPolicy
policy = evaluator.getPolicy();
-
ret.setGroupAccessInfo(groupName, accessInfo.getKey(), accessResult, policy);
+
ret.setGroupAccessInfo(groupName, accessInfo.getKey(), accessResult, policy);
+ }
}
- }
- for (Map.Entry<String, Map<String,
PolicyACLSummary.AccessResult>> roleAccessInfo :
aclSummary.getRolesAccessInfo().entrySet()) {
- final String roleName =
roleAccessInfo.getKey();
+ for (Map.Entry<String,
Map<String, PolicyACLSummary.AccessResult>> roleAccessInfo :
aclSummary.getRolesAccessInfo().entrySet()) {
+ final String roleName =
roleAccessInfo.getKey();
- for (Map.Entry<String,
PolicyACLSummary.AccessResult> accessInfo :
roleAccessInfo.getValue().entrySet()) {
- if (isConditional) {
- accessResult =
ACCESS_CONDITIONAL;
- } else {
- accessResult =
accessInfo.getValue().getResult();
+ for (Map.Entry<String,
PolicyACLSummary.AccessResult> accessInfo :
roleAccessInfo.getValue().entrySet()) {
+ if
(isConditional) {
+
accessResult = ACCESS_CONDITIONAL;
+ } else {
+
accessResult = accessInfo.getValue().getResult();
- if
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
-
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ if
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ }
}
- }
- RangerPolicy policy =
evaluator.getPolicy();
+ RangerPolicy
policy = evaluator.getPolicy();
-
ret.setRoleAccessInfo(roleName, accessInfo.getKey(), accessResult, policy);
+
ret.setRoleAccessInfo(roleName, accessInfo.getKey(), accessResult, policy);
+ }
}
}
}
- }
- ret.finalizeAcls();
+ ret.finalizeAcls();
+ }
}
RangerPerfTracer.logAlways(perf);
@@ -338,22 +389,56 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
@Override
public void setUseForwardedIPAddress(boolean useForwardedIPAddress) {
- policyEngine.setUseForwardedIPAddress(useForwardedIPAddress);
+ try (RangerReadWriteLock.RangerLock writeLock =
policyEngine.getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
writeLock);
+ }
+ }
+
policyEngine.setUseForwardedIPAddress(useForwardedIPAddress);
+ }
}
@Override
public void setTrustedProxyAddresses(String[] trustedProxyAddresses) {
- policyEngine.setTrustedProxyAddresses(trustedProxyAddresses);
+ try (RangerReadWriteLock.RangerLock writeLock =
policyEngine.getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
writeLock);
+ }
+ }
+
policyEngine.setTrustedProxyAddresses(trustedProxyAddresses);
+ }
}
@Override
public RangerServiceDef getServiceDef() {
- return policyEngine.getServiceDef();
+ final RangerServiceDef ret;
+
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
+ ret = policyEngine.getServiceDef();
+ }
+ return ret;
}
@Override
public long getPolicyVersion() {
- return policyEngine.getPolicyVersion();
+ long ret;
+
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
+ ret = policyEngine.getPolicyVersion();
+ }
+ return ret;
}
@Override
@@ -361,12 +446,29 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
@Override
public void setRoles(RangerRoles roles) {
- policyEngine.setRoles(roles);
+ try (RangerReadWriteLock.RangerLock writeLock =
policyEngine.getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
writeLock);
+ }
+ }
+ policyEngine.setRoles(roles);
+ }
+
}
@Override
public Set<String> getRolesFromUserAndGroups(String user, Set<String>
groups) {
- return
policyEngine.getPluginContext().getAuthContext().getRolesForUserAndGroups(user,
groups);
+ Set<String> ret;
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
+ ret =
policyEngine.getPluginContext().getAuthContext().getRolesForUserAndGroups(user,
groups);
+ }
+ return ret;
}
@Override
@@ -375,7 +477,16 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
LOG.debug("==>
RangerPolicyEngineImpl.getUniquelyMatchedZoneName(" + grantRevokeRequest + ")");
}
- String ret =
policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+ String ret;
+
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
+ ret =
policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("<==
RangerPolicyEngineImpl.getUniquelyMatchedZoneName(" + grantRevokeRequest + ") :
" + ret);
@@ -386,21 +497,53 @@ public class RangerPolicyEngineImpl implements
RangerPolicyEngine {
@Override
public List<RangerPolicy> getResourcePolicies(String zoneName) {
- return policyEngine.getResourcePolicies(zoneName);
+ List<RangerPolicy> ret;
+
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
+ List<RangerPolicy> oldPolicies =
policyEngine.getResourcePolicies(zoneName);
+ ret = CollectionUtils.isNotEmpty(oldPolicies) ? new
ArrayList<>(oldPolicies) : oldPolicies;
+ }
+
+ return ret;
}
@Override
public List<RangerPolicy> getResourcePolicies() {
- RangerPolicyRepository policyRepository =
policyEngine.getPolicyRepository();
+ List<RangerPolicy> ret;
- return policyRepository == null ? ListUtils.EMPTY_LIST :
policyRepository.getPolicies();
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
+ RangerPolicyRepository policyRepository =
policyEngine.getPolicyRepository();
+ List<RangerPolicy> oldPolicies = policyRepository ==
null ? ListUtils.EMPTY_LIST : policyRepository.getPolicies();
+ ret = CollectionUtils.isNotEmpty(oldPolicies) ? new
ArrayList<>(oldPolicies) : oldPolicies;
+ }
+ return ret;
}
@Override
public List<RangerPolicy> getTagPolicies() {
- RangerPolicyRepository tagPolicyRepository =
policyEngine.getTagPolicyRepository();
+ List<RangerPolicy> ret;
- return tagPolicyRepository == null ? ListUtils.EMPTY_LIST :
tagPolicyRepository.getPolicies();
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " +
readLock);
+ }
+ }
+ RangerPolicyRepository tagPolicyRepository =
policyEngine.getTagPolicyRepository();
+ List<RangerPolicy> oldPolicies = tagPolicyRepository ==
null ? ListUtils.EMPTY_LIST : tagPolicyRepository.getPolicies();
+ ret = CollectionUtils.isNotEmpty(oldPolicies) ? new
ArrayList<>(oldPolicies) : oldPolicies;
+ }
+ return ret;
}
// This API is used only used by test code
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index aa82c99..df93bd5 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -73,9 +73,9 @@ public class RangerPolicyRepository {
private final RangerPolicyEngineOptions options;
private final RangerPluginContext pluginContext;
private final RangerServiceDef serviceDef;
- private final List<RangerPolicy> policies;
+ private /*final*/ List<RangerPolicy> policies;
private final long policyVersion;
- private final List<RangerContextEnricher> contextEnrichers;
+ private /*final*/ List<RangerContextEnricher> contextEnrichers;
private final AuditModeEnum auditModeEnum;
private final Map<String, AuditInfo> accessAuditCache;
private final String componentServiceName;
@@ -157,111 +157,12 @@ public class RangerPolicyRepository {
this.accessAuditCache = null;
}
- boolean[] flags = new boolean[RangerPolicy.POLICY_TYPES.length];
-
- for (RangerPolicyDelta delta : deltas) {
- final Integer changeType = delta.getChangeType();
- final String serviceType = delta.getServiceType();
- final Long policyId = delta.getPolicyId();
- final Integer policyType = delta.getPolicyType();
-
- if (!serviceType.equals(this.serviceDef.getName())) {
- continue;
- }
-
- RangerPolicyEvaluator evaluator = null;
-
- switch (changeType) {
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE:
- if (delta.getPolicy() == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Could not find policy for policy-id:["
+ policyId + "]");
- }
-
- continue;
- }
- break;
-
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE:
- evaluator = getPolicyEvaluator(policyId);
-
- if (evaluator == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Could not find evaluator for
policy-id:[" + policyId + "]");
- }
- }
- break;
-
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_DELETE:
- evaluator = getPolicyEvaluator(policyId);
- if (evaluator == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Could not find evaluator for
policy-id:[" + policyId + "]");
- }
- }
- break;
-
- default:
- LOG.error("Unknown changeType:[" + changeType + "],
Ignoring");
- break;
- }
-
- evaluator = update(delta, evaluator);
-
- if (evaluator != null) {
- switch (changeType) {
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE:
- policyEvaluatorsMap.put(policyId, evaluator);
- break;
-
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE:
- policyEvaluatorsMap.put(policyId, evaluator);
- break;
-
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_DELETE:
- policyEvaluatorsMap.remove(policyId);
- break;
-
- default:
- break;
- }
-
- flags[policyType] = true;
- }
- }
-
- for (int policyType = 0; policyType < flags.length; policyType++) {
- if (flags[policyType]) {
- Map<String, RangerResourceTrie> trie = getTrie(policyType);
-
- if (trie != null) {
- for (Map.Entry<String, RangerResourceTrie> entry :
trie.entrySet()) {
- entry.getValue().wrapUpUpdate();
- }
- }
- }
- }
+ final boolean isExistingPolicies =
CollectionUtils.isNotEmpty(this.policies);
- if (auditFilterResourceTrie != null) {
- for (Map.Entry<String, RangerResourceTrie> entry :
auditFilterResourceTrie.entrySet()) {
- entry.getValue().wrapUpUpdate();
- }
- }
+ List<RangerContextEnricher> newContextEnrichers =
updateResourceTrie(deltas, policyVersion);
- if (StringUtils.isEmpty(zoneName)) {
- if (CollectionUtils.isNotEmpty(other.getPolicies())) {
- if (CollectionUtils.isNotEmpty(this.getPolicies())) {
- this.contextEnrichers = shareWith(other);
- } else {
- this.contextEnrichers = null;
- }
- } else {
- if (CollectionUtils.isNotEmpty(this.policies)) {
- this.contextEnrichers =
Collections.unmodifiableList(buildContextEnrichers(options));
- } else {
- this.contextEnrichers = null;
- }
- }
+ if (newContextEnrichers != null &&
CollectionUtils.isNotEmpty(this.policies)) {
+ this.contextEnrichers = isExistingPolicies ? shareWith(other) :
buildContextEnrichers(options);
} else {
this.contextEnrichers = null;
}
@@ -288,9 +189,9 @@ public class RangerPolicyRepository {
this.pluginContext = pluginContext;
if (StringUtils.isEmpty(zoneName)) {
- this.policies =
Collections.unmodifiableList(servicePolicies.getPolicies());
+ this.policies = servicePolicies.getPolicies();
} else {
- this.policies =
Collections.unmodifiableList(servicePolicies.getSecurityZones().get(zoneName).getPolicies());
+ this.policies =
servicePolicies.getSecurityZones().get(zoneName).getPolicies();
}
this.policyVersion = servicePolicies.getPolicyVersion() != null ?
servicePolicies.getPolicyVersion() : -1;
@@ -326,7 +227,7 @@ public class RangerPolicyRepository {
init(options);
if (StringUtils.isEmpty(zoneName)) {
- this.contextEnrichers =
Collections.unmodifiableList(buildContextEnrichers(options));
+ this.contextEnrichers = buildContextEnrichers(options);
this.auditPolicyEvaluators =
buildAuditPolicyEvaluators(servicePolicies.getServiceConfig());
} else {
this.contextEnrichers = null;
@@ -358,7 +259,7 @@ public class RangerPolicyRepository {
this.appId = pluginContext.getConfig().getAppId();
this.options = new
RangerPolicyEngineOptions(pluginContext.getConfig().getPolicyEngineOptions());
this.pluginContext = pluginContext;
- this.policies =
Collections.unmodifiableList(normalizeAndPrunePolicies(tagPolicies.getPolicies(),
componentServiceDef.getName()));
+ this.policies =
normalizeAndPrunePolicies(tagPolicies.getPolicies(),
componentServiceDef.getName());
this.policyVersion = tagPolicies.getPolicyVersion() != null ?
tagPolicies.getPolicyVersion() : -1;
String auditMode = tagPolicies.getAuditMode();
@@ -380,7 +281,7 @@ public class RangerPolicyRepository {
init(options);
if (StringUtils.isEmpty(zoneName)) {
- this.contextEnrichers =
Collections.unmodifiableList(buildContextEnrichers(options));
+ this.contextEnrichers = buildContextEnrichers(options);
this.auditPolicyEvaluators =
buildAuditPolicyEvaluators(tagPolicies.getServiceConfig());
} else {
this.contextEnrichers = null;
@@ -892,7 +793,7 @@ public class RangerPolicyRepository {
}
}
- return rangerPolicies;
+ return rangerPolicies == null ? new ArrayList<>() : rangerPolicies;
}
private boolean isPolicyNeedsPruning(RangerPolicy policy, final String
componentType) {
@@ -1049,13 +950,13 @@ public class RangerPolicyRepository {
}
RangerPolicyEvaluator.PolicyEvalOrderComparator comparator = new
RangerPolicyEvaluator.PolicyEvalOrderComparator();
Collections.sort(policyEvaluators, comparator);
- this.policyEvaluators = Collections.unmodifiableList(policyEvaluators);
+ this.policyEvaluators = policyEvaluators;
Collections.sort(dataMaskPolicyEvaluators, comparator);
- this.dataMaskPolicyEvaluators =
Collections.unmodifiableList(dataMaskPolicyEvaluators);
+ this.dataMaskPolicyEvaluators = dataMaskPolicyEvaluators;
Collections.sort(rowFilterPolicyEvaluators, comparator);
- this.rowFilterPolicyEvaluators =
Collections.unmodifiableList(rowFilterPolicyEvaluators);
+ this.rowFilterPolicyEvaluators = rowFilterPolicyEvaluators;
this.policyEvaluatorsMap = createPolicyEvaluatorsMap();
@@ -1269,8 +1170,6 @@ public class RangerPolicyRepository {
if (CollectionUtils.isNotEmpty(evaluators)) {
ret = new ArrayList<>(evaluators);
Collections.sort(ret, new
RangerPolicyEvaluator.PolicyEvalOrderComparator());
-
- ret = Collections.unmodifiableList(ret);
}
return ret;
@@ -1352,7 +1251,7 @@ public class RangerPolicyRepository {
tmpPolicyEvaluatorMap.put(evaluator.getPolicy().getId(),
evaluator);
}
- return Collections.unmodifiableMap(tmpPolicyEvaluatorMap);
+ return tmpPolicyEvaluatorMap;
}
@@ -1532,4 +1431,134 @@ public class RangerPolicyRepository {
return isAudited;
}
}
+
+ void reinit(List<RangerPolicyDelta> deltas, long policyVersion) {
+ final boolean isExistingPolicies =
CollectionUtils.isNotEmpty(this.policies);
+
+ List<RangerContextEnricher> newContextEnrichers =
updateResourceTrie(deltas, policyVersion);
+
+ if (newContextEnrichers != null &&
CollectionUtils.isNotEmpty(this.policies)) {
+ this.contextEnrichers = isExistingPolicies ? newContextEnrichers :
buildContextEnrichers(options);
+ } else {
+ this.contextEnrichers = null;
+ }
+ }
+
+ private List<RangerContextEnricher>
updateResourceTrie(List<RangerPolicyDelta> deltas, long policyVersion) {
+
+ final List<RangerContextEnricher> ret;
+
+ final boolean isExistingPolicies =
CollectionUtils.isNotEmpty(this.policies);
+
+ boolean[] flags = new boolean[RangerPolicy.POLICY_TYPES.length];
+
+ for (RangerPolicyDelta delta : deltas) {
+ final Integer changeType = delta.getChangeType();
+ final String serviceType = delta.getServiceType();
+ final Long policyId = delta.getPolicyId();
+ final Integer policyType = delta.getPolicyType();
+
+ if (!serviceType.equals(this.serviceDef.getName())) {
+ continue;
+ }
+
+ RangerPolicyEvaluator evaluator = null;
+
+ switch (changeType) {
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE:
+ if (delta.getPolicy() == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not find policy for policy-id:["
+ policyId + "]");
+ }
+
+ continue;
+ }
+ break;
+
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE:
+ evaluator = getPolicyEvaluator(policyId);
+
+ if (evaluator == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not find evaluator for
policy-id:[" + policyId + "]");
+ }
+ }
+ break;
+
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_DELETE:
+ evaluator = getPolicyEvaluator(policyId);
+ if (evaluator == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not find evaluator for
policy-id:[" + policyId + "]");
+ }
+ }
+ break;
+
+ default:
+ LOG.error("Unknown changeType:[" + changeType + "],
Ignoring");
+ break;
+ }
+
+ evaluator = update(delta, evaluator);
+
+ if (evaluator != null) {
+ switch (changeType) {
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE:
+ policyEvaluatorsMap.put(policyId, evaluator);
+ break;
+
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE:
+ policyEvaluatorsMap.put(policyId, evaluator);
+ break;
+
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_DELETE:
+ policyEvaluatorsMap.remove(policyId);
+ break;
+
+ default:
+ break;
+ }
+
+ flags[policyType] = true;
+ }
+ }
+
+ for (int policyType = 0; policyType < flags.length; policyType++) {
+ if (flags[policyType]) {
+ Map<String, RangerResourceTrie> trie = getTrie(policyType);
+
+ if (trie != null) {
+ for (Map.Entry<String, RangerResourceTrie> entry :
trie.entrySet()) {
+ entry.getValue().wrapUpUpdate();
+ }
+ }
+ }
+ }
+
+ if (auditFilterResourceTrie != null) {
+ for (Map.Entry<String, RangerResourceTrie> entry :
auditFilterResourceTrie.entrySet()) {
+ entry.getValue().wrapUpUpdate();
+ }
+ }
+
+ if (StringUtils.isEmpty(zoneName)) {
+ if (isExistingPolicies) {
+ if (CollectionUtils.isNotEmpty(this.policies)) {
+ ret = this.contextEnrichers; // Handled by caller
+ } else {
+ ret = null;
+ }
+ } else {
+ if (CollectionUtils.isNotEmpty(this.policies)) {
+ ret = new ArrayList<>(); // Handled by caller
+ } else {
+ ret = null;
+ }
+ }
+ } else {
+ ret = null;
+ }
+
+ return ret;
+ }
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/store/TagStore.java
b/agents-common/src/main/java/org/apache/ranger/plugin/store/TagStore.java
index 795289b..f9f80c9 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/TagStore.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/TagStore.java
@@ -139,4 +139,6 @@ public interface TagStore {
void deleteAllTagObjectsForService(String serviceName) throws Exception;
+ boolean isInPlaceTagUpdateSupported();
+
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerCommonConstants.java
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerCommonConstants.java
index 5ecb280..e0c3f79 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerCommonConstants.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerCommonConstants.java
@@ -21,7 +21,25 @@ package org.apache.ranger.plugin.util;
public class RangerCommonConstants {
- public static final String PROP_COOKIE_NAME =
"ranger.admin.cookie.name";
- public static final String DEFAULT_COOKIE_NAME = "RANGERADMINSESSIONID";
+ public static final String PROP_COOKIE_NAME
= "ranger.admin.cookie.name";
+ public static final String DEFAULT_COOKIE_NAME
= "RANGERADMINSESSIONID";
+ public static final String PLUGIN_CONFIG_SUFFIX_POLICY_DELTA
= ".policy.rest.supports.policy.deltas";
+ public static final String PLUGIN_CONFIG_SUFFIX_TAG_DELTA
= ".tag.rest.supports.policy.deltas";
+ public static final String PLUGIN_CONFIG_SUFFIX_IN_PLACE_POLICY_UPDATES
= ".supports.in.place.policy.updates";
+ public static final String PLUGIN_CONFIG_SUFFIX_IN_PLACE_TAG_UPDATES
= ".supports.in.place.tag.updates";
+ public static final String RANGER_ADMIN_SUFFIX_POLICY_DELTA
= ".supports.policy.deltas";
+ public static final String RANGER_ADMIN_SUFFIX_TAG_DELTA
= ".supports.tag.deltas";
+ public static final String RANGER_ADMIN_SUFFIX_IN_PLACE_POLICY_UPDATES
= ".supports.in.place.policy.updates";
+ public static final String RANGER_ADMIN_SUFFIX_IN_PLACE_TAG_UPDATES
= ".supports.in.place.tag.updates";
-}
\ No newline at end of file
+ public static final boolean PLUGIN_CONFIG_SUFFIX_POLICY_DELTA_DEFAULT
= false;
+ public static final boolean PLUGIN_CONFIG_SUFFIX_TAG_DELTA_DEFAULT
= false;
+ public static final boolean
PLUGIN_CONFIG_SUFFIX_IN_PLACE_POLICY_UPDATES_DEFAULT = false;
+ public static final boolean
PLUGIN_CONFIG_SUFFIX_IN_PLACE_TAG_UPDATES_DEFAULT = false;
+ public static final boolean RANGER_ADMIN_SUFFIX_POLICY_DELTA_DEFAULT
= false;
+ public static final boolean RANGER_ADMIN_SUFFIX_TAG_DELTA_DEFAULT
= false;
+ public static final boolean
RANGER_ADMIN_SUFFIX_IN_PLACE_POLICY_UPDATES_DEFAULT = false;
+ public static final boolean
RANGER_ADMIN_SUFFIX_IN_PLACE_TAG_UPDATES_DEFAULT = false;
+
+
+}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerReadWriteLock.java
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerReadWriteLock.java
new file mode 100644
index 0000000..7f17a52
--- /dev/null
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerReadWriteLock.java
@@ -0,0 +1,98 @@
+/*
+ * 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.ranger.plugin.util;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+public class RangerReadWriteLock {
+
+ private static final RangerLock NO_OP_LOCK = new RangerLock(null);
+
+ private final ReentrantReadWriteLock lock;
+
+ public RangerReadWriteLock(boolean isUseLock) {
+ lock = isUseLock ? new ReentrantReadWriteLock(true) : null;
+ }
+
+ public RangerLock getReadLock() {
+ final RangerLock ret;
+ if (lock != null) {
+ ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
+ readLock.lock();
+ ret = new RangerLock(readLock);
+ } else {
+ ret = NO_OP_LOCK;
+ }
+ return ret;
+ }
+
+ public RangerLock getWriteLock() {
+ final RangerLock ret;
+ if (lock != null) {
+ boolean isLocked = false;
+ ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
+ while (!isLocked) {
+ isLocked = writeLock.tryLock();
+ // Another thread has acquired write lock. Hint to scheduler
to schedule some other thread if needed
+ if (!isLocked && lock.getReadLockCount() == 0) {
+ Thread.yield();
+ }
+ }
+ ret = new RangerLock(writeLock);
+ } else {
+ ret = NO_OP_LOCK;
+ }
+ return ret;
+ }
+
+ @Override
+ public String toString() {
+ if (lock != null) {
+ return "ReadWriteLock:[" + lock.toString() + "], ReadLock:[" +
lock.readLock().toString() + "], WriteLock:[" + lock.writeLock().toString() +
"]";
+ } else {
+ return "ReadWriteLock:[null]";
+ }
+ }
+
+ static final public class RangerLock implements AutoCloseable {
+ private final Lock lock;
+
+ private RangerLock(Lock lock) {
+ this.lock = lock;
+ }
+
+ @Override
+ public void close() {
+ if (lock != null) {
+ lock.unlock();
+ }
+ }
+
+ public boolean isLockingEnabled() {
+ return lock != null;
+ }
+
+ @Override
+ public String toString() {
+ return lock == null ? "null" : lock.toString();
+ }
+ }
+}
diff --git
a/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java
b/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java
index 1beef86..fa17f5d 100644
---
a/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java
+++
b/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java
@@ -71,8 +71,8 @@ public class RangerAdminJersey2RESTClient extends
AbstractRangerAdminClient {
String _sslConfigFileName = null;
String _serviceName = null;
String _clusterName = null;
- String _supportsPolicyDeltas = null;
- String _supportsTagDeltas = null;
+ boolean _supportsPolicyDeltas = false;
+ boolean _supportsTagDeltas = false;
String _pluginId = null;
int _restClientConnTimeOutMs;
int _restClientReadTimeOutMs;
@@ -99,14 +99,8 @@ public class RangerAdminJersey2RESTClient extends
AbstractRangerAdminClient {
if(StringUtil.isEmpty(_clusterName)){
_clusterName =config.get(configPropertyPrefix +
".ambari.cluster.name", "");
}
- _supportsPolicyDeltas = config.get(configPropertyPrefix +
".policy.rest.supports.policy.deltas", "false");
- if (!"true".equalsIgnoreCase(_supportsPolicyDeltas)) {
- _supportsPolicyDeltas = "false";
- }
- _supportsTagDeltas = config.get(configPropertyPrefix +
".tag.rest.supports.tag.deltas", "false");
- if (!"true".equalsIgnoreCase(_supportsTagDeltas)) {
- _supportsTagDeltas = "false";
- }
+ _supportsPolicyDeltas = config.getBoolean(configPropertyPrefix
+ RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA,
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA_DEFAULT);
+ _supportsTagDeltas = config.getBoolean(configPropertyPrefix +
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA,
RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA_DEFAULT);
configURLs = StringUtil.getURLs(tmpUrl);
this.lastKnownActiveUrlIndex = new
Random().nextInt(configURLs.size());
@@ -141,7 +135,7 @@ public class RangerAdminJersey2RESTClient extends
AbstractRangerAdminClient {
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_ACTIVATION_TIME,
Long.toString(lastActivationTimeInMillis));
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID,
_pluginId);
queryParams.put(RangerRESTUtils.REST_PARAM_CLUSTER_NAME,
_clusterName);
-
queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_POLICY_DELTAS,
_supportsPolicyDeltas);
+
queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_POLICY_DELTAS,
Boolean.toString(_supportsPolicyDeltas));
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES,
pluginCapabilities);
if (isSecureMode) {
@@ -383,7 +377,7 @@ public class RangerAdminJersey2RESTClient extends
AbstractRangerAdminClient {
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_KNOWN_POLICY_VERSION,
Long.toString(lastKnownVersion));
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_ACTIVATION_TIME,
Long.toString(lastActivationTimeInMillis));
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID,
_pluginId);
- queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS,
_supportsTagDeltas);
+ queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS,
Boolean.toString(_supportsTagDeltas));
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES,
pluginCapabilities);
String relativeURL = null;
diff --git
a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
index 089bf43..fd5b147 100644
---
a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
+++
b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
@@ -158,11 +158,11 @@ public class RangerPolicyAdminCache {
oldPolicyAdmin.releaseResources(!isPolicyEngineShared);
}
} else {
- LOG.warn("Could not build new policy-engine.
Continuing with the old policy-engine, if any");
+ LOG.warn("Could not build new policy-engine.");
}
}
- return ret != null ? ret : oldPolicyAdmin;
+ return ret;
}
private RangerPolicyAdmin addPolicyAdmin(ServicePolicies policies,
RangerRoles roles, RangerPolicyEngineOptions options) {
diff --git
a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
index 66835bd..2eef20b 100644
---
a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
+++
b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
@@ -45,6 +45,7 @@ import
org.apache.ranger.plugin.service.RangerDefaultRequestProcessor;
import org.apache.ranger.plugin.util.GrantRevokeRequest;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.RangerPerfTracer;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.RangerRoles;
import org.apache.ranger.plugin.util.ServiceDefUtil;
import org.apache.ranger.plugin.util.ServicePolicies;
@@ -81,7 +82,11 @@ public class RangerPolicyAdminImpl implements
RangerPolicyAdmin {
PolicyEngine policyEngine =
other.policyEngine.cloneWithDelta(servicePolicies);
if (policyEngine != null) {
- ret = new RangerPolicyAdminImpl(policyEngine);
+ if (policyEngine == other.policyEngine) {
+ ret = other;
+ } else {
+ ret = new RangerPolicyAdminImpl(policyEngine);
+ }
}
}
@@ -89,7 +94,7 @@ public class RangerPolicyAdminImpl implements
RangerPolicyAdmin {
}
RangerPolicyAdminImpl(ServicePolicies servicePolicies, RangerPluginContext
pluginContext, RangerRoles roles) {
- this.policyEngine = new PolicyEngine(servicePolicies,
pluginContext, roles);
+ this.policyEngine = new PolicyEngine(servicePolicies,
pluginContext, roles, ServiceDBStore.SUPPORTS_IN_PLACE_POLICY_UPDATES);
this.requestProcessor = new
RangerDefaultRequestProcessor(policyEngine);
}
@@ -111,32 +116,41 @@ public class RangerPolicyAdminImpl implements
RangerPolicyAdmin {
perf =
RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG,
"RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(user=" + user +
",accessTypes=" + accessTypes + "resource=" + resource.getAsString() + ")");
}
- final RangerPolicyRepository matchedRepository =
policyEngine.getRepositoryForZone(zoneName);
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
- if (matchedRepository != null) {
- Set<String> roles = getRolesFromUserAndGroups(user, userGroups);
- Set<String> requestedAccesses = new HashSet<>(accessTypes);
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+
+ final RangerPolicyRepository matchedRepository =
policyEngine.getRepositoryForZone(zoneName);
+
+ if (matchedRepository != null) {
+ Set<String> roles = getRolesFromUserAndGroups(user,
userGroups);
+ Set<String> requestedAccesses = new HashSet<>(accessTypes);
- RangerAccessRequestImpl request = new RangerAccessRequestImpl();
- request.setResource(resource);
+ RangerAccessRequestImpl request = new
RangerAccessRequestImpl();
+ request.setResource(resource);
- for (RangerPolicyEvaluator evaluator :
matchedRepository.getLikelyMatchPolicyEvaluators(request,
RangerPolicy.POLICY_TYPE_ACCESS)) {
+ for (RangerPolicyEvaluator evaluator :
matchedRepository.getLikelyMatchPolicyEvaluators(request,
RangerPolicy.POLICY_TYPE_ACCESS)) {
- Set<String> allowedAccesses =
evaluator.getAllowedAccesses(resource, user, userGroups, roles,
requestedAccesses);
- if (CollectionUtils.isNotEmpty(allowedAccesses)) {
- requestedAccesses.removeAll(allowedAccesses);
- if (CollectionUtils.isEmpty(requestedAccesses)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Access granted by policy:[" +
evaluator.getPolicy() + "]");
+ Set<String> allowedAccesses =
evaluator.getAllowedAccesses(resource, user, userGroups, roles,
requestedAccesses);
+ if (CollectionUtils.isNotEmpty(allowedAccesses)) {
+ requestedAccesses.removeAll(allowedAccesses);
+ if (CollectionUtils.isEmpty(requestedAccesses)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Access granted by policy:[" +
evaluator.getPolicy() + "]");
+ }
+ ret = true;
+ break;
}
- ret = true;
- break;
}
}
+
}
}
-
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
@@ -159,36 +173,46 @@ public class RangerPolicyAdminImpl implements
RangerPolicyAdmin {
perf =
RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG,
"RangerPolicyEngine.isDelegatedAdminAccessAllowed(user=" + user + "," +
userGroups + ", roles=" + roles + ")");
}
- final RangerPolicyRepository matchedRepository =
policyEngine.getRepositoryForMatchedZone(policy);
-
- if (matchedRepository != null) {
- // RANGER-3082
- // Convert policy resources to by substituting macros with ASTERISK
- Map<String, RangerPolicyResource> modifiedPolicyResources =
getPolicyResourcesWithMacrosReplaced(policy.getResources(),
wildcardEvalContext);
- Set<String> accessTypes = getAllAccessTypes(policy,
getServiceDef());
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
if (LOG.isDebugEnabled()) {
- LOG.debug("Checking admin-access for the access-types:[" +
accessTypes + "]");
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
}
- if (CollectionUtils.isEmpty(accessTypes)) {
- LOG.info("access-types to check for admin-access are empty!!
Allowing admin access!!");
- ret = true;
- } else {
- for (RangerPolicyEvaluator evaluator :
matchedRepository.getPolicyEvaluators()) {
- Set<String> allowedAccesses =
evaluator.getAllowedAccesses(modifiedPolicyResources, user, userGroups, roles,
accessTypes, evalContext);
- if (CollectionUtils.isNotEmpty(allowedAccesses)) {
- accessTypes.removeAll(allowedAccesses);
- if (CollectionUtils.isEmpty(accessTypes)) {
- ret = true;
- break;
+ final RangerPolicyRepository matchedRepository =
policyEngine.getRepositoryForMatchedZone(policy);
+
+ if (matchedRepository != null) {
+ // RANGER-3082
+ // Convert policy resources to by substituting macros with
ASTERISK
+ Map<String, RangerPolicyResource> modifiedPolicyResources =
getPolicyResourcesWithMacrosReplaced(policy.getResources(),
wildcardEvalContext);
+ Set<String> accessTypes = getAllAccessTypes(policy,
getServiceDef());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking admin-access for the access-types:[" +
accessTypes + "]");
+ }
+
+ if (CollectionUtils.isEmpty(accessTypes)) {
+ LOG.info("access-types to check for admin-access are
empty!! Allowing admin access!!");
+ ret = true;
+ } else {
+ for (RangerPolicyEvaluator evaluator :
matchedRepository.getPolicyEvaluators()) {
+ Set<String> allowedAccesses =
evaluator.getAllowedAccesses(modifiedPolicyResources, user, userGroups, roles,
accessTypes, evalContext);
+ if (CollectionUtils.isNotEmpty(allowedAccesses)) {
+ accessTypes.removeAll(allowedAccesses);
+ if (CollectionUtils.isEmpty(accessTypes)) {
+ ret = true;
+ break;
+ }
}
}
- }
- if (CollectionUtils.isNotEmpty(accessTypes)) {
- LOG.info("Accesses : " + accessTypes + " are not
authorized for the policy:[" + policy.getId() + "] by any of delegated-admin
policies");
+ if (CollectionUtils.isNotEmpty(accessTypes)) {
+ LOG.info("Accesses : " + accessTypes + " are not
authorized for the policy:[" + policy.getId() + "] by any of delegated-admin
policies");
+ }
}
}
+
}
RangerPerfTracer.log(perf);
@@ -208,18 +232,27 @@ public class RangerPolicyAdminImpl implements
RangerPolicyAdmin {
List<RangerPolicy> ret = null;
- RangerPolicyRepository policyRepository =
policyEngine.getRepositoryForZone(zoneName);
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
- if (policyRepository != null) {
- for (RangerPolicyEvaluator evaluator :
policyRepository.getPolicyEvaluators()) {
- if (evaluator.isCompleteMatch(resource, evalContext)) {
- if (ret == null) {
- ret = new ArrayList<>();
- }
+ RangerPolicyRepository policyRepository =
policyEngine.getRepositoryForZone(zoneName);
- ret.add(evaluator.getPolicy());
+ if (policyRepository != null) {
+ for (RangerPolicyEvaluator evaluator :
policyRepository.getPolicyEvaluators()) {
+ if (evaluator.isCompleteMatch(resource, evalContext)) {
+ if (ret == null) {
+ ret = new ArrayList<>();
+ }
+
+ ret.add(evaluator.getPolicy());
+ }
}
}
+
}
if (LOG.isDebugEnabled()) {
@@ -236,20 +269,31 @@ public class RangerPolicyAdminImpl implements
RangerPolicyAdmin {
}
List<RangerPolicy> ret = null;
- RangerPolicyRepository policyRepository =
policyEngine.getRepositoryForMatchedZone(policy);
- if (policyRepository != null) {
- Map<String, RangerPolicyResource> resources =
policy.getResources();
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
- for (RangerPolicyEvaluator evaluator :
policyRepository.getPolicyEvaluators()) {
- if (evaluator.isCompleteMatch(resources, evalContext)) {
- if (ret == null) {
- ret = new ArrayList<>();
- }
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+
+ RangerPolicyRepository policyRepository =
policyEngine.getRepositoryForMatchedZone(policy);
+
+ if (policyRepository != null) {
+ Map<String, RangerPolicyResource> resources =
policy.getResources();
- ret.add(evaluator.getPolicy());
+ for (RangerPolicyEvaluator evaluator :
policyRepository.getPolicyEvaluators()) {
+ if (evaluator.isCompleteMatch(resources, evalContext)) {
+ if (ret == null) {
+ ret = new ArrayList<>();
+ }
+
+ ret.add(evaluator.getPolicy());
+ }
}
}
+
}
if (LOG.isDebugEnabled()) {
@@ -264,8 +308,16 @@ public class RangerPolicyAdminImpl implements
RangerPolicyAdmin {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyAdminImpl.getMatchingPolicies(" +
resource + ")");
}
+ List<RangerPolicy> ret;
- List<RangerPolicy> ret = getMatchingPolicies(resource,
RangerPolicyEngine.ANY_ACCESS);
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = getMatchingPolicies(resource, RangerPolicyEngine.ANY_ACCESS);
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyAdminImpl.getMatchingPolicies(" +
resource + ") : " + ret.size());
@@ -275,27 +327,87 @@ public class RangerPolicyAdminImpl implements
RangerPolicyAdmin {
}
@Override
- public long getPolicyVersion() { return policyEngine.getPolicyVersion(); }
+ public long getPolicyVersion() {
+ long ret;
+
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getPolicyVersion();
+ }
+ return ret;
+ }
@Override
- public long getRoleVersion() { return policyEngine.getRoleVersion(); }
+ public long getRoleVersion() {
+ long ret;
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getRoleVersion();
+ }
+ return ret;
+ }
@Override
- public String getServiceName() { return policyEngine.getServiceName(); }
+ public String getServiceName() {
+ String ret;
+
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getServiceName();
+ }
+ return ret;
+ }
@Override
public RangerServiceDef getServiceDef() {
- return policyEngine.getServiceDef();
+ RangerServiceDef ret;
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getServiceDef();
+ }
+ return ret;
}
@Override
public void setRoles(RangerRoles roles) {
- policyEngine.setRoles(roles);
+ try (RangerReadWriteLock.RangerLock writeLock =
policyEngine.getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + writeLock);
+ }
+ }
+ policyEngine.setRoles(roles);
+ }
}
@Override
public Set<String> getRolesFromUserAndGroups(String user, Set<String>
groups) {
- return
policyEngine.getPluginContext().getAuthContext().getRolesForUserAndGroups(user,
groups);
+ Set<String> ret;
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret =
policyEngine.getPluginContext().getAuthContext().getRolesForUserAndGroups(user,
groups);
+ }
+ return ret;
}
@Override
@@ -303,8 +415,16 @@ public class RangerPolicyAdminImpl implements
RangerPolicyAdmin {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyAdminImpl.getUniquelyMatchedZoneName("
+ grantRevokeRequest + ")");
}
+ String ret;
- String ret =
policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+ try (RangerReadWriteLock.RangerLock readLock =
policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret =
policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyAdminImpl.getUniquelyMatchedZoneName("
+ grantRevokeRequest + ") : " + ret);
diff --git
a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 41980d2..ec788af 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -70,6 +70,7 @@ import org.apache.ranger.db.XXGlobalStateDao;
import org.apache.ranger.db.XXPolicyDao;
import org.apache.ranger.entity.XXTagChangeLog;
import org.apache.ranger.plugin.model.RangerSecurityZone;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.ServiceTags;
import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
import org.apache.ranger.plugin.model.validation.RangerValidator;
@@ -240,6 +241,7 @@ public class ServiceDBStore extends AbstractServiceStore {
public static final String SALT =
PropertiesUtil.getProperty("ranger.password.salt", PasswordUtils.DEFAULT_SALT);
public static final Integer ITERATION_COUNT =
PropertiesUtil.getIntProperty("ranger.password.iteration.count",
PasswordUtils.DEFAULT_ITERATION_COUNT);
public static boolean SUPPORTS_POLICY_DELTAS = false;
+ public static boolean SUPPORTS_IN_PLACE_POLICY_UPDATES = false;
public static Integer RETENTION_PERIOD_IN_DAYS = 7;
public static Integer TAG_RETENTION_PERIOD_IN_DAYS = 3;
@@ -377,10 +379,11 @@ public class ServiceDBStore extends AbstractServiceStore {
synchronized(ServiceDBStore.class) {
if(!legacyServiceDefsInitDone) {
- SUPPORTS_POLICY_DELTAS =
config.getBoolean("ranger.admin.supports.policy.deltas", false);
+ SUPPORTS_POLICY_DELTAS =
config.getBoolean("ranger.admin" +
RangerCommonConstants.RANGER_ADMIN_SUFFIX_POLICY_DELTA,
RangerCommonConstants.RANGER_ADMIN_SUFFIX_POLICY_DELTA_DEFAULT);
RETENTION_PERIOD_IN_DAYS =
config.getInt("ranger.admin.delta.retention.time.in.days", 7);
TAG_RETENTION_PERIOD_IN_DAYS =
config.getInt("ranger.admin.tag.delta.retention.time.in.days", 3);
isRolesDownloadedByService =
config.getBoolean("ranger.support.for.service.specific.role.download", false);
+ SUPPORTS_IN_PLACE_POLICY_UPDATES =
SUPPORTS_POLICY_DELTAS && config.getBoolean("ranger.admin" +
RangerCommonConstants.RANGER_ADMIN_SUFFIX_IN_PLACE_POLICY_UPDATES,
RangerCommonConstants.RANGER_ADMIN_SUFFIX_IN_PLACE_POLICY_UPDATES_DEFAULT);
TransactionTemplate txTemplate = new
TransactionTemplate(txManager);
@@ -2818,7 +2821,7 @@ public class ServiceDBStore extends AbstractServiceStore {
public ServicePolicies getServicePolicyDeltasOrPolicies(String
serviceName, Long lastKnownVersion) throws Exception {
boolean getOnlyDeltas = false;
if (LOG.isDebugEnabled()) {
- LOG.debug("Support for incremental policy updates
enabled using \"ranger.admin.supports.policy.deltas\" configuation parameter
:[" + SUPPORTS_POLICY_DELTAS +"]");
+ LOG.debug("Support for incremental policy updates
enabled using \"ranger.admin" +
RangerCommonConstants.RANGER_ADMIN_SUFFIX_POLICY_DELTA + "\" configuation
parameter :[" + SUPPORTS_POLICY_DELTAS +"]");
}
return getServicePolicies(serviceName, lastKnownVersion,
getOnlyDeltas, SUPPORTS_POLICY_DELTAS);
}
@@ -2827,7 +2830,7 @@ public class ServiceDBStore extends AbstractServiceStore {
public ServicePolicies getServicePolicyDeltas(String serviceName, Long
lastKnownVersion) throws Exception {
boolean getOnlyDeltas = true;
if (LOG.isDebugEnabled()) {
- LOG.debug("Support for incremental policy updates
enabled using \"ranger.admin.supports.policy.deltas\" configuation parameter
:[" + SUPPORTS_POLICY_DELTAS +"]");
+ LOG.debug("Support for incremental policy updates
enabled using \"ranger.admin" +
RangerCommonConstants.RANGER_ADMIN_SUFFIX_POLICY_DELTA + "\" configuation
parameter :[" + SUPPORTS_POLICY_DELTAS +"]");
}
return getServicePolicies(serviceName, lastKnownVersion,
getOnlyDeltas, SUPPORTS_POLICY_DELTAS);
}
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
b/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
index 581f11a..1bdfce0 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
@@ -49,6 +49,7 @@ import
org.apache.ranger.plugin.model.validation.ValidationFailureDetails;
import org.apache.ranger.plugin.store.AbstractTagStore;
import org.apache.ranger.plugin.store.PList;
import org.apache.ranger.plugin.store.RangerServiceResourceSignature;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.apache.ranger.plugin.util.RangerServiceNotFoundException;
import org.apache.ranger.plugin.util.RangerServiceTagsDeltaUtil;
@@ -74,6 +75,7 @@ public class TagDBStore extends AbstractTagStore {
private static boolean SUPPORTS_TAG_DELTAS = false;
private static boolean IS_SUPPORTS_TAG_DELTAS_INITIALIZED = false;
+ public static boolean SUPPORTS_IN_PLACE_TAG_UPDATES = false;
@Autowired
RangerTagDefService rangerTagDefService;
@@ -1270,13 +1272,23 @@ public class TagDBStore extends AbstractTagStore {
return ret;
}
- public static boolean isSupportsTagDeltas() {
- if (!IS_SUPPORTS_TAG_DELTAS_INITIALIZED) {
- RangerAdminConfig config = RangerAdminConfig.getInstance();
+ private static void initStatics() {
+ if (!IS_SUPPORTS_TAG_DELTAS_INITIALIZED) {
+ RangerAdminConfig config =
RangerAdminConfig.getInstance();
+
+ SUPPORTS_TAG_DELTAS = config.getBoolean("ranger.admin"
+ RangerCommonConstants.RANGER_ADMIN_SUFFIX_TAG_DELTA,
RangerCommonConstants.RANGER_ADMIN_SUFFIX_TAG_DELTA_DEFAULT);
+ SUPPORTS_IN_PLACE_TAG_UPDATES = SUPPORTS_TAG_DELTAS
&& config.getBoolean("ranger.admin" +
RangerCommonConstants.RANGER_ADMIN_SUFFIX_IN_PLACE_TAG_UPDATES,
RangerCommonConstants.RANGER_ADMIN_SUFFIX_IN_PLACE_TAG_UPDATES_DEFAULT);
+ IS_SUPPORTS_TAG_DELTAS_INITIALIZED = true;
+ }
+ }
- SUPPORTS_TAG_DELTAS =
config.getBoolean("ranger.admin.supports.tag.deltas", false);
- IS_SUPPORTS_TAG_DELTAS_INITIALIZED = true;
- }
+ public static boolean isSupportsTagDeltas() {
+ initStatics();
return SUPPORTS_TAG_DELTAS;
}
+
+ public boolean isInPlaceTagUpdateSupported() {
+ initStatics();
+ return SUPPORTS_IN_PLACE_TAG_UPDATES;
+ }
}
diff --git
a/security-admin/src/main/java/org/apache/ranger/common/RangerAdminTagEnricher.java
b/security-admin/src/main/java/org/apache/ranger/common/RangerAdminTagEnricher.java
index 09e5c50..c3b70dc 100644
---
a/security-admin/src/main/java/org/apache/ranger/common/RangerAdminTagEnricher.java
+++
b/security-admin/src/main/java/org/apache/ranger/common/RangerAdminTagEnricher.java
@@ -30,6 +30,7 @@ import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.store.ServiceStore;
import org.apache.ranger.plugin.store.TagStore;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.ServiceTags;
public class RangerAdminTagEnricher extends RangerTagEnricher {
@@ -71,9 +72,11 @@ public class RangerAdminTagEnricher extends
RangerTagEnricher {
if (tagStore == null || svcStore == null) {
LOG.error("ServiceDBStore/TagDBStore is not initialized!! Internal
Error!");
} else {
+ super.init();
try {
RangerService service = svcStore.getServiceByName(serviceName);
serviceId = service.getId();
+ createLock();
} catch (Exception e) {
LOG.error("Cannot find service with name:[" + serviceName +
"]", e);
LOG.error("This will cause tag-enricher in Ranger-Admin to
fail!!");
@@ -85,6 +88,15 @@ public class RangerAdminTagEnricher extends
RangerTagEnricher {
}
@Override
+ protected RangerReadWriteLock createLock() {
+ boolean useReadWriteLock = tagStore != null &&
tagStore.isInPlaceTagUpdateSupported();
+
+ LOG.info("Policy-Engine will" + (useReadWriteLock ? " " : " not ") +
"use read-write locking to update tags in place when tag-deltas are provided");
+
+ return new RangerReadWriteLock(useReadWriteLock);
+ }
+
+ @Override
public void enrich(RangerAccessRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminTagEnricher.enrich(" + request + ")");