Search in sources :

Example 6 with AvroSchema

use of com.linkedin.avroutil1.model.AvroSchema 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 7 with AvroSchema

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

the class AvscParser method parseComplexSchema.

private SchemaOrRef parseComplexSchema(JsonObjectExt objectNode, AvscFileParseContext context, boolean topLevel) {
    CodeLocation codeLocation = locationOf(context.getUri(), objectNode);
    Located<String> typeStr = getRequiredString(objectNode, "type", () -> "it is a schema declaration");
    AvroType avroType = AvroType.fromTypeName(typeStr.getValue());
    if (avroType == null) {
        throw new AvroSyntaxException("unknown avro type \"" + typeStr.getValue() + "\" at " + typeStr.getLocation() + ". expecting \"record\", \"enum\" or \"fixed\"");
    }
    LinkedHashMap<String, JsonValueExt> propsMap = parseExtraProps(objectNode, CORE_SCHEMA_PROPERTIES);
    JsonPropertiesContainer props = propsMap.isEmpty() ? JsonPropertiesContainer.EMPTY : new JsonPropertiesContainerImpl(propsMap);
    AvroSchema definedSchema;
    if (avroType.isNamed()) {
        definedSchema = parseNamedSchema(objectNode, context, avroType, codeLocation, props);
    } else if (avroType.isCollection()) {
        definedSchema = parseCollectionSchema(objectNode, context, avroType, codeLocation, props);
    } else if (avroType.isPrimitive()) {
        definedSchema = parseDecoratedPrimitiveSchema(objectNode, context, avroType, codeLocation, props);
    } else {
        throw new IllegalStateException("unhandled avro type " + avroType + " at " + typeStr.getLocation());
    }
    context.defineSchema(definedSchema, topLevel);
    return new SchemaOrRef(codeLocation, definedSchema);
}
Also used : CodeLocation(com.linkedin.avroutil1.model.CodeLocation) AvroSchema(com.linkedin.avroutil1.model.AvroSchema) SchemaOrRef(com.linkedin.avroutil1.model.SchemaOrRef) AvroType(com.linkedin.avroutil1.model.AvroType) AvroSyntaxException(com.linkedin.avroutil1.parser.exceptions.AvroSyntaxException) JsonPropertiesContainer(com.linkedin.avroutil1.model.JsonPropertiesContainer) JsonValueExt(com.linkedin.avroutil1.parser.jsonpext.JsonValueExt)

Example 8 with AvroSchema

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

the class AvscParserTest method testParsingProperties.

@Test
public void testParsingProperties() throws Exception {
    String avsc = TestUtil.load("schemas/TestRecordWithProperties.avsc");
    AvscParser parser = new AvscParser();
    AvscParseResult result = parser.parse(avsc);
    Assert.assertNull(result.getParseError());
    AvroRecordSchema schema = (AvroRecordSchema) result.getTopLevelSchema();
    Assert.assertNotNull(schema);
    Assert.assertEquals(schema.propertyNames(), // order is important
    Arrays.asList("extraNullProp", "extraBooleanProp", "extraIntProp", "extraFloatProp", "extraStringProp", "extraArrayProp", "extraObjectProp"));
    Assert.assertNull(schema.getPropertyAsJsonLiteral("noSuchProp"));
    Assert.assertNull(schema.getPropertyAsObject("noSuchProp"));
    Assert.assertEquals(schema.getPropertyAsJsonLiteral("extraNullProp"), "null");
    Assert.assertEquals(schema.getPropertyAsObject("extraNullProp"), JsonPropertiesContainer.NULL_VALUE);
    Assert.assertEquals(schema.getPropertyAsJsonLiteral("extraBooleanProp"), "true");
    Assert.assertEquals(schema.getPropertyAsObject("extraBooleanProp"), Boolean.TRUE);
    Assert.assertEquals(schema.getPropertyAsJsonLiteral("extraIntProp"), "42");
    Assert.assertEquals(schema.getPropertyAsObject("extraIntProp"), new BigDecimal(42));
    Assert.assertEquals(schema.getPropertyAsJsonLiteral("extraFloatProp"), "4.2");
    // new BigDecimal(4.2d) is actually 4.20000000000000017763568394002504646778106689453125
    // we love floating point precision
    Assert.assertEquals(schema.getPropertyAsObject("extraFloatProp"), new BigDecimal("4.2"));
    Assert.assertEquals(schema.getPropertyAsJsonLiteral("extraStringProp"), "\"a string\"");
    Assert.assertEquals(schema.getPropertyAsObject("extraStringProp"), "a string");
    JSONAssert.assertEquals("[null, 0, false, \"wow\", {\"this\" : \"makes\", \"little\" : \"sense\"}]", schema.getPropertyAsJsonLiteral("extraArrayProp"), JSONCompareMode.STRICT);
    Assert.assertEquals(schema.getPropertyAsObject("extraArrayProp"), Arrays.asList(JsonPropertiesContainer.NULL_VALUE, new BigDecimal(0), Boolean.FALSE, "wow", new LinkedHashMap<String, Object>() {

        {
            put("this", "makes");
            put("little", "sense");
        }
    }));
    JSONAssert.assertEquals("{\"thats\": [\"all\", \"folks\"]}", schema.getPropertyAsJsonLiteral("extraObjectProp"), JSONCompareMode.STRICT);
    Assert.assertEquals(schema.getPropertyAsObject("extraObjectProp"), new LinkedHashMap<String, Object>() {

        {
            put("thats", Arrays.asList("all", "folks"));
        }
    });
    AvroSchemaField stringField = schema.getField("stringField");
    Assert.assertEquals(stringField.propertyNames(), Collections.singletonList("fieldStringProp"));
    Assert.assertEquals(stringField.getPropertyAsJsonLiteral("fieldStringProp"), "\"fieldStringValue\"");
    Assert.assertEquals(stringField.getPropertyAsObject("fieldStringProp"), "fieldStringValue");
    AvroSchema stringSchema = stringField.getSchema();
    Assert.assertEquals(stringSchema.propertyNames(), Arrays.asList("avro.java.string", "typeStringProp"));
    AvroSchema uuidSchema = schema.getField("uuidField").getSchema();
    Assert.assertEquals(uuidSchema.propertyNames(), Collections.singletonList("logicalType"));
}
Also used : AvroSchema(com.linkedin.avroutil1.model.AvroSchema) AvroRecordSchema(com.linkedin.avroutil1.model.AvroRecordSchema) AvroSchemaField(com.linkedin.avroutil1.model.AvroSchemaField) BigDecimal(java.math.BigDecimal) LinkedHashMap(java.util.LinkedHashMap) Test(org.testng.annotations.Test)

Example 9 with AvroSchema

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

the class AvscSchemaWriterTest method testParsingCycle.

/**
 * given an avsc, parses and re-prints it using our code
 * and compares the result to vanilla avro.
 * @param avsc
 */
private void testParsingCycle(String avsc) {
    Schema reference = Schema.parse(avsc);
    AvscParser parser = new AvscParser();
    AvscParseResult parseResults = parser.parse(avsc);
    List<AvscIssue> parseIssues = parseResults.getIssues();
    Assert.assertTrue(parseIssues == null || parseIssues.isEmpty(), "parse issues: " + parseIssues);
    AvroSchema parsed = parseResults.getTopLevelSchema();
    Assert.assertNotNull(parsed);
    AvscSchemaWriter writer = new AvscSchemaWriter();
    AvscFile file = writer.writeSingle(parsed);
    Assert.assertNotNull(file);
    if (HelperConsts.NAMED_TYPES.contains(reference.getType())) {
        // for named schemas the file path is determined by schema name
        Assert.assertNotNull(file.getPathFromRoot());
        String expectedFileName = reference.getFullName().replaceAll("\\.", Matcher.quoteReplacement(File.separator)) + ".avsc";
        Assert.assertEquals(file.getPathFromRoot().toString(), expectedFileName);
    } else {
        // cant auto-name files containing other schema types
        Assert.assertNull(file.getPathFromRoot());
    }
    String avsc2 = file.getContents();
    Schema afterCycle = Schema.parse(avsc2);
    Assert.assertEquals(reference, afterCycle);
}
Also used : AvroSchema(com.linkedin.avroutil1.model.AvroSchema) AvscParser(com.linkedin.avroutil1.parser.avsc.AvscParser) AvscIssue(com.linkedin.avroutil1.parser.avsc.AvscIssue) Schema(org.apache.avro.Schema) AvroSchema(com.linkedin.avroutil1.model.AvroSchema) AvscParseResult(com.linkedin.avroutil1.parser.avsc.AvscParseResult)

Example 10 with AvroSchema

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

the class AvroParseContext method resolveReferences.

public void resolveReferences() {
    sealed = true;
    // build up an index of FQCNs (also find dups)
    knownNamedSchemas = new HashMap<>(individualResults.size());
    duplicates = new HashMap<>(1);
    for (AvscParseResult singleFile : individualResults) {
        Throwable error = singleFile.getParseError();
        if (error != null) {
            // dont touch files with outright failures
            continue;
        }
        Map<String, AvroSchema> namedInFile = singleFile.getDefinedNamedSchemas();
        namedInFile.forEach((fqcn, schema) -> {
            AvscParseResult firstDefinition = knownNamedSchemas.putIfAbsent(fqcn, singleFile);
            if (firstDefinition != null) {
                // TODO - find dups in aliases as well ?
                // this is a dup
                duplicates.compute(fqcn, (k, dups) -> {
                    if (dups == null) {
                        dups = new ArrayList<>(2);
                        dups.add(firstDefinition);
                    }
                    dups.add(singleFile);
                    return dups;
                });
            }
        });
    }
    // TODO - add context-level issues for dups
    // resolve any unresolved references in individual file results from other files
    externalReferences = new ArrayList<>();
    for (AvscParseResult singleFile : individualResults) {
        List<SchemaOrRef> externalRefs = singleFile.getExternalReferences();
        for (SchemaOrRef ref : externalRefs) {
            String simpleName = ref.getRef();
            AvscParseResult simpleNameResolution = knownNamedSchemas.get(simpleName);
            AvscParseResult inheritedNameResolution = null;
            String inheritedName = ref.getInheritedName();
            if (inheritedName != null) {
                inheritedNameResolution = knownNamedSchemas.get(inheritedName);
            }
            // the inherited namespace).
            if (inheritedNameResolution != null) {
                ref.setResolvedTo(inheritedNameResolution.getDefinedNamedSchemas().get(inheritedName));
                if (simpleNameResolution != null) {
                    String msg = "ERROR: Two different schemas found for reference " + simpleName + " with inherited name " + inheritedName + ". Only one should exist.";
                    singleFile.addIssue(new AvscIssue(ref.getCodeLocation(), IssueSeverity.WARNING, msg, new IllegalStateException(msg)));
                }
            } else if (simpleNameResolution != null) {
                ref.setResolvedTo(simpleNameResolution.getDefinedNamedSchemas().get(simpleName));
            } else {
                // fqcn is unresolved in this context
                externalReferences.add(ref);
            }
        }
    }
}
Also used : AvroSchema(com.linkedin.avroutil1.model.AvroSchema) SchemaOrRef(com.linkedin.avroutil1.model.SchemaOrRef)

Aggregations

AvroSchema (com.linkedin.avroutil1.model.AvroSchema)11 AvroArraySchema (com.linkedin.avroutil1.model.AvroArraySchema)5 AvroType (com.linkedin.avroutil1.model.AvroType)5 AvroSchemaField (com.linkedin.avroutil1.model.AvroSchemaField)4 SchemaOrRef (com.linkedin.avroutil1.model.SchemaOrRef)4 AvroLiteral (com.linkedin.avroutil1.model.AvroLiteral)3 AvroMapSchema (com.linkedin.avroutil1.model.AvroMapSchema)3 AvroRecordSchema (com.linkedin.avroutil1.model.AvroRecordSchema)3 JsonArrayBuilder (javax.json.JsonArrayBuilder)3 Test (org.testng.annotations.Test)3 AvroArrayLiteral (com.linkedin.avroutil1.model.AvroArrayLiteral)2 AvroBooleanLiteral (com.linkedin.avroutil1.model.AvroBooleanLiteral)2 AvroBytesLiteral (com.linkedin.avroutil1.model.AvroBytesLiteral)2 AvroDoubleLiteral (com.linkedin.avroutil1.model.AvroDoubleLiteral)2 AvroEnumLiteral (com.linkedin.avroutil1.model.AvroEnumLiteral)2 AvroEnumSchema (com.linkedin.avroutil1.model.AvroEnumSchema)2 AvroFixedLiteral (com.linkedin.avroutil1.model.AvroFixedLiteral)2 AvroFloatLiteral (com.linkedin.avroutil1.model.AvroFloatLiteral)2 AvroIntegerLiteral (com.linkedin.avroutil1.model.AvroIntegerLiteral)2 AvroLongLiteral (com.linkedin.avroutil1.model.AvroLongLiteral)2