/*
 * 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 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.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.RangerConfiguration;
import org.apache.ranger.biz.AssetMgr;
import org.apache.ranger.biz.RangerBizUtil;
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.JSONUtil;
import org.apache.ranger.common.MessageEnums;
import org.apache.ranger.common.PropertiesUtil;
import org.apache.ranger.common.RESTErrorUtil;
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.db.RangerDaoManager;
import org.apache.ranger.entity.XXPolicyExportAudit;
import org.apache.ranger.entity.XXService;
import org.apache.ranger.entity.XXServiceDef;
import org.apache.ranger.entity.XXTrxLog;
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.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.validation.RangerPolicyValidator;
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.plugin.policyengine.RangerPolicyEngineCache;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import org.apache.ranger.plugin.service.ResourceLookupContext;
import org.apache.ranger.plugin.store.PList;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.GrantRevokeRequest;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
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.web.filter.RangerCSRFPreventionFilter;
import org.apache.ranger.service.RangerPluginInfoService;
import org.apache.ranger.service.RangerPolicyService;
import org.apache.ranger.service.RangerServiceDefService;
import org.apache.ranger.service.RangerServiceService;
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.VXResponse;
import org.apache.ranger.view.VXString;
import org.codehaus.jackson.map.ObjectMapper;
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.Gson;
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_UPDATE_IF_EXISTS = "updateIfExists";
	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
	AssetMgr assetMgr;

	@Autowired
	XUserMgr userMgr;

	@Autowired
	ServiceDBStore svcStore;
	
	@Autowired
	ServiceUtil serviceUtil;

	@Autowired
	RangerPolicyService policyService;
	
	@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
    JSONUtil jsonUtil;

	public ServiceREST() {
	}

	@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;

		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());

			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() + ")");
			}
			RangerServiceDefValidator validator = validatorFactory.getServiceDefValidator(svcStore);
			validator.validate(serviceDef, Action.UPDATE);

			bizUtil.hasAdminPermissions("Service-Def");
			bizUtil.hasKMSPermissions("Service-Def", serviceDef.getImplClass());

			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);
			bizUtil.hasKMSPermissions("Service-Def", xServiceDef.getImplclassname());

			String forceDeleteStr = request.getParameter("forceDelete");
			boolean forceDelete = false;
			if(!StringUtils.isEmpty(forceDeleteStr) && forceDeleteStr.equalsIgnoreCase("true")) {
				forceDelete = true;
			}
			
			svcStore.deleteServiceDef(id, forceDelete);
		} 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 (!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 (!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()");
		}

		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;
	}
	
	@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;

		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);

			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() && !xxServiceDef.getImplclassname().equals(EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
					throw restErrorUtil.createRESTException("KeyAdmin can create/update/delete only KMS ",
							MessageEnums.OPER_NO_PERMISSION);
				}
				if ((!session.isKeyAdmin() && !session.isUserAdmin()) && xxServiceDef.getImplclassname().equals(EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
					throw restErrorUtil.createRESTException("User cannot create/update/delete KMS Service",
							MessageEnums.OPER_NO_PERMISSION);
				}
			}
			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) {
		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() + ")");
			}
			RangerServiceValidator validator = validatorFactory.getServiceValidator(svcStore);
			validator.validate(service, Action.UPDATE);

			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());

			ret = svcStore.updateService(service);
		} 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 + ")");
		}

		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);

			bizUtil.hasAdminPermissions("Services");

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

			XXService service = daoManager.getXXService().getById(id);
			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());
			bizUtil.hasKMSPermissions("Service", xxServiceDef.getImplclassname());

			tagStore.deleteAllTagObjectsForService(service.getName());

			svcStore.deleteService(id);
		} 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);
		} 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);
		} 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) {
				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 {
					if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
						perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.grantAccess(serviceName=" + serviceName + ")");
					}

					validateGrantRevokeRequest(grantRequest);
					String               userName   = grantRequest.getGrantor();
					Set<String>          userGroups = userMgr.getGroupsForUser(userName);
					RangerAccessResource resource   = new RangerAccessResourceImpl(grantRequest.getResource());
	
					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) {
							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(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());
	
						for(String accessType : grantRequest.getAccessTypes()) {
							policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, Boolean.TRUE));
						}
	
						policy.getPolicyItems().add(policyItem);
	
						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;
		boolean isAllowed = false;
		boolean isKeyAdmin = bizUtil.isKeyAdmin();
		if(grantRequest!=null){
			if (serviceUtil.isValidService(serviceName, request)) {
				try {
					if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
						perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.scureGrantAccess(serviceName=" + serviceName + ")");
					}

					validateGrantRevokeRequest(grantRequest);

					String               userName   = grantRequest.getGrantor();
					Set<String>          userGroups = userMgr.getGroupsForUser(userName);
					RangerAccessResource resource   = new RangerAccessResourceImpl(grantRequest.getResource());
					boolean isAdmin = hasAdminAccess(serviceName, userName, userGroups, resource);

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

					if (StringUtils.equals(xServiceDef.getImplclassname(), EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
						if (isKeyAdmin) {
							isAllowed = true;
						}else {
							isAllowed = bizUtil.isUserAllowedForGrantRevoke(rangerService, Allowed_User_List_For_Grant_Revoke, userName);
						}
					}else{
						if (isAdmin) {
							isAllowed = true;
						}
						else{
							isAllowed = bizUtil.isUserAllowedForGrantRevoke(rangerService, Allowed_User_List_For_Grant_Revoke, userName);
						}
					}

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

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

							if(policyUpdated) {
								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(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());

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

							policy.getPolicyItems().add(policyItem);

							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 {
					if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
						perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.revokeAccess(serviceName=" + serviceName + ")");
					}

					validateGrantRevokeRequest(revokeRequest);

					String               userName   = revokeRequest.getGrantor();
					Set<String>          userGroups =  userMgr.getGroupsForUser(userName);
					RangerAccessResource resource   = new RangerAccessResourceImpl(revokeRequest.getResource());

					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) {
							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;
		if(revokeRequest!=null){
			if (serviceUtil.isValidService(serviceName,request)) {
				try {
					if(RangerPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
						perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.secureRevokeAccess(serviceName=" + serviceName + ")");
					}

					validateGrantRevokeRequest(revokeRequest);

					String               userName   = revokeRequest.getGrantor();
					Set<String>          userGroups =  userMgr.getGroupsForUser(userName);
					RangerAccessResource resource   = new RangerAccessResourceImpl(revokeRequest.getResource());
					boolean isAdmin = hasAdminAccess(serviceName, userName, userGroups, resource);
					boolean isAllowed = false;
					boolean isKeyAdmin = bizUtil.isKeyAdmin();

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

					if (StringUtils.equals(xServiceDef.getImplclassname(), EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME)) {
						if (isKeyAdmin) {
							isAllowed = true;
						}else {
							isAllowed = bizUtil.isUserAllowedForGrantRevoke(rangerService, Allowed_User_List_For_Grant_Revoke, userName);
						}
					}else{
						if (isAdmin) {
							isAllowed = true;
						}
						else{
							isAllowed = bizUtil.isUserAllowedForGrantRevoke(rangerService, Allowed_User_List_For_Grant_Revoke, userName);
						}
					}

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

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

							if(policyUpdated) {
								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) {
				String serviceName    = request.getParameter(PARAM_SERVICE_NAME);
				String policyName     = request.getParameter(PARAM_POLICY_NAME);
				String updateIfExists = request.getParameter(PARAM_UPDATE_IF_EXISTS);

				if(StringUtils.isNotEmpty(serviceName)) {
					policy.setService(serviceName);
				}

				if(StringUtils.isNotEmpty(policyName)) {
					policy.setName(StringUtils.trim(policyName));
				}

				if(Boolean.valueOf(updateIfExists)) {
					RangerPolicy existingPolicy = null;
					try {
						if(StringUtils.isNotEmpty(policy.getGuid())) {
							existingPolicy = getPolicyByGuid(policy.getGuid());
						}

						if(existingPolicy == null && StringUtils.isNotEmpty(serviceName) && StringUtils.isNotEmpty(policyName)) {
							existingPolicy = getPolicyByName(policy.getService(), policy.getName());
						}

						if(existingPolicy != null) {
							ret = updatePolicy(policy);
						}
					} catch(Exception excp) {
						LOG.info("ServiceREST.createPolicy(): Failed to find/update exising policy, will attempt to create the policy", excp);
					}
				}
			}

			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.getService(), policy.getResources());

				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.getService(), policy.getResources(), 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.getService(), policy.getResources());

			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.getService(), policy.getResources());

			svcStore.deletePolicy(id);
		} 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) {
				ensureAdminAccess(ret.getService(), ret.getResources());
			}
		} 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("/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
				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> policies = svcStore.getPolicies(filter);

				if(filter != null) {
					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)){
				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 = new ObjectMapper().writeValueAsString(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)){
				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 = new ObjectMapper().writeValueAsString(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);

		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)) {
				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 = new ObjectMapper().writeValueAsString(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);
		}
	}
	
	@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("file") InputStream uploadedInputStream,
			@FormDataParam("file") FormDataContentDisposition fileDetail,
			@QueryParam("isOverride") Boolean isOverride) {
		
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.importPoliciesFromFile()");
		}
		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);
			trxLogList.add(xxTrxLog);
			bizUtil.createTrxLog(trxLogList);
			
			if (isOverride == null){
				isOverride = false;
			}
			List<String> serviceNameList = new ArrayList<String>();
			String serviceType = null;
			List<String> serviceTypeList = null;
			SearchFilter filter = searchUtil.getSearchFilter(request,policyService.sortFields);
			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());
					}
				}
			}

			Map<String, String> servicesMappingMap = new LinkedHashMap<String, String>();
			List<String> sourceServices = new ArrayList<String>();
			List<String> destinationServices = new ArrayList<String>();
			if (serviceMapStream != null){
				servicesMappingMap = svcStore.getServiceMap(serviceMapStream);
			}
			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 destonation 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);
					}
				}
			}	
			
			String fileName = fileDetail.getFileName();
			int totalPolicyCreate = 0;
			Map<String, RangerPolicy> policiesMap = new LinkedHashMap<String, RangerPolicy>();
			List<String> dataFileSourceServices = new ArrayList<String>();
			if (fileName.endsWith("json")) {
				try {
					RangerExportPolicyList rangerExportPolicyList = new RangerExportPolicyList();
					List<RangerPolicy> policies = new ArrayList<RangerPolicy>();
					Gson gson = new Gson();
					
					String policiesString = IOUtils.toString(uploadedInputStream);
					policiesString = policiesString.trim();
					if (StringUtils.isNotEmpty(policiesString)){
						gson.fromJson(policiesString, RangerExportPolicyList.class);
						rangerExportPolicyList = new ObjectMapper().readValue(policiesString, RangerExportPolicyList.class);
					} else {
						LOG.error("Provided json file is empty!!");
						throw restErrorUtil.createRESTException("Provided json file is empty!!");
					}
					if (!CollectionUtils.sizeIsEmpty(rangerExportPolicyList.getMetaDataInfo())){
						metaDataInfo = new ObjectMapper().writeValueAsString(rangerExportPolicyList.getMetaDataInfo());
					} else {
						LOG.info("metadata info is not provided!!");
					}
					if (!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!!");
					}
					if (CollectionUtils.sizeIsEmpty(servicesMappingMap) && isOverride){
						if(!CollectionUtils.sizeIsEmpty(policies)){
							for (RangerPolicy policyInJson: policies){
								if (policyInJson != null) {
									if (StringUtils.isNotEmpty(policyInJson.getService().trim())) {
										String serviceName = policyInJson.getService().trim();
										if (CollectionUtils.isNotEmpty(serviceNameList) && serviceNameList.contains(serviceName)) {
											sourceServices.add(serviceName);
											destinationServices.add(serviceName);
										} else if (CollectionUtils.isEmpty(serviceNameList)) {
											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!!");
									}
								}
							}
						}
					}else if (!CollectionUtils.sizeIsEmpty(servicesMappingMap)) {
						if (!CollectionUtils.sizeIsEmpty(policies)){
							for (RangerPolicy policyInJson: policies){
								if (policyInJson != null){
									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!!");
									}
								}
							}
							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.");
							}
						}
					}
					if (isOverride){
						if (LOG.isDebugEnabled()) {
							LOG.debug("Deleting Policy from provided services in servicesMapJson file...");
						}
						if (CollectionUtils.isNotEmpty(sourceServices) && CollectionUtils.isNotEmpty(destinationServices)){
							deletePoliciesProvidedInServiceMap(sourceServices,
									destinationServices, null);
						}
					}
					if (!CollectionUtils.sizeIsEmpty(policies)){
						for (RangerPolicy policyInJson: policies){
							if (policyInJson != null){
								policiesMap = svcStore.createPolicyMap(servicesMappingMap, sourceServices, destinationServices, policyInJson, policiesMap);
							}
						}
					}
					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())) {
												createPolicy(policy, null);
												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{
									createPolicy(policy, null);
									totalPolicyCreate = totalPolicyCreate + 1;
									if (LOG.isDebugEnabled()) {
										LOG.debug("Policy " + policy.getName() + " created successfully.");
									}
								}
							}
						}
						if (LOG.isDebugEnabled()) {
							LOG.debug("Total Policy Created From Json file : " + 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 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);
				}
			}
		}
		Map<Long, RangerPolicy> orderedPolicies = new TreeMap<Long, RangerPolicy>();
		
		if (!CollectionUtils.isEmpty(policyLists)) {
			for (RangerPolicy policy : policyLists) {
				if (policy != null) {
					orderedPolicies.put(policy.getId(), policy);
				}
			}
			if (orderedPolicies.size() > 0) {
				policyLists.clear();
				policyLists.addAll(orderedPolicies.values());
			}
		}
		return policyLists;
	}
	
	private void deletePoliciesProvidedInServiceMap(
			List<String> sourceServices, List<String> destinationServices,
			HttpServletRequest request) {
		int totalDeletedPilicies = 0;
		if (CollectionUtils.isNotEmpty(sourceServices)
				&& CollectionUtils.isNotEmpty(destinationServices)) {
			for (int i = 0; i < sourceServices.size(); i++) {
				if (!destinationServices.get(i).isEmpty()) {
					RangerPolicyList servicePolicies = null;
					servicePolicies = getServicePoliciesByName(destinationServices.get(i), request);
					if (servicePolicies != null) {
						List<RangerPolicy> rangerPolicyList = servicePolicies.getPolicies();
						if (CollectionUtils.isNotEmpty(rangerPolicyList)) {
							for (RangerPolicy rangerPolicy : rangerPolicyList) {
								if (rangerPolicy != null) {
									if (rangerPolicy.getId() != null){
										deletePolicy(rangerPolicy.getId());
										if (LOG.isDebugEnabled()) {
											LOG.debug("Policy " + rangerPolicy.getName() + " deleted successfully." );
										}
										totalDeletedPilicies = totalDeletedPilicies + 1;
									}
								}
							}
						}
					}
				}
			}
		}
		if (LOG.isDebugEnabled()) {
			LOG.debug("Total Deleted Policy : " + totalDeletedPilicies);
		}
	}

	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 + ")");
		}

		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(serviceName=" + serviceName + ")");
			}

			if(isAdminUserWithNoFilterParams(filter)) {
				PList<RangerPolicy> policies = svcStore.getPaginatedServicePolicies(serviceName, 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(serviceName, 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(" + serviceName + ") failed", excp);

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

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

		return ret;
	}

	@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, @Context HttpServletRequest request) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ")");
		}

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

		try {
			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);

				if (servicePolicies == null) {
					downloadedVersion = lastKnownVersion;
					httpCode = HttpServletResponse.SC_NOT_MODIFIED;
					logMsg = "No change since last update";
				} else {
					downloadedVersion = servicePolicies.getPolicyVersion();
					ret = filterServicePolicies(servicePolicies);
					httpCode = HttpServletResponse.SC_OK;
					logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : 0) + " policies. Policy version=" + ret.getPolicyVersion();
				}
			} catch (Throwable excp) {
				LOG.error("getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ", " + lastActivationTime + ") failed");

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

		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 + "): 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,@Context HttpServletRequest request) throws Exception {
		if (LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getSecureServicePoliciesIfUpdated("+ serviceName + ", " + lastKnownVersion + ")");
		}
		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);
					if (servicePolicies == null) {
						downloadedVersion = lastKnownVersion;
						httpCode = HttpServletResponse.SC_NOT_MODIFIED;
						logMsg = "No change since last update";
					} else {
						downloadedVersion = servicePolicies.getPolicyVersion();
						ret = filterServicePolicies(servicePolicies);
						httpCode = HttpServletResponse.SC_OK;
						logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().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");
				httpCode = HttpServletResponse.SC_BAD_REQUEST;
				logMsg = excp.getMessage();
			} finally {
				createPolicyDownloadAudit(serviceName, lastKnownVersion, pluginId, httpCode, request);
				RangerPerfTracer.log(perf);
			}
		}
		assetMgr.createPluginInfo(serviceName, pluginId, request, RangerPluginInfo.ENTITY_TYPE_POLICIES, downloadedVersion, lastKnownVersion, lastActivationTime, httpCode);

		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 + "): count=" + ((ret == null || ret.getPolicies() == null) ? 0 : ret.getPolicies().size()));
		}
		return ret;
	}		

	private void createPolicyDownloadAudit(String serviceName, Long lastKnownVersion, String pluginId, int httpRespCode, 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);

			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;
		RangerPolicyEngine policyEngine = getPolicyEngine(serviceName);

		Map<String, Object> evalContext = new HashMap<String, Object>();
		RangerAccessRequestUtil.setCurrentUserInContext(evalContext, user);

		List<RangerPolicy> policies     = policyEngine != null ? policyEngine.getExactMatchPolicies(resource, evalContext) : 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(String serviceName, Map<String, RangerPolicyResource> resources, String user) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug("==> ServiceREST.getExactMatchPolicyForResource(" + resources + ", " + user + ")");
		}

		RangerPolicy       ret          = null;
		RangerPolicyEngine policyEngine = getPolicyEngine(serviceName);

		Map<String, Object> evalContext = new HashMap<String, Object>();
		RangerAccessRequestUtil.setCurrentUserInContext(evalContext, user);

		List<RangerPolicy> policies     = policyEngine != null ? policyEngine.getExactMatchPolicies(resources, evalContext) : 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(" + resources + ", " + 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");

		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;
		try {
			policy = svcStore.getPolicyFromEventTime(eventTimeStr, policyId);
			if(policy != null) {
				ensureAdminAccess(policy.getService(), policy.getResources());
			}
		} 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) {
		RangerPolicy ret = null;

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

		SearchFilter filter = new SearchFilter();
		filter.setParam(SearchFilter.GUID, guid);
		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 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();
			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)) {
					if (isAdmin || isKeyAdmin) {
						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 { // isKeyAdmin
							if (isKmsService) {
								ret.addAll(listToFilter);
							}
						}

						continue;
					}

					RangerPolicyEngine policyEngine = getDelegatedAdminPolicyEngine(serviceName);

					if (policyEngine != null) {
						if(userGroups == null) {
							userGroups = daoManager.getXXGroupUser().findGroupNamesByUserName(userName);
						}

						for (RangerPolicy policy : listToFilter) {
							if (policyEngine.isAccessAllowed(policy.getResources(), userName, userGroups, RangerPolicyEngine.ADMIN_ACCESS)) {
								ret.add(policy);
							}
						}
					}

				}
			}
		}

		RangerPerfTracer.log(perf);

		return ret;
	}

	void ensureAdminAccess(String serviceName, Map<String, RangerPolicyResource> resources) {
		boolean isAdmin = bizUtil.isAdmin();
		boolean isKeyAdmin = bizUtil.isKeyAdmin();
		String userName = bizUtil.getCurrentUserLoginId();

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

			RangerPolicyEngine policyEngine = getDelegatedAdminPolicyEngine(serviceName);

			if (policyEngine != null) {
				Set<String> userGroups = userMgr.getGroupsForUser(userName);

				isAllowed = hasAdminAccess(serviceName, userName, userGroups, resources);
			}

			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(serviceName);
			XXServiceDef xServiceDef = daoManager.getXXServiceDef().getById(xService.getType());

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

	private boolean hasAdminAccess(String serviceName, String userName, Set<String> userGroups, Map<String, RangerPolicyResource> resources) {
		boolean isAllowed = false;

		RangerPolicyEngine policyEngine = getDelegatedAdminPolicyEngine(serviceName);

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

		return isAllowed;
	}

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

		RangerPolicyEngine policyEngine = getDelegatedAdminPolicyEngine(serviceName);

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

		return isAllowed;
	}

	private RangerPolicyEngine getDelegatedAdminPolicyEngine(String serviceName) {
		if(RangerPolicyEngineCache.getInstance().getPolicyEngineOptions() == null) {
			RangerPolicyEngineOptions options = new RangerPolicyEngineOptions();

			String propertyPrefix = "ranger.admin";

			options.evaluatorType           = RangerPolicyEvaluator.EVALUATOR_TYPE_OPTIMIZED;
			options.cacheAuditResults       = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.cache.audit.results", false);
			options.disableContextEnrichers = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.disable.context.enrichers", true);
			options.disableCustomConditions = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.disable.custom.conditions", true);
			options.evaluateDelegateAdminOnly = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.evaluate.delegateadmin.only", true);

			RangerPolicyEngineCache.getInstance().setPolicyEngineOptions(options);
		}

		RangerPolicyEngine ret = RangerPolicyEngineCache.getInstance().getPolicyEngine(serviceName, svcStore);

		return ret;
	}

	private RangerPolicyEngine getPolicyEngine(String serviceName) throws Exception {
		RangerPolicyEngineOptions options = new RangerPolicyEngineOptions();

		String propertyPrefix = "ranger.admin";

		options.evaluatorType             = RangerPolicyEvaluator.EVALUATOR_TYPE_OPTIMIZED;
		options.cacheAuditResults         = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.cache.audit.results", false);
		options.disableContextEnrichers   = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.disable.context.enrichers", true);
		options.disableCustomConditions   = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.disable.custom.conditions", true);
		options.evaluateDelegateAdminOnly = false;
		options.disableTrieLookupPrefilter = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.disable.trie.lookup.prefilter", false);

		ServicePolicies policies = svcStore.getServicePoliciesIfUpdated(serviceName, -1L);

		RangerPolicyEngine ret = new RangerPolicyEngineImpl("ranger-admin", policies, options);

		return ret;
	}

	@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();
	}

	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 == null ? 0 : filter.getStartIndex();
			int    pageSize   = filter == null ? totalCount : filter.getMaxRows();
			int    toIndex    = Math.min(startIndex + pageSize, totalCount);
			String sortType   = filter == null ? null : filter.getSortType();
			String sortBy     = filter == null ? null : 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());

				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){
		if( request!=null){
			if(CollectionUtils.isEmpty(request.getUsers()) && CollectionUtils.isEmpty(request.getGroups())){
				throw restErrorUtil.createGrantRevokeRESTException( "Grantee users/groups list is empty");
			}
			String grantor=request.getGrantor();
			if(grantor==null || userMgr.getXUserByUserName(grantor) == null) {
				throw restErrorUtil.createGrantRevokeRESTException( "Grantor user "+grantor+" doesn't exist");
			}
			for(String userName:request.getUsers()){
				if(userMgr.getXUserByUserName(userName) == null) {
					throw restErrorUtil.createGrantRevokeRESTException( "Grantee user "+userName+" doesn't exist");
				}
			}
			for(String groupName:request.getGroups()){
				if(userMgr.getGroupByGroupName(groupName)== null) {
					throw restErrorUtil.createGrantRevokeRESTException( "Grantee group "+groupName+" doesn't exist");
				}
			}
		}
	}
}
