You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ab...@apache.org on 2019/10/17 20:13:40 UTC

[ranger] branch master updated: RANGER-2625: Plugin capability/compatibility model

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 1f5619d  RANGER-2625: Plugin capability/compatibility model
1f5619d is described below

commit 1f5619d156680fc1942a8822841d56168867664a
Author: Abhay Kulkarni <ab...@apache.org>
AuthorDate: Thu Oct 17 13:11:17 2019 -0700

    RANGER-2625: Plugin capability/compatibility model
---
 .../ranger/admin/client/RangerAdminRESTClient.java |   4 +
 .../ranger/plugin/model/RangerPluginInfo.java      |  34 +++++
 .../ranger/plugin/util/RangerPluginCapability.java | 168 +++++++++++++++++++++
 .../apache/ranger/plugin/util/RangerRESTUtils.java |   2 +
 .../policyengine/TestRangerPluginCapability.java   |  91 +++++++++++
 .../plugin/test_plugin_capability.json             |  34 +++++
 .../admin/client/RangerAdminJersey2RESTClient.java |   4 +
 .../main/java/org/apache/ranger/biz/AssetMgr.java  |  17 ++-
 .../java/org/apache/ranger/rest/AssetREST.java     |   3 +-
 .../main/java/org/apache/ranger/rest/RoleREST.java |   7 +-
 .../java/org/apache/ranger/rest/ServiceREST.java   |   6 +-
 .../main/java/org/apache/ranger/rest/TagREST.java  |   6 +-
 .../java/org/apache/ranger/rest/TestAssetREST.java |   2 +-
 .../org/apache/ranger/rest/TestServiceREST.java    |  16 +-
 .../java/org/apache/ranger/rest/TestTagREST.java   |  23 ++-
 15 files changed, 394 insertions(+), 23 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 f564ba5..86469fd 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
@@ -54,6 +54,7 @@ public class RangerAdminRESTClient extends AbstractRangerAdminClient {
 	private RangerRESTUtils  restUtils   = new RangerRESTUtils();
 	private String 		     supportsPolicyDeltas;
 	private String 		     supportsTagDeltas;
+	private final String     pluginCapabilities = Long.toHexString(new RangerPluginCapability().getPluginCapabilities());
 
 	public static <T> GenericType<List<T>> getGenericType(final T clazz) {
 
@@ -132,6 +133,7 @@ public class RangerAdminRESTClient extends AbstractRangerAdminClient {
 		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_CAPABILITIES, pluginCapabilities);
 
 		if (isSecureMode) {
 			if (LOG.isDebugEnabled()) {
@@ -210,6 +212,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_CAPABILITIES, pluginCapabilities);
 
 		if (isSecureMode) {
 			if (LOG.isDebugEnabled()) {
@@ -789,6 +792,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_SUPPORTS_TAG_DELTAS, supportsTagDeltas);
+		queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES, pluginCapabilities);
 
 		if (isSecureMode) {
 			PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPluginInfo.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPluginInfo.java
index 4bd374e..90367fe 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPluginInfo.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPluginInfo.java
@@ -64,6 +64,9 @@ public class RangerPluginInfo implements Serializable {
 	public static final String RANGER_ADMIN_LAST_TAG_UPDATE_TIME     = "lastTagUpdateTime";
 	public static final String RANGER_ADMIN_LATEST_TAG_VERSION       = "latestTagVersion";
 
+	public static final String RANGER_ADMIN_CAPABILITIES             = "adminCapabilities";
+	public static final String PLUGIN_INFO_CAPABILITIES              = "pluginCapabilities";
+
 	private Long    id;
 	private Date    createTime;
 	private Date    updateTime;
@@ -320,6 +323,37 @@ public class RangerPluginInfo implements Serializable {
 		return StringUtils.isNotBlank(activeVersionString) ? Long.valueOf(activeVersionString) : null;
 	}
 
+	@JsonIgnore
+	public void setPluginCapabilities(String capabilities) {
+		setCapabilities(PLUGIN_INFO_CAPABILITIES, capabilities);
+	}
+
+	@JsonIgnore
+	public String getPluginCapabilities() {
+		return getCapabilities(PLUGIN_INFO_CAPABILITIES);
+	}
+
+	@JsonIgnore
+	public void setAdminCapabilities(String capabilities) {
+		setCapabilities(RANGER_ADMIN_CAPABILITIES, capabilities);
+	}
+
+	@JsonIgnore
+	public String getAdminCapabilities() {
+		return getCapabilities(RANGER_ADMIN_CAPABILITIES);
+	}
+
+	@JsonIgnore
+	private void setCapabilities(String optionName, String capabilities) {
+		getInfo().put(optionName, capabilities == null ? null : capabilities);
+	}
+
+	@JsonIgnore
+	private String getCapabilities(String optionName) {
+		String capabilitiesString = getInfo().get(optionName);
+		return StringUtils.isNotBlank(capabilitiesString) ? capabilitiesString : null;
+	}
+
 	@Override
 	public String toString() {
 		StringBuilder sb = new StringBuilder();
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerPluginCapability.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerPluginCapability.java
new file mode 100644
index 0000000..53e1a9b
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerPluginCapability.java
@@ -0,0 +1,168 @@
+/*
+ * 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 org.apache.ranger.authorization.utils.JsonUtils;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class RangerPluginCapability {
+
+    /*
+    	- tag-policies
+	- allowExceptions/deny/denyExceptions
+	- masking/row-filtering
+	- Macros - like ${USER}
+       	- tag-based masking/row-filtering
+	- audit mode support
+	- service-def changes - isValidLeaf
+	- validity periods
+	- policy priority
+	- security zones
+	- policy-level conditions
+	- deny AllElse policies
+	- roles
+	- role download timer
+     */
+    private final long pluginCapabilities;
+    private static final String baseRangerCapabilities = computeBaseCapabilities();
+
+    // Any new RANGER_PLUGIN_CAPABILITY needs to be added to the end of this enum. Existing enumerator order should *NOT* be changed //
+    public enum RangerPluginFeature {
+        RANGER_PLUGIN_CAPABILITY_TAG_POLICIES("Tag Policies"),
+        RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING("Masking and Row-filtering"),
+        RANGER_PLUGIN_CAPABILITY_MACROS("Macros"),
+        RANGER_PLUGIN_CAPABILITY_AUDIT_MODE("Audit Mode"),
+        RANGER_PLUGIN_CAPABILITY_RESOURCE_IS_VALID_LEAF("Support for leaf node"),
+        RANGER_PLUGIN_CAPABILITY_VALIDITY_PERIOD("Validity Period"),
+        RANGER_PLUGIN_CAPABILITY_POLICY_PRIORITY("Policy Priority"),
+        RANGER_PLUGIN_CAPABILITY_SECURITY_ZONE("Security Zone"),
+        RANGER_PLUGIN_CAPABILITY_POLICY_LEVEL_CONDITION("Policy-level Condition"),
+        RANGER_PLUGIN_CAPABILITY_DENY_ALL_ELSE_POLICY("Deny-all-else Policy"),
+        RANGER_PLUGIN_CAPABILITY_ROLE("Role"),
+        RANGER_PLUGIN_CAPABILITY_ROLE_DOWNLOAD_TIMER("Role Timer");
+
+        private String name;
+        RangerPluginFeature(String name) {
+            this.name = name;
+        }
+        String getName() { return name; }
+    }
+
+
+    public RangerPluginCapability() {
+
+        long vector = 0L;
+        for (RangerPluginFeature feature : RangerPluginFeature.values()) {
+            vector += 1L << feature.ordinal();
+        }
+        pluginCapabilities = vector;
+    }
+
+    public RangerPluginCapability(long pluginCapabilities) {
+        this.pluginCapabilities = pluginCapabilities;
+    }
+
+    public RangerPluginCapability(List<String> capabilities) {
+
+        long vector = 0L;
+
+        for (String capability : capabilities) {
+            RangerPluginFeature feature;
+            try {
+                feature = RangerPluginFeature.valueOf(capability);
+                vector += 1L << feature.ordinal();
+            } catch (Exception e) {
+                // Ignore
+            }
+        }
+        this.pluginCapabilities = vector;
+    }
+
+    public long getPluginCapabilities() {
+        return pluginCapabilities;
+    }
+
+    public List<String> compare(RangerPluginCapability other) {
+        final List<String> ret;
+
+        if (pluginCapabilities != other.pluginCapabilities) {
+
+            long mismatchedCapabilitiesVector = this.pluginCapabilities ^ other.pluginCapabilities;
+
+            List<String> missingFeatures = toStrings(mismatchedCapabilitiesVector);
+
+            if (mismatchedCapabilitiesVector > (1L << (RangerPluginFeature.values().length))) {
+                missingFeatures.add("unknown");
+            }
+
+            ret = missingFeatures;
+        } else {
+            ret = Collections.EMPTY_LIST;
+        }
+
+        return ret;
+    }
+
+    @Override
+    public String toString() {
+        List<String> capabilities =  toStrings(pluginCapabilities);
+        return JsonUtils.objectToJson(capabilities);
+    }
+
+    public static String getBaseRangerCapabilities() {
+        return baseRangerCapabilities;
+    }
+
+    private static List<String> toStrings(long vector) {
+
+        List<String> ret = new ArrayList<>();
+
+        for (RangerPluginFeature feature : RangerPluginFeature.values()) {
+            long test = 1L << feature.ordinal();
+            if ((test & vector) > 0) {
+                ret.add(feature.name());
+            }
+        }
+
+        return ret;
+    }
+
+
+    private static String computeBaseCapabilities() {
+        List<String> baseCapabilities = Arrays.asList(RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_TAG_POLICIES.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_MACROS.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_AUDIT_MODE.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_RESOURCE_IS_VALID_LEAF.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_VALIDITY_PERIOD.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_POLICY_PRIORITY.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_SECURITY_ZONE.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_POLICY_LEVEL_CONDITION.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_DENY_ALL_ELSE_POLICY.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_ROLE.getName()
+                , RangerPluginFeature.RANGER_PLUGIN_CAPABILITY_ROLE_DOWNLOAD_TIMER.getName());
+
+        return Long.toHexString(new RangerPluginCapability(baseCapabilities).getPluginCapabilities());
+    }
+
+}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java
index d612e7f..52cea4d 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java
@@ -85,6 +85,8 @@ public class RangerRESTUtils {
 	public static final String REST_PARAM_ZONE_NAME		 = "zoneName";
 	public static final String REST_PARAM_EXEC_USER      = "execUser";
 
+	public static final String REST_PARAM_CAPABILITIES   = "pluginCapabilities";
+
 	public static String hostname;
 
 	static {
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerPluginCapability.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerPluginCapability.java
new file mode 100644
index 0000000..53ab87b
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerPluginCapability.java
@@ -0,0 +1,91 @@
+/*
+ * 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.policyengine;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.authorization.utils.JsonUtils;
+import org.apache.ranger.plugin.util.RangerPluginCapability;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+public class TestRangerPluginCapability {
+
+    private static Gson gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z")
+				.setPrettyPrinting()
+				.create();
+
+    @Test
+    public void testRangerPluginCapabilities() {
+        String[] tests = {"/policyengine/plugin/test_plugin_capability.json"};
+
+        runTestsFromResourceFiles(tests);
+    }
+
+    private void runTestsFromResourceFiles(String[] resourceNames) {
+        for(String resourceName : resourceNames) {
+            InputStream inStream = this.getClass().getResourceAsStream(resourceName);
+            InputStreamReader reader   = new InputStreamReader(inStream);
+
+            runTests(reader, resourceName);
+        }
+    }
+
+    private void runTests(InputStreamReader reader, String fileName) {
+        RangerPluginCapabilityTest testCases = gsonBuilder.fromJson(reader, RangerPluginCapabilityTest.class);
+
+        for (RangerPluginCapabilityTest.TestCase testCase : testCases.testCases) {
+            String testName = testCase.name;
+
+            RangerPluginCapability me;
+            if (CollectionUtils.isEmpty(testCase.myCapabilities)) {
+                me = new RangerPluginCapability();
+            } else {
+                me = new RangerPluginCapability(testCase.myCapabilities);
+            }
+            RangerPluginCapability other = new RangerPluginCapability(testCase.otherCapabilities);
+
+            List<String> difference = me.compare(other);
+
+            assertTrue(fileName + "-" + testName + "-" + Arrays.toString(difference.toArray()), StringUtils.equals(JsonUtils.listToJson(difference), JsonUtils.listToJson(testCase.difference)));
+
+        }
+    }
+
+    static class RangerPluginCapabilityTest {
+        List<TestCase> testCases;
+
+        class TestCase {
+            String  name;
+            List<String> myCapabilities;
+            List<String> otherCapabilities;
+
+            List<String> difference;
+        }
+    }
+}
diff --git a/agents-common/src/test/resources/policyengine/plugin/test_plugin_capability.json b/agents-common/src/test/resources/policyengine/plugin/test_plugin_capability.json
new file mode 100644
index 0000000..a9f741b
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/plugin/test_plugin_capability.json
@@ -0,0 +1,34 @@
+{
+  "testCases": [
+    {
+      "name": "Identical capabilities",
+      "myCapabilities": ["RANGER_PLUGIN_CAPABILITY_TAG_POLICIES", "RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING"],
+      "otherCapabilities": ["RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING", "RANGER_PLUGIN_CAPABILITY_TAG_POLICIES"],
+      "difference": []
+    },
+    {
+      "name": "Other has more capabilities",
+      "myCapabilities": ["RANGER_PLUGIN_CAPABILITY_TAG_POLICIES", "RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING"],
+      "otherCapabilities": ["RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING", "RANGER_PLUGIN_CAPABILITY_TAG_POLICIES", "RANGER_PLUGIN_CAPABILITY_POLICY_LEVEL_CONDITION"],
+      "difference": ["RANGER_PLUGIN_CAPABILITY_POLICY_LEVEL_CONDITION"]
+    },
+    {
+      "name": "I have more capabilities",
+      "otherCapabilities": ["RANGER_PLUGIN_CAPABILITY_TAG_POLICIES", "RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING"],
+      "myCapabilities": ["RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING", "RANGER_PLUGIN_CAPABILITY_TAG_POLICIES", "RANGER_PLUGIN_CAPABILITY_POLICY_LEVEL_CONDITION"],
+      "difference": ["RANGER_PLUGIN_CAPABILITY_POLICY_LEVEL_CONDITION"]
+    },
+    {
+      "name": "Using all existing capabilities",
+      "myCapabilities": [],
+      "otherCapabilities": ["RANGER_PLUGIN_CAPABILITY_TAG_POLICIES", "RANGER_PLUGIN_CAPABILITY_ROLE_DOWNLOAD_TIMER","RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING", "RANGER_PLUGIN_CAPABILITY_MACROS", "RANGER_PLUGIN_CAPABILITY_AUDIT_MODE", "RANGER_PLUGIN_CAPABILITY_RESOURCE_IS_VALID_LEAF", "RANGER_PLUGIN_CAPABILITY_VALIDITY_PERIOD", "RANGER_PLUGIN_CAPABILITY_POLICY_PRIORITY","RANGER_PLUGIN_CAPABILITY_SECURITY_ZONE","RANGER_PLUGIN_CAPABILITY_POLICY_LEVEL_CONDITION", "RANGER_PLUGIN_CAP [...]
+      "difference": []
+    },
+    {
+      "name": "Using all existing capabilities, other has fewer",
+      "myCapabilities": [],
+      "otherCapabilities": ["RANGER_PLUGIN_CAPABILITY_ROLE_DOWNLOAD_TIMER","RANGER_PLUGIN_CAPABILITY_MASKING_AND_ROW_FILTERING", "RANGER_PLUGIN_CAPABILITY_MACROS", "RANGER_PLUGIN_CAPABILITY_AUDIT_MODE", "RANGER_PLUGIN_CAPABILITY_RESOURCE_IS_VALID_LEAF", "RANGER_PLUGIN_CAPABILITY_VALIDITY_PERIOD", "RANGER_PLUGIN_CAPABILITY_POLICY_PRIORITY","RANGER_PLUGIN_CAPABILITY_SECURITY_ZONE","RANGER_PLUGIN_CAPABILITY_POLICY_LEVEL_CONDITION", "RANGER_PLUGIN_CAPABILITY_DENY_ALL_ELSE_POLICY","RANGER_PLU [...]
+      "difference": ["RANGER_PLUGIN_CAPABILITY_TAG_POLICIES"]
+    }
+  ]
+}
\ No newline at end of file
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 53be9c2..0fafa6e 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
@@ -78,6 +78,7 @@ public class RangerAdminJersey2RESTClient extends AbstractRangerAdminClient {
 	int	   _restClientReadTimeOutMs;
 	private int lastKnownActiveUrlIndex;
 	private List<String> configURLs;
+	private final String   pluginCapabilities = Long.toHexString(new RangerPluginCapability().getPluginCapabilities());
 
 	@Override
 	public void init(String serviceName, String appId, String configPropertyPrefix) {
@@ -138,6 +139,7 @@ public class RangerAdminJersey2RESTClient extends AbstractRangerAdminClient {
 		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_CAPABILITIES, pluginCapabilities);
 
 		if (isSecureMode) {
 			if (LOG.isDebugEnabled()) {
@@ -223,6 +225,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_CAPABILITIES, pluginCapabilities);
 
 		if (isSecureMode) {
 			if (LOG.isDebugEnabled()) {
@@ -378,6 +381,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_SUPPORTS_TAG_DELTAS, _supportsTagDeltas);
+		queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES, pluginCapabilities);
 
 		String relativeURL = null;
 		ServiceTags serviceTags = null;
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
index e17571f..0f44888 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
@@ -55,6 +55,7 @@ import org.apache.ranger.entity.XXPortalUser;
 import org.apache.ranger.entity.XXTrxLog;
 import org.apache.ranger.entity.XXUser;
 import org.apache.ranger.plugin.model.RangerPluginInfo;
+import org.apache.ranger.plugin.util.RangerPluginCapability;
 import org.apache.ranger.plugin.util.RangerRESTUtils;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.service.*;
@@ -125,6 +126,8 @@ public class AssetMgr extends AssetMgrBase {
 
 	private static final Logger logger = Logger.getLogger(AssetMgr.class);
 
+	private static final String adminCapabilities = Long.toHexString(new RangerPluginCapability().getPluginCapabilities());
+
 	public File getXResourceFile(Long id, String fileType) {
 		VXResource xResource = xResourceService.readResource(id);
 		if (xResource == null) {
@@ -661,7 +664,7 @@ public class AssetMgr extends AssetMgrBase {
 		return ret;
 	}
 
-	public void createPluginInfo(String serviceName, String pluginId, HttpServletRequest request, int entityType, Long downloadedVersion, long lastKnownVersion, long lastActivationTime, int httpCode, String clusterName) {
+	public void createPluginInfo(String serviceName, String pluginId, HttpServletRequest request, int entityType, Long downloadedVersion, long lastKnownVersion, long lastActivationTime, int httpCode, String clusterName, String pluginCapabilities) {
 		RangerRESTUtils restUtils = new RangerRESTUtils();
 
 		final String ipAddress = getRemoteAddress(request);
@@ -683,6 +686,7 @@ public class AssetMgr extends AssetMgrBase {
 		pluginSvcVersionInfo.setAppType(appType);
 		pluginSvcVersionInfo.setHostName(hostName);
 		pluginSvcVersionInfo.setIpAddress(ipAddress);
+		pluginSvcVersionInfo.setPluginCapabilities(StringUtils.isEmpty(pluginCapabilities) ? RangerPluginCapability.getBaseRangerCapabilities() : pluginCapabilities);
 
 		switch (entityType) {
 			case RangerPluginInfo.ENTITY_TYPE_POLICIES:
@@ -807,6 +811,8 @@ public class AssetMgr extends AssetMgrBase {
 					}
 				}
 
+				pluginInfo.setAdminCapabilities(adminCapabilities);
+
 				xObj = pluginInfoService.populateDBObject(pluginInfo);
 
 				if (logger.isDebugEnabled()) {
@@ -837,6 +843,7 @@ public class AssetMgr extends AssetMgrBase {
 					}
 					Long lastKnownPolicyVersion = pluginInfo.getPolicyActiveVersion();
 					Long lastPolicyActivationTime = pluginInfo.getPolicyActivationTime();
+					String lastPluginCapabilityVector  = pluginInfo.getPluginCapabilities();
 
 					if (lastKnownPolicyVersion != null && lastKnownPolicyVersion == -1) {
 						// First download request after plug-in's policy-refresher starts
@@ -851,6 +858,14 @@ public class AssetMgr extends AssetMgrBase {
 						dbObj.setPolicyActivationTime(lastPolicyActivationTime);
 						needsUpdating = true;
 					}
+					if (lastPluginCapabilityVector != null && (dbObj.getPluginCapabilities() == null || !dbObj.getPluginCapabilities().equals(lastPluginCapabilityVector))) {
+						dbObj.setPluginCapabilities(lastPluginCapabilityVector);
+						needsUpdating = true;
+					}
+					if (dbObj.getAdminCapabilities() == null || !dbObj.getAdminCapabilities().equals(adminCapabilities)) {
+						dbObj.setAdminCapabilities(adminCapabilities);
+						needsUpdating = true;
+					}
 				} else if (isTagDownloadRequest(entityType)){
 					if (dbObj.getTagDownloadedVersion() == null || !dbObj.getTagDownloadedVersion().equals(pluginInfo.getTagDownloadedVersion())) {
 						// First download for tags after tag-service is associated with resource-service
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java b/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
index 66a5728..fd6e738 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
@@ -514,6 +514,7 @@ public class AssetREST {
 		String            policyCount = request.getParameter("policyCount");
 		String            agentId     = request.getParameter("agentId");
 		Long              lastKnowPolicyVersion = Long.valueOf(-1);
+		String            capabilityVector = "0";
 
 		if (ipAddress == null) {
 			ipAddress = request.getRemoteAddr();
@@ -524,7 +525,7 @@ public class AssetREST {
 		ServicePolicies servicePolicies = null;
 
 		try {
-			servicePolicies = serviceREST.getServicePoliciesIfUpdated(repository, lastKnowPolicyVersion, 0L, agentId, "", "", false, request);
+			servicePolicies = serviceREST.getServicePoliciesIfUpdated(repository, lastKnowPolicyVersion, 0L, agentId, "", "", false, capabilityVector, request);
 		} catch(Exception excp) {
 			logger.error("failed to retrieve policies for repository " + repository, excp);
 		}
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/RoleREST.java b/security-admin/src/main/java/org/apache/ranger/rest/RoleREST.java
index 3156e48..fa3a318 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/RoleREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/RoleREST.java
@@ -61,6 +61,7 @@ import org.apache.ranger.plugin.model.validation.RangerValidator;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
 import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
 import org.apache.ranger.plugin.util.GrantRevokeRoleRequest;
+import org.apache.ranger.plugin.util.RangerRESTUtils;
 import org.apache.ranger.plugin.util.RangerRoles;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.service.RangerRoleService;
@@ -701,6 +702,7 @@ public class RoleREST {
             @DefaultValue("0") @QueryParam("lastActivationTime") Long lastActivationTime,
             @QueryParam("pluginId") String pluginId,
             @DefaultValue("") @QueryParam("clusterName") String clusterName,
+            @DefaultValue("") @QueryParam(RangerRESTUtils.REST_PARAM_CAPABILITIES) String pluginCapabilities,
             @Context HttpServletRequest request) throws Exception {
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> RoleREST.getRangerRolesIfUpdated("
@@ -747,7 +749,7 @@ public class RoleREST {
             }
         }
 
-        assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_ROLES, downloadedVersion, lastKnownRoleVersion, lastActivationTime, httpCode, clusterName);
+        assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_ROLES, downloadedVersion, lastKnownRoleVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);
 
         if (httpCode != HttpServletResponse.SC_OK) {
             boolean logError = httpCode != HttpServletResponse.SC_NOT_MODIFIED;
@@ -769,6 +771,7 @@ public class RoleREST {
             @DefaultValue("0") @QueryParam("lastActivationTime") Long lastActivationTime,
             @QueryParam("pluginId") String pluginId,
             @DefaultValue("") @QueryParam("clusterName") String clusterName,
+            @DefaultValue("") @QueryParam(RangerRESTUtils.REST_PARAM_CAPABILITIES) String pluginCapabilities,
             @Context HttpServletRequest request) throws Exception {
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> RoleREST.getSecureRangerRolesIfUpdated("
@@ -848,7 +851,7 @@ public class RoleREST {
             }
         }
 
-        assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_ROLES, downloadedVersion, lastKnownRoleVersion, lastActivationTime, httpCode, clusterName);
+        assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_ROLES, downloadedVersion, lastKnownRoleVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);
 
         if (httpCode != HttpServletResponse.SC_OK) {
             boolean logError = httpCode != HttpServletResponse.SC_NOT_MODIFIED;
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index 5b38033..852c2c8 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -2982,6 +2982,7 @@ public class ServiceREST {
 			@DefaultValue("") @QueryParam("clusterName") String clusterName,
 			@DefaultValue("") @QueryParam("zoneName") String zoneName,
 			@DefaultValue("false") @QueryParam("supportsPolicyDeltas") Boolean supportsPolicyDeltas,
+			@DefaultValue("") @QueryParam("pluginCapabilities") String pluginCapabilities,
 			@Context HttpServletRequest request) throws Exception {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceREST.getServicePoliciesIfUpdated("
@@ -3048,7 +3049,7 @@ public class ServiceREST {
 				RangerPerfTracer.log(perf);
 			}
 		}
-		assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_POLICIES, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName);
+		assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_POLICIES, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);
 
 		if(httpCode != HttpServletResponse.SC_OK) {
 			boolean logError = httpCode != HttpServletResponse.SC_NOT_MODIFIED;
@@ -3073,6 +3074,7 @@ public class ServiceREST {
 			@DefaultValue("") @QueryParam("clusterName") String clusterName,
 			@DefaultValue("") @QueryParam("zoneName") String zoneName,
 			@DefaultValue("false") @QueryParam("supportsPolicyDeltas") Boolean supportsPolicyDeltas,
+			@DefaultValue("") @QueryParam("pluginCapabilities") String pluginCapabilities,
 			@Context HttpServletRequest request) throws Exception {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceREST.getSecureServicePoliciesIfUpdated("
@@ -3173,7 +3175,7 @@ public class ServiceREST {
 				RangerPerfTracer.log(perf);
 			}
 		}
-		assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_POLICIES, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName);
+		assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_POLICIES, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);
 
 		if (httpCode != HttpServletResponse.SC_OK) {
 			boolean logError = httpCode != HttpServletResponse.SC_NOT_MODIFIED;
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/TagREST.java b/security-admin/src/main/java/org/apache/ranger/rest/TagREST.java
index 51f33db..8b58208 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/TagREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/TagREST.java
@@ -1108,6 +1108,7 @@ public class TagREST {
                                                    @QueryParam(TagRESTConstants.LAST_KNOWN_TAG_VERSION_PARAM) Long lastKnownVersion,
                                                @DefaultValue("0") @QueryParam(TagRESTConstants.LAST_ACTIVATION_TIME) Long lastActivationTime, @QueryParam("pluginId") String pluginId,
                                                @DefaultValue("false") @QueryParam(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS) Boolean supportsTagDeltas,
+                                               @DefaultValue("") @QueryParam(RangerRESTUtils.REST_PARAM_CAPABILITIES) String pluginCapabilities,
                                                @Context HttpServletRequest request) {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> TagREST.getServiceTagsIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ", " + pluginId + ", " + supportsTagDeltas + ")");
@@ -1141,7 +1142,7 @@ public class TagREST {
 			httpCode = HttpServletResponse.SC_BAD_REQUEST;
 			logMsg   = excp.getMessage();
         } finally {
-            assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_TAGS, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName);
+            assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_TAGS, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);
         }
 
         if(httpCode != HttpServletResponse.SC_OK) {
@@ -1163,6 +1164,7 @@ public class TagREST {
                                                    @QueryParam(TagRESTConstants.LAST_KNOWN_TAG_VERSION_PARAM) Long lastKnownVersion,
                                                      @DefaultValue("0") @QueryParam(TagRESTConstants.LAST_ACTIVATION_TIME) Long lastActivationTime, @QueryParam("pluginId") String pluginId,
                                                      @DefaultValue("false") @QueryParam(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS) Boolean supportsTagDeltas,
+                                                     @DefaultValue("") @QueryParam(RangerRESTUtils.REST_PARAM_CAPABILITIES) String pluginCapabilities,
                                                      @Context HttpServletRequest request) {
 
         if(LOG.isDebugEnabled()) {
@@ -1228,7 +1230,7 @@ public class TagREST {
 			httpCode = HttpServletResponse.SC_BAD_REQUEST;
 			logMsg   = excp.getMessage();
         }  finally {
-            assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_TAGS, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName);
+            assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_TAGS, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);
         }
 
         if(httpCode != HttpServletResponse.SC_OK) {
diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java b/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
index dce3b0b..c4844cf 100644
--- a/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
+++ b/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
@@ -636,7 +636,7 @@ public class TestAssetREST {
 		// Mockito.when(PropertiesUtil.getBooleanProperty("ranger.service.http.enabled",true)).thenReturn(true);
 		try {
 			Mockito.when(serviceREST.getServicePoliciesIfUpdated(Mockito.anyString(), Mockito.anyLong(),
-					Mockito.anyLong(), Mockito.anyString(), Mockito.anyString() , Mockito.anyString() , Mockito.anyBoolean(), (HttpServletRequest) Mockito.any()))
+					Mockito.anyLong(), Mockito.anyString(), Mockito.anyString() , Mockito.anyString() , Mockito.anyBoolean(), Mockito.anyString(), (HttpServletRequest) Mockito.any()))
 					.thenReturn(servicePolicies);
 		} catch (Exception e) {
 			fail("test failed due to: " + e.getMessage());
diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java
index a7e19bf..f687ab8 100644
--- a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java
+++ b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java
@@ -89,6 +89,7 @@ import org.apache.ranger.plugin.service.ResourceLookupContext;
 import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
 import org.apache.ranger.plugin.store.PList;
 import org.apache.ranger.plugin.util.GrantRevokeRequest;
+import org.apache.ranger.plugin.util.RangerPluginCapability;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.plugin.util.ServicePolicies;
 import org.apache.ranger.security.context.RangerContextHolder;
@@ -240,6 +241,8 @@ public class TestServiceREST {
 	@Rule
 	public ExpectedException thrown = ExpectedException.none();
 
+	private String capabilityVector;
+
 	public void setup() {
 		RangerSecurityContext context = new RangerSecurityContext();
 		context.setUserSession(new UserSessionBase());
@@ -247,6 +250,7 @@ public class TestServiceREST {
 		UserSessionBase currentUserSession = ContextUtil
 				.getCurrentUserSession();
 		currentUserSession.setUserAdmin(true);
+		capabilityVector = Long.toHexString(new RangerPluginCapability().getPluginCapabilities());
 	}
 
 	public RangerServiceDef rangerServiceDef() {
@@ -1017,7 +1021,7 @@ public class TestServiceREST {
 
 		ServicePolicies dbServicePolicies = serviceREST
 				.getServicePoliciesIfUpdated(serviceName, lastKnownVersion, 0L,
-						pluginId, "", "", false, request);
+						pluginId, "", "", false, capabilityVector, request);
 		Assert.assertNull(dbServicePolicies);
 	}
 
@@ -1878,7 +1882,7 @@ public class TestServiceREST {
 		Mockito.when(restErrorUtil.createRESTException(Mockito.anyInt(), Mockito.anyString(), Mockito.anyBoolean()))
 				.thenThrow(new WebApplicationException());
 		thrown.expect(WebApplicationException.class);
-		serviceREST.getServicePoliciesIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, "", "", false, request);
+		serviceREST.getServicePoliciesIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, "", "", false, capabilityVector, request);
 	}
 
 	@Test
@@ -1892,7 +1896,7 @@ public class TestServiceREST {
 		Mockito.when(svcStore.getServicePoliciesIfUpdated(Mockito.anyString(), Mockito.anyLong(), Mockito.anyBoolean())).thenReturn(servicePolicies);
 		Mockito.when(zoneStore.getSecurityZonesForService(serviceName)).thenReturn(null);
 		ServicePolicies dbServicePolicies = serviceREST.getServicePoliciesIfUpdated(serviceName, lastKnownVersion, 0L,
-				pluginId, "", "", true, request);
+				pluginId, "", "", true, capabilityVector, request);
 		Assert.assertNotNull(dbServicePolicies);
 	}
 
@@ -1916,7 +1920,7 @@ public class TestServiceREST {
 				.thenThrow(new WebApplicationException());
 		thrown.expect(WebApplicationException.class);
 
-		serviceREST.getSecureServicePoliciesIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, "", "", false, request);
+		serviceREST.getSecureServicePoliciesIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, "", "", false, capabilityVector, request);
 	}
 
 	@Test
@@ -1942,7 +1946,7 @@ public class TestServiceREST {
 				.thenThrow(new WebApplicationException());
 		thrown.expect(WebApplicationException.class);
 
-		serviceREST.getSecureServicePoliciesIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, "", "", false, request);
+		serviceREST.getSecureServicePoliciesIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, "", "", false, capabilityVector, request);
 	}
 
 	@Test
@@ -1968,7 +1972,7 @@ public class TestServiceREST {
 		Mockito.when(svcStore.getServicePoliciesIfUpdated(Mockito.anyString(), Mockito.anyLong(), Mockito.anyBoolean())).thenReturn(sp);
 		Mockito.when(zoneStore.getSecurityZonesForService(serviceName)).thenReturn(null);
         	ServicePolicies dbServiceSecurePolicies = serviceREST.getSecureServicePoliciesIfUpdated(serviceName,
-                		lastKnownVersion, 0L, pluginId, "", "", true, request);
+                		lastKnownVersion, 0L, pluginId, "", "", true, capabilityVector, request);
 		Assert.assertNotNull(dbServiceSecurePolicies);
 		Mockito.verify(serviceUtil).isValidService(serviceName, request);
 		Mockito.verify(xServiceDao).findByName(serviceName);
diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestTagREST.java b/security-admin/src/test/java/org/apache/ranger/rest/TestTagREST.java
index 402f1ce..7fba152 100644
--- a/security-admin/src/test/java/org/apache/ranger/rest/TestTagREST.java
+++ b/security-admin/src/test/java/org/apache/ranger/rest/TestTagREST.java
@@ -37,6 +37,7 @@ import org.apache.ranger.plugin.model.RangerTag;
 import org.apache.ranger.plugin.model.RangerTagDef;
 import org.apache.ranger.plugin.model.RangerTagResourceMap;
 import org.apache.ranger.plugin.store.TagValidator;
+import org.apache.ranger.plugin.util.RangerPluginCapability;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.plugin.util.ServiceTags;
 import org.junit.Assert;
@@ -92,6 +93,12 @@ public class TestTagREST {
 	@Rule
 	public ExpectedException thrown = ExpectedException.none();
 
+	private static String capabilityVector;
+
+	static {
+		capabilityVector = Long.toHexString(new RangerPluginCapability().getPluginCapabilities());
+	}
+
 	@Test
 	public void test1createTagDef() {
 		RangerTagDef oldTagDef = null;
@@ -1412,7 +1419,7 @@ public class TestTagREST {
 		Mockito.when(restErrorUtil.createRESTException(Mockito.anyInt(),Mockito.anyString(), Mockito.anyBoolean())).thenThrow(new WebApplicationException());
 		thrown.expect(WebApplicationException.class);
 		
-		tagREST.getServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false,null);
+		tagREST.getServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, capabilityVector, null);
 		
 		try {
 			Mockito.verify(tagStore).getServiceTagsIfUpdated(serviceName, lastKnownVersion, true);
@@ -1431,7 +1438,7 @@ public class TestTagREST {
 			Mockito.when(tagStore.getServiceTagsIfUpdated(serviceName, lastKnownVersion, true)).thenReturn(oldServiceTag);
 		} catch (Exception e) {
 		}
-		ServiceTags serviceTags = tagREST.getServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false,null);
+		ServiceTags serviceTags = tagREST.getServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, capabilityVector, null);
 		Assert.assertEquals(serviceTags.getServiceName(), oldServiceTag.getServiceName());
 		Assert.assertEquals(serviceTags.getTagVersion(), oldServiceTag.getTagVersion());
 		
@@ -1483,7 +1490,7 @@ public class TestTagREST {
 		} catch (Exception e) {
 		}
 		
-		ServiceTags result = tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, null);
+		ServiceTags result = tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, capabilityVector, null);
 		Assert.assertNotNull(result.getServiceName());
 		Assert.assertEquals(result.getServiceName(), oldServiceTag.getServiceName());
 		Assert.assertEquals(result.getTagVersion(), oldServiceTag.getTagVersion());
@@ -1545,7 +1552,7 @@ public class TestTagREST {
 		} catch (Exception e) {
 		}
 		
-		ServiceTags result = tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, null);
+		ServiceTags result = tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, capabilityVector, null);
 		Assert.assertNotNull(result.getServiceName());
 		Assert.assertEquals(result.getServiceName(), oldServiceTag.getServiceName());
 		Assert.assertEquals(result.getTagVersion(), oldServiceTag.getTagVersion());
@@ -1610,7 +1617,7 @@ public class TestTagREST {
 		} catch (Exception e) {
 		}
 		
-		ServiceTags result = tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, null);
+		ServiceTags result = tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, capabilityVector, null);
 		Assert.assertNotNull(result.getServiceName());
 		Assert.assertEquals(result.getServiceName(), oldServiceTag.getServiceName());
 		Assert.assertEquals(result.getTagVersion(), oldServiceTag.getTagVersion());
@@ -1675,7 +1682,7 @@ public class TestTagREST {
 		} catch (Exception e) {
 		}
 		
-		ServiceTags result = tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, null);
+		ServiceTags result = tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, capabilityVector, null);
 		Assert.assertNotNull(result.getServiceName());
 		Assert.assertEquals(result.getServiceName(), oldServiceTag.getServiceName());
 		Assert.assertEquals(result.getTagVersion(), oldServiceTag.getTagVersion());
@@ -1738,7 +1745,7 @@ public class TestTagREST {
 		Mockito.when(restErrorUtil.createRESTException(Mockito.anyInt(), Mockito.anyString(), Mockito.anyBoolean())).thenThrow(new WebApplicationException());
 		thrown.expect(WebApplicationException.class);
 		
-		tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, null);
+		tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, capabilityVector, null);
 		
 		Mockito.verify(bizUtil).isAdmin();
 		Mockito.verify(bizUtil).isKeyAdmin();
@@ -1797,7 +1804,7 @@ public class TestTagREST {
 		Mockito.when(restErrorUtil.createRESTException(Mockito.anyInt(), Mockito.anyString(), Mockito.anyBoolean())).thenThrow(new WebApplicationException());
 		thrown.expect(WebApplicationException.class);
 		
-		tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, null);
+		tagREST.getSecureServiceTagsIfUpdated(serviceName, lastKnownVersion, 0L, pluginId, false, capabilityVector, null);
 		
 		Mockito.verify(bizUtil).isAdmin();
 		Mockito.verify(bizUtil).isKeyAdmin();