This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 9887eb7e2 RANGER-4749: added TagREST APIs to retrieve by resource and
get paginated resources along with associated tags
9887eb7e2 is described below
commit 9887eb7e274511699874422202b5ef9720017b22
Author: Anand Nadar <[email protected]>
AuthorDate: Fri Mar 22 14:01:48 2024 -0700
RANGER-4749: added TagREST APIs to retrieve by resource and get paginated
resources along with associated tags
Signed-off-by: Madhan Neethiraj <[email protected]>
---
.../ranger/authorization/utils/JsonUtils.java | 11 ++
.../model/RangerServiceResourceWithTags.java | 68 ++++++++++++
.../apache/ranger/plugin/util/SearchFilter.java | 2 +
.../java/org/apache/ranger/biz/TagDBStore.java | 63 +++++++++++
.../org/apache/ranger/common/RangerSearchUtil.java | 98 ++++++++++++++++-
.../main/java/org/apache/ranger/rest/TagREST.java | 38 ++++++-
.../RangerServiceResourceWithTagsService.java | 119 +++++++++++++++++++++
.../RangerServiceResourceWithTagsServiceBase.java | 67 ++++++++++++
.../view/RangerServiceResourceWithTagsList.java | 62 +++++++++++
.../java/org/apache/ranger/biz/TestTagDBStore.java | 56 +++++++++-
.../java/org/apache/ranger/rest/TestTagREST.java | 51 ++++++---
11 files changed, 609 insertions(+), 26 deletions(-)
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 716a1a9ea..8113e4280
---
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.commons.lang.StringUtils;
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 @@ public class JsonUtils {
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 class JsonUtils {
}
}
+ 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 000000000..f3c24d623
--- /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 b0fad0aea..0da5f2aaf 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 class SearchFilter {
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 class SearchFilter {
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 a472fe131..ce5950584
--- 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 @@ package org.apache.ranger.biz;
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.XXTagChangeLog;
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.plugin.util.ServiceTags;
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;
@@ -89,6 +93,9 @@ public class TagDBStore extends AbstractTagStore {
@Autowired
RangerServiceResourceService rangerServiceResourceService;
+ @Autowired
+ RangerServiceResourceWithTagsService
rangerServiceResourceWithTagsService;
+
@Autowired
RangerTagResourceMapService rangerTagResourceMapService;
@@ -714,6 +721,10 @@ public class TagDBStore extends AbstractTagStore {
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 class TagDBStore extends AbstractTagStore {
}
}
}
+
+ 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 c816ad229..fcef33269 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 @@ public class RangerSearchUtil extends SearchUtil {
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));
@@ -358,6 +355,45 @@ public class RangerSearchUtil extends SearchUtil {
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 (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())
@@ -477,6 +513,22 @@ public class RangerSearchUtil extends SearchUtil {
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 class RangerSearchUtil extends SearchUtil {
}
}
+ 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 09d771565..882bf4d86 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.RangerTagResourceMap;
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.RangerRESTUtils;
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.WebApplicationException;
import javax.ws.rs.core.Context;
import java.util.List;
+import java.util.Map;
@Path(TagRESTConstants.TAGDEF_NAME_AND_VERSION)
@Component
@@ -118,6 +122,9 @@ public class TagREST {
@Autowired
RangerServiceResourceService rangerServiceResourceService;
+ @Autowired
+ RangerServiceResourceWithTagsService rangerServiceResourceWithTagsService;
+
@Autowired
RangerTagResourceMapService rangerTagResourceMapService;
@@ -1011,6 +1018,27 @@ public class TagREST {
return ret;
}
+ @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" })
@@ -1041,18 +1069,18 @@ public class TagREST {
@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 000000000..2b3acd17a
--- /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 000000000..57cd20ab3
--- /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 000000000..a40953eef
--- /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 d6ebbc54d..acc9cab3c
--- 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.RangerPolicyConditionDef;
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.store.PList;
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;
@@ -87,6 +90,9 @@ public class TestTagDBStore {
@Mock
RangerServiceResourceService rangerServiceResourceService;
+ @Mock
+ RangerServiceResourceWithTagsService rangerServiceResourceWithTagsService;
+
@Mock
RangerTagResourceMapService rangerTagResourceMapService;
@@ -1185,4 +1191,52 @@ public class TestTagDBStore {
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 98d87bc0a..7165a304d
--- 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.XXService;
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.RangerPluginCapability;
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 @@ public class TestTagREST {
@Mock
RangerServiceResourceService resourceService;
+ @Mock
+ RangerServiceResourceWithTagsService serviceResourceWithTagsService;
+
@Rule
public ExpectedException thrown = ExpectedException.none();
@@ -1134,34 +1140,43 @@ public class TestTagREST {
}
@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 class TestTagREST {
public void test38createTagResourceMap() {
RangerTagResourceMap oldTagResourceMap = null;
RangerTagResourceMap newTagResourceMap = new
RangerTagResourceMap();
+
newTagResourceMap.setTagId(id);
newTagResourceMap.setResourceId(id);
@@ -1187,6 +1203,7 @@ public class TestTagREST {
}
RangerTagResourceMap rangerTagResourceMap =
tagREST.createTagResourceMap(tagGuid, resourceGuid, false);
+
Assert.assertEquals(rangerTagResourceMap.getTagId(),
newTagResourceMap.getTagId());
Assert.assertEquals(rangerTagResourceMap.getResourceId(),
newTagResourceMap.getResourceId());
@@ -1194,10 +1211,12 @@ public class TestTagREST {
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 @@ public class TestTagREST {
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);