/*
 * 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.rest;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.Objects;

import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ranger.admin.client.datatype.RESTResponse;
import org.apache.ranger.authorization.hadoop.config.RangerAdminConfig;
import org.apache.ranger.authorization.utils.StringUtil;
import org.apache.ranger.biz.AssetMgr;
import org.apache.ranger.biz.RangerPolicyAdmin;
import org.apache.ranger.biz.RangerBizUtil;
import org.apache.ranger.biz.RoleDBStore;
import org.apache.ranger.biz.SecurityZoneDBStore;
import org.apache.ranger.biz.ServiceDBStore;
import org.apache.ranger.biz.ServiceMgr;
import org.apache.ranger.biz.TagDBStore;
import org.apache.ranger.biz.XUserMgr;
import org.apache.ranger.common.AppConstants;
import org.apache.ranger.common.ContextUtil;
import org.apache.ranger.common.GUIDUtil;
import org.apache.ranger.common.MessageEnums;
import org.apache.ranger.common.PropertiesUtil;
import org.apache.ranger.common.RESTErrorUtil;
import org.apache.ranger.common.RangerConstants;
import org.apache.ranger.common.RangerSearchUtil;
import org.apache.ranger.common.RangerValidatorFactory;
import org.apache.ranger.common.ServiceUtil;
import org.apache.ranger.common.UserSessionBase;
import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
import org.apache.ranger.db.RangerDaoManager;
import org.apache.ranger.entity.XXPolicyExportAudit;
import org.apache.ranger.entity.XXSecurityZone;
import org.apache.ranger.entity.XXSecurityZoneRefService;
import org.apache.ranger.entity.XXSecurityZoneRefTagService;
import org.apache.ranger.entity.XXService;
import org.apache.ranger.entity.XXServiceDef;
import org.apache.ranger.entity.XXTrxLog;
import org.apache.ranger.entity.XXRole;
import org.apache.ranger.plugin.model.RangerPluginInfo;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerPolicyDelta;
import org.apache.ranger.plugin.model.RangerSecurityZone;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.validation.RangerPolicyValidator;
import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
import org.apache.ranger.plugin.model.validation.RangerServiceValidator;
import org.apache.ranger.plugin.model.validation.RangerValidator.Action;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.biz.RangerPolicyAdminCache;
import org.apache.ranger.biz.RangerPolicyAdminCacheForEngineOptions;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
import org.apache.ranger.plugin.service.ResourceLookupContext;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.store.PList;
import org.apache.ranger.plugin.store.ServiceStore;
import org.apache.ranger.plugin.util.GrantRevokeRequest;
import org.apache.ranger.plugin.util.JsonUtilsV2;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.apache.ranger.plugin.util.SearchFilter;
import org.apache.ranger.plugin.util.ServicePolicies;
import org.apache.ranger.security.context.RangerAPIList;
import org.apache.ranger.security.context.RangerAdminOpContext;
import org.apache.ranger.security.context.RangerContextHolder;
import org.apache.ranger.security.web.filter.RangerCSRFPreventionFilter;
import org.apache.ranger.service.RangerPluginInfoService;
import org.apache.ranger.service.RangerPolicyLabelsService;
import org.apache.ranger.service.RangerPolicyService;
import org.apache.ranger.service.RangerServiceDefService;
import org.apache.ranger.service.RangerServiceService;
import org.apache.ranger.service.RangerTransactionService;
import org.apache.ranger.service.XUserService;
import org.apache.ranger.view.RangerExportPolicyList;
import org.apache.ranger.view.RangerPluginInfoList;
import org.apache.ranger.view.RangerPolicyList;
import org.apache.ranger.view.RangerServiceDefList;
import org.apache.ranger.view.RangerServiceList;
import org.apache.ranger.view.VXGroup;
import org.apache.ranger.view.VXResponse;
import org.apache.ranger.view.VXString;
import org.apache.ranger.view.VXUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.google.gson.JsonSyntaxException;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;


@Path("plugins")
@Component
@Scope("request")
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class ServiceREST {
	private static final Log LOG = LogFactory.getLog(ServiceREST.class);
	private static final Log PERF_LOG = RangerPerfTracer.getPerfLogger("rest.ServiceREST");

	final static public String PARAM_SERVICE_NAME     = "serviceName";
	final static public String PARAM_SERVICE_TYPE     = "serviceType";
	final static public String PARAM_POLICY_NAME      = "policyName";
	final static public String PARAM_ZONE_NAME        = "zoneName";
	final static public String PARAM_UPDATE_IF_EXISTS = "updateIfExists";
	final static public String PARAM_MERGE_IF_EXISTS  = "mergeIfExists";
	final static public String PARAM_DELETE_IF_EXISTS = "deleteIfExists";
	public static final String Allowed_User_List_For_Download = "policy.download.auth.users";
	public static final String Allowed_User_List_For_Grant_Revoke = "policy.grantrevoke.auth.users";

	public static final String isCSRF_ENABLED = "ranger.rest-csrf.enabled";
	public static final String BROWSER_USER_AGENT_PARAM = "ranger.rest-csrf.browser-useragents-regex";
	public static final String CUSTOM_METHODS_TO_IGNORE_PARAM = "ranger.rest-csrf.methods-to-ignore";
	public static final String CUSTOM_HEADER_PARAM = "ranger.rest-csrf.custom-header";
	
	@Autowired
	RESTErrorUtil restErrorUtil;

	@Autowired
	ServiceMgr serviceMgr;

	@Autowired
	XUserService xUserService;

	@Autowired
	AssetMgr assetMgr;

	@Autowired
	XUserMgr userMgr;

	@Autowired
	ServiceDBStore svcStore;

	@Autowired
	RoleDBStore roleDBStore;

	@Autowired
	SecurityZoneDBStore zoneStore;

	@Autowired
	ServiceUtil serviceUtil;

	@Autowired
	RangerPolicyService policyService;
	
	@Autowired
    RangerPolicyLabelsService policyLabelsService;

	@Autowired
	RangerServiceService svcService;
	
	@Autowired
	RangerServiceDefService serviceDefService;

	@Autowired
    RangerPluginInfoService pluginInfoService;

	@Autowired
	RangerSearchUtil searchUtil;
	
    @Autowired
    RangerBizUtil bizUtil;

	@Autowired
	GUIDUtil guidUtil;
	
	@Autowired
	RangerValidatorFactory validatorFactory;

	@Autowired
	RangerDaoManager daoManager;

	@Autowired
	TagDBStore tagStore;

	@Autowired
	RangerTransactionService transactionService;

	@Autowired
	RangerTransactionSynchronizationAdapter rangerTransactionSynchronizationAdapter;
	
	private RangerPolicyEngineOptions delegateAdminOptions;
	private RangerPolicyEngineOptions policySearchAdminOptions;
	private RangerPolicyEngineOptions defaultAdminOptions;
	private final RangerAdminConfig   config = RangerAdminConfig.getInstance();

	public ServiceREST() {
	}

	@PostConstruct
	public void initStore() {
		tagStore.setServiceStore(svcStore);
		delegateAdminOptions = getDelegatedAdminPolicyEngineOptions();
		policySearchAdminOptions = getPolicySearchRangerAdminPolicyEngineOptions();
		defaultAdminOptions = getDefaultRangerAdminPolicyEngineOptions();
	}

	@POST
	@Path("/definitions")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.CREATE_SERVICE_DEF + "\")")
	public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.createServiceDef(" + serviceDef + ")");
		}

		RangerServiceDef ret  = null;
		RangerPerfTracer perf = null;

		/**
		 * If display name is blank (EMPTY String or NULL), use name.
		 */
		if (StringUtils.isBlank(serviceDef.getDisplayName())) {
			serviceDef.setDisplayName(serviceDef.getName());
		}

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.createServiceDef(serviceDefName=" + serviceDef.getName() + ")");
			}
			RangerServiceDefValidator validator = validatorFactory.getServiceDefValidator(svcStore);
			validator.validate(serviceDef, Action.CREATE);

			bizUtil.hasAdminPermissions("Service-Def");
			bizUtil.hasKMSPermissions("Service-Def", serviceDef.getImplClass());
                        bizUtil.blockAuditorRoleUser();
			ret = svcStore.createServiceDef(serviceDef);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("createServiceDef(" + serviceDef + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.createServiceDef(" + serviceDef + "): " + ret);
		}

		return ret;
	}

	@PUT
	@Path("/definitions/{id}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.UPDATE_SERVICE_DEF + "\")")
	public RangerServiceDef updateServiceDef(RangerServiceDef serviceDef) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.updateServiceDef(serviceDefName=" + serviceDef.getName() + ")");
		}

		RangerServiceDef ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.updateServiceDef(" + serviceDef.getName() + ")");
			}

			/**
			 * If display name is blank (EMPTY String or NULL), use previous display name.
			 */
			if (StringUtils.isBlank(serviceDef.getDisplayName())) {
				RangerServiceDef rangerServiceDef = svcStore.getServiceDef(serviceDef.getId());

				// If previous display name is blank (EMPTY String or NULL), user name.
				if (Objects.isNull(rangerServiceDef) || StringUtils.isBlank(rangerServiceDef.getDisplayName())) {
					serviceDef.setDisplayName(serviceDef.getName());
				} else {
					serviceDef.setDisplayName(rangerServiceDef.getDisplayName());
				}
			}

			RangerServiceDefValidator validator = validatorFactory.getServiceDefValidator(svcStore);
			validator.validate(serviceDef, Action.UPDATE);

			bizUtil.hasAdminPermissions("Service-Def");
			bizUtil.hasKMSPermissions("Service-Def", serviceDef.getImplClass());
                        bizUtil.blockAuditorRoleUser();
			ret = svcStore.updateServiceDef(serviceDef);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("updateServiceDef(" + serviceDef + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.updateServiceDef(" + serviceDef + "): " + ret);
		}

		return ret;
	}

	@DELETE
	@Path("/definitions/{id}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.DELETE_SERVICE_DEF + "\")")
	public void deleteServiceDef(@PathParam("id") Long id, @Context HttpServletRequest request) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.deleteServiceDef(" + id + ")");
		}
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.deleteServiceDef(serviceDefId=" + id + ")");
			}
			RangerServiceDefValidator validator = validatorFactory.getServiceDefValidator(svcStore);
			validator.validate(id, Action.DELETE);

			bizUtil.hasAdminPermissions("Service-Def");
			XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(id);
			if (xServiceDef != null) {
				bizUtil.hasKMSPermissions("Service-Def", xServiceDef.getImplclassname());

				String forceDeleteStr = request.getParameter("forceDelete");
				boolean forceDelete = false;
				if (!StringUtils.isEmpty(forceDeleteStr) && "true".equalsIgnoreCase(forceDeleteStr)) {
					forceDelete = true;
				}

				svcStore.deleteServiceDef(id, forceDelete);
			} else {
				LOG.error("Cannot retrieve service-definition:[" + id + "] for deletion");
				throw new Exception("deleteServiceDef(" + id + ") failed");
			}
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("deleteServiceDef(" + id + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.deleteServiceDef(" + id + ")");
		}
	}

	@GET
	@Path("/definitions/{id}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE_DEF + "\")")
	public RangerServiceDef getServiceDef(@PathParam("id") Long id) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServiceDef(" + id + ")");
		}

		RangerServiceDef ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServiceDef(serviceDefId=" + id + ")");
			}
			XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(id);
			if(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME.equals(xServiceDef.getName())) {
				if (!bizUtil.hasModuleAccess(RangerConstants.MODULE_TAG_BASED_POLICIES)) {
					throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User is not having permissions on the tag module.", true);
				}
			}
			if (!bizUtil.hasAccess(xServiceDef, null)) {
				throw restErrorUtil.createRESTException(
						"User is not allowed to access service-def, id: " + xServiceDef.getId(),
						MessageEnums.OPER_NO_PERMISSION);
			}

			ret = svcStore.getServiceDef(id);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("getServiceDef(" + id + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(ret == null) {
			throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getServiceDef(" + id + "): " + ret);
		}

		return ret;
	}

	@GET
	@Path("/definitions/name/{name}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE_DEF_BY_NAME + "\")")
	public RangerServiceDef getServiceDefByName(@PathParam("name") String name) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServiceDefByName(serviceDefName=" + name + ")");
		}

		RangerServiceDef ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServiceDefByName(" + name + ")");
			}
			XXServiceDef xServiceDef = daoManager.getXXServiceDef().findByName(name);
			if (xServiceDef != null) {
				if(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME.equals(xServiceDef.getName())) {
					if (!bizUtil.hasModuleAccess(RangerConstants.MODULE_TAG_BASED_POLICIES)) {
						throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User is not having permissions on the tag module", true);
					}
				}
				if (!bizUtil.hasAccess(xServiceDef, null)) {
					throw restErrorUtil.createRESTException(
							"User is not allowed to access service-def: " + xServiceDef.getName(),
							MessageEnums.OPER_NO_PERMISSION);
				}
			}

			ret = svcStore.getServiceDefByName(name);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("getServiceDefByName(" + name + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(ret == null) {
			throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getServiceDefByName(" + name + "): " + ret);
		}

		return ret;
	}
	
	@GET
	@Path("/definitions")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE_DEFS + "\")")
	public RangerServiceDefList getServiceDefs(@Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServiceDefs()");
		}

		if (!bizUtil.hasModuleAccess(RangerConstants.MODULE_RESOURCE_BASED_POLICIES)) {
			throw restErrorUtil.createRESTException(HttpServletResponse.SC_FORBIDDEN, "User is not having permissions on the "+RangerConstants.MODULE_RESOURCE_BASED_POLICIES+" module.", true);
		}

		RangerServiceDefList ret  = null;
		RangerPerfTracer     perf = null;

		PList<RangerServiceDef> paginatedSvcDefs = null;

		SearchFilter filter = searchUtil.getSearchFilter(request, serviceDefService.sortFields);
		String pageSource= null;
		pageSource=request.getParameter("pageSource");
		if(pageSource!=null)
			filter.setParam("pageSource",pageSource);

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServiceDefs()");
			}
			paginatedSvcDefs = svcStore.getPaginatedServiceDefs(filter);

			if(paginatedSvcDefs != null) {
				ret = new RangerServiceDefList();

				ret.setServiceDefs(paginatedSvcDefs.getList());
				ret.setPageSize(paginatedSvcDefs.getPageSize());
				ret.setResultSize(paginatedSvcDefs.getResultSize());
				ret.setStartIndex(paginatedSvcDefs.getStartIndex());
				ret.setTotalCount(paginatedSvcDefs.getTotalCount());
				ret.setSortBy(paginatedSvcDefs.getSortBy());
				ret.setSortType(paginatedSvcDefs.getSortType());
			}
		} catch(WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("getServiceDefs() failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getServiceDefs(): count=" + (ret == null ? 0 : ret.getListSize()));
		}
		return ret;
	}

	@GET
	@Path("/policies/{serviceDefName}/for-resource")
	@Produces({ "application/json", "application/xml" })
	public List<RangerPolicy> getPoliciesForResource(@PathParam("serviceDefName") String serviceDefName,
												  @DefaultValue("") @QueryParam("serviceName") String serviceName,
												  @Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPoliciesForResource(service-type=" + serviceDefName + ", service-name=" + serviceName + ")");
		}

		List<RangerPolicy> ret = new ArrayList<>();

		List<RangerService> services = new ArrayList<>();
		Map<String, Object> resource = new HashMap<>();

		String validationMessage = validateResourcePoliciesRequest(serviceDefName, serviceName, request, services, resource);

		if (StringUtils.isNotEmpty(validationMessage)) {
			LOG.error("Invalid request: [" + validationMessage + "]");
			throw restErrorUtil.createRESTException(validationMessage,
					MessageEnums.INVALID_INPUT_DATA);
		} else {
			RangerService service = services.get(0);
			if (LOG.isDebugEnabled()) {
				LOG.debug("getServicePolicies with service-name=" + service.getName());
			}

			RangerPolicyAdmin policyAdmin = null;

			try {
				policyAdmin = getPolicyAdminForSearch(service.getName());
			} catch (Exception e) {
				LOG.error("Cannot initialize Policy-Engine", e);
				throw restErrorUtil.createRESTException("Cannot initialize Policy Engine",
						MessageEnums.ERROR_SYSTEM);
			}

			if (policyAdmin != null) {
				ret = policyAdmin.getMatchingPolicies(new RangerAccessResourceImpl(resource));
			}

		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPoliciesForResource(service-type=" + serviceDefName + ", service-name=" + serviceName + ") : " + ret.toString());
		}
		return ret;
	}

	private String validateResourcePoliciesRequest(String serviceDefName, String serviceName, HttpServletRequest request, List<RangerService> services, Map<String, Object> resource) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.validatePoliciesForResourceRequest(service-type=" + serviceDefName + ", service-name=" + serviceName + ")");
		}
		final String ret;

		if (MapUtils.isNotEmpty(request.getParameterMap())) {
			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(SearchFilter.RESOURCE_PREFIX)) {
					resource.put(name.substring(SearchFilter.RESOURCE_PREFIX.length()), values[0]);
				}
			}
		}
		if (MapUtils.isEmpty(resource)) {
			ret = "No resource specified";
		} else {
			RangerServiceDef serviceDef = null;
			try {
				serviceDef = svcStore.getServiceDefByName(serviceDefName);
			} catch (Exception e) {
				LOG.error("Invalid service-type:[" + serviceDefName + "]", e);
			}
			if (serviceDef == null) {
				ret = "Invalid service-type:[" + serviceDefName + "]";
			} else {
				Set<String> resourceDefNames = resource.keySet();
				RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef);
				Set<List<RangerServiceDef.RangerResourceDef>> resourceHierarchies = serviceDefHelper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS, resourceDefNames);
				if (CollectionUtils.isEmpty(resourceHierarchies)) {
					ret = "Invalid resource specified: resource-names:" + resourceDefNames +" are not part of any valid resource hierarchy for service-type:[" + serviceDefName + "]";
				} else {
					if (StringUtils.isNotBlank(serviceName)) {
						RangerService service = null;
						try {
							service = svcStore.getServiceByName(serviceName);
						} catch (Exception e) {
							LOG.error("Invalid service-name:[" + serviceName + "]");
						}
						if (service == null || !StringUtils.equals(service.getType(), serviceDefName)) {
							ret = "Invalid service-name:[" + serviceName + "] or service-name is not of service-type:[" + serviceDefName + "]";
						} else {
							services.add(service);
							ret = StringUtils.EMPTY;
						}
					} else {
						SearchFilter filter = new SearchFilter();
						filter.setParam(SearchFilter.SERVICE_TYPE, serviceDefName);
						List<RangerService> serviceList = null;
						try {
							serviceList = svcStore.getServices(filter);
						} catch (Exception e) {
							LOG.error("Cannot find service of service-type:[" + serviceDefName + "]");
						}
						if (CollectionUtils.isEmpty(serviceList) || serviceList.size() != 1) {
							ret = "Either 0 or more than 1 services found for service-type :[" + serviceDefName + "]";
						} else {
							services.add(serviceList.get(0));
							ret = StringUtils.EMPTY;
						}
					}
				}
			}
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.validatePoliciesForResourceRequest(service-type=" + serviceDefName + ", service-name=" + serviceName + ") : " + ret);
		}
		return ret;
	}

	@POST
	@Path("/services")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.CREATE_SERVICE + "\")")
	public RangerService createService(RangerService service) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.createService(" + service + ")");
		}

		RangerService    ret  = null;
		RangerPerfTracer perf = null;

		/**
		 * If display name is blank (EMPTY String or NULL), use name.
		 */
		if (StringUtils.isBlank(service.getDisplayName())) {
			service.setDisplayName(service.getName());
		}

		try {

			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.createService(serviceName=" + service.getName() + ")");
			}
			RangerServiceValidator validator = validatorFactory.getServiceValidator(svcStore);
			validator.validate(service, Action.CREATE);

			if(!StringUtils.isEmpty(service.getName().trim())){
				service.setName(service.getName().trim());
			}

			if(!StringUtils.isEmpty(service.getDisplayName().trim())){
				service.setDisplayName(service.getDisplayName().trim());
			}

			UserSessionBase session = ContextUtil.getCurrentUserSession();
			XXServiceDef xxServiceDef = daoManager.getXXServiceDef().findByName(service.getType());
			if(session != null && !session.isSpnegoEnabled()){
				bizUtil.hasAdminPermissions("Services");

				// TODO: As of now we are allowing SYS_ADMIN to create all the
				// services including KMS
				bizUtil.hasKMSPermissions("Service", xxServiceDef.getImplclassname());
			}
			if(session != null && session.isSpnegoEnabled()){
				if (session.isKeyAdmin() && !EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xxServiceDef.getImplclassname())) {
					throw restErrorUtil.createRESTException("KeyAdmin can create/update/delete only KMS ",
							MessageEnums.OPER_NO_PERMISSION);
				}
				if ((!session.isKeyAdmin() && !session.isUserAdmin()) && EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xxServiceDef.getImplclassname())) {
					throw restErrorUtil.createRESTException("User cannot create/update/delete KMS Service",
							MessageEnums.OPER_NO_PERMISSION);
				}
			}
                         bizUtil.blockAuditorRoleUser();

			if (StringUtils.isBlank(service.getTagService()) && xxServiceDef != null && !StringUtils.equals(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME, xxServiceDef.getName())) {
				if (LOG.isDebugEnabled()) {
					LOG.debug("Tag service may need to be created and linked with this service:[" + service.getName() + "]");
				}
				scheduleCreateOrGetTagService(service);
			}
			ret = svcStore.createService(service);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("createService(" + service + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.createService(" + service + "): " + ret);
		}

		return ret;
	}

	@PUT
	@Path("/services/{id}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.UPDATE_SERVICE + "\")")
	public RangerService updateService(RangerService service,
                                       @Context HttpServletRequest request) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.updateService(): " + service);
		}

		RangerService    ret  = null;
		RangerPerfTracer perf = null;

		try {

			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.updateService(serviceName=" + service.getName() + ")");
			}

			/**
			 * If display name is blank (EMPTY String or NULL), use previous display name.
			 */
			if (StringUtils.isBlank(service.getDisplayName())) {
				RangerService rangerService = svcStore.getService(service.getId());

				// If previous display name is blank (EMPTY String or NULL), user name.
				if (Objects.isNull(rangerService) || StringUtils.isBlank(rangerService.getDisplayName())) {
					service.setDisplayName(service.getName());
				} else {
					service.setDisplayName(rangerService.getDisplayName());
				}
			}

			RangerServiceValidator validator = validatorFactory.getServiceValidator(svcStore);
			validator.validate(service, Action.UPDATE);

			if(!StringUtils.isEmpty(service.getName().trim())){
				service.setName(service.getName().trim());
			}

			if(!StringUtils.isEmpty(service.getDisplayName().trim())){
				service.setDisplayName(service.getDisplayName().trim());
			}

			bizUtil.hasAdminPermissions("Services");

			// TODO: As of now we are allowing SYS_ADMIN to create all the
			// services including KMS

			XXServiceDef xxServiceDef = daoManager.getXXServiceDef().findByName(service.getType());
			bizUtil.hasKMSPermissions("Service", xxServiceDef.getImplclassname());
                        bizUtil.blockAuditorRoleUser();
			Map<String, Object> options = getOptions(request);

            ret = svcStore.updateService(service, options);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("updateService(" + service + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.updateService(" + service + "): " + ret);
		}

		return ret;
	}

	@DELETE
	@Path("/services/{id}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.DELETE_SERVICE + "\")")
	public void deleteService(@PathParam("id") Long id) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.deleteService(" + id + ")");
		}
		RangerAdminOpContext opContext = new RangerAdminOpContext();
		opContext.setBulkModeContext(true);
		RangerContextHolder.setOpContext(opContext);
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.deleteService(serviceId=" + id + ")");
			}
			RangerServiceValidator validator = validatorFactory.getServiceValidator(svcStore);
			validator.validate(id, Action.DELETE);
			UserSessionBase session = ContextUtil.getCurrentUserSession();
			if (session != null) {
				XXService service = daoManager.getXXService().getById(id);
				if (service != null) {
					//if logged-in user is not the service creator then check admin priv.
					if (!session.getUserId().equals(service.getAddedByUserId())) {
						bizUtil.hasAdminPermissions("Services");
					}
					EmbeddedServiceDefsUtil embeddedServiceDefsUtil = EmbeddedServiceDefsUtil.instance();
					if (service.getType().equals(embeddedServiceDefsUtil.getTagServiceDefId())) {
						List<XXService> referringServices = daoManager.getXXService().findByTagServiceId(id);
						if (!CollectionUtils.isEmpty(referringServices)) {
							Set<String> referringServiceNames = new HashSet<String>();
							for (XXService xXService : referringServices) {
								referringServiceNames.add(xXService.getName());
								if (referringServiceNames.size() >= 10) {
									break;
								}
							}
							if (referringServices.size() <= 10) {
								throw restErrorUtil.createRESTException("Tag service '" + service.getName() + "' is being referenced by " + referringServices.size() + " services: " + referringServiceNames, MessageEnums.OPER_NOT_ALLOWED_FOR_STATE);
							} else {
								throw restErrorUtil.createRESTException("Tag service '" + service.getName() + "' is being referenced by " + referringServices.size() + " services: " + referringServiceNames + " and more..", MessageEnums.OPER_NOT_ALLOWED_FOR_STATE);
							}
						}
					}
					XXServiceDef xxServiceDef = daoManager.getXXServiceDef().getById(service.getType());
					if (!session.getUserId().equals(service.getAddedByUserId())) {
						bizUtil.hasKMSPermissions("Service", xxServiceDef.getImplclassname());
						bizUtil.blockAuditorRoleUser();
					}
					tagStore.deleteAllTagObjectsForService(service.getName());

					svcStore.deleteService(id);
				} else {
					LOG.error("Cannot retrieve service:[" + id + "] for deletion");
					throw new Exception("deleteService(" + id + ") failed");
				}
			} else {
				LOG.error("Cannot retrieve user session.");
				throw new Exception("deleteService(" + id + ") failed");
			}
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("deleteService(" + id + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.deleteService(" + id + ")");
		}
	}

	@GET
	@Path("/services/{id}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE + "\")")
	public RangerService getService(@PathParam("id") Long id) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getService(" + id + ")");
		}

		RangerService    ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getService(serviceId=" + id + ")");
			}
			ret = svcStore.getService(id);
			
			if (ret != null) {
				UserSessionBase userSession = ContextUtil
						.getCurrentUserSession();
				if (userSession != null && userSession.getLoginId() != null) {
					VXUser loggedInVXUser = xUserService
							.getXUserByUserName(userSession.getLoginId());
					if (loggedInVXUser != null) {
						if (loggedInVXUser.getUserRoleList().size() == 1
								&& loggedInVXUser.getUserRoleList().contains(
										RangerConstants.ROLE_USER)) {
							
							ret = hideCriticalServiceDetailsForRoleUser(ret);
						}
					}
				}
			}
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("getService(" + id + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(ret == null) {
			throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getService(" + id + "): " + ret);
		}

		return ret;
	}

	@GET
	@Path("/services/name/{name}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICE_BY_NAME + "\")")
	public RangerService getServiceByName(@PathParam("name") String name) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServiceByName(" + name + ")");
		}

		RangerService    ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getService(serviceName=" + name + ")");
			}
			ret = svcStore.getServiceByName(name);
			
			if (ret != null) {
				UserSessionBase userSession = ContextUtil
						.getCurrentUserSession();
				if (userSession != null && userSession.getLoginId() != null) {
					VXUser loggedInVXUser = xUserService
							.getXUserByUserName(userSession.getLoginId());
					if (loggedInVXUser != null) {
						if (loggedInVXUser.getUserRoleList().size() == 1
								&& loggedInVXUser.getUserRoleList().contains(
										RangerConstants.ROLE_USER)) {

							ret = hideCriticalServiceDetailsForRoleUser(ret);
						}
					}
				}
			}
			
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("getServiceByName(" + name + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(ret == null) {
			throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getServiceByName(" + name + "): " + ret);
		}

		return ret;
	}

	@GET
	@Path("/services")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_SERVICES + "\")")
	public RangerServiceList getServices(@Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServices()");
		}

		RangerServiceList ret  = null;
		RangerPerfTracer  perf = null;

		PList<RangerService> paginatedSvcs = null;

		SearchFilter filter = searchUtil.getSearchFilter(request, svcService.sortFields);

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServices()");
			}
			paginatedSvcs = svcStore.getPaginatedServices(filter);
			
			if(paginatedSvcs!= null && !paginatedSvcs.getList().isEmpty()){
				UserSessionBase userSession = ContextUtil
						.getCurrentUserSession();
				if (userSession != null && userSession.getLoginId() != null) {
					VXUser loggedInVXUser = xUserService
							.getXUserByUserName(userSession.getLoginId());
					if (loggedInVXUser != null) {
						if (loggedInVXUser.getUserRoleList().size() == 1
								&& loggedInVXUser.getUserRoleList().contains(
										RangerConstants.ROLE_USER)) {
							
							List<RangerService> updateServiceList = new ArrayList<RangerService>();
							for(RangerService rangerService : paginatedSvcs.getList()){
								
								if(rangerService != null){
									updateServiceList.add(hideCriticalServiceDetailsForRoleUser(rangerService));
								}
							}
							
							if(updateServiceList != null && !updateServiceList.isEmpty()){
								paginatedSvcs.setList(updateServiceList);
							}
						}
					}
				}
			}

			if(paginatedSvcs != null) {
				ret = new RangerServiceList();

				ret.setServices(paginatedSvcs.getList());
				ret.setPageSize(paginatedSvcs.getPageSize());
				ret.setResultSize(paginatedSvcs.getResultSize());
				ret.setStartIndex(paginatedSvcs.getStartIndex());
				ret.setTotalCount(paginatedSvcs.getTotalCount());
				ret.setSortBy(paginatedSvcs.getSortBy());
				ret.setSortType(paginatedSvcs.getSortType());
			}
		} catch(WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("getServices() failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getServices(): count=" + (ret == null ? 0 : ret.getListSize()));
		}
		return ret;
	}

	public List<RangerService> getServices(SearchFilter filter) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServices():");
		}

		List<RangerService> ret  = null;
		RangerPerfTracer    perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServices()");
			}
			ret = svcStore.getServices(filter);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("getServices() failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getServices(): count=" + (ret == null ? 0 : ret.size()));
		}

		return ret;
	}


	@GET
	@Path("/services/count")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.COUNT_SERVICES + "\")")
	public Long countServices(@Context HttpServletRequest request) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.countServices():");
		}

		Long             ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.countService()");
			}
			List<RangerService> services = getServices(request).getServices();
			
			ret = Long.valueOf(services == null ? 0 : services.size());
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("countServices() failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.countServices(): " + ret);
		}

		return ret;
	}

	@POST
	@Path("/services/validateConfig")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.VALIDATE_CONFIG + "\")")
	public VXResponse validateConfig(RangerService service) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.validateConfig(" + service + ")");
		}

		VXResponse       ret  = new VXResponse();
		RangerPerfTracer perf = null;

		try {
			if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.validateConfig(serviceName=" + service.getName() + ")");
			}
			ret = serviceMgr.validateConfig(service, svcStore);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("validateConfig(" + service + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.validateConfig(" + service + "): " + ret);
		}

		return ret;
	}
	
	@POST
	@Path("/services/lookupResource/{serviceName}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.LOOKUP_RESOURCE + "\")")
	public List<String> lookupResource(@PathParam("serviceName") String serviceName, ResourceLookupContext context) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.lookupResource(" + serviceName + ")");
		}

		List<String>     ret  = new ArrayList<String>();
		RangerPerfTracer perf = null;

		try {
			if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.lookupResource(serviceName=" + serviceName + ")");
			}
			ret = serviceMgr.lookupResource(serviceName, context, svcStore);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("lookupResource(" + serviceName + ", " + context + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.lookupResource(" + serviceName + "): " + ret);
		}

		return ret;
	}

	@POST
	@Path("/services/grant/{serviceName}")
	@Produces({ "application/json", "application/xml" })
	public RESTResponse grantAccess(@PathParam("serviceName") String serviceName, GrantRevokeRequest grantRequest, @Context HttpServletRequest request) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.grantAccess(" + serviceName + ", " + grantRequest + ")");
		}

		RESTResponse     ret  = new RESTResponse();
		RangerPerfTracer perf = null;

		if(grantRequest!=null){
			if (serviceUtil.isValidateHttpsAuthentication(serviceName, request)) {

				try {
					bizUtil.failUnauthenticatedIfNotAllowed();

					if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
						perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.grantAccess(serviceName=" + serviceName + ")");
					}

					// This is an open API - dont care about who calls it. Caller is treated as privileged user
					boolean hasAdminPrivilege = true;
					String loggedInUser = null;
					validateGrantRevokeRequest(grantRequest, hasAdminPrivilege, loggedInUser);

					String               userName   = grantRequest.getGrantor();
					Set<String>          userGroups = CollectionUtils.isNotEmpty(grantRequest.getGrantorGroups()) ? grantRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
					String				 ownerUser  = grantRequest.getOwnerUser();
					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()), ownerUser);
					VXUser               vxUser = xUserService.getXUserByUserName(userName);

					if (vxUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR) || vxUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR)) {
						VXResponse vXResponse = new VXResponse();
						vXResponse.setStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
						vXResponse.setMsgDesc("Operation denied. LoggedInUser=" + vxUser.getId() + " is not permitted to perform the action.");
						throw restErrorUtil.generateRESTException(vXResponse);
					}
					boolean isAdmin = hasAdminAccess(serviceName, userName, userGroups, resource);

					if(!isAdmin) {
						throw restErrorUtil.createGrantRevokeRESTException( "User doesn't have necessary permission to grant access");
					}

					RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource, userName);
	
					if(policy != null) {
						boolean policyUpdated = false;
						policyUpdated = ServiceRESTUtil.processGrantRequest(policy, grantRequest);
	
						if(policyUpdated) {
							policy.setZoneName(grantRequest.getZoneName());
							svcStore.updatePolicy(policy);
						} else {
							LOG.error("processGrantRequest processing failed");
							throw new Exception("processGrantRequest processing failed");
						}
					} else {
						policy = new RangerPolicy();
						policy.setService(serviceName);
						policy.setName("grant-" + System.currentTimeMillis()); // TODO: better policy name
						policy.setDescription("created by grant");
						policy.setIsAuditEnabled(grantRequest.getEnableAudit());
						policy.setCreatedBy(userName);
			
						Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
						Set<String>                       resourceNames   = resource.getKeys();
			
						if(! CollectionUtils.isEmpty(resourceNames)) {
							for(String resourceName : resourceNames) {
								RangerPolicyResource policyResource = new RangerPolicyResource((String) resource.getValue(resourceName));
								policyResource.setIsRecursive(grantRequest.getIsRecursive());
		
								policyResources.put(resourceName, policyResource);
							}
						}
						policy.setResources(policyResources);
	
						RangerPolicyItem policyItem = new RangerPolicyItem();
	
						policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
						policyItem.getUsers().addAll(grantRequest.getUsers());
						policyItem.getGroups().addAll(grantRequest.getGroups());
						policyItem.getRoles().addAll(grantRequest.getRoles());
	
						for(String accessType : grantRequest.getAccessTypes()) {
							policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, Boolean.TRUE));
						}
	
						policy.getPolicyItems().add(policyItem);
						policy.setZoneName(grantRequest.getZoneName());

						svcStore.createPolicy(policy);
					}
				} catch(WebApplicationException excp) {
					throw excp;
				} catch(Throwable excp) {
					LOG.error("grantAccess(" + serviceName + ", " + grantRequest + ") failed", excp);

					throw restErrorUtil.createRESTException(excp.getMessage());
				} finally {
					RangerPerfTracer.log(perf);
				}

				ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
			}
		}
		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.grantAccess(" + serviceName + ", " + grantRequest + "): " + ret);
		}

		return ret;
	}
	
	@POST
	@Path("/secure/services/grant/{serviceName}")
	@Produces({ "application/json", "application/xml" })
	public RESTResponse secureGrantAccess(@PathParam("serviceName") String serviceName, GrantRevokeRequest grantRequest, @Context HttpServletRequest request) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.secureGrantAccess(" + serviceName + ", " + grantRequest + ")");
		}
		RESTResponse     ret  = new RESTResponse();
		RangerPerfTracer perf = null;
		bizUtil.blockAuditorRoleUser();

		if(grantRequest != null) {
			if (serviceUtil.isValidService(serviceName, request)) {
				try {
					if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
						perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.scureGrantAccess(serviceName=" + serviceName + ")");
					}

					XXService xService = daoManager.getXXService().findByName(serviceName);
					XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());
					RangerService rangerService = svcStore.getServiceByName(serviceName);

					String  loggedInUser      = bizUtil.getCurrentUserLoginId();
					boolean hasAdminPrivilege = bizUtil.isAdmin() || bizUtil.isUserServiceAdmin(rangerService, loggedInUser) || bizUtil.isUserAllowedForGrantRevoke(rangerService, loggedInUser);

					validateGrantRevokeRequest(grantRequest, hasAdminPrivilege, loggedInUser);

					String               userName   = grantRequest.getGrantor();
					Set<String>          userGroups = grantRequest.getGrantorGroups();
					String				 ownerUser  = grantRequest.getOwnerUser();

					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()), ownerUser);

					boolean isAllowed = false;

					if (StringUtils.equals(xServiceDef.getImplclassname(), EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
						if (bizUtil.isKeyAdmin() || bizUtil.isUserAllowedForGrantRevoke(rangerService, loggedInUser)) {
							isAllowed = true;
						}
					} else {
						isAllowed = hasAdminPrivilege || hasAdminAccess(serviceName, userName, userGroups, resource);
					}

					if (isAllowed) {
						RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource, userName);

						if(policy != null) {
							boolean policyUpdated = false;
							policyUpdated = ServiceRESTUtil.processGrantRequest(policy, grantRequest);

							if(policyUpdated) {
								policy.setZoneName(grantRequest.getZoneName());
								svcStore.updatePolicy(policy);
							} else {
								LOG.error("processSecureGrantRequest processing failed");
								throw new Exception("processSecureGrantRequest processing failed");
							}
						} else {
							policy = new RangerPolicy();
							policy.setService(serviceName);
							policy.setName("grant-" + System.currentTimeMillis()); // TODO: better policy name
							policy.setDescription("created by grant");
							policy.setIsAuditEnabled(grantRequest.getEnableAudit());
							policy.setCreatedBy(userName);

							Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
							Set<String>                       resourceNames   = resource.getKeys();

							if(! CollectionUtils.isEmpty(resourceNames)) {
								for(String resourceName : resourceNames) {
									RangerPolicyResource policyResource = new RangerPolicyResource((String) resource.getValue(resourceName));
									policyResource.setIsRecursive(grantRequest.getIsRecursive());

									policyResources.put(resourceName, policyResource);
								}
							}
							policy.setResources(policyResources);

							RangerPolicyItem policyItem = new RangerPolicyItem();

							policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
							policyItem.getUsers().addAll(grantRequest.getUsers());
							policyItem.getGroups().addAll(grantRequest.getGroups());
							policyItem.getRoles().addAll(grantRequest.getRoles());

							for(String accessType : grantRequest.getAccessTypes()) {
								policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, Boolean.TRUE));
							}

							policy.getPolicyItems().add(policyItem);
							policy.setZoneName(grantRequest.getZoneName());

							svcStore.createPolicy(policy);
						}
					}else{
						LOG.error("secureGrantAccess(" + serviceName + ", " + grantRequest + ") failed as User doesn't have permission to grant Policy");
						throw restErrorUtil.createGrantRevokeRESTException( "User doesn't have necessary permission to grant access");
					}
				} catch(WebApplicationException excp) {
					throw excp;
				} catch(Throwable excp) {
					LOG.error("secureGrantAccess(" + serviceName + ", " + grantRequest + ") failed", excp);

					throw restErrorUtil.createRESTException(excp.getMessage());
				} finally {
					RangerPerfTracer.log(perf);
				}

				ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
			}
		}
		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.secureGrantAccess(" + serviceName + ", " + grantRequest + "): " + ret);
		}
		return ret;
	}	

	@POST
	@Path("/services/revoke/{serviceName}")
	@Produces({ "application/json", "application/xml" })
	public RESTResponse revokeAccess(@PathParam("serviceName") String serviceName, GrantRevokeRequest revokeRequest, @Context HttpServletRequest request) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.revokeAccess(" + serviceName + ", " + revokeRequest + ")");
		}

		RESTResponse     ret  = new RESTResponse();
		RangerPerfTracer perf = null;
		if(revokeRequest!=null){
			if (serviceUtil.isValidateHttpsAuthentication(serviceName,request)) {

				try {
					bizUtil.failUnauthenticatedIfNotAllowed();

					if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
						perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.revokeAccess(serviceName=" + serviceName + ")");
					}

					// This is an open API - dont care about who calls it. Caller is treated as privileged user
					boolean hasAdminPrivilege = true;
					String loggedInUser = null;
					validateGrantRevokeRequest(revokeRequest, hasAdminPrivilege, loggedInUser);

					String               userName   = revokeRequest.getGrantor();
					Set<String>          userGroups = CollectionUtils.isNotEmpty(revokeRequest.getGrantorGroups()) ? revokeRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
					String				 ownerUser  = revokeRequest.getOwnerUser();
					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()), ownerUser);
					VXUser vxUser = xUserService.getXUserByUserName(userName);

					if (vxUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR) || vxUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR)) {
						VXResponse vXResponse = new VXResponse();
						vXResponse.setStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
						vXResponse.setMsgDesc("Operation denied. LoggedInUser=" + vxUser.getId() + " is not permitted to perform the action.");
						throw restErrorUtil.generateRESTException(vXResponse);
					}
					boolean isAdmin = hasAdminAccess(serviceName, userName, userGroups, resource);

					if(!isAdmin) {
						throw restErrorUtil.createGrantRevokeRESTException("User doesn't have necessary permission to revoke access");
					}

					RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource, userName);

					if(policy != null) {
						boolean policyUpdated = false;
						policyUpdated = ServiceRESTUtil.processRevokeRequest(policy, revokeRequest);

						if(policyUpdated) {
							policy.setZoneName(revokeRequest.getZoneName());
							svcStore.updatePolicy(policy);
						} else {
							LOG.error("processRevokeRequest processing failed");
							throw new Exception("processRevokeRequest processing failed");
						}
					}
				} catch(WebApplicationException excp) {
					throw excp;
				} catch(Throwable excp) {
					LOG.error("revokeAccess(" + serviceName + ", " + revokeRequest + ") failed", excp);

					throw restErrorUtil.createRESTException(excp.getMessage());
				} finally {
					RangerPerfTracer.log(perf);
				}

				ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
			}
		}
		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.revokeAccess(" + serviceName + ", " + revokeRequest + "): " + ret);
		}

		return ret;
	}

	@POST
	@Path("/secure/services/revoke/{serviceName}")
	@Produces({ "application/json", "application/xml" })
	public RESTResponse secureRevokeAccess(@PathParam("serviceName") String serviceName, GrantRevokeRequest revokeRequest, @Context HttpServletRequest request) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.secureRevokeAccess(" + serviceName + ", " + revokeRequest + ")");
		}
		RESTResponse     ret  = new RESTResponse();
		RangerPerfTracer perf = null;
		bizUtil.blockAuditorRoleUser();

		if (revokeRequest != null) {
			if (serviceUtil.isValidService(serviceName,request)) {
				try {
					if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
						perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.secureRevokeAccess(serviceName=" + serviceName + ")");
					}

					XXService xService = daoManager.getXXService().findByName(serviceName);
					XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());
					RangerService rangerService = svcStore.getServiceByName(serviceName);

					String  loggedInUser      = bizUtil.getCurrentUserLoginId();
					boolean hasAdminPrivilege = bizUtil.isAdmin() || bizUtil.isUserServiceAdmin(rangerService, loggedInUser) || bizUtil.isUserAllowedForGrantRevoke(rangerService, loggedInUser);

					validateGrantRevokeRequest(revokeRequest, hasAdminPrivilege, loggedInUser);

					String userName = revokeRequest.getGrantor();
					Set<String> userGroups = revokeRequest.getGrantorGroups();
					String ownerUser = revokeRequest.getOwnerUser();

					RangerAccessResource resource = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()), ownerUser);

					boolean isAllowed = false;

					if (StringUtils.equals(xServiceDef.getImplclassname(), EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
						if (bizUtil.isKeyAdmin() || bizUtil.isUserAllowedForGrantRevoke(rangerService, loggedInUser)) {
							isAllowed = true;
						}
					} else {
						isAllowed = hasAdminPrivilege || hasAdminAccess(serviceName, userName, userGroups, resource);
					}

					if (isAllowed) {
						RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource, userName);

						if(policy != null) {
							boolean policyUpdated = false;
							policyUpdated = ServiceRESTUtil.processRevokeRequest(policy, revokeRequest);

							if(policyUpdated) {
								policy.setZoneName(revokeRequest.getZoneName());
								svcStore.updatePolicy(policy);
							} else {
								LOG.error("processSecureRevokeRequest processing failed");
								throw new Exception("processSecureRevokeRequest processing failed");
							}
						}
					}else{
						LOG.error("secureRevokeAccess(" + serviceName + ", " + revokeRequest + ") failed as User doesn't have permission to revoke Policy");
						throw restErrorUtil.createGrantRevokeRESTException("User doesn't have necessary permission to revoke access");
					}
				} catch(WebApplicationException excp) {
					throw excp;
				} catch(Throwable excp) {
					LOG.error("secureRevokeAccess(" + serviceName + ", " + revokeRequest + ") failed", excp);

					throw restErrorUtil.createRESTException(excp.getMessage());
				} finally {
					RangerPerfTracer.log(perf);
				}

				ret.setStatusCode(RESTResponse.STATUS_SUCCESS);
			}
		}
		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.secureRevokeAccess(" + serviceName + ", " + revokeRequest + "): " + ret);
		}
		return ret;
	}	
	
	@POST
	@Path("/policies")
	@Produces({ "application/json", "application/xml" })
	public RangerPolicy createPolicy(RangerPolicy policy, @Context HttpServletRequest request) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.createPolicy(" + policy + ")");
		}

		RangerPolicy     ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.createPolicy(policyName=" + policy.getName() + ")");
			}

			if(request != null) {
				boolean deleteIfExists=("true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_DELETE_IF_EXISTS)))) ? true : false ;
				if(deleteIfExists) {
					List<RangerPolicy> policies=new ArrayList<RangerPolicy>() { { add(policy); } };
					deleteExactMatchPolicyForResource(policies, request.getRemoteUser(), null);
				}
				boolean updateIfExists=("true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_UPDATE_IF_EXISTS)))) ? true : false ;
				if(updateIfExists) {
					RangerPolicy existingPolicy = null;
					String serviceName = request.getParameter(PARAM_SERVICE_NAME);
					if (serviceName == null) {
						serviceName = (String) request.getAttribute(PARAM_SERVICE_NAME);
					}
					if(StringUtils.isNotEmpty(serviceName)) {
						policy.setService(serviceName);
					}
					String policyName = request.getParameter(PARAM_POLICY_NAME);
					if (policyName == null) {
						policyName = (String) request.getAttribute(PARAM_POLICY_NAME);
					}
					if(StringUtils.isNotEmpty(policyName)) {
						policy.setName(StringUtils.trim(policyName));
					}
					if (StringUtils.isNotEmpty(serviceName) && StringUtils.isNotEmpty(policyName)) {
						String zoneName = request.getParameter(PARAM_ZONE_NAME);
						if(StringUtils.isBlank(zoneName)) {
							zoneName = (String) request.getAttribute(PARAM_ZONE_NAME);
						}
						if (StringUtils.isNotBlank(zoneName)) {
							policy.setZoneName(StringUtils.trim(zoneName));
						}
						if (StringUtils.isNotBlank(zoneName)) {
							existingPolicy = getPolicyByNameAndZone(policy.getService(), policy.getName(), policy.getZoneName());
							if(existingPolicy==null) {
								existingPolicy = getPolicyByGuid(policy.getGuid(), policy.getService(), policy.getZoneName());
							}
						} else {
							existingPolicy = getPolicyByName(policy.getService(), policy.getName());
							if(existingPolicy==null) {
								existingPolicy = getPolicyByGuid(policy.getGuid(), policy.getService(), null);
							}
						}
					}
					try {
						if (existingPolicy != null) {
							policy.setId(existingPolicy.getId());
							ret = updatePolicy(policy);
						}
					} catch (Exception excp){
						LOG.error("updatePolicy(" + policy + ") failed", excp);
						throw restErrorUtil.createRESTException(excp.getMessage());
					}
				}
			}

			if(ret == null) {
				// this needs to happen before validator is called
				// set name of policy if unspecified
				if (StringUtils.isBlank(policy.getName())) { // use of isBlank over isEmpty is deliberate as a blank string does not strike us as a particularly useful policy name!
					String guid = policy.getGuid();
					if (StringUtils.isBlank(guid)) { // use of isBlank is deliberate. External parties could send the guid in, perhaps to sync between dev/test/prod instances?
						guid = guidUtil.genGUID();
						policy.setGuid(guid);
						if (LOG.isDebugEnabled()) {
							LOG.debug("No GUID supplied on the policy!  Ok, setting GUID to [" + guid + "].");
						}
					}
					String name = policy.getService() + "-" + guid;
					policy.setName(name);
					if (LOG.isDebugEnabled()) {
						LOG.debug("Policy did not have its name set!  Ok, setting name to [" + name + "]");
					}
				}
				RangerPolicyValidator validator = validatorFactory.getPolicyValidator(svcStore);
				validator.validate(policy, Action.CREATE, bizUtil.isAdmin());

				ensureAdminAccess(policy);
                                bizUtil.blockAuditorRoleUser();
				ret = svcStore.createPolicy(policy);
			}
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("createPolicy(" + policy + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.createPolicy(" + policy + "): " + ret);
		}

		return ret;
	}

	/*
	The verb for applyPolicy is POST as it could be partial update or a create
	*/

	@POST
	@Path("/policies/apply")
	@Produces({ "application/json", "application/xml" })
	public RangerPolicy applyPolicy(RangerPolicy policy, @Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.applyPolicy(" + policy + ")");
		}

		RangerPolicy ret = null;

		if (policy != null && StringUtils.isNotBlank(policy.getService())) {
			try {
				// Check if applied policy contains any conditions
				if (ServiceRESTUtil.containsRangerCondition(policy)) {
					LOG.error("Applied policy contains condition(s); not supported:" + policy);
					throw new Exception("Applied policy contains condition(s); not supported:" + policy);
				}

				String user = request.getRemoteUser();
				RangerPolicy existingPolicy = getExactMatchPolicyForResource(policy, StringUtils.isNotBlank(user) ? user :"admin");

				if (existingPolicy == null) {
					ret = createPolicy(policy, null);
				} else {
					ServiceRESTUtil.processApplyPolicy(existingPolicy, policy);

					ret = updatePolicy(existingPolicy);
				}
			} catch(WebApplicationException excp) {
				throw excp;
			} catch (Exception exception) {
				LOG.error("Failed to apply policy:", exception);
				throw restErrorUtil.createRESTException(exception.getMessage());
			}
		} else {
			throw restErrorUtil.createRESTException("Non-existing service specified:");
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.applyPolicy(" + policy + ") : " + ret);
		}

		return ret;
	}

	@PUT
	@Path("/policies/{id}")
	@Produces({ "application/json", "application/xml" })
	public RangerPolicy updatePolicy(RangerPolicy policy) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.updatePolicy(" + policy + ")");
		}

		RangerPolicy ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.updatePolicy(policyId=" + policy.getId() + ")");
			}
			RangerPolicyValidator validator = validatorFactory.getPolicyValidator(svcStore);
			validator.validate(policy, Action.UPDATE, bizUtil.isAdmin());

			ensureAdminAccess(policy);
                        bizUtil.blockAuditorRoleUser();
			ret = svcStore.updatePolicy(policy);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("updatePolicy(" + policy + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.updatePolicy(" + policy + "): " + ret);
		}

		return ret;
	}

	@DELETE
	@Path("/policies/{id}")
	@Produces({ "application/json", "application/xml" })
	public void deletePolicy(@PathParam("id") Long id) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.deletePolicy(" + id + ")");
		}

		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.deletePolicy(policyId=" + id + ")");
			}
			RangerPolicyValidator validator = validatorFactory.getPolicyValidator(svcStore);
			validator.validate(id, Action.DELETE);

			RangerPolicy policy = svcStore.getPolicy(id);

			ensureAdminAccess(policy);
                        bizUtil.blockAuditorRoleUser();
			svcStore.deletePolicy(policy);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("deletePolicy(" + id + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.deletePolicy(" + id + ")");
		}
	}

	@GET
	@Path("/policies/{id}")
	@Produces({ "application/json", "application/xml" })
	public RangerPolicy getPolicy(@PathParam("id") Long id) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPolicy(" + id + ")");
		}

		RangerPolicy     ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPolicy(policyId=" + id + ")");
			}
			ret = svcStore.getPolicy(id);

			if(ret != null) {
                                ensureAdminAndAuditAccess(ret);
			}
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("getPolicy(" + id + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(ret == null) {
			throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPolicy(" + id + "): " + ret);
		}

		return ret;
	}

	@GET
	@Path("/policyLabels")
	@Produces({ "application/json", "application/xml" })
	public List<String> getPolicyLabels(@Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPolicyLabels()");
		}

		List<String> ret = new ArrayList<String>();
		RangerPerfTracer perf = null;

		try {
			if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPolicyLabels()");
			}

			SearchFilter filter = searchUtil.getSearchFilter(request, policyLabelsService.sortFields);
			ret = svcStore.getPolicyLabels(filter);
		} catch (WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("getPolicyLabels() failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPolicyLabels()");
		}
		return ret;
	}

        @GET
	@Path("/policies")
	@Produces({ "application/json", "application/xml" })
	public RangerPolicyList getPolicies(@Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPolicies()");
		}

		RangerPolicyList ret  = new RangerPolicyList();
		RangerPerfTracer perf = null;

		SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPolicies()");
			}

			if(isAdminUserWithNoFilterParams(filter)) {
				PList<RangerPolicy> policies = svcStore.getPaginatedPolicies(filter);

				ret = toRangerPolicyList(policies);
			} else {
				// get all policies from the store; pick the page to return after applying filter
				final int savedStartIndex = filter.getStartIndex();
				final int savedMaxRows    = filter.getMaxRows();

				filter.setStartIndex(0);
				filter.setMaxRows(Integer.MAX_VALUE);

				List<RangerPolicy> policies = svcStore.getPolicies(filter);

				filter.setStartIndex(savedStartIndex);
				filter.setMaxRows(savedMaxRows);

				policies = applyAdminAccessFilter(policies);

				ret = toRangerPolicyList(policies, filter);
			}

		} catch(WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("getPolicies() failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPolicies(): count=" + (ret == null ? 0 : ret.getListSize()));
		}
		return ret;
	}

	@GET
	@Path("/policies/downloadExcel")
	@Produces("application/ms-excel")
	public void getPoliciesInExcel(@Context HttpServletRequest request,
			@Context HttpServletResponse response) {

		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPoliciesInExcel()");
		}
		RangerPerfTracer perf = null;
		SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);

		try {
			if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPoliciesInExcel()");
			}
			List<RangerPolicy> policyLists = new ArrayList<RangerPolicy>();
			
			policyLists = getAllFilteredPolicyList(filter, request, policyLists);
			if (CollectionUtils.isNotEmpty(policyLists)){
                                for (RangerPolicy rangerPolicy : policyLists) {
                                        if (rangerPolicy != null) {
                                                ensureAdminAndAuditAccess(rangerPolicy);
                                        }
                                }
				svcStore.getPoliciesInExcel(policyLists, response);
			}else{
				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
				LOG.error("No policies found to download!");
			}
			
			RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
			svcStore.putMetaDataInfo(rangerExportPolicyList);
			String metaDataInfo = JsonUtilsV2.mapToJson(rangerExportPolicyList.getMetaDataInfo());
			
			List<XXTrxLog> trxLogList = new ArrayList<XXTrxLog>();
			XXTrxLog xxTrxLog = new XXTrxLog();
			xxTrxLog.setAction("EXPORT EXCEL");
			xxTrxLog.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
			xxTrxLog.setPreviousValue(metaDataInfo);
			trxLogList.add(xxTrxLog);
			bizUtil.createTrxLog(trxLogList);
		} catch (WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("Error while downloading policy report", excp);
			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}
	}

	@GET
	@Path("/policies/csv")
	@Produces("text/csv")
	public void getPoliciesInCsv(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException {

		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPoliciesInCsv()");
		}
		RangerPerfTracer perf = null;
		
		SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);

		try {
			if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPoliciesInCsv()");
			}
			List<RangerPolicy> policyLists = new ArrayList<RangerPolicy>();
			
			policyLists = getAllFilteredPolicyList(filter, request, policyLists);
			if (CollectionUtils.isNotEmpty(policyLists)){
                                for (RangerPolicy rangerPolicy : policyLists) {
                                        if (rangerPolicy != null) {
                                                ensureAdminAndAuditAccess(rangerPolicy);
                                        }
                                }

				svcStore.getPoliciesInCSV(policyLists, response);
			}else{
				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
				LOG.error("No policies found to download!");
			}
			
			RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
			svcStore.putMetaDataInfo(rangerExportPolicyList);
			String metaDataInfo = JsonUtilsV2.mapToJson(rangerExportPolicyList.getMetaDataInfo());
			
			List<XXTrxLog> trxLogList = new ArrayList<XXTrxLog>();
			XXTrxLog xxTrxLog = new XXTrxLog();
			xxTrxLog.setAction("EXPORT CSV");
			xxTrxLog.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
			xxTrxLog.setPreviousValue(metaDataInfo);
			trxLogList.add(xxTrxLog);
			bizUtil.createTrxLog(trxLogList);
		} catch (WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("Error while downloading policy report", excp);
			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}
	}

	@GET
	@Path("/policies/exportJson")
	@Produces("text/json")
	public void getPoliciesInJson(@Context HttpServletRequest request,
			@Context HttpServletResponse response,
			@QueryParam("checkPoliciesExists") Boolean checkPoliciesExists) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPoliciesInJson()");
		}

		RangerPerfTracer perf = null;
		SearchFilter filter = searchUtil.getSearchFilter(request,policyService.sortFields);
		requestParamsValidation(filter);
		try {
			if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG,"ServiceREST.getPoliciesInJson()");
			}
			if (checkPoliciesExists == null){
				checkPoliciesExists = false;
			}

			List<RangerPolicy> policyLists = new ArrayList<RangerPolicy>();
			
			policyLists = getAllFilteredPolicyList(filter, request, policyLists);

			if (CollectionUtils.isNotEmpty(policyLists)) {
				for (RangerPolicy rangerPolicy : policyLists) {
					if (rangerPolicy != null) {
						ensureAdminAndAuditAccess(rangerPolicy);
					}
				}
				bizUtil.blockAuditorRoleUser();
				svcStore.getPoliciesInJson(policyLists, response);
			} else {
				checkPoliciesExists = true;
				response.setStatus(HttpServletResponse.SC_NO_CONTENT);
				LOG.error("There is no Policy to Export!!");
			}
                        
			if(!checkPoliciesExists){
				RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
				svcStore.putMetaDataInfo(rangerExportPolicyList);
				String metaDataInfo = JsonUtilsV2.mapToJson(rangerExportPolicyList.getMetaDataInfo());
							
				List<XXTrxLog> trxLogList = new ArrayList<XXTrxLog>();
				XXTrxLog xxTrxLog = new XXTrxLog();
				xxTrxLog.setAction("EXPORT JSON");
				xxTrxLog.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
				xxTrxLog.setPreviousValue(metaDataInfo);
				trxLogList.add(xxTrxLog);
				bizUtil.createTrxLog(trxLogList);
			}
		} catch (WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("Error while exporting policy file!!", excp);
			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}
	}
	
	private void requestParamsValidation(SearchFilter filter) {
		Boolean fetchAllZonePolicies = Boolean.valueOf(filter.getParam(SearchFilter.FETCH_ZONE_UNZONE_POLICIES));
		String  zoneName             = filter.getParam(SearchFilter.ZONE_NAME);

		if (fetchAllZonePolicies && StringUtils.isNotEmpty(zoneName)) {
		    throw restErrorUtil.createRESTException("Invalid parameter: " + SearchFilter.ZONE_NAME + " can not be provided, along with " + SearchFilter.FETCH_ZONE_UNZONE_POLICIES + "=true");
		}
	}

	@POST
	@Path("/policies/importPoliciesFromFile")
	@Consumes({MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_JSON})
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAdminOrKeyAdminRole()")
	public void importPoliciesFromFile(
			@Context HttpServletRequest request,
			@FormDataParam("servicesMapJson") InputStream serviceMapStream,
			@FormDataParam("zoneMapJson") InputStream zoneMapStream,
			@FormDataParam("file") InputStream uploadedInputStream,
			@FormDataParam("file") FormDataContentDisposition fileDetail,
			@QueryParam("isOverride") Boolean isOverride,
			@QueryParam("importType") String importType) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.importPoliciesFromFile()");
		}
		RangerAdminOpContext opContext = new RangerAdminOpContext();
		opContext.setBulkModeContext(true);
		RangerContextHolder.setOpContext(opContext);
		RangerPerfTracer perf = null;
		String metaDataInfo = null;
		List<XXTrxLog> trxLogListError = new ArrayList<XXTrxLog>();
		XXTrxLog xxTrxLogError = new XXTrxLog();

		try {
			if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG,"ServiceREST.importPoliciesFromFile()");
			}

			List<XXTrxLog> trxLogList = new ArrayList<XXTrxLog>();
			XXTrxLog xxTrxLog = new XXTrxLog();
			xxTrxLog.setAction("IMPORT START");
			xxTrxLog.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
			xxTrxLog.setPreviousValue("IMPORT START");
			trxLogList.add(xxTrxLog);
			bizUtil.createTrxLog(trxLogList);

			if (isOverride == null){
				isOverride = false;
			}
			List<String> serviceNameList = new ArrayList<String>();

			getServiceNameList(request,serviceNameList);
			Map<String, String> servicesMappingMap = new LinkedHashMap<String, String>();
			List<String> sourceServices = new ArrayList<String>();
			List<String> destinationServices = new ArrayList<String>();
			Map<String, String> zoneMappingMap = new LinkedHashMap<String, String>();
			List<String> sourceZones = new ArrayList<String>();
			List<String> destinationZones = new ArrayList<String>();
			if (zoneMapStream != null) {
				zoneMappingMap = svcStore.getMapFromInputStream(zoneMapStream);
				processZoneMapping(zoneMappingMap, sourceZones, destinationZones);
			}

			if (serviceMapStream != null){
				servicesMappingMap = svcStore.getMapFromInputStream(serviceMapStream);
				processServiceMapping(servicesMappingMap, sourceServices, destinationServices);
			}

			String fileName = fileDetail.getFileName();
			int totalPolicyCreate = 0;
			String zoneNameInJson = null;
			Map<String, RangerPolicy> policiesMap = new LinkedHashMap<String, RangerPolicy>();
			List<String> dataFileSourceServices = new ArrayList<String>();
			if (fileName.endsWith("json")) {
				try {
					RangerExportPolicyList rangerExportPolicyList = null;
					List<RangerPolicy> policies = null;
					rangerExportPolicyList = processPolicyInputJsonForMetaData(uploadedInputStream,rangerExportPolicyList);
					if (rangerExportPolicyList != null && !CollectionUtils.sizeIsEmpty(rangerExportPolicyList.getMetaDataInfo())) {
						metaDataInfo = JsonUtilsV2.mapToJson(rangerExportPolicyList.getMetaDataInfo());
					} else {
						LOG.info("metadata info is not provided!!");
					}
					policies = getPoliciesFromProvidedJson(rangerExportPolicyList);

					int i = 0;
					if (CollectionUtils.sizeIsEmpty(servicesMappingMap) && isOverride){
						if(policies != null && !CollectionUtils.sizeIsEmpty(policies)){
							for (RangerPolicy policyInJson: policies){
								if (policyInJson != null ) {
									if (i == 0 && StringUtils.isNotBlank(policyInJson.getZoneName())) {
										zoneNameInJson = policyInJson.getZoneName().trim();
									}
									if (StringUtils.isNotEmpty(policyInJson.getService().trim())) {
										String serviceName = policyInJson.getService().trim();
										if (CollectionUtils.isNotEmpty(serviceNameList) && serviceNameList.contains(serviceName) && !sourceServices.contains(serviceName) && !destinationServices.contains(serviceName)) {
											sourceServices.add(serviceName);
											destinationServices.add(serviceName);
										} else if (CollectionUtils.isEmpty(serviceNameList) && !sourceServices.contains(serviceName) && !destinationServices.contains(serviceName)) {
											sourceServices.add(serviceName);
											destinationServices.add(serviceName);
										}
									}else{
										LOG.error("Service Name or Policy Name is not provided!!");
										throw restErrorUtil.createRESTException("Service Name or Policy Name is not provided!!");
									}
								}
								i++;
							}
						}
					}else if (!CollectionUtils.sizeIsEmpty(servicesMappingMap)) {
						if (policies != null && !CollectionUtils.sizeIsEmpty(policies)){
							i = 0;
							for (RangerPolicy policyInJson: policies){
								if (policyInJson != null){
									if (i == 0 && StringUtils.isNotBlank(policyInJson.getZoneName())) {
										zoneNameInJson = policyInJson.getZoneName().trim();
									}
									if (StringUtils.isNotEmpty(policyInJson.getService().trim())) {
										dataFileSourceServices.add(policyInJson.getService().trim());
									}else{
										LOG.error("Service Name or Policy Name is not provided!!");
										throw restErrorUtil.createRESTException("Service Name or Policy Name is not provided!!");
									}
									i++;
								}
							}
							if(!dataFileSourceServices.containsAll(sourceServices)){
								LOG.error("Json File does not contain sepcified source service name.");
								throw restErrorUtil.createRESTException("Json File does not contain sepcified source service name.");
							}
						}
					}
					boolean deleteIfExists=("true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_DELETE_IF_EXISTS)))) ? true : false ;
					boolean updateIfExists=("true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_UPDATE_IF_EXISTS)))) ? true : false ;
					String polResource = request.getParameter(SearchFilter.POL_RESOURCE);
					if (updateIfExists) {
						isOverride = false;
					}
					String destinationZoneName = getDestinationZoneName(destinationZones,zoneNameInJson);
					if (deleteIfExists) {
						deleteExactMatchPolicyForResource(policies, request.getRemoteUser(), destinationZoneName);
					}
					if (isOverride && !updateIfExists && StringUtils.isEmpty(polResource)) {
						if (LOG.isDebugEnabled()) {
							LOG.debug("Deleting Policy from provided services in servicesMapJson file...");
						}
						if (CollectionUtils.isNotEmpty(sourceServices) && CollectionUtils.isNotEmpty(destinationServices)) {
							deletePoliciesProvidedInServiceMap(sourceServices, destinationServices,destinationZoneName);//In order to delete Zone specific policies from service
						}
					} else if (updateIfExists && StringUtils.isNotEmpty(polResource)) {
						if (LOG.isDebugEnabled()) {
							LOG.debug("Deleting Policy from provided services in servicesMapJson file for specific resource...");
						}
						if (CollectionUtils.isNotEmpty(sourceServices) && CollectionUtils.isNotEmpty(destinationServices)){
							deletePoliciesForResource(sourceServices, destinationServices, request, policies,destinationZoneName);//In order to delete Zone specific policies from service
						}
					}
					if (policies != null && !CollectionUtils.sizeIsEmpty(policies)){
						for (RangerPolicy policyInJson: policies){
							if (policyInJson != null){
								if (StringUtils.isNotBlank(destinationZoneName)) {
									boolean isZoneServiceExistAtDestination = validateDestZoneServiceMapping(destinationZoneName, policyInJson, servicesMappingMap);
									if(!isZoneServiceExistAtDestination) {
										LOG.warn("provided service of policy in File is not associated with zone");
										continue;
									}
								}
								policiesMap = svcStore.createPolicyMap(zoneMappingMap, sourceZones, destinationZoneName,
										servicesMappingMap, sourceServices, destinationServices, policyInJson,
										policiesMap);// zone Info is also sent for creating policy map
							}
						}
					}

					totalPolicyCreate = createPolicesBasedOnPolicyMap(request,policiesMap, serviceNameList, updateIfExists, totalPolicyCreate);
					if(!(totalPolicyCreate > 0)){
						LOG.error("zero policy is created from provided data file!!");
						throw restErrorUtil.createRESTException("zero policy is created from provided data file!!");
					}

				} catch (IOException e) {
					LOG.error(e.getMessage());
					throw restErrorUtil.createRESTException(e.getMessage());
				}
			}else{
				LOG.error("Provided file format is not supported!!");
				throw restErrorUtil.createRESTException("Provided file format is not supported!!");
			}
		} catch(JsonSyntaxException ex) { 
			LOG.error("Provided json file is not valid!!", ex);
			xxTrxLogError.setAction("IMPORT ERROR");
			xxTrxLogError.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
			if(StringUtils.isNotEmpty(metaDataInfo)){
				xxTrxLogError.setPreviousValue(metaDataInfo);
			}
			trxLogListError.add(xxTrxLogError);
			bizUtil.createTrxLog(trxLogListError);
			throw restErrorUtil.createRESTException(ex.getMessage());
	      }catch (WebApplicationException excp) {
			LOG.error("Error while importing policy from file!!", excp);
			xxTrxLogError.setAction("IMPORT ERROR");
			xxTrxLogError.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
			if(StringUtils.isNotEmpty(metaDataInfo)){
				xxTrxLogError.setPreviousValue(metaDataInfo);
			}
			trxLogListError.add(xxTrxLogError);
			bizUtil.createTrxLog(trxLogListError);
			throw excp;
		} catch (Throwable excp) {
			LOG.error("Error while importing policy from file!!", excp);
			xxTrxLogError.setAction("IMPORT ERROR");
			xxTrxLogError.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
			if(StringUtils.isNotEmpty(metaDataInfo)){
				xxTrxLogError.setPreviousValue(metaDataInfo);
			}
			trxLogListError.add(xxTrxLogError);
			bizUtil.createTrxLog(trxLogListError);
			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
			List<XXTrxLog> trxLogListEnd = new ArrayList<XXTrxLog>();
			XXTrxLog xxTrxLogEnd = new XXTrxLog();
			xxTrxLogEnd.setAction("IMPORT END");
			xxTrxLogEnd.setObjectClassType(AppConstants.CLASS_TYPE_RANGER_POLICY);
			if(StringUtils.isNotEmpty(metaDataInfo)){
				xxTrxLogEnd.setPreviousValue(metaDataInfo);
			}
			trxLogListEnd.add(xxTrxLogEnd);
			bizUtil.createTrxLog(trxLogListEnd);
			if (LOG.isDebugEnabled()) {
				LOG.debug("<== ServiceREST.importPoliciesFromFile()");
			}
		}
	}
	
	private int createPolicesBasedOnPolicyMap(HttpServletRequest request, Map<String, RangerPolicy> policiesMap,
			List<String> serviceNameList, boolean updateIfExists, int totalPolicyCreate) {
		boolean mergeIfExists  = "true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_MERGE_IF_EXISTS)))  ? true : false;
		boolean deleteIfExists = "true".equalsIgnoreCase(StringUtils.trimToEmpty(request.getParameter(PARAM_DELETE_IF_EXISTS))) ? true : false;
		if (!CollectionUtils.sizeIsEmpty(policiesMap.entrySet())) {
			for (Entry<String, RangerPolicy> entry : policiesMap.entrySet()) {
				RangerPolicy policy = entry.getValue();
				if (policy != null){
					if (!CollectionUtils.isEmpty(serviceNameList)) {
						for (String service : serviceNameList) {
							if (StringUtils.isNotEmpty(service.trim()) && StringUtils.isNotEmpty(policy.getService().trim())){
								if (policy.getService().trim().equalsIgnoreCase(service.trim())) {
									if (updateIfExists || mergeIfExists || deleteIfExists) {
										request.setAttribute(PARAM_SERVICE_NAME, policy.getService());
										request.setAttribute(PARAM_POLICY_NAME, policy.getName());
										request.setAttribute(PARAM_ZONE_NAME, policy.getZoneName());
										if(mergeIfExists && !ServiceRESTUtil.containsRangerCondition(policy)) {
											String user = request.getRemoteUser();
											RangerPolicy existingPolicy;
											try {
												existingPolicy = getExactMatchPolicyForResource(policy, StringUtils.isNotBlank(user) ? user :"admin");
											} catch (Exception e) {
												existingPolicy=null;
											}
											if (existingPolicy == null) {
												createPolicy(policy, request);
											} else {
												ServiceRESTUtil.mergeExactMatchPolicyForResource(existingPolicy, policy);
												updatePolicy(existingPolicy);
											}
										} else {
											createPolicy(policy, request);
										}
									} else {
										createPolicy(policy, request);
									}
									totalPolicyCreate = totalPolicyCreate + 1;
									if (LOG.isDebugEnabled()) {
										LOG.debug("Policy " + policy.getName() + " created successfully.");
									}
									break;
								}
							} else {
								LOG.error("Service Name or Policy Name is not provided!!");
								throw restErrorUtil.createRESTException("Service Name or Policy Name is not provided!!");
							}
						}
					} else {
						if (updateIfExists || mergeIfExists || deleteIfExists) {
							request.setAttribute(PARAM_SERVICE_NAME, policy.getService());
							request.setAttribute(PARAM_POLICY_NAME, policy.getName());
							request.setAttribute(PARAM_ZONE_NAME, policy.getZoneName());
							if(mergeIfExists && !ServiceRESTUtil.containsRangerCondition(policy)) {
								String user = request.getRemoteUser();
								RangerPolicy existingPolicy;
								try {
									existingPolicy = getExactMatchPolicyForResource(policy, StringUtils.isNotBlank(user) ? user :"admin");
								} catch (Exception e) {
									existingPolicy=null;
								}
								if (existingPolicy == null) {
									createPolicy(policy, request);
								} else {
									ServiceRESTUtil.mergeExactMatchPolicyForResource(existingPolicy, policy);
									updatePolicy(existingPolicy);
								}
							} else {
								createPolicy(policy, request);
							}
						} else {
							createPolicy(policy, request);
						}
						totalPolicyCreate = totalPolicyCreate + 1;
						if (LOG.isDebugEnabled()) {
							LOG.debug("Policy " + policy.getName() + " created successfully.");
						}
					}
				}
				if(totalPolicyCreate % RangerBizUtil.policyBatchSize == 0) {
					bizUtil.bulkModeOnlyFlushAndClear();
				}
			}
			bizUtil.bulkModeOnlyFlushAndClear();
			if (LOG.isDebugEnabled()) {
				LOG.debug("Total Policy Created From Json file : " + totalPolicyCreate);
			}
		}
		return totalPolicyCreate;
	}

	private List<RangerPolicy> getPoliciesFromProvidedJson(RangerExportPolicyList rangerExportPolicyList) {
		List<RangerPolicy> policies = null;
		if (rangerExportPolicyList != null && !CollectionUtils.sizeIsEmpty(rangerExportPolicyList.getPolicies())) {
			policies = rangerExportPolicyList.getPolicies();
		} else {
			LOG.error("Provided json file does not contain any policy!!");
			throw restErrorUtil.createRESTException("Provided json file does not contain any policy!!");
		}
		return policies;
	}

	private RangerExportPolicyList processPolicyInputJsonForMetaData(InputStream uploadedInputStream,
			RangerExportPolicyList rangerExportPolicyList) throws Exception {
		String policiesString = IOUtils.toString(uploadedInputStream);
		policiesString = policiesString.trim();
		if (StringUtils.isNotEmpty(policiesString)) {
			rangerExportPolicyList = JsonUtilsV2.jsonToObj(policiesString, RangerExportPolicyList.class);
		} else {
			LOG.error("Provided json file is empty!!");
			throw restErrorUtil.createRESTException("Provided json file is empty!!");
		}
		return rangerExportPolicyList;
	}

	private void getServiceNameList(HttpServletRequest request, List<String> serviceNameList) {
		SearchFilter filter = searchUtil.getSearchFilter(request,policyService.sortFields);
		String serviceType = null;
		List<String> serviceTypeList = null;
		if (StringUtils.isNotEmpty(request.getParameter(PARAM_SERVICE_TYPE))){
			serviceType = request.getParameter(PARAM_SERVICE_TYPE);
		}
		if(StringUtils.isNotEmpty(serviceType)){
			serviceTypeList = new ArrayList<String>(Arrays.asList(serviceType.split(",")));
		}
		List<RangerService> rangerServiceList = null;
		List<RangerService> rangerServiceLists = new ArrayList<RangerService>();
		if (CollectionUtils.isNotEmpty(serviceTypeList)){
			for (String s : serviceTypeList) {
				filter.removeParam(PARAM_SERVICE_TYPE);
				filter.setParam(PARAM_SERVICE_TYPE, s.trim());
				rangerServiceList = getServices(filter);
				rangerServiceLists.addAll(rangerServiceList);
			}
		}
		if(!CollectionUtils.sizeIsEmpty(rangerServiceLists)){
			for(RangerService rService : rangerServiceLists){
				if (StringUtils.isNotEmpty(rService.getName())){
					serviceNameList.add(rService.getName());
				}
			}
		}
	}

	private boolean validateDestZoneServiceMapping(String destinationZoneName, RangerPolicy policyInJson,
			Map<String, String> servicesMappingMap) {
		boolean isZoneServiceExistAtDestination = false;
		XXSecurityZone xdestZone = daoManager.getXXSecurityZoneDao().findByZoneName(destinationZoneName);
		if (xdestZone == null) {
			LOG.error("destination zone provided does not exist");
			throw restErrorUtil.createRESTException("destination zone provided does not exist");
		}
		// CHECK IF json policies service is there on destination and asscioated with
		// destination zone.

		String serviceNameToCheck = policyInJson.getService();

		if (StringUtils.isNotBlank(serviceNameToCheck) && servicesMappingMap.containsKey(serviceNameToCheck)) {
			serviceNameToCheck = servicesMappingMap.get(policyInJson.getService());
		}
		List<XXSecurityZoneRefService> serviceZoneMapping = daoManager.getXXSecurityZoneRefService()
				.findByServiceNameAndZoneId(serviceNameToCheck, xdestZone.getId());
		List<XXSecurityZoneRefTagService> tagServiceZoneMapping = daoManager.getXXSecurityZoneRefTagService()
				.findByTagServiceNameAndZoneId(serviceNameToCheck, xdestZone.getId());

		if (!CollectionUtils.isEmpty(serviceZoneMapping) || !CollectionUtils.isEmpty(tagServiceZoneMapping)) {
			isZoneServiceExistAtDestination = true;
		}

		return isZoneServiceExistAtDestination;
	}

	private String getDestinationZoneName(List<String> destinationZones, String zoneNameInJson) {
		String destinationZoneName = null;
		if (CollectionUtils.isNotEmpty(destinationZones)) {
			destinationZoneName = destinationZones.get(0);
		} else {
			destinationZoneName = zoneNameInJson;
		}
		return destinationZoneName;
	}

	private void processServiceMapping(Map<String, String> servicesMappingMap, List<String> sourceServices,
			List<String> destinationServices) {
		if (!CollectionUtils.sizeIsEmpty(servicesMappingMap)) {
			for (Entry<String, String> map : servicesMappingMap.entrySet()) {
				String sourceServiceName = null;
				String destinationServiceName = null;
				if (StringUtils.isNotEmpty(map.getKey().trim()) && StringUtils.isNotEmpty(map.getValue().trim())) {
					sourceServiceName = map.getKey().trim();
					destinationServiceName = map.getValue().trim();
				} else {
					LOG.error("Source service or destination service name is not provided!!");
					throw restErrorUtil
							.createRESTException("Source service or destonation service name is not provided!!");
				}
				if (StringUtils.isNotEmpty(sourceServiceName) && StringUtils.isNotEmpty(destinationServiceName)) {
					sourceServices.add(sourceServiceName);
					destinationServices.add(destinationServiceName);
				}
			}
		}
	}

	private void processZoneMapping(Map<String, String> zoneMappingMap, List<String> sourceZones,
			List<String> destinationZones) {

		if (!CollectionUtils.sizeIsEmpty(zoneMappingMap)) {
			for (Entry<String, String> map : zoneMappingMap.entrySet()) {
				String sourceZoneName = null;
				String destinationZoneName = null;
				if (StringUtils.isNotEmpty(map.getKey().trim()) || StringUtils.isNotEmpty(map.getValue().trim())) {
					// zone to zone
					// zone to unzone
					// unzone to zone
					sourceZoneName = map.getKey().trim();
					destinationZoneName = map.getValue().trim();
					LOG.info("sourceZoneName =" + sourceZoneName + "destinationZoneName = " + destinationZoneName);
				} else if (StringUtils.isEmpty(map.getKey().trim()) && StringUtils.isEmpty(map.getValue().trim())) {
					LOG.info("Unzone to unzone policies import");
				} else {
					LOG.error("Source zone or destination zone name is not provided!!");
					throw restErrorUtil.createRESTException("Source zone or destination zone name is not provided!!");
				}
				if (StringUtils.isNotEmpty(sourceZoneName) || StringUtils.isNotEmpty(destinationZoneName)) {
					sourceZones.add(sourceZoneName);
					destinationZones.add(destinationZoneName);
				}
			}
		}
	}

	private List<RangerPolicy> getAllFilteredPolicyList(SearchFilter filter,
			HttpServletRequest request, List<RangerPolicy> policyLists) {
		String serviceNames = null;
		String serviceType = null;
		List<String> serviceNameList = null;
		List<String> serviceTypeList = null;
		List<String> serviceNameInServiceTypeList = new ArrayList<String>();
		boolean isServiceExists = false;
		
		if (request.getParameter(PARAM_SERVICE_NAME) != null){
			serviceNames = request.getParameter(PARAM_SERVICE_NAME);
		}
		if (StringUtils.isNotEmpty(serviceNames)) {
			serviceNameList = new ArrayList<String>(Arrays.asList(serviceNames.split(",")));
		}
		
		if (request.getParameter(PARAM_SERVICE_TYPE) != null){
			serviceType = request.getParameter(PARAM_SERVICE_TYPE);
		}
		if(StringUtils.isNotEmpty(serviceType)){
			serviceTypeList = new ArrayList<String>(Arrays.asList(serviceType.split(",")));
		}
		
		List<RangerPolicy> policyList = new ArrayList<RangerPolicy>();
		List<RangerPolicy> policyListByServiceName = new ArrayList<RangerPolicy>();
		
		if (filter != null) {
			filter.setStartIndex(0);
			filter.setMaxRows(Integer.MAX_VALUE);
			
			if (!CollectionUtils.isEmpty(serviceTypeList)) {
				for (String s : serviceTypeList) {
					filter.removeParam(PARAM_SERVICE_TYPE);
					if (request.getParameter(PARAM_SERVICE_NAME) != null){
						filter.removeParam(PARAM_SERVICE_NAME);
					}
					filter.setParam(PARAM_SERVICE_TYPE, s.trim());
					policyList = getPolicies(filter);
					policyLists.addAll(policyList);
				}
				if(!CollectionUtils.sizeIsEmpty(policyLists)){
					for (RangerPolicy rangerPolicy:policyLists){
						if (StringUtils.isNotEmpty(rangerPolicy.getService())){
							serviceNameInServiceTypeList.add(rangerPolicy.getService());
						}
					}
				}
			}
			if (!CollectionUtils.isEmpty(serviceNameList) && !CollectionUtils.isEmpty(serviceTypeList)){
				isServiceExists = serviceNameInServiceTypeList.containsAll(serviceNameList);
				if(isServiceExists){
					for (String s : serviceNameList) {
						filter.removeParam(PARAM_SERVICE_NAME);
						filter.removeParam(PARAM_SERVICE_TYPE);
						filter.setParam(PARAM_SERVICE_NAME, s.trim());
						policyList = getPolicies(filter);
						policyListByServiceName.addAll(policyList);
					}
					policyLists = policyListByServiceName;
				}else{
					policyLists = new ArrayList<RangerPolicy>();
				}
			}else if (CollectionUtils.isEmpty(serviceNameList) && CollectionUtils.isEmpty(serviceTypeList)){
				policyLists = getPolicies(filter);
			}
			if (!CollectionUtils.isEmpty(serviceNameList) && CollectionUtils.isEmpty(serviceTypeList)) {
				for (String s : serviceNameList) {
					filter.removeParam(PARAM_SERVICE_NAME);
					filter.setParam(PARAM_SERVICE_NAME, s.trim());
					policyList = getPolicies(filter);
					policyLists.addAll(policyList);
				}
			}
		}
		if (StringUtils.isNotEmpty(request.getParameter("resourceMatch"))
				&& "full".equalsIgnoreCase(request.getParameter("resourceMatch"))) {
			policyLists = serviceUtil.getMatchingPoliciesForResource(request, policyLists);
		}
		Map<Long, RangerPolicy> orderedPolicies = new TreeMap<Long, RangerPolicy>();
		
		if (!CollectionUtils.isEmpty(policyLists)) {
			for (RangerPolicy policy : policyLists) {
				if (policy != null) {
					//set createTime & updateTime Time as null since exported policies dont need this
					policy.setCreateTime(null);
					policy.setUpdateTime(null);
					orderedPolicies.put(policy.getId(), policy);
				}
			}
			if (!orderedPolicies.isEmpty()) {
				policyLists.clear();
				policyLists.addAll(orderedPolicies.values());
			}
		}
		return policyLists;
	}
	
	private void deletePoliciesProvidedInServiceMap(List<String> sourceServices, List<String> destinationServices, String zoneName) throws Exception {
		int totalDeletedPolicies = 0;
		if (CollectionUtils.isNotEmpty(sourceServices)
				&& CollectionUtils.isNotEmpty(destinationServices)) {
			RangerPolicyValidator validator = validatorFactory.getPolicyValidator(svcStore);
			for (int i = 0; i < sourceServices.size(); i++) {
				if (!destinationServices.get(i).isEmpty() ) {
					SearchFilter filter = new SearchFilter();
					filter.setParam("zoneName",zoneName);
					RangerService service=getServiceByName(destinationServices.get(i));
					final RangerPolicyList servicePolicies = getServicePolicies(destinationServices.get(i),filter);
					if (servicePolicies != null) {
						List<RangerPolicy> rangerPolicyList = servicePolicies.getPolicies();
						if (CollectionUtils.isNotEmpty(rangerPolicyList)) {
							for (RangerPolicy rangerPolicy : rangerPolicyList) {
								if (rangerPolicy != null) {
									validator.validate(rangerPolicy.getId(), Action.DELETE);
									ensureAdminAccess(rangerPolicy);
									bizUtil.blockAuditorRoleUser();
									svcStore.deletePolicy(rangerPolicy, service);
									totalDeletedPolicies = totalDeletedPolicies + 1;
									if (totalDeletedPolicies % RangerBizUtil.policyBatchSize == 0) {
										bizUtil.bulkModeOnlyFlushAndClear();
									}
									if (LOG.isDebugEnabled()) {
										LOG.debug("Policy " + rangerPolicy.getName() + " deleted successfully.");
										LOG.debug("TotalDeletedPilicies: " + totalDeletedPolicies);
									}
								}
							}
							bizUtil.bulkModeOnlyFlushAndClear();
						}
					}
				}
			}
		}
		if (LOG.isDebugEnabled()) {
			LOG.debug("Total Deleted Policy : " + totalDeletedPolicies);
		}
	}

	private void deletePoliciesForResource(List<String> sourceServices, List<String> destinationServices, HttpServletRequest request, List<RangerPolicy> exportPolicies, String zoneName)  throws Exception {
		int totalDeletedPolicies = 0;
		if (CollectionUtils.isNotEmpty(sourceServices)
				&& CollectionUtils.isNotEmpty(destinationServices)) {
			Set<String> exportedPolicyNames=new HashSet<String>();
			if (CollectionUtils.isNotEmpty(exportPolicies)) {
				for (RangerPolicy rangerPolicy : exportPolicies) {
					if (rangerPolicy!=null) {
						exportedPolicyNames.add(rangerPolicy.getName());
					}
				}
			}
			for (int i = 0; i < sourceServices.size(); i++) {
				if (!destinationServices.get(i).isEmpty()) {
					RangerPolicyList servicePolicies = null;
					SearchFilter filter = searchUtil.getSearchFilter(request,policyService.sortFields);
					filter.setParam("zoneName", zoneName);
					servicePolicies = getServicePolicies(destinationServices.get(i), filter);
					RangerService service=getServiceByName(destinationServices.get(i));
					if (servicePolicies != null) {
						List<RangerPolicy> rangerPolicyList = servicePolicies.getPolicies();
						if (CollectionUtils.isNotEmpty(rangerPolicyList)) {
							List<RangerPolicy> policiesToBeDeleted = new ArrayList<RangerPolicy>();
							for (RangerPolicy rangerPolicy : rangerPolicyList) {
								if (rangerPolicy != null) {
									Map<String, RangerPolicy.RangerPolicyResource> rangerPolicyResourceMap=rangerPolicy.getResources();
									if (rangerPolicyResourceMap!=null) {
										RangerPolicy.RangerPolicyResource rangerPolicyResource=null;
										if (rangerPolicyResourceMap.containsKey("path")) {
					                        rangerPolicyResource=rangerPolicyResourceMap.get("path");
					                    } else if (rangerPolicyResourceMap.containsKey("database")) {
					                        rangerPolicyResource=rangerPolicyResourceMap.get("database");
					                    }
										if (rangerPolicyResource!=null) {
					                        if (CollectionUtils.isNotEmpty(rangerPolicyResource.getValues()) && rangerPolicyResource.getValues().size()>1) {
					                            continue;
					                        }
					                    }
									}
									if (rangerPolicy.getId() != null) {
										if (!exportedPolicyNames.contains(rangerPolicy.getName())) {
											policiesToBeDeleted.add(rangerPolicy);
										}
									}
								}
							}
							if (CollectionUtils.isNotEmpty(policiesToBeDeleted)) {
								for (RangerPolicy rangerPolicy : policiesToBeDeleted) {
									svcStore.deletePolicy(rangerPolicy, service);
									if (LOG.isDebugEnabled()) {
										LOG.debug("Policy " + rangerPolicy.getName() + " deleted successfully.");
									}
									totalDeletedPolicies = totalDeletedPolicies + 1;
									if (totalDeletedPolicies % RangerBizUtil.policyBatchSize == 0) {
										bizUtil.bulkModeOnlyFlushAndClear();
									}
								}
								bizUtil.bulkModeOnlyFlushAndClear();
							}
						}
					}
				}
			}
		}
	}

	public List<RangerPolicy> getPolicies(SearchFilter filter) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPolicies(filter)");
		}

		List<RangerPolicy> ret  = null;
		RangerPerfTracer   perf = null;

		try {
			if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getPolicies()");
			}
			ret = svcStore.getPolicies(filter);

			ret = applyAdminAccessFilter(ret);
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("getPolicies() failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPolicies(filter): count=" + (ret == null ? 0 : ret.size()));
		}

		return ret;
	}

	@GET
	@Path("/policies/count")
	@Produces({ "application/json", "application/xml" })
	public Long countPolicies( @Context HttpServletRequest request) {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.countPolicies():");
		}

		Long             ret  = null;
		RangerPerfTracer perf = null;

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.countPolicies()");
			}
			List<RangerPolicy> policies = getPolicies(request).getPolicies();

			policies = applyAdminAccessFilter(policies);
			
			ret = Long.valueOf(policies == null ? 0 : policies.size());
		} catch(WebApplicationException excp) {
			throw excp;
		} catch(Throwable excp) {
			LOG.error("countPolicies() failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.countPolicies(): " + ret);
		}

		return ret;
	}

	@GET
	@Path("/policies/service/{id}")
	@Produces({ "application/json", "application/xml" })
	public RangerPolicyList getServicePolicies(@PathParam("id") Long serviceId,
			@Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServicePolicies(" + serviceId + ")");
		}

		RangerPolicyList ret  = new RangerPolicyList();
		RangerPerfTracer perf = null;

		SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);

		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServicePolicies(serviceId=" + serviceId + ")");
			}

			if(isAdminUserWithNoFilterParams(filter)) {
				PList<RangerPolicy> policies = svcStore.getPaginatedServicePolicies(serviceId, filter);

				ret = toRangerPolicyList(policies);
			} else {
				// get all policies from the store; pick the page to return after applying filter
				int savedStartIndex = filter == null ? 0 : filter.getStartIndex();
				int savedMaxRows    = filter == null ? Integer.MAX_VALUE : filter.getMaxRows();

				if(filter != null) {
					filter.setStartIndex(0);
					filter.setMaxRows(Integer.MAX_VALUE);
				}

				List<RangerPolicy> servicePolicies = svcStore.getServicePolicies(serviceId, filter);

				if(filter != null) {
					filter.setStartIndex(savedStartIndex);
					filter.setMaxRows(savedMaxRows);
				}

				servicePolicies = applyAdminAccessFilter(servicePolicies);

				ret = toRangerPolicyList(servicePolicies, filter);
			}
		} catch(WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("getServicePolicies(" + serviceId + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getServicePolicies(" + serviceId + "): count="
					+ (ret == null ? 0 : ret.getListSize()));
		}
		return ret;
	}


	@GET
	@Path("/policies/service/name/{name}")
	@Produces({ "application/json", "application/xml" })
	public RangerPolicyList getServicePoliciesByName(@PathParam("name") String serviceName,
			@Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServicePolicies(" + serviceName + ")");
		}

		SearchFilter filter = searchUtil.getSearchFilter(request, policyService.sortFields);

		RangerPolicyList ret = getServicePolicies(serviceName, filter);

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getServicePolicies(" + serviceName + "): count="
					+ (ret == null ? 0 : ret.getListSize()));
		}

		return ret;
	}

	private RangerPolicyList getServicePolicies(String serviceName, SearchFilter filter) {
		RangerPerfTracer perf = null;
		try {
			if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
				perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServicePolicies(serviceName=" + serviceName + ")");
			}

			if(isAdminUserWithNoFilterParams(filter)) {
				PList<RangerPolicy> policies = svcStore.getPaginatedServicePolicies(serviceName, filter);

				return toRangerPolicyList(policies);
			} else {
				// get all policies from the store; pick the page to return after applying filter
				int savedStartIndex = filter == null ? 0 : filter.getStartIndex();
				int savedMaxRows    = filter == null ? Integer.MAX_VALUE : filter.getMaxRows();

				if(filter != null) {
					filter.setStartIndex(0);
					filter.setMaxRows(Integer.MAX_VALUE);
				}

				List<RangerPolicy> servicePolicies = svcStore.getServicePolicies(serviceName, filter);

				if(filter != null) {
					filter.setStartIndex(savedStartIndex);
					filter.setMaxRows(savedMaxRows);
				}

				servicePolicies = applyAdminAccessFilter(servicePolicies);

				return toRangerPolicyList(servicePolicies, filter);
			}
		} catch(WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("getServicePolicies(" + serviceName + ") failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		} finally {
			RangerPerfTracer.log(perf);
		}
	}

	@GET
	@Path("/policies/download/{serviceName}")
	@Produces({ "application/json", "application/xml" })
	public ServicePolicies getServicePoliciesIfUpdated(
			@PathParam("serviceName") String serviceName,
			@QueryParam("lastKnownVersion") Long lastKnownVersion,
			@DefaultValue("0") @QueryParam("lastActivationTime") Long lastActivationTime,
			@QueryParam("pluginId") String pluginId,
			@DefaultValue("") @QueryParam("clusterName") String clusterName,
			@DefaultValue("") @QueryParam("zoneName") String zoneName,
			@DefaultValue("false") @QueryParam("supportsPolicyDeltas") Boolean supportsPolicyDeltas,
			@DefaultValue("") @QueryParam("pluginCapabilities") String pluginCapabilities,
			@Context HttpServletRequest request) throws Exception {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServicePoliciesIfUpdated("
					+ serviceName + ", " + lastKnownVersion + ", "
					+ lastActivationTime + ", " + pluginId + ", "
					+ clusterName + ", " + supportsPolicyDeltas + ")");
		}

		ServicePolicies ret      = null;
		int             httpCode = HttpServletResponse.SC_OK;
		String          logMsg   = null;
		RangerPerfTracer perf    = null;
		Long downloadedVersion   = null;
		boolean isValid          = false;

		try {
			bizUtil.failUnauthenticatedIfNotAllowed();

			isValid = serviceUtil.isValidateHttpsAuthentication(serviceName, request);
		} catch (WebApplicationException webException) {
			httpCode = webException.getResponse().getStatus();
			logMsg = webException.getResponse().getEntity().toString();
		} catch (Exception e) {
			httpCode = HttpServletResponse.SC_BAD_REQUEST;
			logMsg = e.getMessage();
		}
		if (isValid) {
			if (lastKnownVersion == null) {
				lastKnownVersion = Long.valueOf(-1);
			}

			try {
				if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
					perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getServicePoliciesIfUpdated(serviceName=" + serviceName + ",lastKnownVersion=" + lastKnownVersion + ",lastActivationTime=" + lastActivationTime + ")");
				}
				ServicePolicies servicePolicies = svcStore.getServicePoliciesIfUpdated(serviceName, lastKnownVersion, !supportsPolicyDeltas);

				if (servicePolicies == null) {
					downloadedVersion = lastKnownVersion;
					httpCode = HttpServletResponse.SC_NOT_MODIFIED;
					logMsg = "No change since last update";
				} else {
					Map<String, RangerSecurityZone.RangerSecurityZoneService> securityZones = zoneStore.getSecurityZonesForService(serviceName);
					ServicePolicies updatedServicePolicies = servicePolicies;
					if (MapUtils.isNotEmpty(securityZones)) {
						updatedServicePolicies = RangerPolicyAdminCache.getUpdatedServicePoliciesForZones(servicePolicies, securityZones);
						patchAssociatedTagServiceInSecurityZoneInfos(updatedServicePolicies);
					}
					downloadedVersion = updatedServicePolicies.getPolicyVersion();
					if (lastKnownVersion == -1L || !supportsPolicyDeltas) {
						ret = filterServicePolicies(updatedServicePolicies);
					} else {
						ret = updatedServicePolicies;
					}

					httpCode = HttpServletResponse.SC_OK;
					logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : (ret.getPolicyDeltas() != null ? ret.getPolicyDeltas().size() : 0)) + " policies. Policy version=" + ret.getPolicyVersion();
				}
			} catch (Throwable excp) {
				LOG.error("getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ") failed", excp);

				httpCode = HttpServletResponse.SC_BAD_REQUEST;
				logMsg = excp.getMessage();
			} finally {
				createPolicyDownloadAudit(serviceName, lastKnownVersion, pluginId, httpCode, clusterName, zoneName, request);
				RangerPerfTracer.log(perf);
			}
		}
		assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_POLICIES, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);

		if(httpCode != HttpServletResponse.SC_OK) {
			boolean logError = httpCode != HttpServletResponse.SC_NOT_MODIFIED;
			throw restErrorUtil.createRESTException(httpCode, logMsg, logError);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ", " + pluginId + ", " + clusterName + ", " + supportsPolicyDeltas + "): count=" + ((ret == null || ret.getPolicies() == null) ? 0 : ret.getPolicies().size()));
		}

		return ret;
	}

	@GET
	@Path("/secure/policies/download/{serviceName}")
	@Produces({ "application/json", "application/xml" })
	public ServicePolicies getSecureServicePoliciesIfUpdated(
			@PathParam("serviceName") String serviceName,
			@QueryParam("lastKnownVersion") Long lastKnownVersion,
			@DefaultValue("0") @QueryParam("lastActivationTime") Long lastActivationTime,
			@QueryParam("pluginId") String pluginId,
			@DefaultValue("") @QueryParam("clusterName") String clusterName,
			@DefaultValue("") @QueryParam("zoneName") String zoneName,
			@DefaultValue("false") @QueryParam("supportsPolicyDeltas") Boolean supportsPolicyDeltas,
			@DefaultValue("") @QueryParam("pluginCapabilities") String pluginCapabilities,
			@Context HttpServletRequest request) throws Exception {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getSecureServicePoliciesIfUpdated("
					+ serviceName + ", " + lastKnownVersion + ", " 
					+ lastActivationTime + ", " + pluginId + ", "
					+ clusterName + ", " + supportsPolicyDeltas + ")");
		}
		ServicePolicies ret = null;
		int httpCode = HttpServletResponse.SC_OK;
		String logMsg = null;
		RangerPerfTracer perf = null;
		boolean isAllowed = false;
		boolean isAdmin = bizUtil.isAdmin();
		boolean isKeyAdmin = bizUtil.isKeyAdmin();
		request.setAttribute("downloadPolicy", "secure");
		Long downloadedVersion = null;
		boolean isValid = false;
		try {
			isValid = serviceUtil.isValidService(serviceName, request);
		} catch (WebApplicationException webException) {
			httpCode = webException.getResponse().getStatus();
			logMsg = webException.getResponse().getEntity().toString();
		} catch (Exception e) {
			httpCode = HttpServletResponse.SC_BAD_REQUEST;
			logMsg = e.getMessage();
		}
		if (isValid) {
			if (lastKnownVersion == null) {
				lastKnownVersion = Long.valueOf(-1);
			}
			try {
				if (RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
					perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.getSecureServicePoliciesIfUpdated(serviceName=" + serviceName + ",lastKnownVersion=" + lastKnownVersion + ",lastActivationTime=" + lastActivationTime + ")");
				}
				XXService xService = daoManager.getXXService().findByName(serviceName);
				XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());
				RangerService rangerService = null;

				if (StringUtils.equals(xServiceDef.getImplclassname(), EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
					rangerService = svcStore.getServiceByNameForDP(serviceName);
					if (isKeyAdmin) {
						isAllowed = true;
					} else {
						if (rangerService != null) {
							isAllowed = bizUtil.isUserAllowed(rangerService, Allowed_User_List_For_Download);
							if (!isAllowed) {
								isAllowed = bizUtil.isUserAllowed(rangerService, Allowed_User_List_For_Grant_Revoke);
							}
						}
					}
				} else {
					rangerService = svcStore.getServiceByName(serviceName);
					if (isAdmin) {
						isAllowed = true;
					} else {
						if (rangerService != null) {
							isAllowed = bizUtil.isUserAllowed(rangerService, Allowed_User_List_For_Download);
							if (!isAllowed) {
								isAllowed = bizUtil.isUserAllowed(rangerService, Allowed_User_List_For_Grant_Revoke);
							}
						}
					}
				}
				if (isAllowed) {
					ServicePolicies servicePolicies = svcStore.getServicePoliciesIfUpdated(serviceName, lastKnownVersion, !supportsPolicyDeltas);
					if (servicePolicies == null) {
						downloadedVersion = lastKnownVersion;
						httpCode = HttpServletResponse.SC_NOT_MODIFIED;
						logMsg = "No change since last update";
					} else {
						Map<String, RangerSecurityZone.RangerSecurityZoneService> securityZones = zoneStore.getSecurityZonesForService(serviceName);
						ServicePolicies updatedServicePolicies = servicePolicies;
						if (MapUtils.isNotEmpty(securityZones)) {
							updatedServicePolicies = RangerPolicyAdminCache.getUpdatedServicePoliciesForZones(servicePolicies, securityZones);
							patchAssociatedTagServiceInSecurityZoneInfos(updatedServicePolicies);
						}
						downloadedVersion = updatedServicePolicies.getPolicyVersion();
						if (lastKnownVersion == -1L || !supportsPolicyDeltas) {
							ret = filterServicePolicies(updatedServicePolicies);
						} else {
							ret = updatedServicePolicies;
						}
						httpCode = HttpServletResponse.SC_OK;
						logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : (ret.getPolicyDeltas() != null ? ret.getPolicyDeltas().size() : 0)) + " policies. Policy version=" + ret.getPolicyVersion();
					}

				} else {
					LOG.error("getSecureServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ") failed as User doesn't have permission to download Policy");
					httpCode = HttpServletResponse.SC_UNAUTHORIZED;
					logMsg = "User doesn't have permission to download policy";
				}
			} catch (Throwable excp) {
				LOG.error("getSecureServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ") failed", excp);
				httpCode = HttpServletResponse.SC_BAD_REQUEST;
				logMsg = excp.getMessage();
			} finally {
				createPolicyDownloadAudit(serviceName, lastKnownVersion, pluginId, httpCode, clusterName, zoneName, request);
				RangerPerfTracer.log(perf);
			}
		}
		assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_POLICIES, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode, clusterName, pluginCapabilities);

		if (httpCode != HttpServletResponse.SC_OK) {
			boolean logError = httpCode != HttpServletResponse.SC_NOT_MODIFIED;
			throw restErrorUtil.createRESTException(httpCode, logMsg, logError);
		}
		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getSecureServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ", " + pluginId + ", " + clusterName + ", " + supportsPolicyDeltas + "): count=" + ((ret == null || ret.getPolicies() == null) ? 0 : ret.getPolicies().size()));
		}
		return ret;
	}

	@DELETE
	@Path("/server/policydeltas")
	@PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
	public void deletePolicyDeltas(@DefaultValue("7") @QueryParam("days") Integer olderThan, @Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.deletePolicyDeltas(" + olderThan + ")");
		}

		svcStore.resetPolicyUpdateLog(olderThan, RangerPolicyDelta.CHANGE_TYPE_INVALIDATE_POLICY_DELTAS);

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.deletePolicyDeltas(" + olderThan + ")");
		}
	}

	private void createPolicyDownloadAudit(String serviceName, Long lastKnownVersion, String pluginId, int httpRespCode, String clusterName, String zoneName, HttpServletRequest request) {
		try {
			String ipAddress = request.getHeader("X-FORWARDED-FOR");

			if (ipAddress == null) {
				ipAddress = request.getRemoteAddr();
			}

			XXPolicyExportAudit policyExportAudit = new XXPolicyExportAudit();

			policyExportAudit.setRepositoryName(serviceName);
			policyExportAudit.setAgentId(pluginId);
			policyExportAudit.setClientIP(ipAddress);
			policyExportAudit.setRequestedEpoch(lastKnownVersion);
			policyExportAudit.setHttpRetCode(httpRespCode);
			policyExportAudit.setClusterName(clusterName);
			policyExportAudit.setZoneName(zoneName);
			assetMgr.createPolicyAudit(policyExportAudit);
		} catch(Exception excp) {
			LOG.error("error while creating policy download audit", excp);
		}
	}

	private RangerPolicy getExactMatchPolicyForResource(String serviceName, RangerAccessResource resource, String user) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getExactMatchPolicyForResource(" + resource + ", " + user + ")");
		}

		RangerPolicy       ret         = null;
		RangerPolicyAdmin  policyAdmin = getPolicyAdmin(serviceName);
		List<RangerPolicy> policies    = policyAdmin != null ? policyAdmin.getExactMatchPolicies(resource, null) : null;

		if(CollectionUtils.isNotEmpty(policies)) {
			// at this point, ret is a policy in policy-engine; the caller might update the policy (for grant/revoke); so get a copy from the store
			ret = svcStore.getPolicy(policies.get(0).getId());
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getExactMatchPolicyForResource(" + resource + ", " + user + "): " + ret);
		}

		return ret;
	}

	private RangerPolicy getExactMatchPolicyForResource(RangerPolicy policy, String user) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getExactMatchPolicyForResource(" + policy + ", " + user + ")");
		}

		RangerPolicy       ret         = null;
		RangerPolicyAdmin  policyAdmin = getPolicyAdmin(policy.getService());
		List<RangerPolicy> policies    = policyAdmin != null ? policyAdmin.getExactMatchPolicies(policy, null) : null;

		if(CollectionUtils.isNotEmpty(policies)) {
			// at this point, ret is a policy in policy-engine; the caller might update the policy (for grant/revoke); so get a copy from the store
			if(policies.size()==1) {
				ret = svcStore.getPolicy(policies.get(0).getId());
			} else {
				if (StringUtils.isNotEmpty(policy.getZoneName())) {
					for(RangerPolicy existingPolicy:policies) {
						if (StringUtils.equals(policy.getZoneName(), existingPolicy.getZoneName())) {
							ret = svcStore.getPolicy(existingPolicy.getId());
							break;
						}
					}
				}
			}
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getExactMatchPolicyForResource(" + policy + ", " + user + "): " + ret);
		}

		return ret;
	}

	@GET
	@Path("/policies/eventTime")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_POLICY_FROM_EVENT_TIME + "\")")
	public RangerPolicy getPolicyFromEventTime(@Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPolicyFromEventTime()");
		}

		String eventTimeStr = request.getParameter("eventTime");
		String policyIdStr = request.getParameter("policyId");
		String versionNoStr = request.getParameter("versionNo");

		if (StringUtils.isEmpty(eventTimeStr) || StringUtils.isEmpty(policyIdStr)) {
			throw restErrorUtil.createRESTException("EventTime or policyId cannot be null or empty string.",
					MessageEnums.INVALID_INPUT_DATA);
		}

		Long policyId = Long.parseLong(policyIdStr);

		RangerPolicy policy=null;

		if (!StringUtil.isEmpty(versionNoStr)) {
			int policyVersion = Integer.parseInt(versionNoStr);
			try {
				policy = svcStore.getPolicyForVersionNumber(policyId, policyVersion);
				if (policy != null) {
					ensureAdminAndAuditAccess(policy);
				}
			} catch (WebApplicationException excp) {
				throw excp;
			} catch (Throwable excp) {
				// Ignore any other exception and go for fetching the policy by eventTime
			}
		}

		if (policy == null) {
			try {
				policy = svcStore.getPolicyFromEventTime(eventTimeStr, policyId);
				if (policy != null) {
					ensureAdminAndAuditAccess(policy);
				}
			} catch (WebApplicationException excp) {
				throw excp;
			} catch (Throwable excp) {
				LOG.error("getPolicy(" + policyId + ") failed", excp);

				throw restErrorUtil.createRESTException(excp.getMessage());
			}
		}

		if(policy == null) {
			throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPolicy(" + policyId + "): " + policy);
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPolicyFromEventTime()");
		}

		return policy;
	}

	@GET
	@Path("/policy/{policyId}/versionList")
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_POLICY_VERSION_LIST + "\")")
	public VXString getPolicyVersionList(@PathParam("policyId") Long policyId) {

		VXString policyVersionListStr = svcStore.getPolicyVersionList(policyId);

		return policyVersionListStr;
	}

	@GET
	@Path("/policy/{policyId}/version/{versionNo}")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_POLICY_FOR_VERSION_NO + "\")")
	public RangerPolicy getPolicyForVersionNumber(@PathParam("policyId") Long policyId,
			@PathParam("versionNo") int versionNo) {
		return svcStore.getPolicyForVersionNumber(policyId, versionNo);
	}

	@GET
	@Path("/plugins/info")
	@Produces({ "application/json", "application/xml" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_PLUGINS_INFO + "\")")
	public RangerPluginInfoList getPluginsInfo(@Context HttpServletRequest request) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPluginsInfo()");
		}

		RangerPluginInfoList ret = null;

		SearchFilter filter = searchUtil.getSearchFilter(request, pluginInfoService.getSortFields());

		try {
			PList<RangerPluginInfo> paginatedPluginsInfo = pluginInfoService.searchRangerPluginInfo(filter);
			if (paginatedPluginsInfo != null) {
				ret = new RangerPluginInfoList();

				ret.setPluginInfoList(paginatedPluginsInfo.getList());
				ret.setPageSize(paginatedPluginsInfo.getPageSize());
				ret.setResultSize(paginatedPluginsInfo.getResultSize());
				ret.setStartIndex(paginatedPluginsInfo.getStartIndex());
				ret.setTotalCount(paginatedPluginsInfo.getTotalCount());
				ret.setSortBy(paginatedPluginsInfo.getSortBy());
				ret.setSortType(paginatedPluginsInfo.getSortType());
			}
		} catch (WebApplicationException excp) {
			throw excp;
		} catch (Throwable excp) {
			LOG.error("getPluginsInfo() failed", excp);

			throw restErrorUtil.createRESTException(excp.getMessage());
		}
		if (LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPluginsInfo()");
		}

		return ret;
	}

	private RangerPolicy getPolicyByGuid(String guid, String serviceName, String zoneName) {
		RangerPolicy ret = null;

		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPolicyByGuid(" + guid +")");
		}

		SearchFilter filter = new SearchFilter();
		filter.setParam(SearchFilter.GUID, guid);
		filter.setParam(SearchFilter.SERVICE_NAME, serviceName);
		if(StringUtils.isNotEmpty(zoneName)) {
			filter.setParam(SearchFilter.ZONE_NAME, zoneName);
		}
		List<RangerPolicy> policies = getPolicies(filter);

		if (CollectionUtils.isNotEmpty(policies)) {
			ret = policies.get(0);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPolicyByGuid(" + guid + ")" + ret);
		}
		return ret;
	}

	private RangerPolicy getPolicyByName(String serviceName,String policyName) {
		RangerPolicy ret = null;
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPolicyByName(" + serviceName + "," + policyName + ")");
		}

		SearchFilter filter = new SearchFilter();
		filter.setParam(SearchFilter.SERVICE_NAME, serviceName);
		filter.setParam(SearchFilter.POLICY_NAME, policyName);
		List<RangerPolicy> policies = getPolicies(filter);

		if (CollectionUtils.isNotEmpty(policies)) {
			ret = policies.get(0);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPolicyByName(" + serviceName + "," + policyName + ")" + ret);
		}
		return ret;
	}

	private RangerPolicy getPolicyByNameAndZone(String serviceName, String policyName, String zoneName) {
		RangerPolicy ret = null;
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getPolicyByNameAndZone(" + serviceName + "," + policyName + "," + zoneName + ")");
		}

		SearchFilter filter = new SearchFilter();
		filter.setParam(SearchFilter.SERVICE_NAME, serviceName);
		filter.setParam(SearchFilter.POLICY_NAME, policyName);
		filter.setParam(SearchFilter.ZONE_NAME, zoneName);
		List<RangerPolicy> policies = getPolicies(filter);

		if (CollectionUtils.isNotEmpty(policies) && policies.size()==1) {
			ret = policies.get(0);
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug("<== ServiceREST.getPolicyByNameAndZone(" + serviceName + "," + policyName + "," + zoneName + ")");
		}
		return ret;
	}

	private List<RangerPolicy> applyAdminAccessFilter(List<RangerPolicy> policies) {
		List<RangerPolicy> ret = new ArrayList<RangerPolicy>();
		RangerPerfTracer  perf = null;

		if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
			perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.applyAdminAccessFilter(policyCount=" + (policies == null ? 0 : policies.size()) + ")");
		}

		if (CollectionUtils.isNotEmpty(policies)) {
			boolean     isAdmin    = bizUtil.isAdmin();
			boolean     isKeyAdmin = bizUtil.isKeyAdmin();
			String      userName   = bizUtil.getCurrentUserLoginId();
                        boolean	    isAuditAdmin = bizUtil.isAuditAdmin();
                        boolean     isAuditKeyAdmin = bizUtil.isAuditKeyAdmin();
			Set<String> userGroups = null;

			Map<String, List<RangerPolicy>> servicePoliciesMap = new HashMap<String, List<RangerPolicy>>();

			for (int i = 0; i < policies.size(); i++) {
				RangerPolicy       policy      = policies.get(i);
				String             serviceName = policy.getService();
				List<RangerPolicy> policyList  = servicePoliciesMap.get(serviceName);

				if (policyList == null) {
					policyList = new ArrayList<RangerPolicy>();

					servicePoliciesMap.put(serviceName, policyList);
				}
					policyList.add(policy);
				}

			for (Map.Entry<String, List<RangerPolicy>> entry : servicePoliciesMap.entrySet()) {
				String             serviceName  = entry.getKey();
				List<RangerPolicy> listToFilter = entry.getValue();

				if (CollectionUtils.isNotEmpty(listToFilter)) {
					boolean isServiceAdminUser = isAdmin || svcStore.isServiceAdminUser(serviceName, userName);
					if (isAdmin || isKeyAdmin || isAuditAdmin
							|| isAuditKeyAdmin) {
						XXService xService = daoManager.getXXService()
								.findByName(serviceName);
						Long serviceDefId = xService.getType();
						boolean isKmsService = serviceDefId
								.equals(EmbeddedServiceDefsUtil.instance()
										.getKmsServiceDefId());

						if (isAdmin) {
							if (!isKmsService) {
								ret.addAll(listToFilter);
							}
						} else if (isAuditAdmin) {
							if (!isKmsService) {
								ret.addAll(listToFilter);
							}
						} else if (isAuditKeyAdmin) {
							if (isKmsService) {
								ret.addAll(listToFilter);
							}
						} else if (isKeyAdmin) {
							if (isKmsService) {
								ret.addAll(listToFilter);
							}
						} 
						continue;
					}

					RangerPolicyAdmin policyAdmin = getPolicyAdminForDelegatedAdmin(serviceName);

					if (policyAdmin != null) {
						if(userGroups == null) {
							userGroups = daoManager.getXXGroupUser().findGroupNamesByUserName(userName);
						}
						Set<String> roles = policyAdmin.getRolesFromUserAndGroups(userName, userGroups);

						for (RangerPolicy policy : listToFilter) {
							if (policyAdmin.isAccessAllowed(policy, userName, userGroups, roles, RangerPolicyEngine.ADMIN_ACCESS)
									|| (!StringUtils.isEmpty(policy.getZoneName()) && (serviceMgr.isZoneAdmin(policy.getZoneName()) || serviceMgr.isZoneAuditor(policy.getZoneName())))
									|| isServiceAdminUser) {
								ret.add(policy);
							}
						}
					}

				}
			}
		}

		RangerPerfTracer.log(perf);

		return ret;
	}
	
	void ensureAdminAccess(RangerPolicy policy) {
		boolean isAdmin = bizUtil.isAdmin();
		boolean isKeyAdmin = bizUtil.isKeyAdmin();
		String userName = bizUtil.getCurrentUserLoginId();
		boolean isSvcAdmin = isAdmin || svcStore.isServiceAdminUser(policy.getService(), userName);

		if (!isAdmin && !isKeyAdmin && !isSvcAdmin) {
			boolean isAllowed = false;

			Set<String> userGroups = userMgr.getGroupsForUser(userName);
			
			//for zone policy create /update / delete
			if(!StringUtils.isEmpty(policy.getZoneName()) && serviceMgr.isZoneAdmin(policy.getZoneName())){
				isAllowed = true;
			}else{
				isAllowed = hasAdminAccess(policy, userName, userGroups);
			}
			
			

			if (!isAllowed) {
				throw restErrorUtil.createRESTException(HttpServletResponse.SC_UNAUTHORIZED,
						"User '" + userName + "' does not have delegated-admin privilege on given resources", true);
			}
		} else {

			XXService xService = daoManager.getXXService().findByName(policy.getService());
			XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());

			if (isAdmin) {
				if (EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xServiceDef.getImplclassname())) {
					throw restErrorUtil.createRESTException(
							"KMS Policies/Services/Service-Defs are not accessible for user '" + userName + "'.",
							MessageEnums.OPER_NO_PERMISSION);
				}
			} else if (isKeyAdmin) {
				if (!EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xServiceDef.getImplclassname())) {
					throw restErrorUtil.createRESTException(
							"Only KMS Policies/Services/Service-Defs are accessible for user '" + userName + "'.",
							MessageEnums.OPER_NO_PERMISSION);
				}
			}
		}
	}

	private RangerPolicyEngineOptions getDelegatedAdminPolicyEngineOptions() {
		RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();

		final String propertyPrefix = "ranger.admin";

		opts.configureDelegateAdmin(config, propertyPrefix);

		return opts;
	}

	private RangerPolicyEngineOptions getPolicySearchRangerAdminPolicyEngineOptions() {
		RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();

		final String propertyPrefix = "ranger.admin";

		opts.configureRangerAdminForPolicySearch(config, propertyPrefix);
		return opts;
	}

	private RangerPolicyEngineOptions getDefaultRangerAdminPolicyEngineOptions() {
		RangerPolicyEngineOptions opts = new RangerPolicyEngineOptions();

		final String propertyPrefix = "ranger.admin";

		opts.configureDefaultRangerAdmin(config, propertyPrefix);
		return opts;
	}

	private boolean hasAdminAccess(RangerPolicy policy, String userName, Set<String> userGroups) {
		boolean           isAllowed   = false;
		RangerPolicyAdmin policyAdmin = getPolicyAdminForDelegatedAdmin(policy.getService());

		if(policyAdmin != null) {
			Set<String> roles = policyAdmin.getRolesFromUserAndGroups(userName, userGroups);

			isAllowed = policyAdmin.isAccessAllowed(policy, userName, userGroups, roles, RangerPolicyEngine.ADMIN_ACCESS);
		}

		return isAllowed;
	}
	private boolean hasAdminAccess(String serviceName, String userName, Set<String> userGroups, RangerAccessResource resource) {
		boolean isAllowed = false;

		RangerPolicyAdmin policyAdmin = getPolicyAdminForDelegatedAdmin(serviceName);

		if(policyAdmin != null) {
			isAllowed = policyAdmin.isAccessAllowed(resource, userName, userGroups, RangerPolicyEngine.ADMIN_ACCESS);
		}

		return isAllowed;
	}

	public RangerPolicyAdmin getPolicyAdminForDelegatedAdmin(String serviceName) {
		return RangerPolicyAdminCacheForEngineOptions.getInstance().getServicePoliciesAdmin(serviceName, svcStore, zoneStore, roleDBStore, delegateAdminOptions);
	}

	private RangerPolicyAdmin getPolicyAdminForSearch(String serviceName) {
		return RangerPolicyAdminCacheForEngineOptions.getInstance().getServicePoliciesAdmin(serviceName, svcStore, zoneStore, roleDBStore, policySearchAdminOptions);
	}

	private RangerPolicyAdmin getPolicyAdmin(String serviceName) {
		return RangerPolicyAdminCacheForEngineOptions.getInstance().getServicePoliciesAdmin(serviceName, svcStore, zoneStore,roleDBStore, defaultAdminOptions);
	}

	@GET
	@Path("/checksso")
	@Produces(MediaType.TEXT_PLAIN)
	public String checkSSO() {
		return String.valueOf(bizUtil.isSSOEnabled());
	}
	
	@GET
	@Path("/csrfconf")
	@Produces({ "application/json"})
	public HashMap<String, Object> getCSRFProperties() {
		return getCSRFPropertiesMap();
	}

        @GET
        @Path("/metrics/type/{type}")
        @Produces({ "application/json", "application/xml" })
        @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\""+ RangerAPIList.GET_METRICS_BY_TYPE + "\")")
        public String getMetricByType(@PathParam("type") String type) {
                if (LOG.isDebugEnabled()) {
                        LOG.debug("==> ServiceREST.getMetricByType(serviceDefName=" + type + ")");
                }
                // as of now we are allowing only users with Admin role to access this
                // API
                bizUtil.checkSystemAdminAccess();
                bizUtil.blockAuditorRoleUser();
                String ret = null;
                try {
                        ret = svcStore.getMetricByType(type);
                } catch (WebApplicationException excp) {
                        throw excp;
                } catch (Throwable excp) {
                        LOG.error("getMetricByType(" + type + ") failed", excp);
                        throw restErrorUtil.createRESTException(excp.getMessage());
                }
                if (ret == null) {
                        throw restErrorUtil.createRESTException(HttpServletResponse.SC_NOT_FOUND, "Not found", true);
                }

                if (LOG.isDebugEnabled()) {
                        LOG.debug("<== ServiceREST.getMetricByType(" + type + "): " + ret);
                }
                return ret;
        }

	private HashMap<String, Object> getCSRFPropertiesMap() {
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put(isCSRF_ENABLED, PropertiesUtil.getBooleanProperty(isCSRF_ENABLED, true));
		map.put(CUSTOM_HEADER_PARAM, PropertiesUtil.getProperty(CUSTOM_HEADER_PARAM, RangerCSRFPreventionFilter.HEADER_DEFAULT));
		map.put(BROWSER_USER_AGENT_PARAM, PropertiesUtil.getProperty(BROWSER_USER_AGENT_PARAM, RangerCSRFPreventionFilter.BROWSER_USER_AGENTS_DEFAULT));
		map.put(CUSTOM_METHODS_TO_IGNORE_PARAM, PropertiesUtil.getProperty(CUSTOM_METHODS_TO_IGNORE_PARAM, RangerCSRFPreventionFilter.METHODS_TO_IGNORE_DEFAULT));
		return map;
	}
	
	boolean isAdminUserWithNoFilterParams(SearchFilter filter) {
		return (filter == null || MapUtils.isEmpty(filter.getParams())) &&
			   (bizUtil.isAdmin() || bizUtil.isKeyAdmin());
	}

	private RangerPolicyList toRangerPolicyList(PList<RangerPolicy> policyList) {
		RangerPolicyList ret = new RangerPolicyList();

		if(policyList != null) {
			ret.setPolicies(policyList.getList());
			ret.setPageSize(policyList.getPageSize());
			ret.setResultSize(policyList.getResultSize());
			ret.setStartIndex(policyList.getStartIndex());
			ret.setTotalCount(policyList.getTotalCount());
			ret.setSortBy(policyList.getSortBy());
			ret.setSortType(policyList.getSortType());
		}

		return ret;
	}

	private RangerPolicyList toRangerPolicyList(List<RangerPolicy> policyList, SearchFilter filter) {
		RangerPolicyList ret = new RangerPolicyList();

		if(CollectionUtils.isNotEmpty(policyList)) {
			int    totalCount = policyList.size();
			int    startIndex = filter.getStartIndex();
			int    pageSize   = filter.getMaxRows();
			int    toIndex    = Math.min(startIndex + pageSize, totalCount);
			String sortType   = filter.getSortType();
			String sortBy     = filter.getSortBy();

			List<RangerPolicy> retList = new ArrayList<RangerPolicy>();
			for(int i = startIndex; i < toIndex; i++) {
				retList.add(policyList.get(i));
			}

			ret.setPolicies(retList);
			ret.setPageSize(pageSize);
			ret.setResultSize(retList.size());
			ret.setStartIndex(startIndex);
			ret.setTotalCount(totalCount);
			ret.setSortBy(sortBy);
			ret.setSortType(sortType);
		}

		return ret;
	}

	private ServicePolicies filterServicePolicies(ServicePolicies servicePolicies) {
		ServicePolicies ret = null;
		boolean containsDisabledResourcePolicies = false;
		boolean containsDisabledTagPolicies = false;

		if (servicePolicies != null) {
			List<RangerPolicy> policies = null;

			policies = servicePolicies.getPolicies();
			if (CollectionUtils.isNotEmpty(policies)) {
				for (RangerPolicy policy : policies) {
					if (!policy.getIsEnabled()) {
						containsDisabledResourcePolicies = true;
						break;
					}
				}
			}

			if (servicePolicies.getTagPolicies() != null) {
				policies = servicePolicies.getTagPolicies().getPolicies();
				if (CollectionUtils.isNotEmpty(policies)) {
					for (RangerPolicy policy : policies) {
						if (!policy.getIsEnabled()) {
							containsDisabledTagPolicies = true;
							break;
						}
					}
				}
			}

			if (!containsDisabledResourcePolicies && !containsDisabledTagPolicies) {
				ret = servicePolicies;
			} else {
				ret = new ServicePolicies();

				ret.setServiceDef(servicePolicies.getServiceDef());
				ret.setServiceId(servicePolicies.getServiceId());
				ret.setServiceName(servicePolicies.getServiceName());
				ret.setPolicyVersion(servicePolicies.getPolicyVersion());
				ret.setPolicyUpdateTime(servicePolicies.getPolicyUpdateTime());
				ret.setPolicies(servicePolicies.getPolicies());
				ret.setTagPolicies(servicePolicies.getTagPolicies());
				ret.setSecurityZones(servicePolicies.getSecurityZones());

				if (containsDisabledResourcePolicies) {
					List<RangerPolicy> filteredPolicies = new ArrayList<RangerPolicy>();
					for (RangerPolicy policy : servicePolicies.getPolicies()) {
						if (policy.getIsEnabled()) {
							filteredPolicies.add(policy);
						}
					}
					ret.setPolicies(filteredPolicies);
				}

				if (containsDisabledTagPolicies) {
					ServicePolicies.TagPolicies tagPolicies = new ServicePolicies.TagPolicies();

					tagPolicies.setServiceDef(servicePolicies.getTagPolicies().getServiceDef());
					tagPolicies.setServiceId(servicePolicies.getTagPolicies().getServiceId());
					tagPolicies.setServiceName(servicePolicies.getTagPolicies().getServiceName());
					tagPolicies.setPolicyVersion(servicePolicies.getTagPolicies().getPolicyVersion());
					tagPolicies.setPolicyUpdateTime(servicePolicies.getTagPolicies().getPolicyUpdateTime());

					List<RangerPolicy> filteredPolicies = new ArrayList<RangerPolicy>();
					for (RangerPolicy policy : servicePolicies.getTagPolicies().getPolicies()) {
						if (policy.getIsEnabled()) {
							filteredPolicies.add(policy);
						}
					}
					tagPolicies.setPolicies(filteredPolicies);

					ret.setTagPolicies(tagPolicies);
				}
			}
		}

		return ret;
	}

	private void validateGrantRevokeRequest(GrantRevokeRequest request, final boolean hasAdminPrivilege, final String loggedInUser) {
		if (request != null) {
			validateUsersGroupsAndRoles(request.getUsers(),request.getGroups(), request.getRoles());
			validateGrantor(request.getGrantor());
			validateGrantees(request.getUsers());
			validateGroups(request.getGroups());
			validateRoles(request.getRoles());

			if (!hasAdminPrivilege) {
				if (!StringUtils.equals(request.getGrantor(), loggedInUser) || StringUtils.isNotBlank(request.getOwnerUser())) {
					throw restErrorUtil.createGrantRevokeRESTException("Invalid grant/revoke request - contains grantor or userOwner specification");
				}
				request.setGrantorGroups(userMgr.getGroupsForUser(request.getGrantor()));
			}
		}
	}

	private void validateUsersGroupsAndRoles(Set<String> users, Set<String> groups, Set<String> roles){
		if(CollectionUtils.isEmpty(users) && CollectionUtils.isEmpty(groups) && CollectionUtils.isEmpty(roles)) {
			throw restErrorUtil.createGrantRevokeRESTException("Grantee users/groups/roles list is empty");
		}
	}

	private void validateGrantor(String grantor)  {
		VXUser   vxUser = null;
		if (grantor != null) {
			try {
				vxUser = userMgr.getXUserByUserName(grantor);
				if (vxUser == null) {
					throw restErrorUtil.createGrantRevokeRESTException("Grantor user " + grantor + " doesn't exist");
				}
			} catch (Exception e) {
				throw restErrorUtil.createGrantRevokeRESTException("Grantor user " + grantor + " doesn't exist");
			}
		}
	}

	private void validateGrantees(Set<String> grantees) {
		VXUser   vxUser = null;
		for (String userName : grantees) {
			try {
				vxUser = userMgr.getXUserByUserName(userName);
				if (vxUser == null) {
					throw restErrorUtil.createGrantRevokeRESTException("Grantee user " + userName + " doesn't exist");
				}
			} catch (Exception e) {
				throw restErrorUtil.createGrantRevokeRESTException("Grantee user " + userName + " doesn't exist");
			}
		}
	}

	private void validateGroups(Set<String> groups) {
		VXGroup   vxGroup = null;
		for (String groupName : groups) {
			try {
				vxGroup = userMgr.getGroupByGroupName(groupName);
				if (vxGroup == null) {
					throw restErrorUtil.createGrantRevokeRESTException( "Grantee group "+ groupName +" doesn't exist");
				}
			} catch (Exception e) {
				throw restErrorUtil.createGrantRevokeRESTException( "Grantee group "+ groupName +" doesn't exist");
			}
		}
	}

	private void validateRoles(Set<String> roles)  {
		XXRole xxRole = null;
		for (String role : roles) {
			try {
				xxRole = daoManager.getXXRole().findByRoleName(role);
				if (xxRole == null) {
					throw restErrorUtil.createGrantRevokeRESTException( "Grantee role "+ role +" doesn't exist");
				}
			} catch (Exception e) {
				throw restErrorUtil.createGrantRevokeRESTException( "Grantee role "+ role +" doesn't exist");
			}
		}
	}

	private Map<String, Object> getOptions(HttpServletRequest request) {
	    Map<String, Object> ret = null;
	    if (request != null) {
	        String isForceRenameOption = request.getParameter(ServiceStore.OPTION_FORCE_RENAME);
	        if (StringUtils.isNotBlank(isForceRenameOption)) {
	            ret = new HashMap<String, Object>();
	            ret.put(ServiceStore.OPTION_FORCE_RENAME, Boolean.valueOf(isForceRenameOption));
            }
        }
        return ret;
    }
	
	private RangerService hideCriticalServiceDetailsForRoleUser(RangerService rangerService){
		RangerService ret = rangerService;
		
		ret.setConfigs(null);
		ret.setDescription(null);
		ret.setCreatedBy(null);
		ret.setUpdatedBy(null);
		ret.setCreateTime(null);
		ret.setUpdateTime(null);
		ret.setPolicyVersion(null);
		ret.setPolicyUpdateTime(null);
		ret.setTagVersion(null);
		ret.setTagUpdateTime(null);
		ret.setVersion(null);
		
		return ret;
	}

	void ensureAdminAndAuditAccess(RangerPolicy policy) {
		boolean isAdmin = bizUtil.isAdmin();
		boolean isKeyAdmin = bizUtil.isKeyAdmin();
		String userName = bizUtil.getCurrentUserLoginId();
		boolean isAuditAdmin = bizUtil.isAuditAdmin();
		boolean isAuditKeyAdmin = bizUtil.isAuditKeyAdmin();
		boolean isSvcAdmin = isAdmin || svcStore.isServiceAdminUser(policy.getService(), userName) || (!StringUtils.isEmpty(policy.getZoneName()) && (serviceMgr.isZoneAdmin(policy.getZoneName()) || serviceMgr.isZoneAuditor(policy.getZoneName())));
		if (!isAdmin && !isKeyAdmin && !isSvcAdmin && !isAuditAdmin && !isAuditKeyAdmin) {
			boolean isAllowed = false;

			Set<String> userGroups = userMgr.getGroupsForUser(userName);
			isAllowed = hasAdminAccess(policy, userName, userGroups);

			if (!isAllowed) {
				throw restErrorUtil.createRESTException(HttpServletResponse.SC_UNAUTHORIZED, "User '"
						+ userName + "' does not have delegated-admin privilege on given resources", true);
			}
		} else {

			XXService xService = daoManager.getXXService().findByName(policy.getService());
			XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());

			if (isAdmin || isAuditAdmin) {
				if (EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xServiceDef.getImplclassname())) {
					throw restErrorUtil.createRESTException(
							"KMS Policies/Services/Service-Defs are not accessible for user '"
									+ userName + "'.", MessageEnums.OPER_NO_PERMISSION);
				}
			} else if (isKeyAdmin || isAuditKeyAdmin) {
				if (!EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xServiceDef.getImplclassname())) {
					throw restErrorUtil.createRESTException("Only KMS Policies/Services/Service-Defs are accessible for user '"
							+ userName + "'.", MessageEnums.OPER_NO_PERMISSION);
				}
			}
		}
	}

	private void patchAssociatedTagServiceInSecurityZoneInfos(ServicePolicies servicePolicies) {
		if (servicePolicies != null && MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
			// Get list of zones that associated tag-service (if any) is associated with
			List<String> zonesInAssociatedTagService = new ArrayList<>();

			String tagServiceName = servicePolicies.getTagPolicies() != null ? servicePolicies.getTagPolicies().getServiceName() : null;
			if (StringUtils.isNotEmpty(tagServiceName)) {
				try {
					RangerService tagService = svcStore.getServiceByName(tagServiceName);
					if (tagService != null && tagService.getIsEnabled()) {
						zonesInAssociatedTagService = daoManager.getXXSecurityZoneDao().findZonesByTagServiceName(tagServiceName);
					}
				} catch (Exception exception) {
					LOG.warn("Could not get service associated with [" + tagServiceName + "]", exception);
				}
			}
			if (CollectionUtils.isNotEmpty(zonesInAssociatedTagService)) {
				for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> entry : servicePolicies.getSecurityZones().entrySet()) {
					String zoneName = entry.getKey();
					ServicePolicies.SecurityZoneInfo securityZoneInfo = entry.getValue();

					securityZoneInfo.setContainsAssociatedTagService(zonesInAssociatedTagService.contains(zoneName));
				}
			}
		}
	}

	private void scheduleCreateOrGetTagService(RangerService resourceService) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> scheduleCreateOrGetTagService(resourceService=" + resourceService.getName() + ")");
		}
		final boolean isAutoCreateTagService = config.getBoolean("ranger.tagservice.auto.create", true);

		if (isAutoCreateTagService) {

			String tagServiceName = config.get("ranger.tagservice.auto.name");

			if (StringUtils.isBlank(tagServiceName)) {
				tagServiceName = getGeneratedTagServiceName(resourceService.getName());
			}

			if (StringUtils.isNotBlank(tagServiceName)) {
				if (LOG.isDebugEnabled()) {
					LOG.debug("Attempting to get/create and possibly link to tag-service:[" + tagServiceName + "]");
				}

				final boolean isAutoLinkTagService = config.getBoolean("ranger.tagservice.auto.link", true);
				RangerService tagService = null;

				try {
					tagService = svcStore.getServiceByName(tagServiceName);
				} catch (Exception e) {
					LOG.info("failed to retrieve tag-service [" + tagServiceName + "]. Will attempt to create.", e);
				}

				if (tagService == null) {
					final TagServiceOperationContext context = new TagServiceOperationContext(tagServiceName, resourceService.getName(), isAutoLinkTagService);

					Runnable createAndLinkTagServiceTask = new Runnable() {
						@Override
						public void run() {
							Runnable realTask = new Runnable() {
								@Override
								public void run() {
									doCreateAndLinkTagService(context);
								}
							};
							transactionService.scheduleToExecuteInOwnTransaction(realTask, 0L);
						}
					};

					rangerTransactionSynchronizationAdapter.executeOnTransactionCommit(createAndLinkTagServiceTask);

				} else if (isAutoLinkTagService) {
					resourceService.setTagService(tagServiceName);
				}
			}
		}
		if (LOG.isDebugEnabled()) {
			LOG.debug("<== scheduleCreateOrGetTagService(resourceService=" + resourceService.getName() + ")");
		}
	}

	private String getGeneratedTagServiceName(String resourceServiceName) {
		int lastIndexOfMarker = StringUtils.lastIndexOf(resourceServiceName, '_');
		if (lastIndexOfMarker != -1) {
			return resourceServiceName.substring(0, lastIndexOfMarker) + "_tag";
		} else {
			return null;
		}
	}

	private final class TagServiceOperationContext {
		final String tagServiceName;
		final String resourceServiceName;
		final boolean isAutoLinkTagService;

		TagServiceOperationContext(@Nonnull String tagserviceName, @Nonnull String resourceServiceName, boolean isAutoLinkTagService) {
			this.tagServiceName = tagserviceName;
			this.resourceServiceName = resourceServiceName;
			this.isAutoLinkTagService = isAutoLinkTagService;
		}

		@Override
		public String toString() {
			return "{tagServiceName=" + tagServiceName + ", resourceServiceName=" + resourceServiceName + ", isAutoLinkTagService=" + isAutoLinkTagService + "}";
		}
	}

	private void doCreateAndLinkTagService(final TagServiceOperationContext context) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> doCreateAndLinkTagService(context=" + context + ")");
		}

		RangerService resourceService = null;

		try {
			resourceService = svcStore.getServiceByName(context.resourceServiceName);
			LOG.info("Successfully retrieved resource-service:[" + resourceService.getName() + "]");
		} catch (Exception e) {
			LOG.error("Resource-service:[" + context.resourceServiceName + "] cannot be retrieved");
		}

		if (resourceService != null) {

			RangerService tagService = new RangerService();

			tagService.setName(context.tagServiceName);
			tagService.setType(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME);

			LOG.info("creating tag-service [" + context.tagServiceName + "]");

			RangerService service;

			try {
				service = svcStore.createService(tagService);
				LOG.info("Created tag-service:[" + service.getName() + "]");
			} catch (Exception e) {
				LOG.info("Failed to create tag-service " + context.tagServiceName, e);
			}

			if (context.isAutoLinkTagService) {
				Runnable linkTagServiceTask = new Runnable() {
					@Override
					public void run() {
						Runnable realTask = new Runnable() {
							@Override
							public void run() {
								doLinkTagService(context);
							}
						};
						transactionService.scheduleToExecuteInOwnTransaction(realTask, 0L);
					}
				};
				rangerTransactionSynchronizationAdapter.executeOnTransactionCompletion(linkTagServiceTask);
			}
		}

		if (LOG.isDebugEnabled()) {
			LOG.debug("<== doCreateAndLinkTagService(context=" + context + ")");
		}
	}

	private void doLinkTagService(final TagServiceOperationContext context) {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> doLinkTagService(context=" + context + ")");
		}
		try {
			RangerService resourceService = svcStore.getServiceByName(context.resourceServiceName);
			LOG.info("Successfully retrieved resource-service:[" + resourceService.getName() + "]");

			RangerService tagService = svcStore.getServiceByName(context.tagServiceName);
			LOG.info("Successfully retrieved tag-service:[" + tagService.getName() + "]");

			if (!StringUtils.equals(tagService.getName(), resourceService.getTagService())) {
				resourceService.setTagService(tagService.getName());

				LOG.info("Linking resource-service[" + resourceService.getName() + "] with tag-service [" + tagService.getName() + "]");

				RangerService service = svcStore.updateService(resourceService, null);

				LOG.info("Updated resource-service:[" + service.getName() + "]");
			}
		} catch (Exception e) {
			LOG.error("Failed to link service[" + context.resourceServiceName + "] with tag-service [" + context.tagServiceName + "]");
		}
		if (LOG.isDebugEnabled()) {
			LOG.debug("<== doLinkTagService(context=" + context + ")");
		}
	}

	private void deleteExactMatchPolicyForResource(List<RangerPolicy> policies, String user, String zoneName) throws Exception {
		if (CollectionUtils.isNotEmpty(policies)) {
			long totalDeletedPolicies = 0;
			for (RangerPolicy rangerPolicy : policies) {
				RangerPolicy existingPolicy = null ;
				try {
					if(zoneName!=null) {
						rangerPolicy.setZoneName(zoneName);
					}
					existingPolicy = getExactMatchPolicyForResource(rangerPolicy, StringUtils.isNotBlank(user) ? user :"admin");
				} catch (Exception e) {
					existingPolicy=null;
				}
				if (existingPolicy != null) {
					svcStore.deletePolicy(existingPolicy, null);
					totalDeletedPolicies = totalDeletedPolicies + 1;
					if (totalDeletedPolicies % RangerBizUtil.policyBatchSize == 0) {
						bizUtil.bulkModeOnlyFlushAndClear();
					}
					if (LOG.isDebugEnabled()) {
						LOG.debug("Policy " + rangerPolicy.getName() + " deleted successfully.");
					}
				}
			}
			bizUtil.bulkModeOnlyFlushAndClear();
		}
	}
}


