RANGER-4749: added TagREST APIs to retrieve by resource and get paginated resources along with associated tags
Signed-off-by: Madhan Neethiraj <madhan@apache.org>
diff --git a/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java b/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java
old mode 100644
new mode 100755
index 716a1a9..8113e42
--- a/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java
+++ b/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java
@@ -26,6 +26,7 @@
import org.apache.ranger.plugin.model.AuditFilter;
import org.apache.ranger.plugin.model.RangerGds.RangerTagDataMaskInfo;
import org.apache.ranger.plugin.model.RangerPrincipal;
+import org.apache.ranger.plugin.model.RangerTag;
import org.apache.ranger.plugin.model.RangerValidityRecurrence;
import org.apache.ranger.plugin.model.RangerValiditySchedule;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
@@ -51,6 +52,7 @@
private static final Type TYPE_LIST_RANGER_TAG_MASK_INFO = new TypeToken<List<RangerTagDataMaskInfo>>() {}.getType();
private static final Type TYPE_MAP_RANGER_MASK_INFO = new TypeToken<Map<String, RangerPolicyItemDataMaskInfo>>() {}.getType();
private static final Type TYPE_MAP_RANGER_POLICY_RESOURCE = new TypeToken<Map<String, RangerPolicyResource>>() {}.getType();
+ private static final Type TYPE_LIST_RANGER_TAG = new TypeToken<List<RangerTag>>() {}.getType();
private static final ThreadLocal<Gson> gson = new ThreadLocal<Gson>() {
@Override
@@ -189,6 +191,15 @@
}
}
+ public static List<RangerTag> jsonToRangerTagList(String jsonStr) {
+ try {
+ return gson.get().fromJson(jsonStr, TYPE_LIST_RANGER_TAG);
+ } catch (Exception e) {
+ LOG.error("Cannot get List<RangerTag> from " + jsonStr, e);
+ return null;
+ }
+ }
+
public static Map<String, RangerPolicyItemDataMaskInfo> jsonToMapMaskInfo(String jsonStr) {
try {
return gson.get().fromJson(jsonStr, TYPE_MAP_RANGER_MASK_INFO);
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceResourceWithTags.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceResourceWithTags.java
new file mode 100755
index 0000000..f3c24d6
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceResourceWithTags.java
@@ -0,0 +1,68 @@
+/*
+ * 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.model;
+
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY)
+@JsonIgnoreProperties(ignoreUnknown=true)
+public class RangerServiceResourceWithTags extends RangerServiceResource implements java.io.Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private List<RangerTag> associatedTags;
+
+ public List<RangerTag> getAssociatedTags() {
+ return associatedTags;
+ }
+
+ public void setAssociatedTags(List<RangerTag> associatedTags) {
+ this.associatedTags = associatedTags;
+ }
+
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerServiceResourceWithTags={ ");
+
+ super.toString(sb);
+
+ sb.append("associatedTags=[");
+ if (associatedTags != null) {
+ String prefix = "";
+
+ for (RangerTag associatedTag : associatedTags) {
+ sb.append(prefix);
+
+ associatedTag.toString(sb);
+
+ prefix = ", ";
+ }
+ }
+ sb.append("] ");
+
+ sb.append(" }");
+
+ return sb;
+ }
+}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
index b0fad0a..0da5f2a 100755
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
@@ -76,6 +76,7 @@
public static final String TAG_DEF_ID = "tagDefId"; // search
public static final String TAG_DEF_GUID = "tagDefGuid"; // search
+ public static final String TAG_NAMES = "tagNames"; // search
public static final String TAG_TYPE = "tagType"; // search
public static final String TAG_TYPE_PARTIAL = "tagTypePartial"; // search
public static final String TAG_SOURCE = "tagSource"; // search
@@ -88,6 +89,7 @@
public static final String TAG_RESOURCE_GUID = "resourceGuid"; // search
public static final String TAG_RESOURCE_SERVICE_NAME = "resourceServiceName"; // search
public static final String TAG_RESOURCE_SIGNATURE = "resourceSignature"; // search
+ public static final String TAG_RESOURCE_ELEMENTS = "resourceElements"; // search
public static final String TAG_MAP_ID = "tagResourceMapId"; // search
public static final String TAG_MAP_GUID = "tagResourceMapGuid"; // search
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
old mode 100644
new mode 100755
index a472fe1..ce59505
--- a/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
@@ -21,6 +21,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -45,6 +46,7 @@
import org.apache.ranger.entity.XXTagDef;
import org.apache.ranger.entity.XXTagResourceMap;
import org.apache.ranger.plugin.model.*;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.validation.RangerValidityScheduleValidator;
import org.apache.ranger.plugin.model.validation.ValidationFailureDetails;
import org.apache.ranger.plugin.store.AbstractTagStore;
@@ -59,7 +61,9 @@
import org.apache.ranger.service.RangerTagDefService;
import org.apache.ranger.service.RangerTagResourceMapService;
import org.apache.ranger.service.RangerTagService;
+import org.apache.ranger.view.RangerServiceResourceWithTagsList;
import org.apache.ranger.service.RangerServiceResourceService;
+import org.apache.ranger.service.RangerServiceResourceWithTagsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -90,6 +94,9 @@
RangerServiceResourceService rangerServiceResourceService;
@Autowired
+ RangerServiceResourceWithTagsService rangerServiceResourceWithTagsService;
+
+ @Autowired
RangerTagResourceMapService rangerTagResourceMapService;
@Autowired
@@ -714,6 +721,10 @@
return ret;
}
+ public RangerServiceResourceWithTagsList getPaginatedServiceResourcesWithTags(SearchFilter filter) throws Exception {
+ return rangerServiceResourceWithTagsService.searchServiceResourcesWithTags(filter);
+ }
+
@Override
public RangerTagResourceMap createTagResourceMap(RangerTagResourceMap tagResourceMap) throws Exception {
@@ -1386,4 +1397,56 @@
}
}
}
+
+ public RangerServiceResource getRangerServiceResource(String serviceName, Map<String, String[]> resourceMap) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> TagDBStore.getRangerServiceResource(): serviceName={" + serviceName + "}");
+ }
+
+ Map<String, RangerPolicyResource> resourceElements = new HashMap<>();
+
+ for (Map.Entry<String, String[]> entry : resourceMap.entrySet()) {
+ String[] parts = entry.getKey().split("\\.");
+ String[] valueArray = entry.getValue();
+
+ if (parts.length < 1 || valueArray == null) {
+ continue;
+ }
+
+ String key = parts[0];
+
+ RangerPolicyResource policyResource = resourceElements.get(key);
+
+ if (policyResource == null) {
+ policyResource = new RangerPolicyResource();
+
+ resourceElements.put(key, policyResource);
+ }
+
+ if (parts.length == 1) {
+ List<String> valueList = new ArrayList<>();
+
+ for (String str : valueArray) {
+ valueList.add(str.trim());
+ }
+ } else if (parts.length == 2 && valueArray[0] != null) {
+ String subKey = parts[1];
+ String value = valueArray[0];
+
+ if (subKey.equalsIgnoreCase("isExcludes")) {
+ policyResource.setIsExcludes(Boolean.parseBoolean(value.trim()));
+ } else if (subKey.equalsIgnoreCase("isRecursive")) {
+ policyResource.setIsRecursive(Boolean.parseBoolean(value.trim()));
+ }
+ }
+ }
+
+ RangerServiceResource ret = new RangerServiceResource(serviceName, resourceElements);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== TagDBStore.getRangerServiceResource(): (serviceName={" + serviceName + "} RangerServiceResource={" + ret + "})");
+ }
+
+ return ret;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java b/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
index c816ad2..fcef332 100755
--- a/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
@@ -19,11 +19,7 @@
package org.apache.ranger.common;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import javax.annotation.Nonnull;
import javax.persistence.EntityManager;
@@ -106,6 +102,7 @@
ret.setParam(SearchFilter.TAG_SERVICE_NAME_PARTIAL, request.getParameter(SearchFilter.TAG_SERVICE_NAME_PARTIAL));
ret.setParam(SearchFilter.TAG_RESOURCE_GUID, request.getParameter(SearchFilter.TAG_RESOURCE_GUID));
ret.setParam(SearchFilter.TAG_RESOURCE_SIGNATURE, request.getParameter(SearchFilter.TAG_RESOURCE_SIGNATURE));
+ ret.setParam(SearchFilter.TAG_RESOURCE_ELEMENTS, request.getParameter(SearchFilter.TAG_RESOURCE_ELEMENTS));
ret.setParam(SearchFilter.TAG_DEF_GUID, request.getParameter(SearchFilter.TAG_DEF_GUID));
ret.setParam(SearchFilter.TAG_DEF_ID, request.getParameter(SearchFilter.TAG_DEF_ID));
ret.setParam(SearchFilter.TAG_ID, request.getParameter(SearchFilter.TAG_ID));
@@ -368,6 +365,45 @@
whereClause.append(" and ").append(searchField.getCustomCondition());
}
}
+ } else if (isMultiValue && searchField.getDataType() == SearchField.DATA_TYPE.STR_LIST) {
+ List<String> strValueList = new ArrayList<>();
+
+ for (Object value : multiValue) {
+ strValueList.add(String.valueOf(value));
+ }
+
+ if (!strValueList.isEmpty()) {
+ if (searchField.getCustomCondition() == null) {
+ if (strValueList.size() <= minInListLength) {
+ whereClause.append(" and ");
+
+ if (strValueList.size() > 1) {
+ whereClause.append(" ( ");
+ }
+
+ for (int count = 0; count < strValueList.size(); count++) {
+ if (count > 0) {
+ whereClause.append(" or ");
+ }
+
+ whereClause.append(searchField.getFieldName()).append("= :")
+ .append(searchField.getClientFieldName()).append("_").append(count);
+ }
+
+ if (strValueList.size() > 1) {
+ whereClause.append(" ) ");
+ }
+
+ } else {
+ whereClause.append(" and ")
+ .append(searchField.getFieldName())
+ .append(" in ")
+ .append(" (:").append(searchField.getClientFieldName()).append(")");
+ }
+ } else {
+ whereClause.append(" and ").append(searchField.getCustomCondition());
+ }
+ }
} else if (searchField.getDataType() == SearchField.DATA_TYPE.INTEGER) {
Integer paramVal = restErrorUtil.parseInt(searchCriteria.getParam(searchField.getClientFieldName()),
"Invalid value for " + searchField.getClientFieldName(),
@@ -477,6 +513,22 @@
query.setParameter(searchField.getClientFieldName(), intValueList);
}
}
+ } else if (isMultiValue && searchField.getDataType() == SearchField.DATA_TYPE.STR_LIST) {
+ List<String> strValueList = new ArrayList<>();
+
+ for (Object value : multiValue) {
+ strValueList.add(String.valueOf(value));
+ }
+
+ if (!strValueList.isEmpty()) {
+ if (strValueList.size() <= minInListLength) {
+ for (int idx = 0; idx < strValueList.size(); idx++) {
+ query.setParameter(searchField.getClientFieldName() + "_" + idx, strValueList.get(idx));
+ }
+ } else {
+ query.setParameter(searchField.getClientFieldName(), strValueList);
+ }
+ }
} else if (searchField.getDataType() == SearchField.DATA_TYPE.INTEGER) {
Integer paramVal = restErrorUtil.parseInt(searchCriteria.getParam(searchField.getClientFieldName()),
"Invalid value for " + searchField.getClientFieldName(),
@@ -599,6 +651,42 @@
}
}
+ public void extractStringList(HttpServletRequest request, SearchFilter searchFilter, String paramName,
+ String userFriendlyParamName, String listName, String[] validValues, String regEx) {
+ String[] values = getParamMultiValues(request, paramName);
+
+ if (values != null) {
+ List<String> stringList = new ArrayList<>(values.length);
+
+ for (String value : values) {
+ if (!stringUtil.isEmpty(regEx)) {
+ restErrorUtil.validateString(value, regEx, "Invalid value for " + userFriendlyParamName, MessageEnums.INVALID_INPUT_DATA, null, paramName);
+ }
+
+ stringList.add(value);
+ }
+
+ searchFilter.setMultiValueParam(paramName, stringList.toArray());
+ }
+ }
+
+ public Map<String, String[]> getMultiValueParamsWithPrefix(HttpServletRequest request, String prefix, boolean stripPrefix) {
+ Map<String, String[]> ret = new HashMap<String, String[]>();
+ for (Map.Entry<String, String[]> e : request.getParameterMap().entrySet()) {
+ String name = e.getKey();
+ String[] values = e.getValue();
+
+ if (!StringUtils.isEmpty(name) && !ArrayUtils.isEmpty(values)
+ && name.startsWith(prefix)) {
+ if(stripPrefix) {
+ name = name.substring(prefix.length());
+ }
+ ret.put(name, values);
+ }
+ }
+ return ret;
+ }
+
/**
* @param request
* @param paramName
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 09d7715..882bf4d 100755
--- a/security-admin/src/main/java/org/apache/ranger/rest/TagREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/TagREST.java
@@ -40,6 +40,7 @@
import org.apache.ranger.plugin.model.RangerTagDef;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.store.PList;
+import org.apache.ranger.plugin.store.RangerServiceResourceSignature;
import org.apache.ranger.plugin.store.TagStore;
import org.apache.ranger.plugin.store.TagValidator;
import org.apache.ranger.plugin.util.RangerPerfTracer;
@@ -47,9 +48,11 @@
import org.apache.ranger.plugin.util.SearchFilter;
import org.apache.ranger.plugin.util.ServiceTags;
import org.apache.ranger.service.RangerServiceResourceService;
+import org.apache.ranger.service.RangerServiceResourceWithTagsService;
import org.apache.ranger.service.RangerTagDefService;
import org.apache.ranger.service.RangerTagResourceMapService;
import org.apache.ranger.service.RangerTagService;
+import org.apache.ranger.view.RangerServiceResourceWithTagsList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -75,6 +78,7 @@
import javax.ws.rs.core.Context;
import java.util.List;
+import java.util.Map;
@Path(TagRESTConstants.TAGDEF_NAME_AND_VERSION)
@Component
@@ -119,6 +123,9 @@
RangerServiceResourceService rangerServiceResourceService;
@Autowired
+ RangerServiceResourceWithTagsService rangerServiceResourceWithTagsService;
+
+ @Autowired
RangerTagResourceMapService rangerTagResourceMapService;
public TagREST() {
@@ -1012,6 +1019,27 @@
}
@GET
+ @Path(TagRESTConstants.RESOURCE_RESOURCE + "service/{serviceName}/resource")
+ @Produces({ "application/json" })
+ @PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
+ public RangerServiceResource getServiceResourceByResource(@PathParam("serviceName") String serviceName, @Context HttpServletRequest request) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> TagREST.getServiceResourceByResource(" + serviceName + ")");
+ }
+
+ Map<String, String[]> resourceMap = searchUtil.getMultiValueParamsWithPrefix(request, SearchFilter.RESOURCE_PREFIX, true);
+ RangerServiceResource serviceResource = tagStore.getRangerServiceResource(serviceName, resourceMap);
+
+ serviceResource = getServiceResourceByServiceAndResourceSignature(serviceName, new RangerServiceResourceSignature(serviceResource).getSignature());
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== TagREST.getServiceResourceByResource(serviceName={" + serviceName + "} RangerServiceResource={" + serviceResource + "})");
+ }
+
+ return serviceResource;
+ }
+
+ @GET
@Path(TagRESTConstants.RESOURCES_RESOURCE)
@Produces({ "application/json" })
@PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
@@ -1041,18 +1069,18 @@
@Path(TagRESTConstants.RESOURCES_RESOURCE_PAGINATED)
@Produces({ "application/json" })
@PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
- public PList<RangerServiceResource> getServiceResources(@Context HttpServletRequest request) {
+ public RangerServiceResourceWithTagsList getServiceResourcesWithTags(@Context HttpServletRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> TagREST.getServiceResources()");
}
- final PList<RangerServiceResource> ret;
+ RangerServiceResourceWithTagsList ret;
try {
- SearchFilter filter = searchUtil.getSearchFilter(request, rangerServiceResourceService.sortFields);
+ SearchFilter filter = searchUtil.getSearchFilter(request, rangerServiceResourceWithTagsService.sortFields);
searchUtil.extractIntList(request, filter, SearchFilter.TAG_RESOURCE_IDS, "Tag resource list");
-
- ret = tagStore.getPaginatedServiceResources(filter);
+ searchUtil.extractStringList(request, filter, SearchFilter.TAG_NAMES, "Tag type List", "tagTypes", null, null);
+ ret = tagStore.getPaginatedServiceResourcesWithTags(filter);
} catch (Exception excp) {
LOG.error("getServiceResources() failed", excp);
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceResourceWithTagsService.java b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceResourceWithTagsService.java
new file mode 100755
index 0000000..2b3acd1
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceResourceWithTagsService.java
@@ -0,0 +1,119 @@
+/*
+ * 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.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.biz.RangerTagDBRetriever;
+import org.apache.ranger.common.SearchField;
+import org.apache.ranger.common.SortField;
+import org.apache.ranger.common.SearchField.DATA_TYPE;
+import org.apache.ranger.common.SearchField.SEARCH_TYPE;
+import org.apache.ranger.entity.XXServiceResource;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceResourceWithTags;
+import org.apache.ranger.plugin.util.SearchFilter;
+import org.apache.ranger.view.RangerServiceResourceWithTagsList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RangerServiceResourceWithTagsService extends RangerServiceResourceWithTagsServiceBase<XXServiceResource, RangerServiceResourceWithTags> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RangerServiceResourceWithTagsService.class);
+
+ public RangerServiceResourceWithTagsService() {
+ searchFields.add(new SearchField(SearchFilter.TAG_RESOURCE_ID, "obj.id", DATA_TYPE.INTEGER, SEARCH_TYPE.FULL));
+ searchFields.add(new SearchField(SearchFilter.TAG_SERVICE_ID, "obj.serviceId", DATA_TYPE.INTEGER, SEARCH_TYPE.FULL));
+ searchFields.add(new SearchField(SearchFilter.TAG_SERVICE_NAME, "service.name", DATA_TYPE.STRING, SEARCH_TYPE.FULL, "XXService service", "obj.serviceId = service.id"));
+ searchFields.add(new SearchField(SearchFilter.TAG_SERVICE_NAME_PARTIAL, "service.name", DATA_TYPE.STRING, SEARCH_TYPE.PARTIAL, "XXService service", "obj.serviceId = service.id"));
+ searchFields.add(new SearchField(SearchFilter.TAG_RESOURCE_GUID, "obj.guid", DATA_TYPE.STRING, SEARCH_TYPE.FULL));
+ searchFields.add(new SearchField(SearchFilter.TAG_RESOURCE_SIGNATURE, "obj.resourceSignature", DATA_TYPE.STRING, SEARCH_TYPE.FULL));
+ searchFields.add(new SearchField(SearchFilter.TAG_RESOURCE_IDS, "obj.id", DATA_TYPE.INT_LIST, SEARCH_TYPE.FULL));
+ searchFields.add(new SearchField(SearchFilter.TAG_RESOURCE_ELEMENTS, "obj.serviceResourceElements", DATA_TYPE.STRING, SEARCH_TYPE.PARTIAL));
+ searchFields.add(new SearchField(SearchFilter.TAG_NAMES, "tagDef.name", DATA_TYPE.STR_LIST, SEARCH_TYPE.FULL, "XXTagResourceMap map, XXTag tag, XXTagDef tagDef", "obj.id = map.resourceId and map.tagId = tag.id and tag.type = tagDef.id"));
+
+ sortFields.add(new SortField(SearchFilter.TAG_RESOURCE_ID, "obj.id", true, SortField.SORT_ORDER.ASC));
+ sortFields.add(new SortField(SearchFilter.TAG_SERVICE_ID, "obj.serviceId"));
+ sortFields.add(new SortField(SearchFilter.CREATE_TIME, "obj.createTime"));
+ sortFields.add(new SortField(SearchFilter.UPDATE_TIME, "obj.updateTime"));
+ }
+
+ @Override
+ protected XXServiceResource mapViewToEntityBean(RangerServiceResourceWithTags viewBean, XXServiceResource t, int OPERATION_CONTEXT) {
+ return null;
+ }
+
+ @Override
+ protected void validateForCreate(RangerServiceResourceWithTags vObj) {
+ }
+
+ @Override
+ protected void validateForUpdate(RangerServiceResourceWithTags vObj, XXServiceResource entityObj) {
+ }
+
+ public RangerServiceResourceWithTags getPopulatedViewObject(XXServiceResource xObj) {
+ return this.populateViewBean(xObj);
+ }
+
+ public RangerServiceResourceWithTagsList searchServiceResourcesWithTags(SearchFilter filter) {
+ LOG.debug("==> searchServiceResourcesWithTags({})", filter);
+
+ RangerServiceResourceWithTagsList ret = new RangerServiceResourceWithTagsList();
+ List<XXServiceResource> xObjList = super.searchResources(filter, searchFields, sortFields, ret);
+ List<RangerServiceResourceWithTags> resourceList = new ArrayList<>();
+
+ if (xObjList != null) {
+ for (XXServiceResource resource:xObjList) {
+ resourceList.add(getPopulatedViewObject(resource));
+ }
+ }
+
+ ret.setResourceList(resourceList);
+
+ LOG.debug("<== searchServiceResourcesWithTags({}): ret={}", filter, ret);
+
+ return ret;
+ }
+
+ @Override
+ protected RangerServiceResourceWithTags mapEntityToViewBean(RangerServiceResourceWithTags serviceResourceWithTags, XXServiceResource xxServiceResource) {
+ RangerServiceResourceWithTags ret = super.mapEntityToViewBean(serviceResourceWithTags, xxServiceResource);
+
+ if (StringUtils.isNotEmpty(xxServiceResource.getServiceResourceElements())) {
+ Map<String, RangerPolicyResource> serviceResourceElements = RangerTagDBRetriever.gsonBuilder.fromJson(xxServiceResource.getServiceResourceElements(), RangerServiceResourceService.subsumedDataType);
+
+ if (MapUtils.isNotEmpty(serviceResourceElements)) {
+ ret.setResourceElements(serviceResourceElements);
+ } else {
+ LOG.info("Empty serviceResourceElement in [" + ret + "]!!");
+ }
+ } else {
+ LOG.info("Empty string representing serviceResourceElements in [" + xxServiceResource + "]!!");
+ }
+
+ return ret;
+ }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceResourceWithTagsServiceBase.java b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceResourceWithTagsServiceBase.java
new file mode 100755
index 0000000..57cd20a
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceResourceWithTagsServiceBase.java
@@ -0,0 +1,67 @@
+/*
+ * 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.service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.ranger.authorization.utils.JsonUtils;
+import org.apache.ranger.entity.XXService;
+import org.apache.ranger.entity.XXServiceResource;
+import org.apache.ranger.plugin.model.RangerServiceResourceWithTags;
+import org.apache.ranger.plugin.store.PList;
+import org.apache.ranger.plugin.util.SearchFilter;
+
+public abstract class RangerServiceResourceWithTagsServiceBase<T extends XXServiceResource, V extends RangerServiceResourceWithTags> extends RangerBaseModelService<T, V> {
+
+ @Override
+ protected V mapEntityToViewBean(V vObj, T xObj) {
+ XXService xService = daoMgr.getXXService().getById(xObj.getServiceId());
+
+ vObj.setGuid(xObj.getGuid());
+ vObj.setVersion(xObj.getVersion());
+ vObj.setIsEnabled(xObj.getIsEnabled());
+ vObj.setServiceName(xService.getName());
+ vObj.setAssociatedTags(JsonUtils.jsonToRangerTagList(xObj.getTags()));
+
+ return vObj;
+ }
+
+ public PList<V> searchServiceResources(SearchFilter searchFilter) {
+ PList<V> retList = new PList<V>();
+ List<V> resourceList = new ArrayList<V>();
+ List<T> xResourceList = searchRangerObjects(searchFilter, searchFields, sortFields, retList);
+
+ for (T xResource : xResourceList) {
+ V taggedRes = populateViewBean(xResource);
+
+ resourceList.add(taggedRes);
+ }
+
+ retList.setList(resourceList);
+ retList.setResultSize(resourceList.size());
+ retList.setPageSize(searchFilter.getMaxRows());
+ retList.setStartIndex(searchFilter.getStartIndex());
+ retList.setSortType(searchFilter.getSortType());
+ retList.setSortBy(searchFilter.getSortBy());
+
+ return retList;
+ }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/view/RangerServiceResourceWithTagsList.java b/security-admin/src/main/java/org/apache/ranger/view/RangerServiceResourceWithTagsList.java
new file mode 100644
index 0000000..a40953e
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/view/RangerServiceResourceWithTagsList.java
@@ -0,0 +1,62 @@
+/*
+ * 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.view;
+
+import java.util.List;
+
+import org.apache.ranger.common.view.VList;
+import org.apache.ranger.plugin.model.RangerServiceResourceWithTags;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+@JsonAutoDetect(getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, fieldVisibility = Visibility.ANY)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+public class RangerServiceResourceWithTagsList extends VList {
+ private static final long serialVersionUID = 1L;
+
+ List<RangerServiceResourceWithTags> resourceList;
+
+ public RangerServiceResourceWithTagsList() {
+ super();
+ }
+
+ public RangerServiceResourceWithTagsList(List<RangerServiceResourceWithTags> objList) {
+ super(objList);
+
+ this.resourceList = objList;
+ }
+
+ public List<RangerServiceResourceWithTags> getResourceList() {
+ return resourceList;
+ }
+
+ public void setResourceList(List<RangerServiceResourceWithTags> resourceList) {
+ this.resourceList = resourceList;
+ }
+
+ @Override
+ public int getListSize() {
+ return (resourceList != null) ? resourceList.size() : 0;
+ }
+
+ @Override
+ public List<RangerServiceResourceWithTags> getList() {
+ return resourceList;
+ }
+}
diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestTagDBStore.java b/security-admin/src/test/java/org/apache/ranger/biz/TestTagDBStore.java
old mode 100644
new mode 100755
index d6ebbc5..acc9cab
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestTagDBStore.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestTagDBStore.java
@@ -46,6 +46,7 @@
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef;
import org.apache.ranger.plugin.model.RangerServiceResource;
+import org.apache.ranger.plugin.model.RangerServiceResourceWithTags;
import org.apache.ranger.plugin.model.RangerTag;
import org.apache.ranger.plugin.model.RangerTagDef;
import org.apache.ranger.plugin.model.RangerTagResourceMap;
@@ -53,9 +54,11 @@
import org.apache.ranger.plugin.util.SearchFilter;
import org.apache.ranger.plugin.util.ServiceTags;
import org.apache.ranger.service.RangerServiceResourceService;
+import org.apache.ranger.service.RangerServiceResourceWithTagsService;
import org.apache.ranger.service.RangerTagDefService;
import org.apache.ranger.service.RangerTagResourceMapService;
import org.apache.ranger.service.RangerTagService;
+import org.apache.ranger.view.RangerServiceResourceWithTagsList;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Rule;
@@ -88,6 +91,9 @@
RangerServiceResourceService rangerServiceResourceService;
@Mock
+ RangerServiceResourceWithTagsService rangerServiceResourceWithTagsService;
+
+ @Mock
RangerTagResourceMapService rangerTagResourceMapService;
@Mock
@@ -1185,4 +1191,52 @@
return xxTagResourceMap;
}
-}
+
+ @Test
+ public void tesGetPaginatedServiceResourcesWithTags() throws Exception {
+ RangerServiceResourceWithTagsList rangerServiceResourceViewList = createRangerServiceResourceWithTagsViewList();
+ SearchFilter searchFilter = new SearchFilter();
+
+ Mockito.when(rangerServiceResourceWithTagsService.searchServiceResourcesWithTags(searchFilter)).thenReturn(rangerServiceResourceViewList);
+
+ RangerServiceResourceWithTagsList returnedRangerServiceResourcePList = tagDBStore.getPaginatedServiceResourcesWithTags(searchFilter);
+
+ Assert.assertNotNull(returnedRangerServiceResourcePList);
+ Assert.assertEquals(returnedRangerServiceResourcePList.getList().size(), 1);
+
+ RangerServiceResourceWithTags returnedRangerServiceResource = returnedRangerServiceResourcePList.getResourceList().get(0);
+
+ Assert.assertEquals(returnedRangerServiceResource.getId(), id);
+ Assert.assertEquals(returnedRangerServiceResource.getGuid(), gId);
+ Assert.assertNotNull(returnedRangerServiceResource.getAssociatedTags());
+ Assert.assertEquals(rangerServiceResourceViewList.getResourceList().get(0).getAssociatedTags().size(), returnedRangerServiceResource.getAssociatedTags().size());
+ }
+
+ private RangerServiceResourceWithTagsList createRangerServiceResourceWithTagsViewList() {
+ RangerServiceResourceWithTagsList rangerServiceResourceViewList = new RangerServiceResourceWithTagsList();
+ List<RangerServiceResourceWithTags> rangerServiceResourceList = new ArrayList<>();
+ RangerServiceResourceWithTags rangerServiceResource = new RangerServiceResourceWithTags();
+ List<RangerTag> associatedTags = new ArrayList<>();
+
+ associatedTags.add(createRangerTag());
+
+ rangerServiceResource.setId(id);
+ rangerServiceResource.setCreateTime(new Date());
+ rangerServiceResource.setGuid(gId);
+ rangerServiceResource.setVersion(lastKnownVersion);
+ rangerServiceResource.setServiceName(serviceName);
+ rangerServiceResource.setAssociatedTags(associatedTags);
+
+ rangerServiceResourceList.add(rangerServiceResource);
+
+ rangerServiceResourceViewList.setResourceList(rangerServiceResourceList);
+ rangerServiceResourceViewList.setPageSize(0);
+ rangerServiceResourceViewList.setResultSize(1);
+ rangerServiceResourceViewList.setSortBy("asc");
+ rangerServiceResourceViewList.setSortType("1");
+ rangerServiceResourceViewList.setStartIndex(0);
+ rangerServiceResourceViewList.setTotalCount(1);
+
+ return rangerServiceResourceViewList;
+ }
+}
\ No newline at end of file
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
old mode 100644
new mode 100755
index 98d87bc..7165a30
--- 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.entity.XXServiceDef;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceResource;
+import org.apache.ranger.plugin.model.RangerServiceResourceWithTags;
import org.apache.ranger.plugin.model.RangerTag;
import org.apache.ranger.plugin.model.RangerTagDef;
import org.apache.ranger.plugin.model.RangerTagResourceMap;
@@ -46,8 +47,10 @@
import org.apache.ranger.plugin.util.SearchFilter;
import org.apache.ranger.plugin.util.ServiceTags;
import org.apache.ranger.service.RangerServiceResourceService;
+import org.apache.ranger.service.RangerServiceResourceWithTagsService;
import org.apache.ranger.service.RangerTagDefService;
import org.apache.ranger.service.RangerTagService;
+import org.apache.ranger.view.RangerServiceResourceWithTagsList;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Rule;
@@ -110,6 +113,9 @@
@Mock
RangerServiceResourceService resourceService;
+ @Mock
+ RangerServiceResourceWithTagsService serviceResourceWithTagsService;
+
@Rule
public ExpectedException thrown = ExpectedException.none();
@@ -1134,34 +1140,43 @@
}
@Test
- public void test64getServiceResources() {
- HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
- SearchFilter searchFilter = new SearchFilter();
- PList<RangerServiceResource> ret = new PList<RangerServiceResource>();
- List<RangerServiceResource> serviceResourceList = new ArrayList<RangerServiceResource>();
- RangerServiceResource rangerServiceResource = new RangerServiceResource();
+ public void test64getServiceResourcesWithTags() {
+ HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+ SearchFilter searchFilter = new SearchFilter();
+ RangerServiceResourceWithTagsList ret = new RangerServiceResourceWithTagsList();
+ List<RangerServiceResourceWithTags> serviceResourceList = new ArrayList<RangerServiceResourceWithTags>();
+ RangerServiceResourceWithTags rangerServiceResource = new RangerServiceResourceWithTags();
+ List<RangerTag> associatedTags = new ArrayList<RangerTag>();
+ RangerTag rangerTag = new RangerTag();
+
+ rangerTag.setId(id);
+ rangerTag.setGuid(gId);
+ rangerTag.setType(name);
+ associatedTags.add(rangerTag);
rangerServiceResource.setId(id);
rangerServiceResource.setServiceName(serviceName);
+ rangerServiceResource.setAssociatedTags(associatedTags);
serviceResourceList.add(rangerServiceResource);
- ret.setList(serviceResourceList);
+ ret.setResourceList(serviceResourceList);
- Mockito.when(searchUtil.getSearchFilter(Mockito.any(HttpServletRequest.class), eq(resourceService.sortFields)))
- .thenReturn(searchFilter);
+ Mockito.when(searchUtil.getSearchFilter(Mockito.any(HttpServletRequest.class), eq(resourceService.sortFields))).thenReturn(searchFilter);
try {
- Mockito.when(tagStore.getPaginatedServiceResources((SearchFilter) Mockito.any())).thenReturn(ret);
+ Mockito.when(tagStore.getPaginatedServiceResourcesWithTags(Mockito.any())).thenReturn(ret);
} catch (Exception e) {
}
- PList<RangerServiceResource> result = tagREST.getServiceResources(request);
+ RangerServiceResourceWithTagsList result = tagREST.getServiceResourcesWithTags(request);
- Assert.assertNotNull(result.getList().get(0).getId());
- Assert.assertEquals(result.getList().get(0).getId(), serviceResourceList.get(0).getId());
- Assert.assertEquals(result.getList().get(0).getServiceName(), serviceResourceList.get(0).getServiceName());
+ Assert.assertNotNull(result.getResourceList().get(0).getId());
+ Assert.assertEquals(result.getResourceList().get(0).getId(), serviceResourceList.get(0).getId());
+ Assert.assertEquals(result.getResourceList().get(0).getServiceName(), serviceResourceList.get(0).getServiceName());
+ Assert.assertEquals(result.getResourceList().get(0).getAssociatedTags().size(), 1);
+ Assert.assertEquals(result.getResourceList().get(0).getAssociatedTags().get(0).getType(), name);
try {
- Mockito.verify(tagStore).getPaginatedServiceResources((SearchFilter) Mockito.any());
+ Mockito.verify(tagStore).getPaginatedServiceResourcesWithTags((SearchFilter) Mockito.any());
} catch (Exception e) {
}
}
@@ -1170,6 +1185,7 @@
public void test38createTagResourceMap() {
RangerTagResourceMap oldTagResourceMap = null;
RangerTagResourceMap newTagResourceMap = new RangerTagResourceMap();
+
newTagResourceMap.setTagId(id);
newTagResourceMap.setResourceId(id);
@@ -1187,6 +1203,7 @@
}
RangerTagResourceMap rangerTagResourceMap = tagREST.createTagResourceMap(tagGuid, resourceGuid, false);
+
Assert.assertEquals(rangerTagResourceMap.getTagId(), newTagResourceMap.getTagId());
Assert.assertEquals(rangerTagResourceMap.getResourceId(), newTagResourceMap.getResourceId());
@@ -1194,10 +1211,12 @@
Mockito.verify(tagStore).getTagResourceMapForTagAndResourceGuid(tagGuid, resourceGuid);
} catch (Exception e) {
}
+
try {
Mockito.verify(validator).preCreateTagResourceMap(tagGuid, resourceGuid);
} catch (Exception e) {
}
+
try {
Mockito.verify(tagStore).createTagResourceMap(newTagResourceMap);
} catch (Exception e) {
@@ -1212,7 +1231,9 @@
Mockito.when(tagStore.getTagResourceMapForTagAndResourceGuid(tagGuid, resourceGuid)).thenReturn(oldTagResourceMap);
} catch (Exception e) {
}
+
Mockito.when(restErrorUtil.createRESTException(Mockito.anyInt(),Mockito.anyString(), Mockito.anyBoolean())).thenThrow(new WebApplicationException());
+
thrown.expect(WebApplicationException.class);
tagREST.createTagResourceMap(tagGuid, resourceGuid, false);