Search in sources :

Example 1 with AvroEnumSchema

use of com.linkedin.avroutil1.model.AvroEnumSchema in project avro-util by linkedin.

the class SpecificRecordClassGeneratorTest method testSimpleEnum.

@Test
public void testSimpleEnum() throws Exception {
    String avsc = TestUtil.load("schemas/SimpleEnum.avsc");
    SpecificRecordClassGenerator generator = new SpecificRecordClassGenerator();
    AvscParser parser = new AvscParser();
    AvscParseResult result = parser.parse(avsc);
    Assert.assertNull(result.getParseError());
    AvroEnumSchema enumSchema = (AvroEnumSchema) result.getTopLevelSchema();
    Assert.assertNotNull(enumSchema);
    JavaFileObject javaSourceFile = generator.generateSpecificRecordClass(enumSchema, SpecificRecordGenerationConfig.BROAD_COMPATIBILITY);
    CompilerHelper.assertCompiles(javaSourceFile);
}
Also used : AvroEnumSchema(com.linkedin.avroutil1.model.AvroEnumSchema) JavaFileObject(javax.tools.JavaFileObject) AvscParser(com.linkedin.avroutil1.parser.avsc.AvscParser) AvscParseResult(com.linkedin.avroutil1.parser.avsc.AvscParseResult) Test(org.testng.annotations.Test)

Example 2 with AvroEnumSchema

use of com.linkedin.avroutil1.model.AvroEnumSchema in project avro-util by linkedin.

the class AvscParserTest method testSimpleParse.

@Test
public void testSimpleParse() throws Exception {
    String avsc = TestUtil.load("schemas/TestRecord.avsc");
    AvscParser parser = new AvscParser();
    AvscParseResult result = parser.parse(avsc);
    Assert.assertNull(result.getParseError());
    AvroSchema schema = result.getTopLevelSchema();
    Assert.assertNotNull(schema);
    Assert.assertEquals(schema.type(), AvroType.RECORD);
    AvroRecordSchema recordSchema = (AvroRecordSchema) schema;
    Assert.assertEquals(recordSchema.getFullName(), "com.acme.TestRecord");
    List<AvroSchemaField> fields = recordSchema.getFields();
    Assert.assertNotNull(fields);
    Assert.assertEquals(fields.size(), 11);
    Assert.assertEquals(fields.get(0).getPosition(), 0);
    Assert.assertEquals(fields.get(0).getName(), "booleanField");
    Assert.assertEquals(fields.get(0).getSchema().type(), AvroType.BOOLEAN);
    Assert.assertEquals(fields.get(1).getPosition(), 1);
    Assert.assertEquals(fields.get(1).getName(), "intField");
    Assert.assertEquals(fields.get(1).getSchema().type(), AvroType.INT);
    Assert.assertEquals(fields.get(2).getPosition(), 2);
    Assert.assertEquals(fields.get(2).getName(), "longField");
    Assert.assertEquals(fields.get(2).getSchema().type(), AvroType.LONG);
    Assert.assertEquals(fields.get(3).getPosition(), 3);
    Assert.assertEquals(fields.get(3).getName(), "floatField");
    Assert.assertEquals(fields.get(3).getSchema().type(), AvroType.FLOAT);
    Assert.assertEquals(fields.get(4).getPosition(), 4);
    Assert.assertEquals(fields.get(4).getName(), "doubleField");
    Assert.assertEquals(fields.get(4).getSchema().type(), AvroType.DOUBLE);
    Assert.assertEquals(fields.get(5).getPosition(), 5);
    Assert.assertEquals(fields.get(5).getName(), "bytesField");
    Assert.assertEquals(fields.get(5).getSchema().type(), AvroType.BYTES);
    Assert.assertEquals(fields.get(6).getPosition(), 6);
    Assert.assertEquals(fields.get(6).getName(), "stringField");
    Assert.assertEquals(fields.get(6).getSchema().type(), AvroType.STRING);
    Assert.assertEquals(fields.get(7).getPosition(), 7);
    Assert.assertEquals(fields.get(7).getName(), "enumField");
    Assert.assertEquals(fields.get(7).getSchema().type(), AvroType.ENUM);
    AvroEnumSchema simpleEnumSchema = (AvroEnumSchema) fields.get(7).getSchema();
    Assert.assertEquals(simpleEnumSchema.getFullName(), "innerNamespace.SimpleEnum");
    Assert.assertEquals(simpleEnumSchema.getSymbols(), Arrays.asList("A", "B", "C"));
    Assert.assertEquals(fields.get(8).getPosition(), 8);
    Assert.assertEquals(fields.get(8).getName(), "fixedField");
    Assert.assertEquals(fields.get(8).getSchema().type(), AvroType.FIXED);
    Assert.assertEquals(((AvroFixedSchema) fields.get(8).getSchema()).getFullName(), "com.acme.SimpleFixed");
    Assert.assertEquals(((AvroFixedSchema) fields.get(8).getSchema()).getSize(), 7);
    Assert.assertEquals(fields.get(9).getPosition(), 9);
    Assert.assertEquals(fields.get(9).getName(), "strArrayField");
    Assert.assertEquals(fields.get(9).getSchema().type(), AvroType.ARRAY);
    Assert.assertEquals(((AvroArraySchema) fields.get(9).getSchema()).getValueSchema().type(), AvroType.NULL);
    Assert.assertEquals(fields.get(10).getPosition(), 10);
    Assert.assertEquals(fields.get(10).getName(), "enumMapField");
    Assert.assertEquals(fields.get(10).getSchema().type(), AvroType.MAP);
    AvroSchema mapValueSchema = ((AvroMapSchema) fields.get(10).getSchema()).getValueSchema();
    Assert.assertSame(mapValueSchema, simpleEnumSchema);
}
Also used : AvroEnumSchema(com.linkedin.avroutil1.model.AvroEnumSchema) AvroArraySchema(com.linkedin.avroutil1.model.AvroArraySchema) AvroSchema(com.linkedin.avroutil1.model.AvroSchema) AvroMapSchema(com.linkedin.avroutil1.model.AvroMapSchema) AvroRecordSchema(com.linkedin.avroutil1.model.AvroRecordSchema) AvroSchemaField(com.linkedin.avroutil1.model.AvroSchemaField) Test(org.testng.annotations.Test)

Example 3 with AvroEnumSchema

use of com.linkedin.avroutil1.model.AvroEnumSchema in project avro-util by linkedin.

the class AvscParserTest method testParseBadEnumDefault.

@Test
public void testParseBadEnumDefault() throws Exception {
    String avsc = TestUtil.load("schemas/TestBadEnumDefault.avsc");
    AvscParser parser = new AvscParser();
    AvscParseResult result = parser.parse(avsc);
    AvroRecordSchema recordSchema = (AvroRecordSchema) result.getTopLevelSchema();
    List<AvscIssue> issues = result.getIssues(recordSchema);
    Assert.assertFalse(issues.stream().noneMatch(issue -> issue.getMessage().contains("default value")));
    AvroEnumSchema enumSchema = (AvroEnumSchema) recordSchema.getField("enumField").getSchema();
    issues = result.getIssues(enumSchema);
    Assert.assertFalse(issues.stream().noneMatch(issue -> issue.getMessage().contains("default value")));
}
Also used : Arrays(java.util.Arrays) TestUtil(com.linkedin.avroutil1.testcommon.TestUtil) UnresolvedReferenceException(com.linkedin.avroutil1.parser.exceptions.UnresolvedReferenceException) Test(org.testng.annotations.Test) SchemaOrRef(com.linkedin.avroutil1.model.SchemaOrRef) AvroSchemaField(com.linkedin.avroutil1.model.AvroSchemaField) JSONAssert(org.skyscreamer.jsonassert.JSONAssert) GenericData(org.apache.avro.generic.GenericData) AvroArraySchema(com.linkedin.avroutil1.model.AvroArraySchema) LinkedHashMap(java.util.LinkedHashMap) BigDecimal(java.math.BigDecimal) AvroFixedSchema(com.linkedin.avroutil1.model.AvroFixedSchema) Assert(org.testng.Assert) JsonPropertiesContainer(com.linkedin.avroutil1.model.JsonPropertiesContainer) AvroLogicalType(com.linkedin.avroutil1.model.AvroLogicalType) AvroUnionSchema(com.linkedin.avroutil1.model.AvroUnionSchema) AvroMapSchema(com.linkedin.avroutil1.model.AvroMapSchema) Schema(org.apache.avro.Schema) AvroEnumSchema(com.linkedin.avroutil1.model.AvroEnumSchema) AvroPrimitiveSchema(com.linkedin.avroutil1.model.AvroPrimitiveSchema) IOException(java.io.IOException) AvroSchema(com.linkedin.avroutil1.model.AvroSchema) Collectors(java.util.stream.Collectors) AvroJavaStringRepresentation(com.linkedin.avroutil1.model.AvroJavaStringRepresentation) List(java.util.List) AvroRecordSchema(com.linkedin.avroutil1.model.AvroRecordSchema) JSONCompareMode(org.skyscreamer.jsonassert.JSONCompareMode) AvroSyntaxException(com.linkedin.avroutil1.parser.exceptions.AvroSyntaxException) AvroType(com.linkedin.avroutil1.model.AvroType) Collections(java.util.Collections) JsonParseException(com.linkedin.avroutil1.parser.exceptions.JsonParseException) AvroEnumSchema(com.linkedin.avroutil1.model.AvroEnumSchema) AvroRecordSchema(com.linkedin.avroutil1.model.AvroRecordSchema) Test(org.testng.annotations.Test)

Example 4 with AvroEnumSchema

use of com.linkedin.avroutil1.model.AvroEnumSchema in project avro-util by linkedin.

the class AvscParser method parseNamedSchema.

private AvroNamedSchema parseNamedSchema(JsonObjectExt objectNode, AvscFileParseContext context, AvroType avroType, CodeLocation codeLocation, JsonPropertiesContainer extraProps) {
    AvroName schemaName = parseSchemaName(objectNode, context, avroType);
    List<AvroName> aliases = parseAliases(objectNode, context, avroType, schemaName);
    // technically the avro spec does not allow "doc" on type fixed, but screw that
    Located<String> docStr = getOptionalString(objectNode, "doc");
    String doc = docStr != null ? docStr.getValue() : null;
    boolean namespaceChanged = false;
    // check if context namespace changed
    if (!context.getCurrentNamespace().equals(schemaName.getNamespace())) {
        context.pushNamespace(schemaName.getNamespace());
        namespaceChanged = true;
    }
    AvroNamedSchema namedSchema;
    switch(avroType) {
        case RECORD:
            AvroRecordSchema recordSchema = new AvroRecordSchema(codeLocation, schemaName, aliases, doc, extraProps);
            JsonArrayExt fieldsNode = getRequiredArray(objectNode, "fields", () -> "all avro records must have fields");
            List<AvroSchemaField> fields = new ArrayList<>(fieldsNode.size());
            for (int fieldNum = 0; fieldNum < fieldsNode.size(); fieldNum++) {
                // !=null
                JsonValueExt fieldDeclNode = (JsonValueExt) fieldsNode.get(fieldNum);
                JsonValue.ValueType fieldNodeType = fieldDeclNode.getValueType();
                if (fieldNodeType != JsonValue.ValueType.OBJECT) {
                    throw new AvroSyntaxException("field " + fieldNum + " for record " + schemaName.getSimpleName() + " at " + fieldDeclNode.getStartLocation() + " expected to be an OBJECT, not a " + JsonPUtil.describe(fieldNodeType) + " (" + fieldDeclNode + ")");
                }
                TextLocation fieldStartLocation = Util.convertLocation(fieldDeclNode.getStartLocation());
                TextLocation fieldEndLocation = Util.convertLocation(fieldDeclNode.getEndLocation());
                CodeLocation fieldCodeLocation = new CodeLocation(context.getUri(), fieldStartLocation, fieldEndLocation);
                JsonObjectExt fieldDecl = (JsonObjectExt) fieldDeclNode;
                Located<String> fieldName = getRequiredString(fieldDecl, "name", () -> "all record fields must have a name");
                JsonValueExt fieldTypeNode = getRequiredNode(fieldDecl, "type", () -> "all record fields must have a type");
                Located<String> locatedDocField = getOptionalString(fieldDecl, "doc");
                String docField = locatedDocField == null ? null : locatedDocField.getValue();
                SchemaOrRef fieldSchema = parseSchemaDeclOrRef(fieldTypeNode, context, false);
                JsonValueExt fieldDefaultValueNode = fieldDecl.get("default");
                AvroLiteral defaultValue = null;
                if (fieldDefaultValueNode != null) {
                    if (fieldSchema.isResolved()) {
                        LiteralOrIssue defaultValurOrIssue = parseLiteral(fieldDefaultValueNode, fieldSchema.getSchema(), fieldName.getValue(), context);
                        if (defaultValurOrIssue.getIssue() == null) {
                            defaultValue = defaultValurOrIssue.getLiteral();
                        }
                    // TODO - handle issues
                    } else {
                        // TODO - implement delayed default value parsing
                        throw new UnsupportedOperationException("delayed parsing of default value for " + fieldName.getValue() + " TBD");
                    }
                }
                LinkedHashMap<String, JsonValueExt> props = parseExtraProps(fieldDecl, CORE_FIELD_PROPERTIES);
                JsonPropertiesContainer propsContainer = props.isEmpty() ? JsonPropertiesContainer.EMPTY : new JsonPropertiesContainerImpl(props);
                AvroSchemaField field = new AvroSchemaField(fieldCodeLocation, fieldName.getValue(), docField, fieldSchema, defaultValue, propsContainer);
                fields.add(field);
            }
            recordSchema.setFields(fields);
            namedSchema = recordSchema;
            break;
        case ENUM:
            JsonArrayExt symbolsNode = getRequiredArray(objectNode, "symbols", () -> "all avro enums must have symbols");
            List<String> symbols = new ArrayList<>(symbolsNode.size());
            for (int ordinal = 0; ordinal < symbolsNode.size(); ordinal++) {
                JsonValueExt symbolNode = (JsonValueExt) symbolsNode.get(ordinal);
                JsonValue.ValueType symbolNodeType = symbolNode.getValueType();
                if (symbolNodeType != JsonValue.ValueType.STRING) {
                    throw new AvroSyntaxException("symbol " + ordinal + " for enum " + schemaName.getSimpleName() + " at " + symbolNode.getStartLocation() + " expected to be a STRING, not a " + JsonPUtil.describe(symbolNodeType) + " (" + symbolNode + ")");
                }
                symbols.add(symbolNode.toString());
            }
            String defaultSymbol = null;
            Located<String> defaultStr = getOptionalString(objectNode, "default");
            if (defaultStr != null) {
                defaultSymbol = defaultStr.getValue();
                if (!symbols.contains(defaultSymbol)) {
                    context.addIssue(AvscIssues.badEnumDefaultValue(locationOf(context.getUri(), defaultStr), defaultSymbol, schemaName.getSimpleName(), symbols));
                    // TODO - support "fixing" by selecting 1st symbol as default?
                    defaultSymbol = null;
                }
            }
            namedSchema = new AvroEnumSchema(codeLocation, schemaName, aliases, doc, symbols, defaultSymbol, extraProps);
            break;
        case FIXED:
            JsonValueExt sizeNode = getRequiredNode(objectNode, "size", () -> "fixed types must have a size property");
            if (sizeNode.getValueType() != JsonValue.ValueType.NUMBER || !(((JsonNumberExt) sizeNode).isIntegral())) {
                throw new AvroSyntaxException("size for fixed " + schemaName.getSimpleName() + " at " + sizeNode.getStartLocation() + " expected to be an INTEGER, not a " + JsonPUtil.describe(sizeNode.getValueType()) + " (" + sizeNode + ")");
            }
            int fixedSize = ((JsonNumberExt) sizeNode).intValue();
            Parsed<AvroLogicalType> logicalTypeResult = parseLogicalType(objectNode, context, avroType, codeLocation);
            if (logicalTypeResult.hasIssues()) {
                context.addIssues(logicalTypeResult.getIssues());
            }
            namedSchema = new AvroFixedSchema(codeLocation, schemaName, aliases, doc, fixedSize, logicalTypeResult.getData(), extraProps);
            break;
        default:
            throw new IllegalStateException("unhandled: " + avroType + " for object at " + codeLocation.getStart());
    }
    if (namespaceChanged) {
        context.popNamespace();
    }
    return namedSchema;
}
Also used : AvroSyntaxException(com.linkedin.avroutil1.parser.exceptions.AvroSyntaxException) ArrayList(java.util.ArrayList) JsonPropertiesContainer(com.linkedin.avroutil1.model.JsonPropertiesContainer) AvroNamedSchema(com.linkedin.avroutil1.model.AvroNamedSchema) JsonArrayExt(com.linkedin.avroutil1.parser.jsonpext.JsonArrayExt) AvroEnumSchema(com.linkedin.avroutil1.model.AvroEnumSchema) AvroFixedSchema(com.linkedin.avroutil1.model.AvroFixedSchema) AvroLiteral(com.linkedin.avroutil1.model.AvroLiteral) JsonNumberExt(com.linkedin.avroutil1.parser.jsonpext.JsonNumberExt) CodeLocation(com.linkedin.avroutil1.model.CodeLocation) SchemaOrRef(com.linkedin.avroutil1.model.SchemaOrRef) AvroName(com.linkedin.avroutil1.model.AvroName) JsonValue(javax.json.JsonValue) AvroRecordSchema(com.linkedin.avroutil1.model.AvroRecordSchema) AvroLogicalType(com.linkedin.avroutil1.model.AvroLogicalType) JsonObjectExt(com.linkedin.avroutil1.parser.jsonpext.JsonObjectExt) JsonValueExt(com.linkedin.avroutil1.parser.jsonpext.JsonValueExt) TextLocation(com.linkedin.avroutil1.model.TextLocation) AvroSchemaField(com.linkedin.avroutil1.model.AvroSchemaField)

Example 5 with AvroEnumSchema

use of com.linkedin.avroutil1.model.AvroEnumSchema in project avro-util by linkedin.

the class SpecificRecordClassGeneratorTest method testHugeEnum.

@Test
public void testHugeEnum() throws Exception {
    String avsc = TestUtil.load("schemas/SimpleEnumWithHugeDoc.avsc");
    SpecificRecordClassGenerator generator = new SpecificRecordClassGenerator();
    AvscParser parser = new AvscParser();
    AvscParseResult result = parser.parse(avsc);
    Assert.assertNull(result.getParseError());
    AvroEnumSchema enumSchema = (AvroEnumSchema) result.getTopLevelSchema();
    Assert.assertNotNull(enumSchema);
    JavaFileObject javaSourceFile = generator.generateSpecificRecordClass(enumSchema, SpecificRecordGenerationConfig.BROAD_COMPATIBILITY);
    CompilerHelper.assertCompiles(javaSourceFile);
}
Also used : AvroEnumSchema(com.linkedin.avroutil1.model.AvroEnumSchema) JavaFileObject(javax.tools.JavaFileObject) AvscParser(com.linkedin.avroutil1.parser.avsc.AvscParser) AvscParseResult(com.linkedin.avroutil1.parser.avsc.AvscParseResult) Test(org.testng.annotations.Test)

Aggregations

AvroEnumSchema (com.linkedin.avroutil1.model.AvroEnumSchema)7 AvroFixedSchema (com.linkedin.avroutil1.model.AvroFixedSchema)4 AvroRecordSchema (com.linkedin.avroutil1.model.AvroRecordSchema)4 Test (org.testng.annotations.Test)4 AvroArraySchema (com.linkedin.avroutil1.model.AvroArraySchema)3 AvroSchema (com.linkedin.avroutil1.model.AvroSchema)3 AvroSchemaField (com.linkedin.avroutil1.model.AvroSchemaField)3 AvroType (com.linkedin.avroutil1.model.AvroType)3 AvroLiteral (com.linkedin.avroutil1.model.AvroLiteral)2 AvroLogicalType (com.linkedin.avroutil1.model.AvroLogicalType)2 AvroMapSchema (com.linkedin.avroutil1.model.AvroMapSchema)2 AvroName (com.linkedin.avroutil1.model.AvroName)2 AvroPrimitiveSchema (com.linkedin.avroutil1.model.AvroPrimitiveSchema)2 JsonPropertiesContainer (com.linkedin.avroutil1.model.JsonPropertiesContainer)2 SchemaOrRef (com.linkedin.avroutil1.model.SchemaOrRef)2 AvscParseResult (com.linkedin.avroutil1.parser.avsc.AvscParseResult)2 AvscParser (com.linkedin.avroutil1.parser.avsc.AvscParser)2 AvroSyntaxException (com.linkedin.avroutil1.parser.exceptions.AvroSyntaxException)2 JsonArrayExt (com.linkedin.avroutil1.parser.jsonpext.JsonArrayExt)2 JsonNumberExt (com.linkedin.avroutil1.parser.jsonpext.JsonNumberExt)2