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 + ")");

Reply via email to