Search in sources :

Example 26 with DataType

use of org.apache.nifi.serialization.record.DataType in project nifi by apache.

the class StandardSchemaValidator method getCanonicalDataType.

private DataType getCanonicalDataType(final DataType dataType, final Object rawValue, final StandardSchemaValidationResult result, final String fieldPrefix, final RecordField field) {
    final RecordFieldType fieldType = dataType.getFieldType();
    final DataType canonicalDataType;
    if (fieldType == RecordFieldType.CHOICE) {
        canonicalDataType = DataTypeUtils.chooseDataType(rawValue, (ChoiceDataType) dataType);
        if (canonicalDataType == null) {
            result.addValidationError(new StandardValidationError(concat(fieldPrefix, field), rawValue, ValidationErrorType.INVALID_FIELD, "Value is of type " + rawValue.getClass().getName() + " but was expected to be of type " + dataType));
            return null;
        }
    } else {
        canonicalDataType = dataType;
    }
    return canonicalDataType;
}
Also used : RecordDataType(org.apache.nifi.serialization.record.type.RecordDataType) DataType(org.apache.nifi.serialization.record.DataType) ChoiceDataType(org.apache.nifi.serialization.record.type.ChoiceDataType) MapDataType(org.apache.nifi.serialization.record.type.MapDataType) ArrayDataType(org.apache.nifi.serialization.record.type.ArrayDataType) ChoiceDataType(org.apache.nifi.serialization.record.type.ChoiceDataType) RecordFieldType(org.apache.nifi.serialization.record.RecordFieldType)

Example 27 with DataType

use of org.apache.nifi.serialization.record.DataType in project nifi by apache.

the class StandardSchemaValidator method isTypeCorrect.

private boolean isTypeCorrect(final Object value, final DataType dataType) {
    switch(dataType.getFieldType()) {
        case ARRAY:
            if (!(value instanceof Object[])) {
                return false;
            }
            final ArrayDataType arrayDataType = (ArrayDataType) dataType;
            final DataType elementType = arrayDataType.getElementType();
            final Object[] array = (Object[]) value;
            for (final Object arrayVal : array) {
                if (!isTypeCorrect(arrayVal, elementType)) {
                    return false;
                }
            }
            return true;
        case MAP:
            if (!(value instanceof Map)) {
                return false;
            }
            final MapDataType mapDataType = (MapDataType) dataType;
            final DataType valueDataType = mapDataType.getValueType();
            final Map<?, ?> map = (Map<?, ?>) value;
            for (final Object mapValue : map.values()) {
                if (!isTypeCorrect(mapValue, valueDataType)) {
                    return false;
                }
            }
            return true;
        case RECORD:
            return value instanceof Record;
        case CHOICE:
            final ChoiceDataType choiceDataType = (ChoiceDataType) dataType;
            for (final DataType choice : choiceDataType.getPossibleSubTypes()) {
                if (isTypeCorrect(value, choice)) {
                    return true;
                }
            }
            return false;
        case BIGINT:
            return value instanceof BigInteger;
        case BOOLEAN:
            return value instanceof Boolean;
        case BYTE:
            return value instanceof Byte;
        case CHAR:
            return value instanceof Character;
        case DATE:
            return value instanceof java.sql.Date;
        case DOUBLE:
            return value instanceof Double;
        case FLOAT:
            // Same goes for Short/Integer
            return value instanceof Float;
        case INT:
            return value instanceof Integer;
        case LONG:
            return value instanceof Long;
        case SHORT:
            return value instanceof Short;
        case STRING:
            return value instanceof String;
        case TIME:
            return value instanceof java.sql.Time;
        case TIMESTAMP:
            return value instanceof java.sql.Timestamp;
    }
    return false;
}
Also used : MapDataType(org.apache.nifi.serialization.record.type.MapDataType) BigInteger(java.math.BigInteger) RecordDataType(org.apache.nifi.serialization.record.type.RecordDataType) DataType(org.apache.nifi.serialization.record.DataType) ChoiceDataType(org.apache.nifi.serialization.record.type.ChoiceDataType) MapDataType(org.apache.nifi.serialization.record.type.MapDataType) ArrayDataType(org.apache.nifi.serialization.record.type.ArrayDataType) BigInteger(java.math.BigInteger) Record(org.apache.nifi.serialization.record.Record) ChoiceDataType(org.apache.nifi.serialization.record.type.ChoiceDataType) ArrayDataType(org.apache.nifi.serialization.record.type.ArrayDataType) Map(java.util.Map)

Example 28 with DataType

use of org.apache.nifi.serialization.record.DataType in project nifi by apache.

the class StandardSchemaValidator method verifyComplexType.

private void verifyComplexType(final DataType dataType, final Object rawValue, final StandardSchemaValidationResult result, final String fieldPrefix, final RecordField field) {
    // If the field type is RECORD, or if the field type is a CHOICE that allows for a RECORD and the value is a RECORD, then we
    // need to dig into each of the sub-fields. To do this, we first need to determine the 'canonical data type'.
    final DataType canonicalDataType = getCanonicalDataType(dataType, rawValue, result, fieldPrefix, field);
    if (canonicalDataType == null) {
        return;
    }
    // Now that we have the 'canonical data type', we check if it is a Record. If so, we need to validate each sub-field.
    if (canonicalDataType.getFieldType() == RecordFieldType.RECORD) {
        verifyChildRecord(canonicalDataType, rawValue, dataType, result, field, fieldPrefix);
    }
    if (canonicalDataType.getFieldType() == RecordFieldType.ARRAY) {
        final ArrayDataType arrayDataType = (ArrayDataType) canonicalDataType;
        final DataType elementType = arrayDataType.getElementType();
        final Object[] arrayObject = (Object[]) rawValue;
        int i = 0;
        for (final Object arrayValue : arrayObject) {
            verifyComplexType(elementType, arrayValue, result, fieldPrefix + "[" + i + "]", field);
            i++;
        }
    }
}
Also used : RecordDataType(org.apache.nifi.serialization.record.type.RecordDataType) DataType(org.apache.nifi.serialization.record.DataType) ChoiceDataType(org.apache.nifi.serialization.record.type.ChoiceDataType) MapDataType(org.apache.nifi.serialization.record.type.MapDataType) ArrayDataType(org.apache.nifi.serialization.record.type.ArrayDataType) ArrayDataType(org.apache.nifi.serialization.record.type.ArrayDataType)

Example 29 with DataType

use of org.apache.nifi.serialization.record.DataType in project nifi by apache.

the class StandardSchemaValidator method validate.

private SchemaValidationResult validate(final Record record, final RecordSchema schema, final String fieldPrefix) {
    // Ensure that for every field in the schema, the type is correct (if we care) and that
    // a value is present (unless it is nullable).
    final StandardSchemaValidationResult result = new StandardSchemaValidationResult();
    for (final RecordField field : schema.getFields()) {
        final Object rawValue = record.getValue(field);
        // If there is no value, then it is always valid unless the field is required.
        if (rawValue == null) {
            if (!field.isNullable() && field.getDefaultValue() == null) {
                result.addValidationError(new StandardValidationError(concat(fieldPrefix, field), ValidationErrorType.MISSING_FIELD, "Field is required"));
            }
            continue;
        }
        // Check that the type is correct.
        final DataType dataType = field.getDataType();
        if (validationContext.isStrictTypeChecking()) {
            if (!isTypeCorrect(rawValue, dataType)) {
                result.addValidationError(new StandardValidationError(concat(fieldPrefix, field), rawValue, ValidationErrorType.INVALID_FIELD, "Value is of type " + rawValue.getClass().getName() + " but was expected to be of type " + dataType));
                continue;
            }
        } else {
            // but will be false if the value is "123" and should be an Array or Record.
            if (!DataTypeUtils.isCompatibleDataType(rawValue, dataType)) {
                result.addValidationError(new StandardValidationError(concat(fieldPrefix, field), rawValue, ValidationErrorType.INVALID_FIELD, "Value is of type " + rawValue.getClass().getName() + " but was expected to be of type " + dataType));
                continue;
            }
        }
        // If the field type is RECORD, or if the field type is a CHOICE that allows for a RECORD and the value is a RECORD, then we
        // need to dig into each of the sub-fields. To do this, we first need to determine the 'canonical data type'.
        final DataType canonicalDataType = getCanonicalDataType(dataType, rawValue, result, fieldPrefix, field);
        if (canonicalDataType == null) {
            continue;
        }
        // Now that we have the 'canonical data type', we check if it is a Record. If so, we need to validate each sub-field.
        verifyComplexType(dataType, rawValue, result, fieldPrefix, field);
    }
    if (!validationContext.isExtraFieldAllowed()) {
        for (final String fieldName : record.getRawFieldNames()) {
            if (!schema.getDataType(fieldName).isPresent()) {
                result.addValidationError(new StandardValidationError(fieldPrefix + "/" + fieldName, ValidationErrorType.EXTRA_FIELD, "Field is not present in the schema"));
            }
        }
    }
    return result;
}
Also used : RecordField(org.apache.nifi.serialization.record.RecordField) RecordDataType(org.apache.nifi.serialization.record.type.RecordDataType) DataType(org.apache.nifi.serialization.record.DataType) ChoiceDataType(org.apache.nifi.serialization.record.type.ChoiceDataType) MapDataType(org.apache.nifi.serialization.record.type.MapDataType) ArrayDataType(org.apache.nifi.serialization.record.type.ArrayDataType)

Example 30 with DataType

use of org.apache.nifi.serialization.record.DataType in project nifi by apache.

the class TestStandardSchemaValidator method testValidateCorrectSimpleTypesStrictValidation.

@Test
public void testValidateCorrectSimpleTypesStrictValidation() throws ParseException {
    final List<RecordField> fields = new ArrayList<>();
    for (final RecordFieldType fieldType : RecordFieldType.values()) {
        if (fieldType == RecordFieldType.CHOICE) {
            final List<DataType> possibleTypes = new ArrayList<>();
            possibleTypes.add(RecordFieldType.INT.getDataType());
            possibleTypes.add(RecordFieldType.LONG.getDataType());
            fields.add(new RecordField(fieldType.name().toLowerCase(), fieldType.getChoiceDataType(possibleTypes)));
        } else if (fieldType == RecordFieldType.MAP) {
            fields.add(new RecordField(fieldType.name().toLowerCase(), fieldType.getMapDataType(RecordFieldType.INT.getDataType())));
        } else {
            fields.add(new RecordField(fieldType.name().toLowerCase(), fieldType.getDataType()));
        }
    }
    final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
    df.setTimeZone(TimeZone.getTimeZone("gmt"));
    final long time = df.parse("2017/01/01 17:00:00.000").getTime();
    final Map<String, Object> intMap = new LinkedHashMap<>();
    intMap.put("height", 48);
    intMap.put("width", 96);
    final RecordSchema schema = new SimpleRecordSchema(fields);
    final Map<String, Object> valueMap = new LinkedHashMap<>();
    valueMap.put("string", "string");
    valueMap.put("boolean", true);
    valueMap.put("byte", (byte) 1);
    valueMap.put("char", 'c');
    valueMap.put("short", (short) 8);
    valueMap.put("int", 9);
    valueMap.put("bigint", BigInteger.valueOf(8L));
    valueMap.put("long", 8L);
    valueMap.put("float", 8.0F);
    valueMap.put("double", 8.0D);
    valueMap.put("date", new Date(time));
    valueMap.put("time", new Time(time));
    valueMap.put("timestamp", new Timestamp(time));
    valueMap.put("record", null);
    valueMap.put("array", null);
    valueMap.put("choice", 48L);
    valueMap.put("map", intMap);
    final Record record = new MapRecord(schema, valueMap);
    final SchemaValidationContext validationContext = new SchemaValidationContext(schema, false, true);
    final StandardSchemaValidator validator = new StandardSchemaValidator(validationContext);
    final SchemaValidationResult result = validator.validate(record);
    assertTrue(result.isValid());
    assertNotNull(result.getValidationErrors());
    assertTrue(result.getValidationErrors().isEmpty());
}
Also used : SimpleRecordSchema(org.apache.nifi.serialization.SimpleRecordSchema) MapRecord(org.apache.nifi.serialization.record.MapRecord) RecordField(org.apache.nifi.serialization.record.RecordField) ArrayList(java.util.ArrayList) Time(java.sql.Time) Timestamp(java.sql.Timestamp) Date(java.sql.Date) LinkedHashMap(java.util.LinkedHashMap) SimpleDateFormat(java.text.SimpleDateFormat) DateFormat(java.text.DateFormat) DataType(org.apache.nifi.serialization.record.DataType) SchemaValidationResult(org.apache.nifi.serialization.record.validation.SchemaValidationResult) Record(org.apache.nifi.serialization.record.Record) MapRecord(org.apache.nifi.serialization.record.MapRecord) RecordFieldType(org.apache.nifi.serialization.record.RecordFieldType) SimpleDateFormat(java.text.SimpleDateFormat) RecordSchema(org.apache.nifi.serialization.record.RecordSchema) SimpleRecordSchema(org.apache.nifi.serialization.SimpleRecordSchema) Test(org.junit.Test)

Aggregations

DataType (org.apache.nifi.serialization.record.DataType)45 RecordField (org.apache.nifi.serialization.record.RecordField)36 RecordSchema (org.apache.nifi.serialization.record.RecordSchema)27 ArrayDataType (org.apache.nifi.serialization.record.type.ArrayDataType)24 SimpleRecordSchema (org.apache.nifi.serialization.SimpleRecordSchema)22 RecordDataType (org.apache.nifi.serialization.record.type.RecordDataType)22 ChoiceDataType (org.apache.nifi.serialization.record.type.ChoiceDataType)21 MapDataType (org.apache.nifi.serialization.record.type.MapDataType)20 ArrayList (java.util.ArrayList)17 RecordFieldType (org.apache.nifi.serialization.record.RecordFieldType)17 HashMap (java.util.HashMap)15 Record (org.apache.nifi.serialization.record.Record)14 Map (java.util.Map)13 MapRecord (org.apache.nifi.serialization.record.MapRecord)13 Test (org.junit.Test)13 LinkedHashMap (java.util.LinkedHashMap)11 List (java.util.List)11 ComponentLog (org.apache.nifi.logging.ComponentLog)10 File (java.io.File)9 IOException (java.io.IOException)9