use of com.linkedin.data.schema.validation.ValidationResult in project rest.li by linkedin.
the class TestPatchFilterValidator method testPatchFilterValidator.
@Test
public void testPatchFilterValidator() throws IOException {
String schemaText = "{\n" + " \"type\" : \"record\",\n" + " \"name\" : \"Foo\",\n" + " \"fields\" : [\n" + " { \"name\" : \"fooInt\", \"type\" : \"int\", \"optional\" : true },\n" + " { \"name\" : \"fooString\", \"type\" : \"string\", \"optional\" : true },\n" + " {\n" + " \"name\" : \"bar\",\n" + " \"type\" : {\n" + " \"type\" : \"record\",\n" + " \"name\" : \"Bar\",\n" + " \"fields\" : [\n" + " { \"name\" : \"barInt\", \"type\" : \"int\", \"optional\" : true },\n" + " { \"name\" : \"barString\", \"type\" : \"string\", \"optional\" : true },\n" + " {\n" + " \"name\" : \"baz\",\n" + " \"type\" : {\n" + " \"type\" : \"record\",\n" + " \"name\" : \"Baz\",\n" + " \"fields\" : [\n" + " { \"name\" : \"bazInt\", \"type\" : \"int\", \"optional\" : true },\n" + " { \"name\" : \"bazString\", \"type\" : \"string\", \"optional\" : true }\n" + " ]\n" + " },\n" + " \"optional\" : true\n" + " }\n" + " ]\n" + " },\n" + " \"optional\" : true\n" + " }\n" + " ]\n" + "}\n";
Object[][] inputs = { // }
{ // deleted /fooInt
"{ }", "{ \"$delete\" : [ \"fooInt\" ] }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, ""), asList(Mode.ANCESTOR_AND_SET, "") }, { // must not call validator for parents and ancestors not modified
"{ \"fooString\" : \"excluded\", \"bar\" : { \"barInt\" : -1 } }", "{ \"$delete\" : [ \"fooInt\" ] }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, ""), asList(Mode.ANCESTOR_AND_SET, "") }, { // deleted /bar/barInt
"{ \"bar\" : { } }", "{ \"bar\" : { \"$delete\" : [ \"barInt\" ] } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar"), asList(Mode.ANCESTOR_AND_SET, "", "/bar") }, { // must not call validator for parents and ancestors not modified
"{ \"fooInt\" : -1, \"fooString\" : \"excluded\", \"bar\" : { } }", "{ \"bar\" : { \"$delete\" : [ \"barInt\" ] } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar"), asList(Mode.ANCESTOR_AND_SET, "", "/bar") }, { // deleted /bar/baz/bazInt
"{ \"bar\" : { \"baz\" : { } } }", "{ \"bar\" : { \"baz\" : { \"$delete\" : [ \"bazInt\" ] } } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar/baz"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz") }, { // must not call validator for parents and ancestors not modified
"{ \"fooInt\" : -1, \"fooString\" : \"excluded\", \"bar\" : { \"barInt\" : -1, \"baz\" : { } } }", "{ \"bar\" : { \"baz\" : { \"$delete\" : [ \"bazInt\" ] } } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar/baz"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz") }, { // deleted /bar/baz
"{ \"bar\" : { } }", "{ \"bar\" : { \"$delete\" : [ \"baz\" ] } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar"), asList(Mode.ANCESTOR_AND_SET, "", "/bar") }, { // must not call validator for parents and ancestors not modified
"{ \"fooInt\" : -1, \"fooString\" : \"excluded\", \"bar\" : { \"barInt\" : -1 } }", "{ \"bar\" : { \"$delete\" : [ \"baz\" ] } }", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET, "/bar"), asList(Mode.ANCESTOR_AND_SET, "", "/bar") }, { // set /fooInt (set field in root record)
"{ \"fooInt\" : 2 }", "{ \"$set\" : { \"fooInt\" : 2 } }", "", asList(Mode.SET_ONLY, "/fooInt"), asList(Mode.PARENT_AND_SET, "", "/fooInt"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt") }, { // must not call validator for parents and ancestors not modified
"{ \"fooInt\" : 2, \"fooString\" : \"excluded\", \"bar\" : { \"baz\" : { } } }", "{ \"$set\" : { \"fooInt\" : 2 } }", "", asList(Mode.SET_ONLY, "/fooInt"), asList(Mode.PARENT_AND_SET, "", "/fooInt"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excluded\",\n" + " \"bar\" : {\n" + " \"barInt\" : 2,\n" + " \"barString\" : \"excluded\",\n" + " \"baz\" : {}\n" + " }\n" + "}", "{ \"bar\" : { \"$set\" : { \"barInt\" : 2 } } }", "", asList(Mode.SET_ONLY, "/bar/barInt"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/barInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/barInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : -1,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"barString\" : \"x\",\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"excludes\"\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"$set\" : { \"barString\" : \"x\" } } }", "", asList(Mode.SET_ONLY, "/bar/barString"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/barString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/barString") }, { // set /bar/baz/bazInt (set field in nested grandchild record)
"{ \"bar\" : { \"baz\" : { \"bazInt\" : 2 } } }", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excluded\",\n" + " \"bar\" : {\n" + " \"barInt\" : 2,\n" + " \"barString\" : \"excluded\",\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"excluded\"\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : -1,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"excludes\"\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // set /bar (set record in root record)
"{ \"bar\" : { \"baz\" : { \"bazInt\" : 2 } } }", "{ \"$set\" : { \"bar\" : { \"baz\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar", "/bar/baz", "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excluded\",\n" + " \"bar\" : {\n" + " \"baz\" : {\n" + " \"bazInt\" : 2\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // set /bar/baz (set record in nested child record)
"{ \"bar\" : { \"baz\" : { \"bazInt\" : 2 } } }", "{ \"bar\" : { \"$set\" : { \"baz\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excluded\",\n" + " \"bar\" : {\n" + " \"barInt\" : 2,\n" + " \"barString\" : \"excluded\",\n" + " \"baz\" : {\n" + " \"bazInt\" : 2\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"$set\" : { \"baz\" : { \"bazInt\" : 2 } } } }", "", asList(Mode.SET_ONLY, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call validator for parents and ancestors not modified
"{\n" + " \"fooInt\" : -1,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"barString\" : \"excludes\",\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{ \"bar\" : { \"$set\" : { \"baz\" : { \"bazInt\" : 2, \"bazString\" : \"x\" } } } }", "", asList(Mode.SET_ONLY, "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString") }, { // set /fooInt, /fooString (set multiple fields in root record)
"{ \"fooInt\" : 2, \"fooString\" : \"x\" }", "{ \"$set\" : { \"fooInt\" : 2, \"fooString\" : \"x\" } }", "", asList(Mode.SET_ONLY, "/fooInt", "/fooString"), asList(Mode.PARENT_AND_SET, "", "/fooInt", "/fooString"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt", "/fooString") }, { // set /bar/barInt, /bar/barString (set multiple fields in nested child record)
"{ \"bar\" : { \"barInt\" : 2, \"barString\" : \"x\" } }", "{ \"bar\" : { \"$set\" : { \"barInt\" : 2, \"barString\" : \"x\" } } }", "", asList(Mode.SET_ONLY, "/bar/barInt", "/bar/barString"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/barInt", "/bar/barString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/barInt", "/bar/barString") }, { // set /bar/baz/bazInt, /bar/baz/bazString (set multiple fields in nested grandchild record)
"{ \"bar\" : { \"baz\" : { \"bazInt\" : 2, \"bazString\" : \"x\" } } }", "{ \"bar\" : { \"baz\" : { \"$set\" : { \"bazInt\" : 2, \"bazString\" : \"x\" } } } }", "", asList(Mode.SET_ONLY, "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString") }, { // set /fooInt, /bar/barInt, /bar/baz/bazInt
"{\n" + " \"fooInt\" : 2,\n" + " \"bar\" : {\n" + " \"barInt\" : 2,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2\n" + " }\n" + " }\n" + "}", "{\n" + " \"$set\" : { \"fooInt\" : 2 },\n" + " \"bar\" : {\n" + " \"$set\" : { \"barInt\" : 2 },\n" + " \"baz\" : {\n" + " \"$set\" : { \"bazInt\" : 2 }\n" + " }\n" + " }\n" + "}", "", asList(Mode.SET_ONLY, "/fooInt", "/bar/barInt", "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "", "/fooInt", "/bar", "/bar/barInt", "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt", "/bar", "/bar/barInt", "/bar/baz", "/bar/baz/bazInt") }, { // nothing set
"{\n" + " \"fooInt\" : -1,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : -1,\n" + " \"bazString\" : \"excludes\"\n" + " }\n" + " }\n" + "}", "{}", "", asList(Mode.SET_ONLY), asList(Mode.PARENT_AND_SET), asList(Mode.ANCESTOR_AND_SET) }, { // must not call next validator for /fooString, /bar/barInt
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{\n" + " \"$set\" : { \"fooInt\" : 2 },\n" + " \"bar\" : {\n" + " \"$set\" : {\n" + " \"baz\" : { \"bazInt\" : 2, \"bazString\" : \"x\" }\n" + " }\n" + " }\n" + "}", "", asList(Mode.SET_ONLY, "/fooInt", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.PARENT_AND_SET, "", "/fooInt", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.ANCESTOR_AND_SET, "", "/fooInt", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString") }, { // must not call next validator for /fooInt, /fooString, /bar/barInt
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{\n" + " \"$set\" : {\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "/bar", asList(Mode.SET_ONLY, "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.PARENT_AND_SET, "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt", "/bar/baz/bazString") }, { // must not call next validator for /fooInt, /fooString, /bar/barInt
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{\n" + " \"baz\" : {\n" + " \"$set\" : {\n" + " \"bazInt\" : 2\n" + " }\n" + " }\n" + "}", "/bar", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") }, { // must not call next validator for /fooInt, /fooString, /bar/barInt
"{\n" + " \"fooInt\" : 2,\n" + " \"fooString\" : \"excludes\",\n" + " \"bar\" : {\n" + " \"barInt\" : -1,\n" + " \"baz\" : {\n" + " \"bazInt\" : 2,\n" + " \"bazString\" : \"x\"\n" + " }\n" + " }\n" + "}", "{\n" + " \"$set\" : { \"bazInt\" : 2 }\n" + "}", "/bar/baz", asList(Mode.SET_ONLY, "/bar/baz/bazInt"), asList(Mode.PARENT_AND_SET, "/bar/baz", "/bar/baz/bazInt"), asList(Mode.ANCESTOR_AND_SET, "", "/bar", "/bar/baz", "/bar/baz/bazInt") } };
DataSchema schema = dataSchemaFromString(schemaText);
ValidationOptions options = new ValidationOptions(RequiredMode.CAN_BE_ABSENT_IF_HAS_DEFAULT, CoercionMode.NORMAL);
for (Object[] row : inputs) {
String value = (String) row[0];
String patch = (String) row[1];
String patchPath = (String) row[2];
DataMap valueMap = dataMapFromString(value);
DataMap opMap = dataMapFromString(patch);
if (debug) {
out.println("Value: " + value);
out.println("Patch: " + patch);
if (patchPath.isEmpty() == false)
out.println("PatchPath: " + patchPath);
}
for (int i = 3; i < row.length; i++) {
VisitedValidator visitedValidator = new VisitedValidator();
@SuppressWarnings("unchecked") List<Object> check = (List<Object>) row[i];
Mode mode = (Mode) check.get(0);
Validator validator;
if (patchPath.isEmpty()) {
validator = new PatchFilterValidator(visitedValidator, opMap, mode);
} else {
DataElement patchElement = DataElementUtil.element(valueMap, schema, patchPath);
assertNotSame(patchElement, null);
validator = new PatchFilterValidator(visitedValidator, opMap, mode, patchElement);
}
ValidationResult result = ValidateDataAgainstSchema.validate(valueMap, schema, options, validator);
if (debug) {
out.println("Mode: " + mode);
out.print("Result: " + result);
out.println("VisitedPaths: " + visitedValidator._visitedPaths);
}
assertTrue(result.isValid());
for (int j = 1; j < check.size(); j++) {
assertTrue(visitedValidator._visitedPaths.contains(check.get(j)));
}
assertEquals(visitedValidator._visitedPaths.size(), check.size() - 1);
}
}
}
use of com.linkedin.data.schema.validation.ValidationResult in project rest.li by linkedin.
the class AbstractSchemaParser method validateDefaults.
/**
* Validate that the default value complies with the {@link DataSchema} of the record.
*
* @param recordSchema of the record.
*/
protected void validateDefaults(RecordDataSchema recordSchema) {
for (RecordDataSchema.Field field : recordSchema.getFields()) {
Object value = field.getDefault();
if (value != null) {
DataSchema valueSchema = field.getType();
ValidationResult result = ValidateDataAgainstSchema.validate(value, valueSchema, _validationOptions);
if (result.isValid() == false) {
startErrorMessage(value).append("Default value ").append(value).append(" of field \"").append(field.getName()).append("\" declared in record \"").append(recordSchema.getFullName()).append("\" failed validation.\n");
MessageUtil.appendMessages(errorMessageBuilder(), result.getMessages());
}
Object fixed = result.getFixed();
field.setDefault(fixed);
}
if (field.getDefault() instanceof DataComplex) {
((DataComplex) field.getDefault()).setReadOnly();
}
}
}
use of com.linkedin.data.schema.validation.ValidationResult in project rest.li by linkedin.
the class AnyRecordValidator method validate.
@Override
public void validate(ValidatorContext context) {
DataElement dataElement = context.dataElement();
Object value = dataElement.getValue();
DataSchema schema = dataElement.getSchema();
if (schema.getType() != DataSchema.Type.RECORD || (((RecordDataSchema) schema).getFullName()).equals(SCHEMA_NAME) == false) {
context.addResult(new Message(context.dataElement().path(), "%1$s invoked on schema that is not %2$s", AnyRecordValidator.class.getName(), SCHEMA_NAME));
} else if (value.getClass() != DataMap.class) {
context.addResult(new Message(context.dataElement().path(), "%1$s expects data to be a DataMap, data is %2$s", AnyRecordValidator.class.getName(), value));
} else {
DataMap dataMap = (DataMap) value;
if (dataMap.size() != 1) {
context.addResult(new Message(context.dataElement().path(), "%1$s expects data to be a DataMap with one entry, data is %2$s", AnyRecordValidator.class.getName(), value));
} else {
Map.Entry<String, Object> entry = dataMap.entrySet().iterator().next();
String anySchemaName = entry.getKey();
Object anyValue = entry.getValue();
DataSchema anySchema = schemaFromName(context, anySchemaName);
if (anySchema != null) {
DataElement anyElement = new SimpleDataElement(anyValue, entry.getKey(), anySchema, dataElement);
// do we want to have cache for anySchemaName to validator
// do we care about classMap argument to DataSchemaAnnotationValidator
DataSchemaAnnotationValidator validator = new DataSchemaAnnotationValidator(anySchema);
if (validator.isInitOk() == false) {
boolean errorIfNotValidated = getParameter(context.validationOptions()).isValidSchema();
context.addResult(new Message(context.dataElement().path(), errorIfNotValidated, "%1$s failed to initialize %2$s with %3$s", AnyRecordValidator.class.getName(), DataSchemaAnnotationValidator.class.getSimpleName(), anySchema));
addResult(context, errorIfNotValidated, validator.getInitMessages());
} else {
ValidationResult result = ValidateDataAgainstSchema.validate(anyElement, context.validationOptions(), validator);
addResult(context, result.getMessages());
if (result.hasFix())
context.setHasFix(true);
if (result.hasFixupReadOnlyError())
context.setHasFixupReadOnlyError(true);
}
}
}
}
}
use of com.linkedin.data.schema.validation.ValidationResult in project rest.li by linkedin.
the class TestAnyRecordValidator method testValidationResultFlags.
@Test
public void testValidationResultFlags() throws IOException {
Object[][] inputs = { { ANYRECORDCLIENT_SCHEMA, "{" + " \"required\" : {\n" + " \"com.linkedin.data.schema.validator.AnyRecord\" : {\n" + " \"com.linkedin.Cat\" : { \"c\" : 1 }\n" + " }\n" + " }\n" + "}", false, new ValidationOptions(RequiredMode.IGNORE, CoercionMode.NORMAL), ResultFlag.VALID, ResultFlag.HAS_FIX, ResultFlag.NOT_HAS_FIXUP_READONLY_ERROR, new String[] {} }, { ANYRECORDCLIENT_SCHEMA, "{" + " \"required\" : {\n" + " \"com.linkedin.data.schema.validator.AnyRecord\" : {\n" + " \"com.linkedin.Cat\" : { \"c\" : 1 }\n" + " }\n" + " }\n" + "}", true, new ValidationOptions(RequiredMode.IGNORE, CoercionMode.NORMAL), ResultFlag.NOT_VALID, ResultFlag.HAS_FIX, ResultFlag.HAS_FIXUP_READONLY_ERROR, new String[] { "ERROR", "/required/com.linkedin.data.schema.validator.AnyRecord/com.linkedin.Cat/c", "cannot be fixed because DataMap backing com.linkedin.Cat type is read-only" } } };
final boolean debug = false;
final AnyRecordValidator.Parameter anyRecordValidatorParameter = new AnyRecordValidator.Parameter(true, _resolver);
for (Object[] row : inputs) {
int i = 0;
DataSchema schema = (DataSchema) row[i++];
DataMap object = TestUtil.dataMapFromString((String) row[i++]);
boolean makeReadOnly = (Boolean) row[i++];
ValidationOptions options = (ValidationOptions) row[i++];
if (makeReadOnly) {
object.makeReadOnly();
}
AnyRecordValidator.setParameter(options, anyRecordValidatorParameter);
DataSchemaAnnotationValidator validator = new DataSchemaAnnotationValidator(schema);
if (debug)
TestUtil.out.println(validator);
ValidationResult result = ValidateDataAgainstSchema.validate(object, schema, options, validator);
checkValidationResult(result, row, i, debug);
}
}
use of com.linkedin.data.schema.validation.ValidationResult in project rest.li by linkedin.
the class TestValidator method testValidatorPriority.
@Test
public void testValidatorPriority() throws IOException {
Map<String, Class<? extends Validator>> validatorClassMap = new HashMap<String, Class<? extends Validator>>();
validatorClassMap.put("v1", OrderValidator.class);
validatorClassMap.put("v2", OrderValidator.class);
validatorClassMap.put("v3", OrderValidator.class);
validatorClassMap.put("v4", OrderValidator.class);
validatorClassMap.put("v5", OrderValidator.class);
validatorClassMap.put("v6", OrderValidator.class);
Object[][] inputs = { { // positive priority values
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"record\",\n" + " \"fields\" : [], \n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : 1, \"name\" : \"p1\" },\n" + " \"v2\" : { \"validatorPriority\" : 2, \"name\" : \"p2\" },\n" + " \"v3\" : { \"validatorPriority\" : 3, \"name\" : \"p3\" },\n" + " \"v4\" : { \"validatorPriority\" : 4, \"name\" : \"p4\" },\n" + " \"v5\" : { \"validatorPriority\" : 5, \"name\" : \"p5\" },\n" + " \"v6\" : { \"validatorPriority\" : 6, \"name\" : \"p6\" }\n" + " }\n" + "}\n", "{}", new String[] { ":p6", ":p5", ":p5", ":p4", ":p4", ":p3", ":p3", ":p2", ":p2", ":p1" } }, { // negative priority values
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"record\",\n" + " \"fields\" : [], \n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"p-1\" },\n" + " \"v2\" : { \"validatorPriority\" : 0, \"name\" : \"p=0\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"p+1\" }\n" + " }\n" + "}\n", "{}", new String[] { ":p+1", ":p=0", ":p=0", ":p-1" } }, { // default priority value
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"record\",\n" + " \"fields\" : [], \n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"p-1\" },\n" + " \"v2\" : { \"name\" : \"pdefault\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"p+1\" }\n" + " }\n" + "}\n", "{}", new String[] { ":p+1", ":pdefault", ":pdefault", ":p-1" } }, { // same priority values
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"record\",\n" + " \"fields\" : [], \n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"p-1a\" },\n" + " \"v2\" : { \"validatorPriority\" : -1, \"name\" : \"p-1b\" },\n" + " \"v3\" : { \"validatorPriority\" : 0, \"name\" : \"p0a\" },\n" + " \"v4\" : { \"validatorPriority\" : 0, \"name\" : \"p0b\" },\n" + " \"v5\" : { \"validatorPriority\" : 1, \"name\" : \"p+1a\" },\n" + " \"v6\" : { \"validatorPriority\" : 1, \"name\" : \"p+1b\" }\n" + " }\n" + "}\n", "{}", new String[] { ":p+1a", ":p0a", ":p+1a", ":p0b", ":p+1b", ":p0a", ":p+1b", ":p0b", ":p0a", ":p-1a", ":p0a", ":p-1b", ":p0b", ":p-1a", ":p0b", ":p-1b" } }, { // typeref inner before outer
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"record\",\n" + " \"fields\" : [\n" + " {\n" + " \"name\" : \"i\",\n" + " \"type\" : {\n" + " \"type\" : \"typeref\",\n" + " \"name\" : \"Ref1\",\n" + " \"ref\" : {\n" + " \"type\" : \"typeref\",\n" + " \"name\" : \"Ref2\",\n" + " \"ref\" : \"int\",\n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"r2-1\" },\n" + " \"v2\" : { \"name\" : \"r2=0\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"r2+1\" }\n" + " }\n" + " },\n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"r1-1\" },\n" + " \"v2\" : { \"name\" : \"r1=0\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"r1+1\" }\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}\n", "{\n" + " \"i\" : 4\n" + "}", new String[] { "/i:r2+1", "/i:r2=0", "/i:r2=0", "/i:r2-1", "/i:r2-1", "/i:r1+1", "/i:r1+1", "/i:r1=0", "/i:r1=0", "/i:r1-1" } }, { // array items before array
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"record\",\n" + " \"fields\" : [\n" + " {\n" + " \"name\" : \"a\",\n" + " \"type\" : {\n" + " \"type\" : \"array\",\n" + " \"items\" : {\n" + " \"type\" : \"typeref\",\n" + " \"name\" : \"IntRef\",\n" + " \"ref\" : \"int\",\n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"i-1\" },\n" + " \"v2\" : { \"name\" : \"i=0\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"i+1\" }\n" + " }\n" + " },\n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"a-1\" },\n" + " \"v2\" : { \"name\" : \"a=0\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"a+1\" }\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}\n", "{\n" + " \"a\" : [ 1 ]\n" + "}", new String[] { "/a/0:i+1", "/a/0:i=0", "/a/0:i=0", "/a/0:i-1", "/a/0:i-1", "/a:a+1", "/a:a+1", "/a:a=0", "/a:a=0", "/a:a-1" } }, { // map values before map
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"record\",\n" + " \"fields\" : [\n" + " {\n" + " \"name\" : \"m\",\n" + " \"type\" : {\n" + " \"type\" : \"map\",\n" + " \"values\" : {\n" + " \"type\" : \"typeref\",\n" + " \"name\" : \"IntRef\",\n" + " \"ref\" : \"int\",\n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"v-1\" },\n" + " \"v2\" : { \"name\" : \"v=0\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"v+1\" }\n" + " }\n" + " },\n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"m-1\" },\n" + " \"v2\" : { \"name\" : \"m=0\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"m+1\" }\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}\n", "{\n" + " \"m\" : { \"x\" : 1 } }\n" + "}", new String[] { "/m/x:v+1", "/m/x:v=0", "/m/x:v=0", "/m/x:v-1", "/m/x:v-1", "/m:m+1", "/m:m+1", "/m:m=0", "/m:m=0", "/m:m-1" } }, { // union member before typeref of union
"{\n" + " \"name\" : \"Foo\",\n" + " \"type\" : \"record\",\n" + " \"fields\" : [\n" + " {\n" + " \"name\" : \"u\",\n" + " \"type\" : {\n" + " \"type\" : \"typeref\",\n" + " \"name\" : \"Union\",\n" + " \"ref\" : [\n" + " {\n" + " \"type\" : \"typeref\",\n" + " \"name\" : \"Int\",\n" + " \"ref\" : \"int\",\n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"i-1\" },\n" + " \"v2\" : { \"name\" : \"i=0\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"i+1\" }\n" + " }\n" + " },\n" + " \"string\"\n" + " ],\n" + " \"validate\" : {\n" + " \"v1\" : { \"validatorPriority\" : -1, \"name\" : \"u-1\" },\n" + " \"v2\" : { \"name\" : \"u=0\" },\n" + " \"v3\" : { \"validatorPriority\" : 1, \"name\" : \"u+1\" }\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}\n", "{\n" + " \"u\" : { \"int\" : 4 }\n" + "}", new String[] { "/u/int:i+1", "/u/int:i=0", "/u/int:i=0", "/u/int:i-1", "/u/int:i-1", "/u:u+1", "/u:u+1", "/u:u=0", "/u:u=0", "/u:u-1" } } };
boolean debug = false;
for (Object[] row : inputs) {
int i = 0;
String schemaText = (String) row[i++];
String dataMapText = (String) row[i++];
DataSchema schema = dataSchemaFromString(schemaText);
DataMap dataMap = dataMapFromString(dataMapText);
DataSchemaAnnotationValidator dataSchemaAnnotationValidator = new DataSchemaAnnotationValidator();
dataSchemaAnnotationValidator.init(schema, validatorClassMap);
if (debug)
out.println(dataSchemaAnnotationValidator.getInitMessages());
assertTrue(dataSchemaAnnotationValidator.isInitOk());
if (debug)
out.println(dataSchemaAnnotationValidator);
dataSchemaAnnotationValidator.setDebugMode(debug);
OrderValidator._orderList.clear();
ValidationOptions validationOptions = new ValidationOptions();
ValidationResult validationResult = ValidateDataAgainstSchema.validate(dataMap, schema, validationOptions, dataSchemaAnnotationValidator);
assertTrue(validationResult.isValid());
if (debug)
out.println(validationResult.getMessages());
if (debug)
out.println(OrderValidator._orderList);
String[] expectedRelations = (String[]) row[i++];
assertTrue(expectedRelations.length % 2 == 0);
for (int r = 0; r < expectedRelations.length; r += 2) {
OrderRelation orderRelation = new OrderRelation(new OrderEntry(expectedRelations[r]), new OrderEntry(expectedRelations[r + 1]));
assertTrue(orderRelation.isSatisfied(OrderValidator._orderList));
}
}
}
Aggregations