<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.ranger.plugin.model.validation;

import java.util.*;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ranger.plugin.errors.ValidationErrorCode;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
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.RangerPolicy.RangerRowFilterPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicyResourceSignature;
import org.apache.ranger.plugin.model.RangerSecurityZone;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.RangerValiditySchedule;
import org.apache.ranger.plugin.store.ServiceStore;

public class RangerPolicyValidator extends RangerValidator {

	private static final Log LOG = LogFactory.getLog(RangerPolicyValidator.class);

	public RangerPolicyValidator(ServiceStore store) {
		super(store);
	}

	public void validate(RangerPolicy policy, Action action, boolean isAdmin) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug(String.format("==> RangerPolicyValidator.validate(%s, %s, %s)", policy, action, isAdmin));
		}

		List<ValidationFailureDetails> failures = new ArrayList<>();
		boolean valid = isValid(policy, action, isAdmin, failures);
		String message = "";
		try {
			if (!valid) {
				message = serializeFailures(failures);
				throw new Exception(message);
			}
		} finally {
			if(LOG.isDebugEnabled()) {
				LOG.debug(String.format("<== RangerPolicyValidator.validate(%s, %s, %s): %s, reason[%s]", policy, action, isAdmin, valid, message));
			}
		}
	}

	@Override
	boolean isValid(Long id, Action action, List<ValidationFailureDetails> failures) {
		if(LOG.isDebugEnabled()) {
			LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s)", id, action, failures));
		}

		boolean valid = true;
		if (action != Action.DELETE) {
			ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_UNSUPPORTED_ACTION;
			failures.add(new ValidationFailureDetailsBuilder()
				.isAnInternalError()
				.becauseOf(error.getMessage())
				.errorCode(error.getErrorCode())
				.build());
			valid = false;
		} else if (id == null) {
			ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD;
			failures.add(new ValidationFailureDetailsBuilder()
					.becauseOf("policy id was null/missing")
					.field("id")
					.isMissing()
					.errorCode(error.getErrorCode())
					.becauseOf(error.getMessage("id"))
					.build());
			valid = false;
		} else if (getPolicy(id) == null) {
			if (LOG.isDebugEnabled()) {
				LOG.debug("No policy found for id[" + id + "]! ok!");
			}
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s): %s", id, action, failures, valid));
		}
		return valid;
	}

	boolean isValid(RangerPolicy policy, Action action, boolean isAdmin, List<ValidationFailureDetails> failures) {
		if(LOG.isDebugEnabled()) {
			LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s, %s)", policy, action, isAdmin, failures));
		}

		if (!(action == Action.CREATE || action == Action.UPDATE)) {
			throw new IllegalArgumentException("isValid(RangerPolicy, ...) is only supported for create/update");
		}
		boolean valid = true;
		if (policy == null) {
			ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_NULL_POLICY_OBJECT;
			failures.add(new ValidationFailureDetailsBuilder()
				.field("policy")
				.isMissing()
				.becauseOf(error.getMessage())
				.errorCode(error.getErrorCode())
				.build());
			valid = false;
		} else {
			Integer priority = policy.getPolicyPriority();
			if (priority != null) {
				if (priority < RangerPolicy.POLICY_PRIORITY_NORMAL || priority > RangerPolicy.POLICY_PRIORITY_OVERRIDE) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_INVALID_PRIORITY;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("policyPriority")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage("out of range"))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				}
			}
			Long id = policy.getId();
			RangerPolicy existingPolicy = null;

			if (action == Action.UPDATE) { // id is ignored for CREATE
				if (id == null) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD;
					failures.add(new ValidationFailureDetailsBuilder()
						.field("id")
						.isMissing()
						.becauseOf(error.getMessage("id"))
						.errorCode(error.getErrorCode())
						.build());
					valid = false;
				}

				existingPolicy = getPolicy(id);

				if (existingPolicy == null) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_POLICY_ID;
					failures.add(new ValidationFailureDetailsBuilder()
						.field("id")
						.isSemanticallyIncorrect()
						.becauseOf(error.getMessage(id))
						.errorCode(error.getErrorCode())
						.build());
					valid = false;
				}
			}
			String policyName  = policy.getName();
			String serviceName = policy.getService();
			String zoneName    = policy.getZoneName();

			RangerService service = null;
			RangerSecurityZone zone = null;
			boolean serviceNameValid = false;
			if (StringUtils.isBlank(serviceName)) {
				ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD;
				failures.add(new ValidationFailureDetailsBuilder()
						.field("service name")
						.isMissing()
						.becauseOf(error.getMessage("service name"))
						.errorCode(error.getErrorCode())
						.build());
				valid = false;
			} else {
				service = getService(serviceName);
				if (service == null) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_SERVICE_NAME;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("service name")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage(serviceName))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				} else {
					serviceNameValid = true;
				}
			}

			if (StringUtils.isNotEmpty(zoneName)) {
				zone = getSecurityZone(zoneName);
				if (zone == null) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_NONEXISTANT_ZONE_NAME;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("zoneName")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage(id, zoneName))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				}
			}

			if (StringUtils.isBlank(policyName)) {
				ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD;
				failures.add(new ValidationFailureDetailsBuilder()
					.field("name")
					.isMissing()
					.becauseOf(error.getMessage("name"))
					.errorCode(error.getErrorCode())
					.build());
				valid = false;
			} else {
				if (service != null && (StringUtils.isEmpty(zoneName) || zone != null)) {
					Long zoneId = zone != null ? zone.getId() : RangerSecurityZone.RANGER_UNZONED_SECURITY_ZONE_ID;
					Long policyId = getPolicyId(service.getId(), policyName, zoneId);

					if (policyId != null) {
						if (action == Action.CREATE) {
							ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_NAME_CONFLICT;
							failures.add(new ValidationFailureDetailsBuilder()
									.field("policy name")
									.isSemanticallyIncorrect()
									.becauseOf(error.getMessage(policyId, serviceName))
									.errorCode(error.getErrorCode())
									.build());
							valid = false;
						} else if (!policyId.equals(id)) { // action == UPDATE
							ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_NAME_CONFLICT;
							failures.add(new ValidationFailureDetailsBuilder()
									.field("id/name")
									.isSemanticallyIncorrect()
									.becauseOf(error.getMessage(policyId, serviceName))
									.errorCode(error.getErrorCode())
									.build());
							valid = false;
						}
					}
				}
			}

			if(existingPolicy != null) {
				if(! StringUtils.equalsIgnoreCase(existingPolicy.getService(), policy.getService())) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_UPDATE_MOVE_SERVICE_NOT_ALLOWED;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("service name")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage(policy.getId(), existingPolicy.getService(), policy.getService()))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				}

				int existingPolicyType = existingPolicy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : existingPolicy.getPolicyType();
				int policyType         = policy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : policy.getPolicyType();

				if(existingPolicyType != policyType) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_TYPE_CHANGE_NOT_ALLOWED;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("policy type")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage(policy.getId(), existingPolicyType, policyType))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				}

				String existingZoneName = existingPolicy.getZoneName();

				if (!StringUtils.equals(existingZoneName, zoneName)) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_UPDATE_ZONE_NAME_NOT_ALLOWED;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("zoneName")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage(id, existingZoneName, zoneName))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				}
			}

			boolean          isAuditEnabled   = getIsAuditEnabled(policy);
			String           serviceDefName   = null;
			RangerServiceDef serviceDef       = null;
			int              policyItemsCount = 0;

			int policyType=policy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : policy.getPolicyType();
			switch (policyType) {<commit_msg>RANGER-2400: policy name needs to be unique within security zone and service - part 2<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.ranger.plugin.model.validation;

import java.util.*;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ranger.plugin.errors.ValidationErrorCode;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
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.RangerPolicy.RangerRowFilterPolicyItem;
import org.apache.ranger.plugin.model.RangerPolicyResourceSignature;
import org.apache.ranger.plugin.model.RangerSecurityZone;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.RangerValiditySchedule;
import org.apache.ranger.plugin.store.ServiceStore;

public class RangerPolicyValidator extends RangerValidator {

	private static final Log LOG = LogFactory.getLog(RangerPolicyValidator.class);

	public RangerPolicyValidator(ServiceStore store) {
		super(store);
	}

	public void validate(RangerPolicy policy, Action action, boolean isAdmin) throws Exception {
		if(LOG.isDebugEnabled()) {
			LOG.debug(String.format("==> RangerPolicyValidator.validate(%s, %s, %s)", policy, action, isAdmin));
		}

		List<ValidationFailureDetails> failures = new ArrayList<>();
		boolean valid = isValid(policy, action, isAdmin, failures);
		String message = "";
		try {
			if (!valid) {
				message = serializeFailures(failures);
				throw new Exception(message);
			}
		} finally {
			if(LOG.isDebugEnabled()) {
				LOG.debug(String.format("<== RangerPolicyValidator.validate(%s, %s, %s): %s, reason[%s]", policy, action, isAdmin, valid, message));
			}
		}
	}

	@Override
	boolean isValid(Long id, Action action, List<ValidationFailureDetails> failures) {
		if(LOG.isDebugEnabled()) {
			LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s)", id, action, failures));
		}

		boolean valid = true;
		if (action != Action.DELETE) {
			ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_UNSUPPORTED_ACTION;
			failures.add(new ValidationFailureDetailsBuilder()
				.isAnInternalError()
				.becauseOf(error.getMessage())
				.errorCode(error.getErrorCode())
				.build());
			valid = false;
		} else if (id == null) {
			ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD;
			failures.add(new ValidationFailureDetailsBuilder()
					.becauseOf("policy id was null/missing")
					.field("id")
					.isMissing()
					.errorCode(error.getErrorCode())
					.becauseOf(error.getMessage("id"))
					.build());
			valid = false;
		} else if (getPolicy(id) == null) {
			if (LOG.isDebugEnabled()) {
				LOG.debug("No policy found for id[" + id + "]! ok!");
			}
		}

		if(LOG.isDebugEnabled()) {
			LOG.debug(String.format("<== RangerPolicyValidator.isValid(%s, %s, %s): %s", id, action, failures, valid));
		}
		return valid;
	}

	boolean isValid(RangerPolicy policy, Action action, boolean isAdmin, List<ValidationFailureDetails> failures) {
		if(LOG.isDebugEnabled()) {
			LOG.debug(String.format("==> RangerPolicyValidator.isValid(%s, %s, %s, %s)", policy, action, isAdmin, failures));
		}

		if (!(action == Action.CREATE || action == Action.UPDATE)) {
			throw new IllegalArgumentException("isValid(RangerPolicy, ...) is only supported for create/update");
		}
		boolean valid = true;
		if (policy == null) {
			ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_NULL_POLICY_OBJECT;
			failures.add(new ValidationFailureDetailsBuilder()
				.field("policy")
				.isMissing()
				.becauseOf(error.getMessage())
				.errorCode(error.getErrorCode())
				.build());
			valid = false;
		} else {
			Integer priority = policy.getPolicyPriority();
			if (priority != null) {
				if (priority < RangerPolicy.POLICY_PRIORITY_NORMAL || priority > RangerPolicy.POLICY_PRIORITY_OVERRIDE) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_INVALID_PRIORITY;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("policyPriority")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage("out of range"))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				}
			}
			Long id = policy.getId();
			RangerPolicy existingPolicy = null;

			if (action == Action.UPDATE) { // id is ignored for CREATE
				if (id == null) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD;
					failures.add(new ValidationFailureDetailsBuilder()
						.field("id")
						.isMissing()
						.becauseOf(error.getMessage("id"))
						.errorCode(error.getErrorCode())
						.build());
					valid = false;
				}

				existingPolicy = getPolicy(id);

				if (existingPolicy == null) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_POLICY_ID;
					failures.add(new ValidationFailureDetailsBuilder()
						.field("id")
						.isSemanticallyIncorrect()
						.becauseOf(error.getMessage(id))
						.errorCode(error.getErrorCode())
						.build());
					valid = false;
				}
			}
			String policyName  = policy.getName();
			String serviceName = policy.getService();
			String zoneName    = policy.getZoneName();

			RangerService service = null;
			RangerSecurityZone zone = null;
			boolean serviceNameValid = false;
			if (StringUtils.isBlank(serviceName)) {
				ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD;
				failures.add(new ValidationFailureDetailsBuilder()
						.field("service name")
						.isMissing()
						.becauseOf(error.getMessage("service name"))
						.errorCode(error.getErrorCode())
						.build());
				valid = false;
			} else {
				service = getService(serviceName);
				if (service == null) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_SERVICE_NAME;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("service name")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage(serviceName))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				} else {
					serviceNameValid = true;
				}
			}

			if (StringUtils.isNotEmpty(zoneName)) {
				zone = getSecurityZone(zoneName);
				if (zone == null) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_NONEXISTANT_ZONE_NAME;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("zoneName")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage(id, zoneName))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				}
			}

			if (StringUtils.isBlank(policyName)) {
				ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD;
				failures.add(new ValidationFailureDetailsBuilder()
					.field("name")
					.isMissing()
					.becauseOf(error.getMessage("name"))
					.errorCode(error.getErrorCode())
					.build());
				valid = false;
			} else {
				if (service != null && (StringUtils.isEmpty(zoneName) || zone != null)) {
					Long zoneId = zone != null ? zone.getId() : RangerSecurityZone.RANGER_UNZONED_SECURITY_ZONE_ID;
					Long policyId = getPolicyId(service.getId(), policyName, zoneId);

					if (policyId != null) {
						if (action == Action.CREATE) {
							ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_NAME_CONFLICT;
							failures.add(new ValidationFailureDetailsBuilder()
									.field("policy name")
									.isSemanticallyIncorrect()
									.becauseOf(error.getMessage(policyId, serviceName))
									.errorCode(error.getErrorCode())
									.build());
							valid = false;
						} else if (!policyId.equals(id)) { // action == UPDATE
							ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_NAME_CONFLICT;
							failures.add(new ValidationFailureDetailsBuilder()
									.field("id/name")
									.isSemanticallyIncorrect()
									.becauseOf(error.getMessage(policyId, serviceName))
									.errorCode(error.getErrorCode())
									.build());
							valid = false;
						}
					}
				}
			}

			if(existingPolicy != null) {
				if (!StringUtils.equalsIgnoreCase(existingPolicy.getService(), policy.getService())) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_UPDATE_MOVE_SERVICE_NOT_ALLOWED;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("service name")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage(policy.getId(), existingPolicy.getService(), policy.getService()))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				}

				int existingPolicyType = existingPolicy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : existingPolicy.getPolicyType();
				int policyType         = policy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : policy.getPolicyType();

				if (existingPolicyType != policyType) {
					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_TYPE_CHANGE_NOT_ALLOWED;
					failures.add(new ValidationFailureDetailsBuilder()
							.field("policy type")
							.isSemanticallyIncorrect()
							.becauseOf(error.getMessage(policy.getId(), existingPolicyType, policyType))
							.errorCode(error.getErrorCode())
							.build());
					valid = false;
				}

				String existingZoneName = existingPolicy.getZoneName();

				if (StringUtils.isNotEmpty(zoneName) || StringUtils.isNotEmpty(existingZoneName)) {
					if (!StringUtils.equals(existingZoneName, zoneName)) {
						ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_UPDATE_ZONE_NAME_NOT_ALLOWED;
						failures.add(new ValidationFailureDetailsBuilder()
								.field("zoneName")
								.isSemanticallyIncorrect()
								.becauseOf(error.getMessage(id, existingZoneName, zoneName))
								.errorCode(error.getErrorCode())
								.build());
						valid = false;
					}
				}
			}

			boolean          isAuditEnabled   = getIsAuditEnabled(policy);
			String           serviceDefName   = null;
			RangerServiceDef serviceDef       = null;
			int              policyItemsCount = 0;

			int policyType=policy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : policy.getPolicyType();
			switch (policyType) {
{'fraction_non_alphanumeric': 0.11421045813722527, 'fraction_numerical': 0.0006476963599464571, 'mean_word_length': 3.948717948717949, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '381753', 'n_tokens_mistral': 8379, 'n_tokens_neox': 6732, 'n_words': 1327}