You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/06/26 23:58:39 UTC

incubator-ranger git commit: RANGER-274: Added TagServiceDef impl class support and tested AdminClient as a tag provider. Added search based on policyResources, added unit testing framework. Added APIs for tag-sync use

Repository: incubator-ranger
Updated Branches:
  refs/heads/tag-policy 3bed641fe -> ca8879858


RANGER-274: Added TagServiceDef impl class support and tested AdminClient as a tag provider. Added search based on policyResources, added unit testing framework. Added APIs for tag-sync use

Signed-off-by: Madhan Neethiraj <ma...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/ca887985
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/ca887985
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/ca887985

Branch: refs/heads/tag-policy
Commit: ca88798585780e4f7f8bd0859a6d0fedc468fbfd
Parents: 3bed641
Author: Abhay Kulkarni <ak...@hortonworks.com>
Authored: Mon Jun 22 14:28:50 2015 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Fri Jun 26 14:58:31 2015 -0700

----------------------------------------------------------------------
 .../admin/client/RangerAdminRESTClient.java     | 105 +++++++++++
 .../RangerAdminTagRetriever.java                |  95 ++++++++++
 .../contextenricher/RangerTagProvider.java      |   2 +-
 .../RangerDefaultPolicyResourceMatcher.java     |  53 ++++++
 .../RangerPolicyResourceMatcher.java            |   2 +
 .../ranger/plugin/store/AbstractTagStore.java   |  18 ++
 .../ranger/plugin/store/TagPredicateUtil.java   |   7 +-
 .../apache/ranger/plugin/store/TagStore.java    |  10 +
 .../ranger/plugin/store/file/TagFileStore.java  | 139 +++++++++++++-
 .../plugin/store/rest/ServiceRESTStore.java     |   3 +
 .../ranger/plugin/util/RangerRESTUtils.java     |   8 +
 .../ranger/services/tag/RangerServiceTag.java   | 146 +++++++++++++++
 .../service-defs/ranger-servicedef-tag.json     |  43 ++++-
 .../ranger/plugin/store/TestTagStore.java       | 183 +++++++++++++++++++
 .../java/org/apache/ranger/biz/ServiceMgr.java  |   4 +
 .../java/org/apache/ranger/rest/TagREST.java    | 100 +++++++++-
 .../apache/ranger/rest/TagRESTConstants.java    |   8 +
 17 files changed, 912 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
----------------------------------------------------------------------
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 f74bc6d..59cb106 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
@@ -21,18 +21,27 @@
 
 
 import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.GenericType;
 import com.sun.jersey.api.client.WebResource;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.security.AccessControlException;
 import org.apache.ranger.admin.client.datatype.RESTResponse;
 import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+import org.apache.ranger.plugin.model.RangerResource;
 import org.apache.ranger.plugin.util.GrantRevokeRequest;
 import org.apache.ranger.plugin.util.RangerRESTClient;
 import org.apache.ranger.plugin.util.RangerRESTUtils;
 import org.apache.ranger.plugin.util.ServicePolicies;
 
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 
 public class RangerAdminRESTClient implements RangerAdminClient {
 	private static final Log LOG = LogFactory.getLog(RangerAdminRESTClient.class);
@@ -159,4 +168,100 @@ public class RangerAdminRESTClient implements RangerAdminClient {
 		
 		return ret;
 	}
+
+	public void init(String serviceName, Map<String, String> configs) {
+		this.serviceName = serviceName;
+		// Get all configuration parameter to connect to DGI from configs
+		String url               = configs.get("URL");
+		String sslConfigFileName = configs.get("SSL_CONFIG_FILE_NAME");
+		String userName = configs.get("username");
+		String password = configs.get("password");
+
+		init(url, sslConfigFileName);
+		if (restClient != null) {
+			restClient.setBasicAuthInfo(userName, password);
+		}
+	}
+
+	public  List<RangerResource> getTaggedResources(String componentType) throws Exception {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerAdminRESTClient.getTaggedResources(" +  serviceName + ", " + componentType + "): ");
+		}
+
+		ParameterizedType parameterizedGenericType = new ParameterizedType() {
+			public Type[] getActualTypeArguments() {
+				return new Type[] { new RangerResource().getClass() };
+			}
+
+			public Type getRawType() {
+				return List.class;
+			}
+
+			public Type getOwnerType() {
+				return List.class;
+			}
+		};
+
+		GenericType<List<RangerResource>> genericType = new GenericType<List<RangerResource>>(
+				parameterizedGenericType) {
+		};
+
+		List<RangerResource> ret;
+
+		WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_GET_TAGGED_RESOURCES)
+				.queryParam(RangerRESTUtils.TAG_SERVICE_NAME_PARAM, serviceName)
+				.queryParam(RangerRESTUtils.COMPONENT_TYPE_PARAM, componentType);
+		ClientResponse response = webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+
+		if(response != null && response.getStatus() == 200) {
+			ret = response.getEntity(genericType);
+		} else {
+			RESTResponse resp = RESTResponse.fromClientResponse(response);
+			LOG.error("Error getting taggedResources. request=" + webResource.toString()
+					+ ", response=" + resp.toString() + ", serviceName=" + serviceName + ", componentType=" + componentType);
+			throw new Exception(resp.getMessage());
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerAdminRESTClient.getTaggedResources(" +  serviceName + ", " + componentType + "): " + ret);
+		}
+
+		return ret;
+	}
+
+	public Set<String> getTagNames(String componentType, String tagNamePattern) throws Exception {
+		// TODO
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerAdminRESTClient.getTagNames(" +  serviceName + ", " + componentType
+					+ ", " + tagNamePattern + "): ");
+		}
+
+		Set<String> ret = null;
+
+		WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_LOOKUP_TAG_NAMES)
+				.queryParam(RangerRESTUtils.TAG_SERVICE_NAME_PARAM, serviceName)
+				.queryParam(RangerRESTUtils.TAG_PATTERN_PARAM, tagNamePattern);
+
+		if (StringUtils.isNotBlank(componentType)) {
+			webResource.queryParam(RangerRESTUtils.COMPONENT_TYPE_PARAM, componentType);
+		}
+
+		ClientResponse response = webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+
+		if(response != null && response.getStatus() == 200) {
+			ret = (Set<String>)response.getEntity(Set.class);
+		} else {
+			RESTResponse resp = RESTResponse.fromClientResponse(response);
+			LOG.error("Error getting taggedResources. request=" + webResource.toString()
+					+ ", response=" + resp.toString() + ", serviceName=" + serviceName + ", componentType=" + componentType);
+			throw new Exception(resp.getMessage());
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerAdminRESTClient.getTagNames(" +  serviceName + ", " + componentType + ", " + tagNamePattern + "): " + ret);
+		}
+
+		return ret;
+	}
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAdminTagRetriever.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAdminTagRetriever.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAdminTagRetriever.java
new file mode 100644
index 0000000..4ffe746
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAdminTagRetriever.java
@@ -0,0 +1,95 @@
+/*
+ * 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.contextenricher;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.admin.client.RangerAdminRESTClient;
+import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+import org.apache.ranger.plugin.model.RangerResource;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class RangerAdminTagRetriever extends RangerTagRefresher {
+	private static final Log LOG = LogFactory.getLog(RangerAdminTagRetriever.class);
+
+	private final String componentType;
+	private final String tagServiceName;
+	private RangerTagReceiver receiver;
+	private RangerAdminRESTClient rangerAdminRESTClient;
+
+	public RangerAdminTagRetriever(final String componentType, final String tagServiceName, final long pollingIntervalMs, final RangerTagReceiver enricher) {
+		super(pollingIntervalMs);
+		this.componentType = componentType;
+		this.tagServiceName = tagServiceName;
+		setReceiver(enricher);
+	}
+
+	@Override
+	public void init(Map<String, Object> options) {
+
+		String propertyPrefix    = "ranger.plugin.tag";
+		String url               = RangerConfiguration.getInstance().get(propertyPrefix + ".provider.rest.url", "http://node-1.example.com:6080");
+		String sslConfigFileName = RangerConfiguration.getInstance().get(propertyPrefix + ".provider.rest.ssl.config.file", "abcd");
+		String userName               = RangerConfiguration.getInstance().get(propertyPrefix + ".provider.login.username", "admin");
+		String password = RangerConfiguration.getInstance().get(propertyPrefix + ".provider.login.password", "admin");
+
+		Map<String, String> configs = new HashMap<String, String>();
+
+		configs.put("URL", url);
+		configs.put("SSL_CONFIG_FILE_NAME", sslConfigFileName);
+		configs.put("username", userName);
+		configs.put("password", password);
+
+		rangerAdminRESTClient = new RangerAdminRESTClient();
+		rangerAdminRESTClient.init(tagServiceName, configs);
+
+	}
+
+	@Override
+	public void setReceiver(RangerTagReceiver receiver) {
+		this.receiver = receiver;
+	}
+
+	@Override
+	public void retrieveTags() {
+		if (rangerAdminRESTClient != null) {
+			List<RangerResource> resources = null;
+
+			try {
+				resources = rangerAdminRESTClient.getTaggedResources(componentType);
+			} catch (Exception exp) {
+				LOG.error("RangerAdminTagRetriever.retrieveTags() - Error retrieving resources");
+			}
+
+			if (receiver != null && resources != null) {
+				receiver.setRangerResources(resources);
+			} else {
+				LOG.error("RangerAdminTagRetriever.retrieveTags() - No receiver to send resources to !!");
+			}
+		} else {
+			LOG.error("RangerAdminTagRetriever.retrieveTags() - No TagFileStore ...");
+		}
+	}
+
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java
index 61c8907..993cdfb 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagProvider.java
@@ -63,7 +63,7 @@ public class RangerTagProvider extends RangerAbstractContextEnricher implements
 			tagRefresher = new RangerTagFileStoreRetriever(serviceDef.getName(), serviceName, pollingIntervalMs, this);
 			tagProviderType = TagProviderTypeEnum.FILESTORE_BASED_TAG_PROVIDER;
 		} else if (tagProviderTypeString.equals(TagProviderTypeEnum.RANGER_ADMIN_TAG_PROVIDER.toString())) {
-			// TODO
+			tagRefresher = new RangerAdminTagRetriever(serviceDef.getName(), serviceName, pollingIntervalMs, this);
 			tagProviderType = TagProviderTypeEnum.RANGER_ADMIN_TAG_PROVIDER;
 		} else if (tagProviderTypeString.equals(TagProviderTypeEnum.EXTERNAL_SYSTEM_TAG_PROVIDER.toString())) {
 			// TODO

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
index 572a11b..b78b908 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
@@ -499,4 +499,57 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		return ret;
 	}
 
+	@Override
+	public boolean isSingleAndExactMatch(Map<String, RangerPolicyResource> resources) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isSingleAndExactMatch(" + resources + ")");
+		}
+
+		boolean ret = false;
+
+		if(serviceDef != null && serviceDef.getResources() != null) {
+			Collection<String> resourceKeys = resources == null ? null : resources.keySet();
+			Collection<String> policyKeys   = matchers == null ? null : matchers.keySet();
+
+			boolean keysMatch = false;
+
+			if (resourceKeys != null && policyKeys != null) {
+				keysMatch = CollectionUtils.isEqualCollection(resourceKeys, policyKeys);
+			}
+
+			if(keysMatch) {
+				for(RangerResourceDef resourceDef : serviceDef.getResources()) {
+					String                resourceName   = resourceDef.getName();
+					RangerPolicyResource  resourceValues = resources == null ? null : resources.get(resourceName);
+					RangerResourceMatcher matcher        = matchers == null ? null : matchers.get(resourceName);
+
+					if(resourceValues == null || CollectionUtils.isEmpty(resourceValues.getValues())) {
+						ret = matcher == null;
+					} else if(matcher != null) {
+						for(String resourceValue : resourceValues.getValues()) {
+							ret = matcher.isMatch(resourceValue);
+
+							if(! ret) {
+								break;
+							}
+						}
+					}
+
+					if(! ret) {
+						break;
+					}
+				}
+			} else {
+				if(LOG.isDebugEnabled()) {
+					LOG.debug("isSingleAndExactMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys);
+				}
+			}
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isSingleAndExactMatch(" + resources + "): " + ret);
+		}
+
+		return ret;
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
index d23178b..cc80c8a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
@@ -42,5 +42,7 @@ public interface RangerPolicyResourceMatcher {
 
 	boolean isExactHeadMatch(RangerAccessResource resource);
 
+	boolean isSingleAndExactMatch(Map<String, RangerPolicyResource> resources);
+
 	StringBuilder toString(StringBuilder sb);
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractTagStore.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractTagStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractTagStore.java
index d23744b..97b3b1f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractTagStore.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractTagStore.java
@@ -29,6 +29,24 @@ import java.util.List;
 import java.util.UUID;
 
 public abstract class AbstractTagStore implements TagStore {
+
+	protected ServiceStore svcStore;
+
+	@Override
+	public void init() throws Exception {
+
+		if (svcStore == null) {
+			throw new Exception("TagStore does not reference a valid ServiceStore");
+		}
+
+		svcStore.init();
+	}
+
+	@Override
+	final public void setServiceStore(ServiceStore svcStore) {
+		this.svcStore = svcStore;
+	}
+
 	protected void preCreate(RangerBaseModelObject obj) throws Exception {
 		obj.setId(0L);
 		obj.setGuid(UUID.randomUUID().toString());

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/store/TagPredicateUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/TagPredicateUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/TagPredicateUtil.java
index 2c9ccc0..f62414f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/TagPredicateUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/TagPredicateUtil.java
@@ -32,11 +32,8 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class TagPredicateUtil extends AbstractPredicateUtil {
-	private TagStore tagStore = null;
-	public TagPredicateUtil(TagStore tagStore) {
-		super();
-		this.tagStore = tagStore;
-	}
+
+	public TagPredicateUtil() { super(); }
 
 	@Override
 	public void addPredicates(SearchFilter filter, List<Predicate> predicates) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/store/TagStore.java
----------------------------------------------------------------------
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 a43cbf9..599da3f 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
@@ -19,11 +19,14 @@
 
 package org.apache.ranger.plugin.store;
 
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerResource;
 import org.apache.ranger.plugin.model.RangerTagDef;
 import org.apache.ranger.plugin.util.SearchFilter;
 
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Interface to backing store for the top-level TAG model objects
@@ -32,6 +35,8 @@ import java.util.List;
 public interface TagStore {
     void init() throws Exception;
 
+    void setServiceStore(ServiceStore svcStore);
+
     RangerTagDef createTagDef(RangerTagDef tagDef) throws Exception;
 
     RangerTagDef updateTagDef(RangerTagDef TagDef) throws Exception;
@@ -54,10 +59,15 @@ public interface TagStore {
 
     RangerResource getResource(Long id) throws Exception;
 
+    public List<RangerResource> getResources(String componentType, Map<String, RangerPolicy.RangerPolicyResource> resourceSpec) throws Exception;
+
     List<RangerResource> getResources(String tagServiceName, String componentType) throws Exception;
 
     List<RangerResource> getResources(SearchFilter filter) throws Exception;
 
     PList<RangerResource> getPaginatedResources(SearchFilter filter) throws Exception;
 
+    Set<String> getTags(String tagServiceName, String serviceType) throws Exception;
+
+    Set<String> lookupTags(String tagServiceName, String serviceType, String tagNamePattern) throws Exception;
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/store/file/TagFileStore.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/file/TagFileStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/file/TagFileStore.java
index ad0bc66..35833a3 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/file/TagFileStore.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/file/TagFileStore.java
@@ -20,20 +20,27 @@
 package org.apache.ranger.plugin.store.file;
 
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.fs.Path;
 import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerResource;
+import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerTagDef;
+import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
 import org.apache.ranger.plugin.store.AbstractTagStore;
 import org.apache.ranger.plugin.store.TagPredicateUtil;
+import org.apache.ranger.plugin.store.rest.ServiceRESTStore;
 import org.apache.ranger.plugin.util.SearchFilter;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public class TagFileStore extends AbstractTagStore {
 	private static final Log LOG = LogFactory.getLog(TagFileStore.class);
@@ -71,6 +78,7 @@ public class TagFileStore extends AbstractTagStore {
 
 		tagDataDir = RangerConfiguration.getInstance().get(PROPERTY_TAG_FILE_STORE_DIR, "file:///etc/ranger/data");
 		fileStoreUtil = new FileStoreUtil();
+		predicateUtil = new TagPredicateUtil();
 
 		if (LOG.isDebugEnabled())
 
@@ -85,6 +93,7 @@ public class TagFileStore extends AbstractTagStore {
 			LOG.debug("==> TagFileStore.init()");
 		}
 
+		super.init();
 		fileStoreUtil.initStore(tagDataDir);
 
 		if (LOG.isDebugEnabled()) {
@@ -97,7 +106,6 @@ public class TagFileStore extends AbstractTagStore {
 			LOG.debug("==> TagFileStore.initStore()");
 		}
 		fileStoreUtil.initStore(tagDataDir);
-		predicateUtil = new TagPredicateUtil(this);
 
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("<== TagFileStore.initStore()");
@@ -296,6 +304,12 @@ public class TagFileStore extends AbstractTagStore {
 			throw new Exception(resource.getId() + ": resource already exists (id=" + existing.getId() + ")");
 		}
 
+		List<RangerResource> existingResources = getResources(resource.getComponentType(), resource.getResourceSpec());
+
+		if (CollectionUtils.isNotEmpty(existingResources)) {
+			throw new Exception("resource(s) with same specification already exists");
+		}
+
 		RangerResource ret;
 
 		try {
@@ -408,6 +422,64 @@ public class TagFileStore extends AbstractTagStore {
 	}
 
 	@Override
+	public List<RangerResource> getResources(String componentType, Map<String, RangerPolicy.RangerPolicyResource> resourceSpec) throws Exception {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> TagFileStore.getResources( " + componentType + " )");
+		}
+
+		if (this.svcStore == null) {
+			LOG.error("TagFileStore.getResources() - TagFileStore object does not have reference to a valid ServiceStore.");
+			throw new Exception("TagFileStore.getResources() - TagFileStore object does not have reference to a valid ServiceStore.");
+		}
+
+		List<RangerResource> ret = null;
+		RangerServiceDef serviceDef = null;
+
+		try {
+			serviceDef = svcStore.getServiceDefByName(componentType);
+		} catch (Exception exception) {
+			LOG.error("TagFileStore.getResource - failed to get serviceDef for " + componentType);
+			throw new Exception("Invalid component-type: " + componentType);
+		}
+
+		if (MapUtils.isNotEmpty(resourceSpec)) {
+
+			ret = getResources(null, componentType);
+			List<RangerResource> notMatchedResources = new ArrayList<>();
+
+			if (CollectionUtils.isNotEmpty(ret)) {
+				for (RangerResource resource : ret) {
+
+					RangerDefaultPolicyResourceMatcher policyResourceMatcher =
+							new RangerDefaultPolicyResourceMatcher();
+
+					policyResourceMatcher.setPolicyResources(resource.getResourceSpec());
+
+					policyResourceMatcher.setServiceDef(serviceDef);
+
+					policyResourceMatcher.init();
+
+					boolean isMatch = policyResourceMatcher.isSingleAndExactMatch(resourceSpec);
+
+					if (! isMatch) {
+						notMatchedResources.add(resource);
+						break;
+					}
+
+				}
+
+				ret.removeAll(notMatchedResources);
+			}
+		} else {
+			ret = null;
+		}
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== TagFileStore.getResources(" + componentType + ") = " + ret);
+		}
+		return ret;
+	}
+
+	@Override
 	public List<RangerResource> getResources(String tagServiceName, String componentType) throws Exception {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> TagFileStore.getResources(" + tagServiceName + ", " + componentType + ")");
@@ -550,5 +622,66 @@ public class TagFileStore extends AbstractTagStore {
 		return ret;
 	}
 
+	@Override
+	public Set<String> getTags(String tagServiceName, String componentType) throws Exception {
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> TagFileStore.getTags(" + tagServiceName + ", " + componentType + ")");
+		}
+
+		Set<String> ret = new HashSet<String>();
+
+		List<RangerResource> resources = getResources(tagServiceName, componentType);
+		if (CollectionUtils.isNotEmpty(resources)) {
+			for (RangerResource resource : resources) {
+				List<RangerResource.RangerResourceTag> tags = resource.getTags();
+
+				if (CollectionUtils.isNotEmpty(tags)) {
+					for (RangerResource.RangerResourceTag tag : tags) {
+						ret.add(tag.getName());
+					}
+				}
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== TagFileStore.getTags(" + tagServiceName + ", " + componentType + ")");
+		}
+
+		return ret;
+	}
+
+	@Override
+	public Set<String> lookupTags(String tagServiceName, String componentType, String tagNamePattern) throws Exception {
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> TagFileStore.lookupTags(" + tagServiceName + ", " + componentType + ", " + tagNamePattern + ")");
+		}
+
+		Set<String> tagNameSet = getTags(tagServiceName, componentType);
+		Set<String> matchedTagSet = new HashSet<String>();
+
+		if (CollectionUtils.isNotEmpty(tagNameSet)) {
+			Pattern p = Pattern.compile(tagNamePattern);
+			for (String tagName : tagNameSet) {
+				Matcher m = p.matcher(tagName);
+				if (LOG.isDebugEnabled()) {
+					LOG.debug("TagFileStore.lookupTags) - Trying to match .... tagNamePattern=" + tagNamePattern + ", tagName=" + tagName);
+				}
+				if (m.matches()) {
+					if (LOG.isDebugEnabled()) {
+						LOG.debug("TagFileStore.lookupTags) - Match found.... tagNamePattern=" + tagNamePattern + ", tagName=" + tagName);
+					}
+					matchedTagSet.add(tagName);
+				}
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== TagFileStore.lookupTags(" + tagServiceName + ", " + componentType + ", " + tagNamePattern + ")");
+		}
+
+		return matchedTagSet;
+	}
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java
index 7bcc072..5886cf5 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java
@@ -89,8 +89,11 @@ public class ServiceRESTStore extends AbstractServiceStore {
 	public void init() throws Exception {
 		String restUrl       = RangerConfiguration.getInstance().get("ranger.service.store.rest.url");
 		String sslConfigFile = RangerConfiguration.getInstance().get("ranger.service.store.rest.ssl.config.file");
+		String userName = RangerConfiguration.getInstance().get("ranger.service.store.rest.basicauth.username");
+		String password = RangerConfiguration.getInstance().get("ranger.service.store.rest.basicauth.password");
 
 		restClient = new RangerRESTClient(restUrl, sslConfigFile);
+		restClient.setBasicAuthInfo(userName, password);
 	}
 
 	@Override

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java
----------------------------------------------------------------------
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 03b0d2e..af35c32 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
@@ -40,6 +40,14 @@ public class RangerRESTUtils {
 	public static final String REST_URL_SERVICE_GRANT_ACCESS              = "/service/plugins/services/grant/";
 	public static final String REST_URL_SERVICE_REVOKE_ACCESS             = "/service/plugins/services/revoke/";
 
+	public static final String REST_URL_GET_TAGGED_RESOURCES = "/service/tag-def/v1/resources";
+	public static final String TAG_SERVICE_NAME_PARAM = "tagservicename";
+	public static final String COMPONENT_TYPE_PARAM = "componenttype";
+	public static final String TAG_PATTERN_PARAM = "tagpattern";
+
+	public static final String REST_URL_GET_TAG_NAMES = "/service/tag-def/v1/tag-names";
+	public static final String REST_URL_LOOKUP_TAG_NAMES = "/service/tag-def/v1/lookup-tags";
+
 	public static final String REST_EXPECTED_MIME_TYPE = "application/json" ;
 	public static final String REST_MIME_TYPE_JSON     = "application/json" ;
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/java/org/apache/ranger/services/tag/RangerServiceTag.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/services/tag/RangerServiceTag.java b/agents-common/src/main/java/org/apache/ranger/services/tag/RangerServiceTag.java
new file mode 100644
index 0000000..7c7fa96
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/services/tag/RangerServiceTag.java
@@ -0,0 +1,146 @@
+package org.apache.ranger.services.tag;
+
+import java.util.*;
+
+import org.apache.commons.collections.MapUtils;
+import org.apache.ranger.admin.client.RangerAdminRESTClient;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.service.RangerBaseService;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class RangerServiceTag extends RangerBaseService {
+
+	private static final Log LOG = LogFactory.getLog(RangerServiceTag.class);
+
+	public static final String TAG	= "tag";
+
+	public RangerServiceTag() {
+		super();
+	}
+
+	@Override
+	public void init(RangerServiceDef serviceDef, RangerService service) {
+		super.init(serviceDef, service);
+	}
+
+	@Override
+	public HashMap<String,Object> validateConfig() throws Exception {
+		HashMap<String, Object> ret = new HashMap<String, Object>();
+		String 	serviceName  	    = getServiceName();
+		boolean connectivityStatus = false;
+		String message = null;
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerServiceTag.validateConfig -  Service: (" + serviceName + " )");
+		}
+
+		if (MapUtils.isEmpty(configs)) {
+			message = "Configuration is null or empty";
+
+		} else {
+			String url = configs.get("URL");
+			String sslConfigFileName = configs.get("SSL_CONFIG_FILE_NAME");
+			String userName = configs.get("username");
+			String password = configs.get("password");
+
+			if (url == null || sslConfigFileName == null || userName == null || password == null) {
+				message = "Either URL, SSL_CONFIG_FILE_NAME, username or password not provided in configuration";
+			} else {
+
+				RangerAdminRESTClient adminRESTClient = new RangerAdminRESTClient();
+				adminRESTClient.init(serviceName, configs);
+
+				try {
+					adminRESTClient.getTagNames(null, ".*");	// Dont care about componentType
+					connectivityStatus = true;
+				} catch (Exception e) {
+					LOG.error("RangerServiceTag.validateConfig() Error:" + e);
+					connectivityStatus = false;
+					message = "Cannot connect to TagResource Repository, " + e;
+				}
+			}
+		}
+
+		ret.put("connectivityStatus", connectivityStatus);
+		ret.put("message", message);
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerServiceTag.validateConfig - Response : (" + ret + " )");
+		}
+
+		return ret;
+	}
+
+	@Override
+	public List<String> lookupResource(ResourceLookupContext context) throws Exception {
+		String 	serviceName  	   = getServiceName();
+		Map<String,String> configs = getConfigs();
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerServiceTag.lookupResource -  Context: (" + context + ")");
+		}
+
+		Set<String> tagNameSet = new HashSet<>();
+
+		if (MapUtils.isNotEmpty(configs)) {
+			String url = configs.get("URL");
+			String sslConfigFileName = configs.get("SSL_CONFIG_FILE_NAME");
+			String userName = configs.get("username");
+			String password = configs.get("password");
+
+			if (url != null && sslConfigFileName != null && userName != null && password != null) {
+
+				if (context != null) {
+
+					String userInput = context.getUserInput();
+					String resource = context.getResourceName();
+					Map<String, List<String>> resourceMap = context.getResources();
+					final Set<String> userProvidedTagSet = new HashSet<String>();
+
+					if (resource != null && resourceMap != null && resourceMap.get(TAG) != null) {
+
+						for (String tag : resourceMap.get(TAG)) {
+							userProvidedTagSet.add(tag);
+						}
+
+						try {
+							String suffix = ".*";
+							String tagNamePattern;
+
+							if (userInput == null) {
+								tagNamePattern = suffix;
+							} else {
+								tagNamePattern = userInput + suffix;
+							}
+
+							if(LOG.isDebugEnabled()) {
+								LOG.debug("RangerServiceTag.lookupResource -  tagNamePattern : (" + tagNamePattern + ")");
+							}
+
+							RangerAdminRESTClient adminRESTClient = new RangerAdminRESTClient();
+							adminRESTClient.init(serviceName, configs);
+
+							tagNameSet = adminRESTClient.getTagNames(null, tagNamePattern); // Dont care about componentType
+
+							tagNameSet.removeAll(userProvidedTagSet);
+
+						} catch (Exception e) {
+							LOG.error("RangerServiceTag.lookupResource -  Error : " + e);
+						}
+					}
+				}
+
+			}
+
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerServiceTag.lookupResource()");
+		}
+
+		return new ArrayList<String>(tagNameSet);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json
----------------------------------------------------------------------
diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json
index c095279..1593280 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-tag.json
@@ -7,7 +7,8 @@
   "guid": "0d047248-baff-4cf9-8e9e-d5d377284b2e",
   "options":
   {
-    "ui.pages":"tag-based-policies"
+    "ui.pages":"tag-based-policies",
+    "ui.isMultiline":"true"
   },
   "resources":
   [
@@ -38,7 +39,45 @@
 
   "configs":
   [
-  
+    {
+      "itemId": 1,
+      "name": "username",
+      "type": "string",
+      "subType": "",
+      "mandatory": true,
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Username"
+    },
+
+    {
+      "itemId": 2,
+      "name": "password",
+      "type": "password",
+      "subType": "",
+      "mandatory": true,
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Password"
+    },
+
+    {
+      "itemId": 3,
+      "name": "URL",
+      "type": "string",
+      "mandatory": true,
+      "label": "URL for tag provider"
+    },
+
+    {
+      "itemId": 4,
+      "name": "SSL_CONFIG_FILE_NAME",
+      "type": "string",
+      "mandatory": true,
+      "label": "SSL Config file"
+    }
   ],
 
   "enums":

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagStore.java
----------------------------------------------------------------------
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagStore.java b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagStore.java
new file mode 100644
index 0000000..15aecd6
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/store/TestTagStore.java
@@ -0,0 +1,183 @@
+/*
+ * 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.store;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.*;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.*;
+import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
+import org.apache.ranger.plugin.model.*;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.store.file.TagFileStore;
+import org.apache.ranger.plugin.store.rest.ServiceRESTStore;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+public class TestTagStore {
+	static TagStore tagStore = null;
+	static SearchFilter filter   = null;
+	static Path filePath = new Path("file:///etc/ranger/data/ranger-admin-test-site.xml");
+	static Configuration config = new Configuration();
+
+	static final String sdName      = "tagDef-unit-test-TestTagStore";
+	static final String serviceName = "tag-unit-test-TestTagStore";
+	static final String policyName  = "tag-1";
+
+	@BeforeClass
+	public static void setupTest() throws Exception {
+
+		/*
+		tearDownAfterClass();
+
+		FileSystem fs = filePath.getFileSystem(config);
+
+		FSDataOutputStream outStream  = fs.create(filePath, true);
+		OutputStreamWriter writer = null;
+
+
+		writer = new OutputStreamWriter(outStream);
+
+		writer.write("<configuration>\n" +
+				"        <property>\n" +
+				"                <name>ranger.service.store.rest.url</name>\n" +
+				"                <value>http://node-1.example.com:6080</value>\n" +
+				"        </property>\n" +
+				"        <property>\n" +
+				"                <name>ranger.service.store.rest.basicauth.username</name>\n" +
+				"                <value>admin</value>\n" +
+				"        </property>\n" +
+				"        <property>\n" +
+				"                <name>ranger.service.store.rest.basicauth.password</name>\n" +
+				"                <value>admin</value>\n" +
+				"        </property>\n" +
+				"        <property>\n" +
+				"                <name>ranger.tag.store.file.dir</name>\n" +
+				"                <value>file:///etc/ranger/data</value>\n" +
+				"        </property>\n" +
+				"</configuration>\n");
+
+		writer.close();
+
+		RangerConfiguration config = RangerConfiguration.getInstance();
+		config.addResource(filePath);
+
+		tagStore = TagFileStore.getInstance();
+		tagStore.setServiceStore(new ServiceRESTStore());
+		tagStore.init();
+		*/
+
+	}
+
+	//@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+
+		/*
+		Path dirPath = new Path("file:///etc/ranger/data");
+		FileSystem fs = dirPath.getFileSystem(config);
+
+		try {
+			if(fs.exists(dirPath) && fs.isDirectory(dirPath)) {
+				PathFilter filter = new PathFilter() {
+					@Override
+					public boolean accept(Path path) {
+						return path.getName().endsWith(".json") ||
+								path.getName().endsWith(".crc");
+					}
+				};
+
+				RemoteIterator<LocatedFileStatus> files = fs.listFiles(dirPath, false);
+
+				if(files != null) {
+					while (files.hasNext()) {
+						LocatedFileStatus fileStatus = files.next();
+						Path path = fileStatus.getPath();
+						if (fs.isFile(path) && path.getName().endsWith(".json") || path.getName().endsWith(".crc")) {
+							fs.delete(path, true);
+						}
+					}
+				}
+			}
+		} catch(IOException excp) {
+		}
+
+		fs.delete(filePath, true);
+
+		*/
+	}
+
+	@Test
+	public void testTagStore() throws Exception {
+
+		/*
+		List<RangerResource> taggedResources = tagStore.getResources(filter);
+
+		int initResourceCount = taggedResources == null ? 0 : taggedResources.size();
+
+		RangerResource rr = new RangerResource();
+		rr.setComponentType("hive");
+		rr.setTagServiceName("tagdev");
+
+		Map<String, RangerPolicyResource> resourceSpec = new HashMap<>();
+
+		RangerPolicyResource policyResource = new RangerPolicyResource();
+		policyResource.setValues(Arrays.asList("default", "hr", "finance"));
+		resourceSpec.put("database", policyResource);
+
+		policyResource = new RangerPolicyResource();
+		policyResource.setValues(Arrays.asList("table1", "employee", "invoice"));
+		resourceSpec.put("table", policyResource);
+
+		policyResource = new RangerPolicyResource();
+		policyResource.setValues(Arrays.asList("column1", "ssn", "vendor"));
+		resourceSpec.put("column", policyResource);
+
+		rr.setResourceSpec(resourceSpec);
+
+		List<RangerResource.RangerResourceTag> tags = new ArrayList<>();
+
+		tags.add(new RangerResource.RangerResourceTag("PII", null));
+		tags.add(new RangerResource.RangerResourceTag("FINANCE", null));
+
+		rr.setTags(tags);
+
+		RangerResource createdResource = tagStore.createResource(rr);
+
+		assertNotNull("createResource() failed", createdResource);
+
+		taggedResources = tagStore.getResources(filter);
+		assertEquals("createResource() failed", initResourceCount + 1, taggedResources == null ? 0 : taggedResources.size());
+
+		taggedResources = tagStore.getResources("hive", resourceSpec);
+		assertEquals("createResource() failed", initResourceCount + 1, taggedResources == null ? 0 : taggedResources.size());
+
+		resourceSpec.remove("column");
+		taggedResources = tagStore.getResources("hive", resourceSpec);
+		assertEquals("createResource() failed", initResourceCount, taggedResources == null ? 0 : taggedResources.size());
+*/
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
index 576090f..218eee3 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
@@ -219,6 +219,10 @@ public class ServiceMgr {
 							ret = (Class<RangerBaseService>)cls;
 
 							serviceTypeClassMap.put(serviceType, ret);
+
+							if(LOG.isDebugEnabled()) {
+								LOG.debug("ServiceMgr.getClassForServiceType(" + serviceType + "): service-class " + clsName + " added to cache");
+							}
 						} catch (Exception excp) {
 							LOG.warn("ServiceMgr.getClassForServiceType(" + serviceType + "): failed to find service-class '" + clsName + "'. Resource lookup will not be available", excp);
 							//Let's propagate the error

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/security-admin/src/main/java/org/apache/ranger/rest/TagREST.java
----------------------------------------------------------------------
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 c8e387c..7ed17c2 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
@@ -22,10 +22,13 @@ package org.apache.ranger.rest;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.biz.ServiceDBStore;
 import org.apache.ranger.common.RESTErrorUtil;
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerResource;
 import org.apache.ranger.plugin.model.RangerTagDef;
 import org.apache.ranger.plugin.store.file.TagFileStore;
+import org.apache.ranger.plugin.store.rest.ServiceRESTStore;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
@@ -37,6 +40,8 @@ import javax.servlet.http.HttpServletResponse;
 import javax.ws.rs.*;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 @Path(TagRESTConstants.TAGDEF_NAME_AND_VERSION)
 
@@ -52,12 +57,22 @@ public class TagREST {
 
     /*
     @Autowired
+    ServiceRESTStore svcStore;
+    */
+
+    @Autowired
+    ServiceDBStore svcStore;
+
+    /*
+    @Autowired
     TagFileStore tagStore;
     */
 
     private TagFileStore tagStore;
+
     public TagREST() {
         tagStore = TagFileStore.getInstance();
+        tagStore.setServiceStore(svcStore);
     }
 
     @POST
@@ -374,13 +389,13 @@ public class TagREST {
     @GET
     @Path(TagRESTConstants.RESOURCES_RESOURCE)
     @Produces({ "application/json", "application/xml" })
-    public List<RangerResource> getResources(@DefaultValue("") @QueryParam(TagRESTConstants.TAG_SERVICE_NAME_PARAM) String tagServiceName,
-                                             @DefaultValue("") @QueryParam(TagRESTConstants.COMPONENT_TYPE_PARAM) String componentType) {
+    public List<RangerResource> getResources(@QueryParam(TagRESTConstants.TAG_SERVICE_NAME_PARAM) String tagServiceName,
+                                             @QueryParam(TagRESTConstants.COMPONENT_TYPE_PARAM) String componentType) {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> TagREST.getResources(" + tagServiceName + ", " + componentType + ")");
         }
 
-        List<RangerResource> ret;
+        List<RangerResource> ret = null;
 
         try {
             ret = tagStore.getResources(tagServiceName, componentType);
@@ -409,4 +424,83 @@ public class TagREST {
 
         return ret;
     }
+    @GET
+    @Path(TagRESTConstants.TAGNAMES_RESOURCE)
+    @Produces({ "application/json", "application/xml" })
+    public Set<String> getTagNames(@QueryParam(TagRESTConstants.TAG_SERVICE_NAME_PARAM) String tagServiceName,
+                                   @DefaultValue("") @QueryParam(TagRESTConstants.COMPONENT_TYPE_PARAM) String componentType) {
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> TagREST.getTagNames(" + tagServiceName + ")");
+        }
+        Set<String> tagNames = null;
+
+        try {
+            tagNames = tagStore.getTags(tagServiceName, componentType);
+        } catch(Exception excp) {
+            LOG.error("getTags(" + tagServiceName + ") failed", excp);
+
+            throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== TagREST.getTagNames(" + tagServiceName + ")");
+        }
+        return tagNames;
+    }
+
+    @GET
+    @Path(TagRESTConstants.LOOKUP_TAGS_RESOURCE)
+    @Produces({ "application/json", "application/xml" })
+    public Set<String> lookupTags(@QueryParam(TagRESTConstants.TAG_SERVICE_NAME_PARAM) String tagServiceName,
+                                  @DefaultValue("") @QueryParam(TagRESTConstants.COMPONENT_TYPE_PARAM) String componentType,
+                                    @DefaultValue(".*") @QueryParam(TagRESTConstants.TAG_PATTERN_PARAM) String tagNamePattern) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> TagREST.lookupTags(" + tagServiceName  + ", " + tagNamePattern + ")");
+        }
+        Set<String> matchingTagNames = null;
+
+        try {
+            matchingTagNames = tagStore.lookupTags(tagServiceName, componentType, tagNamePattern);
+        } catch(Exception excp) {
+            LOG.error("lookupTags(" + tagServiceName + ") failed", excp);
+
+            throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, excp.getMessage(), true);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== TagREST.lookupTags(" + tagServiceName + ")");
+        }
+        return matchingTagNames;
+    }
+
+    @GET
+    @Path(TagRESTConstants.RESOURCES_BY_SPEC_RESOURCE)
+    @Produces({ "application/json", "application/xml" })
+    public List<RangerResource> getResourcesBySpec(@QueryParam(TagRESTConstants.COMPONENT_TYPE_PARAM) String componentType) throws Exception {
+
+        return null;
+    }
+
+    @PUT
+    @Path(TagRESTConstants.RESOURCE_SET_RESOURCE)
+    @Produces({ "application/json", "application/xml" })
+    public String setResource(RangerResource rangerResource, String componentType) {
+        return null;
+    }
+
+    @PUT
+    @Path(TagRESTConstants.RESOURCES_SET_RESOURCE)
+    @Produces({ "application/json", "application/xml" })
+    public Map<String, RangerPolicy.RangerPolicyResource> setResources(List<RangerResource> resources, String componentType) {
+        return null;
+    }
+
+    @PUT
+    @Path(TagRESTConstants.RESOURCE_UPDATE_RESOURCE)
+    @Produces({ "application/json", "application/xml" })
+    public String updateResourceTags(RangerResource resource, String componentType, List<RangerResource.RangerResourceTag> tagsToAdd,
+                                 List<RangerResource.RangerResourceTag> tagsToDelete) {
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/ca887985/security-admin/src/main/java/org/apache/ranger/rest/TagRESTConstants.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/TagRESTConstants.java b/security-admin/src/main/java/org/apache/ranger/rest/TagRESTConstants.java
index 27c9b19..5dcc133 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/TagRESTConstants.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/TagRESTConstants.java
@@ -22,8 +22,15 @@ package org.apache.ranger.rest;
 public class TagRESTConstants {
 	public static final String TAGDEF_NAME_AND_VERSION = "tag-def/v1";
 	static final String TAGS_RESOURCE = "tags";
+	static final String TAGNAMES_RESOURCE = "tag-names";
 	static final String TAG_RESOURCE = "tag";
 	static final String RESOURCES_RESOURCE = "resources";
+	static final String RESOURCES_BY_SPEC_RESOURCE = "resources-by-spec";
+	static final String RESOURCE_SET_RESOURCE = "set-resource";
+	static final String RESOURCES_SET_RESOURCE = "set-resources";
+	static final String RESOURCE_UPDATE_RESOURCE = "update-resource";
+
+	static final String LOOKUP_TAGS_RESOURCE = "lookup-tags";
 	static final String RESOURCES_IF_UPDATED_RESOURCE = "resources";
 	static final String RESOURCE_RESOURCE = "resource";
 	static final String ACTION_SUB_RESOURCE = "update";
@@ -34,6 +41,7 @@ public class TagRESTConstants {
 
 	public static final String TAG_SERVICE_NAME_PARAM = "tagservicename";
 	public static final String COMPONENT_TYPE_PARAM = "componenttype";
+	public static final String TAG_PATTERN_PARAM = "tagpattern";