You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by al...@apache.org on 2016/03/03 01:06:47 UTC

[23/50] [abbrv] incubator-ranger git commit: RANGER-593 User friendly error messages for service def validation error failures

RANGER-593 User friendly error messages for service def validation error failures


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/153e7a0e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/153e7a0e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/153e7a0e

Branch: refs/heads/HDP-2.3.2-groupid
Commit: 153e7a0ea9ec9472d0b44d56b8e8edbd169df3e5
Parents: 8f03ed1
Author: Alok Lal <al...@apache.org>
Authored: Mon Aug 3 12:50:39 2015 -0700
Committer: Alok Lal <al...@apache.org>
Committed: Wed Sep 2 13:09:42 2015 -0700

----------------------------------------------------------------------
 .../plugin/errors/ValidationErrorCode.java      |  24 ++-
 .../validation/RangerServiceDefValidator.java   | 180 ++++++++++++-------
 .../plugin/errors/TestValidationErrorCode.java  |  14 ++
 3 files changed, 155 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/153e7a0e/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
index 77d16f5..c40efc9 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
@@ -26,7 +26,7 @@ import java.text.MessageFormat;
 import java.util.Arrays;
 
 public enum ValidationErrorCode {
-
+    // SERVICE VALIDATION
     SERVICE_VALIDATION_ERR_UNSUPPORTED_ACTION(1001, "Internal error: unsupported action[{0}]; isValid(Long) is only supported for DELETE"),
     SERVICE_VALIDATION_ERR_MISSING_FIELD(1002, "Internal error: missing field[{0}]"),
     SERVICE_VALIDATION_ERR_NULL_SERVICE_OBJECT(1003, "Internal error: service object passed in was null"),
@@ -38,6 +38,28 @@ public enum ValidationErrorCode {
     SERVICE_VALIDATION_ERR_MISSING_SERVICE_DEF(1009, "service def [{0}] was null/empty/blank"),
     SERVICE_VALIDATION_ERR_INVALID_SERVICE_DEF(1010, "service def named[{0}] not found"),
     SERVICE_VALIDATION_ERR_REQUIRED_PARM_MISSING(1011, "required configuration parameter is missing; missing parameters: {0}"),
+
+    // SERVICE-DEF VALIDATION
+    SERVICE_DEF_VALIDATION_ERR_UNSUPPORTED_ACTION(2001, "Internal error: unsupported action[{0}]; isValid(Long) is only supported for DELETE"),
+    SERVICE_DEF_VALIDATION_ERR_MISSING_FIELD(2002, "Internal error: missing field[{0}]"),
+    SERVICE_DEF_VALIDATION_ERR_NULL_SERVICE_DEF_OBJECT(2003, "Internal error: service def object passed in was null"),
+    SERVICE_DEF_VALIDATION_ERR_EMPTY_SERVICE_DEF_ID(2004, "Internal error: service def id was null/empty/blank"),
+    SERVICE_DEF_VALIDATION_ERR_INVALID_SERVICE_DEF_ID(2005, "No service def found for id [{0}]"),
+    SERVICE_DEF_VALIDATION_ERR_INVALID_SERVICE_DEF_NAME(2006, "Service def name[{0}] was null/empty/blank"),
+    SERVICE_DEF_VALIDATION_ERR_SERVICE_DEF_NAME_CONFICT(2007, "service def with the name[{0}] already exists"),
+    SERVICE_DEF_VALIDATION_ERR_ID_NAME_CONFLICT(2008, "id/name conflict: another service def already exists with name[{0}], its id is [{1}]"),
+    SERVICE_DEF_VALIDATION_ERR_IMPLIED_GRANT_UNKNOWN_ACCESS_TYPE(2009, "implied grant[{0}] contains an unknown access types[{1}]"),
+    SERVICE_DEF_VALIDATION_ERR_IMPLIED_GRANT_IMPLIES_ITSELF(2010, "implied grants list [{0}] for access type[{1}] contains itself"),
+    SERVICE_DEF_VALIDATION_ERR_POLICY_CONDITION_NULL_EVALUATOR(2011, "evaluator on policy condition definition[{0}] was null/empty!"),
+    SERVICE_DEF_VALIDATION_ERR_CONFIG_DEF_UNKNOWN_ENUM(2012, "subtype[{0}] of service def config[{1}] was not among defined enums[{2}]"),
+    SERVICE_DEF_VALIDATION_ERR_CONFIG_DEF_UNKNOWN_ENUM_VALUE(2013, "default value[{0}] of service def config[{1}] was not among the valid values[{2}] of enums[{3}]"),
+    SERVICE_DEF_VALIDATION_ERR_CONFIG_DEF_MISSING_TYPE(2014, "type of service def config[{0}] was null/empty"),
+    SERVICE_DEF_VALIDATION_ERR_CONFIG_DEF_INVALID_TYPE(2015, "type[{0}] of service def config[{1}] is not among valid types: {2}"),
+    SERVICE_DEF_VALIDATION_ERR_RESOURCE_GRAPH_INVALID(2016, "Resource graph implied by various resources, e.g. parent value is invalid.  Valid graph must forest (union of disjoint trees)."),
+    SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_NULL_OBJECT(2017, "Internal error: An enum def in enums collection is null"),
+    SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_NO_VALUES(2018, "enum [{0}] does not have any elements"),
+    SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_INVALID_DEFAULT_INDEX(2019, "default index[{0}] for enum [{1}] is invalid"),
+    SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_NULL_ENUM_ELEMENT(2020, "An enum element in enum element collection of enum [{0}] is null"),
     ;
 
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/153e7a0e/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java
index 32d0f1a..75372c2 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java
@@ -31,6 +31,7 @@ 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.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumDef;
@@ -78,15 +79,20 @@ public class RangerServiceDefValidator extends RangerValidator {
 
 		boolean valid = true;
 		if (action != Action.DELETE) {
-			failures.add(new ValidationFailureDetailsBuilder()
-				.isAnInternalError()
-				.becauseOf("unsupported action[" + action + "]; isValid(Long) is only supported for DELETE")
-				.build());
+			ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_UNSUPPORTED_ACTION;
+			failures.add(new RangerServiceDefValidationErrorBuilder()
+					.isAnInternalError()
+					.errorCode(error.getErrorCode())
+					.becauseOf(error.getMessage(action))
+					.build());
 			valid = false;
 		} else if (id == null) {
-			failures.add(new ValidationFailureDetailsBuilder()
+			ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_MISSING_FIELD;
+			failures.add(new RangerServiceDefValidationErrorBuilder()
 				.field("id")
 				.isMissing()
+				.errorCode(error.getErrorCode())
+				.becauseOf(error.getMessage("id"))
 				.build());
 			valid = false;
 		} else if (getServiceDef(id) == null) {
@@ -111,12 +117,12 @@ public class RangerServiceDefValidator extends RangerValidator {
 		}
 		boolean valid = true;
 		if (serviceDef == null) {
-			String message = "service def object passed in was null";
-			LOG.debug(message);
-			failures.add(new ValidationFailureDetailsBuilder()
+			ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_NULL_SERVICE_DEF_OBJECT;
+			failures.add(new RangerServiceDefValidationErrorBuilder()
 				.field("service def")
 				.isMissing()
-				.becauseOf(message)
+				.errorCode(error.getErrorCode())
+				.becauseOf(error.getMessage(action))
 				.build());
 			valid = false;
 		} else {
@@ -154,19 +160,21 @@ public class RangerServiceDefValidator extends RangerValidator {
 
 		if (action == Action.UPDATE) { // id is ignored for CREATE
 			if (id == null) {
-				String message = "service def id was null/empty/blank"; 
-				LOG.debug(message);
-				failures.add(new ValidationFailureDetailsBuilder()
+				ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_EMPTY_SERVICE_DEF_ID;
+				failures.add(new RangerServiceDefValidationErrorBuilder()
 					.field("id")
 					.isMissing()
-					.becauseOf(message)
+					.errorCode(error.getErrorCode())
+					.becauseOf(error.getMessage())
 					.build());
 				valid = false;
 			} else if (getServiceDef(id) == null) {
-				failures.add(new ValidationFailureDetailsBuilder()
+				ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_INVALID_SERVICE_DEF_ID;
+				failures.add(new RangerServiceDefValidationErrorBuilder()
 					.field("id")
 					.isSemanticallyIncorrect()
-					.becauseOf("no service def exists with id[" + id +"]")
+					.errorCode(error.getErrorCode())
+					.becauseOf(error.getMessage(id))
 					.build());
 				valid = false;
 			}
@@ -185,28 +193,32 @@ public class RangerServiceDefValidator extends RangerValidator {
 		boolean valid = true;
 
 		if (StringUtils.isBlank(name)) {
-			String message = "service def name[" + name + "] was null/empty/blank"; 
-			LOG.debug(message);
-			failures.add(new ValidationFailureDetailsBuilder()
+			ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_INVALID_SERVICE_DEF_NAME;
+			failures.add(new RangerServiceDefValidationErrorBuilder()
 				.field("name")
 				.isMissing()
-				.becauseOf(message)
+				.errorCode(error.getErrorCode())
+				.becauseOf(error.getMessage(name))
 				.build());
 			valid = false;
 		} else {
 			RangerServiceDef otherServiceDef = getServiceDef(name);
 			if (otherServiceDef != null && action == Action.CREATE) {
-				failures.add(new ValidationFailureDetailsBuilder()
+				ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_SERVICE_DEF_NAME_CONFICT;
+				failures.add(new RangerServiceDefValidationErrorBuilder()
 					.field("name")
 					.isSemanticallyIncorrect()
-					.becauseOf("service def with the name[" + name + "] already exists")
+					.errorCode(error.getErrorCode())
+					.becauseOf(error.getMessage(name))
 					.build());
 				valid = false;
 			} else if (otherServiceDef != null && !Objects.equals(id, otherServiceDef.getId())) {
-				failures.add(new ValidationFailureDetailsBuilder()
+				ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_ID_NAME_CONFLICT;
+				failures.add(new RangerServiceDefValidationErrorBuilder()
 					.field("id/name")
 					.isSemanticallyIncorrect()
-					.becauseOf("id/name conflict: another service def already exists with name[" + name + "], its id is [" + otherServiceDef.getId() + "]")
+					.errorCode(error.getErrorCode())
+					.becauseOf(error.getMessage(name, otherServiceDef.getId()))
 					.build());
 				valid = false;
 			}
@@ -225,10 +237,12 @@ public class RangerServiceDefValidator extends RangerValidator {
 		
 		boolean valid = true;
 		if (CollectionUtils.isEmpty(accessTypeDefs)) {
-			failures.add(new ValidationFailureDetailsBuilder()
+			ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_MISSING_FIELD;
+			failures.add(new RangerServiceDefValidationErrorBuilder()
 				.field("access types")
 				.isMissing()
-				.becauseOf("access types collection was null/empty")
+				.errorCode(error.getErrorCode())
+				.becauseOf(error.getMessage("access types"))
 				.build());
 			valid = false;
 		} else {
@@ -248,22 +262,26 @@ public class RangerServiceDefValidator extends RangerValidator {
 				Collection<String> impliedGrants = getImpliedGrants(def);
 				Set<String> unknownAccessTypes = Sets.difference(Sets.newHashSet(impliedGrants), accessNames);
 				if (!unknownAccessTypes.isEmpty()) {
-					failures.add(new ValidationFailureDetailsBuilder()
+					ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_IMPLIED_GRANT_UNKNOWN_ACCESS_TYPE;
+					failures.add(new RangerServiceDefValidationErrorBuilder()
 						.field("implied grants")
 						.subField(unknownAccessTypes.iterator().next())  // we return just on item here.  Message has all unknow items
 						.isSemanticallyIncorrect()
-						.becauseOf("implied grant[" + impliedGrants + "] contains an unknown access types[" + unknownAccessTypes + "]")
+						.errorCode(error.getErrorCode())
+						.becauseOf(error.getMessage(impliedGrants, unknownAccessTypes))
 						.build());
 					valid = false;
 				}
 				// implied grant should not imply itself! 
 				String name = def.getName(); // note: this name could be null/blank/empty!
 				if (impliedGrants.contains(name)) {
-					failures.add(new ValidationFailureDetailsBuilder()
+					ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_IMPLIED_GRANT_IMPLIES_ITSELF;
+					failures.add(new RangerServiceDefValidationErrorBuilder()
 						.field("implied grants")
 						.subField(name)
 						.isSemanticallyIncorrect()
-						.becauseOf("implied grants list [" + impliedGrants + "] for access type[" + name + "] contains itself")
+						.errorCode(error.getErrorCode())
+						.becauseOf(error.getMessage(impliedGrants, name))
 						.build());
 					valid = false;
 				}
@@ -292,13 +310,13 @@ public class RangerServiceDefValidator extends RangerValidator {
 				String name = conditionDef.getName();
 				valid = isUnique(name, names, "policy condition def name", "policy condition defs", failures) && valid;
 				if (StringUtils.isBlank(conditionDef.getEvaluator())) {
-					String reason = String.format("evaluator on policy condition definition[%s] was null/empty!", name);
-					LOG.debug(reason);
-					failures.add(new ValidationFailureDetailsBuilder()
+					ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_POLICY_CONDITION_NULL_EVALUATOR;
+					failures.add(new RangerServiceDefValidationErrorBuilder()
 						.field("policy condition def evaluator")
 						.subField(name)
 						.isMissing()
-						.becauseOf(reason)
+						.errorCode(error.getErrorCode())
+						.becauseOf(error.getMessage(name))
 						.build());
 					valid = false;
 				}
@@ -355,12 +373,13 @@ public class RangerServiceDefValidator extends RangerValidator {
 			String configName = configDef.getName();
 			
 			if (!enumTypes.contains(subType)) {
-				String reason = String.format("subtype[%s] of service def config[%s] was not among defined enums[%s]", subType, configName, enumTypes);
-				failures.add(new ValidationFailureDetailsBuilder()
+				ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_CONFIG_DEF_UNKNOWN_ENUM;
+				failures.add(new RangerServiceDefValidationErrorBuilder()
 					.field("config def subtype")
 					.subField(configName)
 					.isSemanticallyIncorrect()
-					.becauseOf(reason)
+					.errorCode(error.getErrorCode())
+					.becauseOf(error.getMessage(subType, configName, enumTypes))
 					.build());
 				valid = false;
 			} else {
@@ -370,13 +389,14 @@ public class RangerServiceDefValidator extends RangerValidator {
 					RangerEnumDef enumDef = enumDefsMap.get(subType);
 					Set<String> enumValues = getEnumValues(enumDef);
 					if (!enumValues.contains(defaultValue)) {
-						String reason = String.format("default value[%s] of service def config[%s] was not among the valid values[%s] of enums[%s]", defaultValue, configName, enumValues, subType);
-						failures.add(new ValidationFailureDetailsBuilder()
-							.field("config def default value")
-							.subField(configName)
-							.isSemanticallyIncorrect()
-							.becauseOf(reason)
-							.build());
+						ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_CONFIG_DEF_UNKNOWN_ENUM_VALUE;
+						failures.add(new RangerServiceDefValidationErrorBuilder()
+								.field("config def default value")
+								.subField(configName)
+								.isSemanticallyIncorrect()
+								.errorCode(error.getErrorCode())
+								.becauseOf(error.getMessage(defaultValue, configName, enumValues, subType))
+								.build());
 						valid = false;
 					}
 				}
@@ -397,21 +417,23 @@ public class RangerServiceDefValidator extends RangerValidator {
 
 		Set<String> validTypes = ImmutableSet.of("bool", "enum", "int", "string", "password", "path");
 		if (StringUtils.isBlank(type)) {
-			String reason = String.format("type of service def config[%s] was null/empty", configName);
-			failures.add(new ValidationFailureDetailsBuilder()
+			ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_CONFIG_DEF_MISSING_TYPE;
+			failures.add(new RangerServiceDefValidationErrorBuilder()
 				.field("config def type")
 				.subField(configName)
 				.isMissing()
-				.becauseOf(reason)
+				.errorCode(error.getErrorCode())
+				.becauseOf(error.getMessage(configName))
 				.build());
 			valid = false;
 		} else if (!validTypes.contains(type)) {
-			String reason = String.format("type[%s] of service def config[%s] is not among valid types: %s", type, configName, validTypes);
-			failures.add(new ValidationFailureDetailsBuilder()
+			ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_CONFIG_DEF_INVALID_TYPE;
+			failures.add(new RangerServiceDefValidationErrorBuilder()
 				.field("config def type")
 				.subField(configName)
 				.isSemanticallyIncorrect()
-				.becauseOf(reason)
+				.errorCode(error.getErrorCode())
+				.becauseOf(error.getMessage(type, configName, validTypes))
 				.build());
 			valid = false;
 		}
@@ -430,11 +452,12 @@ public class RangerServiceDefValidator extends RangerValidator {
 
 		List<RangerResourceDef> resources = serviceDef.getResources();
 		if (CollectionUtils.isEmpty(resources)) {
-			String reason = "service def resources collection was null/empty";
-			failures.add(new ValidationFailureDetailsBuilder()
+			ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_MISSING_FIELD;
+			failures.add(new RangerServiceDefValidationErrorBuilder()
 					.field("resources")
 					.isMissing()
-					.becauseOf(reason)
+					.errorCode(error.getErrorCode())
+					.becauseOf(error.getMessage("resources"))
 					.build());
 			valid = false;
 		} else {
@@ -463,10 +486,12 @@ public class RangerServiceDefValidator extends RangerValidator {
 		// We don't want this helper to get into the cache or to use what is in the cache!!
 		RangerServiceDefHelper defHelper = _factory.createServiceDefHelper(serviceDef, false);
 		if (!defHelper.isResourceGraphValid()) {
-			failures.add(new ValidationFailureDetailsBuilder()
+			ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_RESOURCE_GRAPH_INVALID;
+			failures.add(new RangerServiceDefValidationErrorBuilder()
 				.field("resource graph")
 				.isSemanticallyIncorrect()
-				.becauseOf("Resource graph implied by various resources, e.g. parent value is invalid.  Valid graph must forest (union of disjoint trees).")
+				.errorCode(error.getErrorCode())
+				.becauseOf(error.getMessage())
 				.build());
 			valid = false;
 		}
@@ -498,10 +523,12 @@ public class RangerServiceDefValidator extends RangerValidator {
 			Set<Long> ids = new HashSet<Long>();
 			for (RangerEnumDef enumDef : enumDefs) {
 				if (enumDef == null) {
-					failures.add(new ValidationFailureDetailsBuilder()
+					ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_NULL_OBJECT;
+					failures.add(new RangerServiceDefValidationErrorBuilder()
 						.field("enum def")
 						.isMissing()
-						.becauseOf("An enum def in enums collection is null")
+						.errorCode(error.getErrorCode())
+						.becauseOf(error.getMessage())
 						.build());
 					valid = false;
 				} else {
@@ -511,11 +538,13 @@ public class RangerServiceDefValidator extends RangerValidator {
 					valid = isUnique(enumDef.getItemId(), ids, "enum def itemId", "enum defs", failures) && valid;		
 					// enum must contain at least one valid value and those values should be non-blank and distinct
 					if (CollectionUtils.isEmpty(enumDef.getElements())) {
-						failures.add(new ValidationFailureDetailsBuilder()
+						ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_NO_VALUES;
+						failures.add(new RangerServiceDefValidationErrorBuilder()
 							.field("enum values")
 							.subField(enumName)
 							.isMissing()
-							.becauseOf("enum [" + enumName + "] does not have any elements")
+							.errorCode(error.getErrorCode())
+							.becauseOf(error.getMessage(enumName))
 							.build());
 						valid = false;
 					} else {
@@ -523,11 +552,13 @@ public class RangerServiceDefValidator extends RangerValidator {
 						// default index should be valid
 						int defaultIndex = getEnumDefaultIndex(enumDef);
 						if (defaultIndex < 0 || defaultIndex >= enumDef.getElements().size()) { // max index is one less than the size of the elements list
-							failures.add(new ValidationFailureDetailsBuilder()
+							ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_INVALID_DEFAULT_INDEX;
+							failures.add(new RangerServiceDefValidationErrorBuilder()
 								.field("enum default index")
 								.subField(enumName)
 								.isSemanticallyIncorrect()
-								.becauseOf("default index[" + defaultIndex + "] for enum [" + enumName + "] is invalid")
+								.errorCode(error.getErrorCode())
+								.becauseOf(error.getMessage(defaultIndex, enumName))
 								.build());
 							valid = false;
 						}
@@ -556,11 +587,13 @@ public class RangerServiceDefValidator extends RangerValidator {
 			Set<Long> ids = new HashSet<Long>();
 			for (RangerEnumElementDef elementDef : enumElementsDefs) {
 				if (elementDef == null) {
-					failures.add(new ValidationFailureDetailsBuilder()
+					ValidationErrorCode error = ValidationErrorCode.SERVICE_DEF_VALIDATION_ERR_ENUM_DEF_NULL_ENUM_ELEMENT;
+					failures.add(new RangerServiceDefValidationErrorBuilder()
 						.field("enum element")
 						.subField(enumName)
 						.isMissing()
-						.becauseOf("An enum element in enum element collection of enum [" + enumName + "] is null")
+						.errorCode(error.getErrorCode())
+						.becauseOf(error.getMessage(enumName))
 						.build());
 					valid = false;
 				} else {
@@ -575,4 +608,27 @@ public class RangerServiceDefValidator extends RangerValidator {
 		}
 		return valid;
 	}
+
+	static class RangerServiceDefValidationErrorBuilder extends ValidationFailureDetailsBuilder {
+
+		@Override
+		ValidationFailureDetails build() {
+			return new RangerServiceDefValidationFailure(_errorCode, _fieldName, _subFieldName, _missing, _semanticError, _internalError, _reason);
+		}
+	}
+
+	static class RangerServiceDefValidationFailure extends  ValidationFailureDetails {
+
+		public RangerServiceDefValidationFailure(int errorCode, String fieldName, String subFieldName, boolean missing, boolean semanticError, boolean internalError, String reason) {
+			super(errorCode, fieldName, subFieldName, missing, semanticError, internalError, reason);
+		}
+
+		// TODO remove and move to baseclass when all 3 move to new message framework
+		@Override
+		public String toString() {
+			LOG.debug("RangerServiceDefValidationFailure.toString");
+			return String.format("%s: %d, %s", "Policy validation failure", _errorCode, _reason);
+		}
+	}
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/153e7a0e/agents-common/src/test/java/org/apache/ranger/plugin/errors/TestValidationErrorCode.java
----------------------------------------------------------------------
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/errors/TestValidationErrorCode.java b/agents-common/src/test/java/org/apache/ranger/plugin/errors/TestValidationErrorCode.java
index d6b2d16..46b1966 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/errors/TestValidationErrorCode.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/errors/TestValidationErrorCode.java
@@ -21,6 +21,7 @@ package org.apache.ranger.plugin.errors;
 
 import com.google.common.collect.ImmutableSet;
 import junit.framework.TestCase;
+import org.apache.ranger.plugin.model.validation.ValidationFailureDetails;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -69,4 +70,17 @@ public class TestValidationErrorCode extends TestCase {
             }
         }
     }
+
+    /**
+     * Test if the values assigned to the validation error code are unique or not.
+     */
+    public void testValidationErrorCodesUnique() {
+        Set<Integer> errorCodes = new HashSet<>();
+        for (ValidationErrorCode anEnum : ValidationErrorCode.values()) {
+            int errorCode = anEnum.getErrorCode();
+            // errorCode that we see must not have been seen so far.
+            assertFalse("ValidationErrorCode: error code [" + errorCode + "] used multiple times!", errorCodes.contains(errorCode));
+            errorCodes.add(errorCode);
+        }
+    }
 }
\ No newline at end of file