Search in sources :

Example 1 with ExtensionSchemaAnnotationHandler

use of com.linkedin.data.schema.annotation.ExtensionSchemaAnnotationHandler in project rest.li by linkedin.

the class TestAnnotationCompatibilityChecker method annotationCompatibilityCheckTestData.

@DataProvider
private Object[][] annotationCompatibilityCheckTestData() throws IOException {
    // Set up expected result: both previous schema and current schema contain the same PathSpecs.
    CompatibilityCheckContext checkContext = generateAnnotationCheckContext(new PathSpec("TestSchema1/field1/$field"));
    CompatibilityCheckContext checkContext1 = generateAnnotationCheckContext(new PathSpec("TestSchema1/field2/$field"));
    AnnotationCompatibilityResult expectResultWithCompatibleChange1 = generateExpectResult(new CompatibilityMessage(checkContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_COMPATIBLE_CHANGE, "Updating annotation field \"%s\" value is backward compatible change", ANNOTATION_FIELD_NAME));
    AnnotationCompatibilityResult expectResultWithInCompatibleChange1 = generateExpectResult(new CompatibilityMessage(checkContext1.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Deleting existed annotation \"%s\" is backward incompatible change", BAR_ANNOTATION_NAMESPACE));
    // Set up expected result: only previous schema contains the resolvedProperty with the same annotation namespace as SchemaAnnotationHandler
    CompatibilityCheckContext checkContext2 = generateAnnotationCheckContext(new PathSpec("TestSchema2/field1/$field"));
    AnnotationCompatibilityResult expectResult2 = generateExpectResult(new CompatibilityMessage(checkContext2.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Adding new annotation \"%s\" is backward compatible change", BAR_ANNOTATION_NAMESPACE));
    // Set up expected result: only current schema contains the resolvedProperty with the same annotation namespace as SchemaAnnotationHandler
    CompatibilityCheckContext checkContext3 = generateAnnotationCheckContext(new PathSpec("TestSchema3/field1/$field"));
    AnnotationCompatibilityResult expectResult3 = generateExpectResult(new CompatibilityMessage(checkContext3.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Deleting existed annotation \"%s\" is backward incompatible change", BAR_ANNOTATION_NAMESPACE));
    // Set up expected results: multiple handlers.
    CompatibilityCheckContext checkContext4 = generateAnnotationCheckContext(new PathSpec("TestSchema4/field1/$field"));
    AnnotationCompatibilityResult barHandlerExpectResult = generateExpectResult(new CompatibilityMessage(checkContext4.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Adding new annotation \"%s\" is backward compatible change", BAR_ANNOTATION_NAMESPACE));
    AnnotationCompatibilityResult bazHandlerExpectResult = generateExpectResult(new CompatibilityMessage(checkContext4.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_COMPATIBLE_CHANGE, "Updating annotation field \"%s\" value is backward compatible change", ANNOTATION_FIELD_NAME));
    // Set up expected results: field has annotation, field type schema also has annotation.
    AnnotationCompatibilityResult fieldAnnotationResult = new AnnotationCompatibilityResult();
    CompatibilityCheckContext checkContext5 = generateAnnotationCheckContext(new PathSpec("TestSchema5/field1"));
    AnnotationCompatibilityResult fieldTypeSchemaAnnotationResult = generateExpectResult(new CompatibilityMessage(checkContext5.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_COMPATIBLE_CHANGE, "Updating annotation field \"%s\" value is backward compatible change", ANNOTATION_FIELD_NAME));
    // Set up expected results: field has annotation, field type schema also has annotation.
    CompatibilityCheckContext unionMemberKeyCheckContext = generateAnnotationCheckContext(new PathSpec("TestSchema6/field1/u1/$unionMemberKey"));
    AnnotationCompatibilityResult unionMemberKeyAnnotationResult = generateExpectResult(new CompatibilityMessage(unionMemberKeyCheckContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_COMPATIBLE_CHANGE, "Updating annotation field \"%s\" value is backward compatible change", ANNOTATION_FIELD_NAME));
    CompatibilityCheckContext unionMemberSchemaCheckContext = generateAnnotationCheckContext(new PathSpec("TestSchema6/field1/u1"));
    AnnotationCompatibilityResult unionMemberSchemaAnnotationResult = generateExpectResult(new CompatibilityMessage(unionMemberSchemaCheckContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_COMPATIBLE_CHANGE, "Updating annotation field \"%s\" value is backward compatible change", ANNOTATION_FIELD_NAME));
    // Set up expected result: an extension annotation field value is updated.
    CompatibilityCheckContext schoolContext = generateAnnotationCheckContext(new PathSpec("SchoolExtensions/testField/$field"));
    AnnotationCompatibilityResult schoolExtensionExpectResult = generateExpectResult(new CompatibilityMessage(schoolContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Updating extension annotation field: \"%s\" value is considering as a backward incompatible change.", "using"));
    // Set up expected result: an extension annotation field is removed.
    CompatibilityCheckContext fruitContext = generateAnnotationCheckContext(new PathSpec("FruitExtensions/testField/$field"));
    AnnotationCompatibilityResult fruitExtensionExpectResult = generateExpectResult(new CompatibilityMessage(fruitContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Removing extension annotation field: \"%s\" is considering as a backward incompatible change.", "params"));
    // Set up expected result: a new field with annotation is added.
    CompatibilityCheckContext fooContext = generateAnnotationCheckContext(new PathSpec("FooExtensions/barField/$field"));
    AnnotationCompatibilityResult fooExtensionExpectResult = generateExpectResult(new CompatibilityMessage(fooContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_COMPATIBLE_CHANGE, "Adding extension annotation on new field: \"%s\" is backward compatible change", "barField"));
    // Existing fields annotations do not change, checkCompatibility will return an empty result.
    AnnotationCompatibilityResult emptyResult = new AnnotationCompatibilityResult();
    // Set up expected result: an extension annotation is removed.
    CompatibilityCheckContext albumContext = generateAnnotationCheckContext(new PathSpec("AlbumExtensions/testField/$field"));
    AnnotationCompatibilityResult albumExtensionExpectResult = generateExpectResult(new CompatibilityMessage(albumContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Removing extension annotation is a backward incompatible change.", ""));
    // Set up expected result: an extension annotation is removed.
    CompatibilityCheckContext companyContext = generateAnnotationCheckContext(new PathSpec("CompanyExtensions/testField/$field"));
    AnnotationCompatibilityResult companyExtensionExpectResult = generateExpectResult(new CompatibilityMessage(companyContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Adding extension annotation field: \"%s\" is a backward incompatible change.", "using"));
    // Set up expected result: a field with extension annotation is removed.
    CompatibilityCheckContext bookContext = generateAnnotationCheckContext(new PathSpec("BookExtensions/testField/$field"));
    AnnotationCompatibilityResult bookExtensionExpectResult = generateExpectResult(new CompatibilityMessage(bookContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Removing field: \"%s\" with extension annotation is a backward incompatible change.", "testField"));
    // Set up expected result: adding extension annotation on an existing field
    CompatibilityCheckContext jobContext = generateAnnotationCheckContext(new PathSpec("JobExtensions/testField/$field"));
    AnnotationCompatibilityResult jobExtensionExpectResult = generateExpectResult(new CompatibilityMessage(jobContext.getPathSpecToSchema(), CompatibilityMessage.Impact.ANNOTATION_INCOMPATIBLE_CHANGE, "Adding extension annotation on an existing field: \"%s\" is backward incompatible change", "testField"));
    return new Object[][] { { "previousSchema/TestSchema1.pdl", "currentSchema/TestSchema1.pdl", Collections.singletonList(generateSchemaAnnotationHandler(BAR_ANNOTATION_NAMESPACE)), Arrays.asList(expectResultWithCompatibleChange1, expectResultWithInCompatibleChange1) }, { "previousSchema/TestSchema2.pdl", "currentSchema/TestSchema2.pdl", Collections.singletonList(generateSchemaAnnotationHandler(BAR_ANNOTATION_NAMESPACE)), Collections.singletonList(expectResult2) }, { "previousSchema/TestSchema3.pdl", "currentSchema/TestSchema3.pdl", Collections.singletonList(generateSchemaAnnotationHandler(BAR_ANNOTATION_NAMESPACE)), Collections.singletonList(expectResult3) }, { "previousSchema/TestSchema4.pdl", "currentSchema/TestSchema4.pdl", Arrays.asList(generateSchemaAnnotationHandler(BAR_ANNOTATION_NAMESPACE), generateSchemaAnnotationHandler(BAZ_ANNOTATION_NAMESPACE)), Arrays.asList(barHandlerExpectResult, bazHandlerExpectResult) }, { "previousSchema/TestSchema5.pdl", "currentSchema/TestSchema5.pdl", Arrays.asList(generateSchemaAnnotationHandler(BAR_ANNOTATION_NAMESPACE), generateSchemaAnnotationHandler(BAZ_ANNOTATION_NAMESPACE)), Arrays.asList(fieldAnnotationResult, fieldTypeSchemaAnnotationResult) }, { "previousSchema/TestSchema6.pdl", "currentSchema/TestSchema6.pdl", Arrays.asList(generateSchemaAnnotationHandler(BAR_ANNOTATION_NAMESPACE), generateSchemaAnnotationHandler(BAZ_ANNOTATION_NAMESPACE)), Arrays.asList(unionMemberSchemaAnnotationResult, unionMemberKeyAnnotationResult) }, { "previousSchema/SchoolExtensions.pdl", "currentSchema/SchoolExtensions.pdl", Collections.singletonList(new ExtensionSchemaAnnotationHandler()), Collections.singletonList(schoolExtensionExpectResult) }, { "previousSchema/FruitExtensions.pdl", "currentSchema/FruitExtensions.pdl", Collections.singletonList(new ExtensionSchemaAnnotationHandler()), Collections.singletonList(fruitExtensionExpectResult) }, { "previousSchema/FooExtensions.pdl", "currentSchema/FooExtensions.pdl", Collections.singletonList(new ExtensionSchemaAnnotationHandler()), Arrays.asList(emptyResult, fooExtensionExpectResult) }, { "previousSchema/AlbumExtensions.pdl", "currentSchema/AlbumExtensions.pdl", Collections.singletonList(new ExtensionSchemaAnnotationHandler()), Collections.singletonList(albumExtensionExpectResult) }, { "previousSchema/CompanyExtensions.pdl", "currentSchema/CompanyExtensions.pdl", Collections.singletonList(new ExtensionSchemaAnnotationHandler()), Collections.singletonList(companyExtensionExpectResult) }, { "previousSchema/BookExtensions.pdl", "currentSchema/BookExtensions.pdl", Collections.singletonList(new ExtensionSchemaAnnotationHandler()), Arrays.asList(bookExtensionExpectResult, emptyResult) }, { "previousSchema/JobExtensions.pdl", "currentSchema/JobExtensions.pdl", Collections.singletonList(new ExtensionSchemaAnnotationHandler()), Collections.singletonList(jobExtensionExpectResult) }, { "previousSchema/IdentityExtensions.pdl", "currentSchema/IdentityExtensions.pdl", Collections.singletonList(new ExtensionSchemaAnnotationHandler()), Collections.singletonList(emptyResult) } };
}
Also used : ExtensionSchemaAnnotationHandler(com.linkedin.data.schema.annotation.ExtensionSchemaAnnotationHandler) AnnotationCompatibilityResult(com.linkedin.data.schema.annotation.SchemaAnnotationHandler.AnnotationCompatibilityResult) CompatibilityCheckContext(com.linkedin.data.schema.annotation.SchemaAnnotationHandler.CompatibilityCheckContext) PathSpec(com.linkedin.data.schema.PathSpec) DataProvider(org.testng.annotations.DataProvider)

Example 2 with ExtensionSchemaAnnotationHandler

use of com.linkedin.data.schema.annotation.ExtensionSchemaAnnotationHandler in project rest.li by linkedin.

the class PegasusSchemaSnapshotCompatibilityChecker method main.

public static void main(String[] args) throws Exception {
    final CommandLineParser parser = new GnuParser();
    CommandLine cl = parser.parse(_options, args);
    if (cl.hasOption('h')) {
        help();
        System.exit(0);
    }
    String[] cliArgs = cl.getArgs();
    if (cliArgs.length != 2) {
        _logger.error("Invalid arguments!");
        help();
        System.exit(1);
    }
    String prevSnapshotDir = cliArgs[0];
    String currSnapshotDir = cliArgs[1];
    List<String> prevSnapshotAndCurrSnapshotPairs = getMatchingPrevAndCurrSnapshotPairs(prevSnapshotDir, currSnapshotDir);
    CompatibilityLevel compatLevel = null;
    if (cl.hasOption("cl")) {
        try {
            compatLevel = CompatibilityLevel.valueOf(cl.getOptionValue("cl").toUpperCase());
        } catch (IllegalArgumentException e) {
            _logger.error("Invalid compatibilityLevel: " + cl.getOptionValue("cl") + e.getMessage());
            help();
            System.exit(1);
        }
    } else {
        compatLevel = CompatibilityLevel.DEFAULT;
    }
    CompatibilityOptions.Mode compatMode = null;
    if (cl.hasOption("cm")) {
        try {
            compatMode = CompatibilityOptions.Mode.valueOf(cl.getOptionValue("cm").toUpperCase());
        } catch (IllegalArgumentException e) {
            _logger.error("Invalid compatibilityOption Mode: " + cl.getOptionValue("cm") + e.getMessage());
            help();
            System.exit(1);
        }
    } else {
        compatMode = CompatibilityOptions.Mode.SCHEMA;
    }
    if (cl.hasOption('e')) {
        _handlers.add(new ExtensionSchemaAnnotationHandler());
    }
    if (cl.hasOption("jar") && cl.hasOption("className")) {
        String handlerJarPaths = cl.getOptionValue("jar");
        String classNames = cl.getOptionValue("className");
        try {
            _handlers = ClassJarPathUtil.getAnnotationHandlers(handlerJarPaths, classNames);
        } catch (IllegalStateException e) {
            _logger.error("Error while doing schema compatibility check, could not get SchemaAnnotationHandler classes: " + e.getMessage());
            System.exit(1);
        }
    }
    PegasusSchemaSnapshotCompatibilityChecker compatibilityChecker = new PegasusSchemaSnapshotCompatibilityChecker();
    for (int i = 1; i < prevSnapshotAndCurrSnapshotPairs.size(); i += 2) {
        String prevSnapshot = prevSnapshotAndCurrSnapshotPairs.get(i - 1);
        String currentSnapshot = prevSnapshotAndCurrSnapshotPairs.get(i);
        compatibilityChecker.checkPegasusSchemaCompatibility(prevSnapshot, currentSnapshot, compatMode);
    }
    if (cl.hasOption("report")) {
        File reportFile = new File(cl.getOptionValue("report"));
        String compatibilityReport = new CompatibilityReport(compatibilityChecker._infoMap, compatLevel).createReport();
        Files.write(reportFile.toPath(), compatibilityReport.getBytes(StandardCharsets.UTF_8));
        System.exit(0);
    }
    System.exit(compatibilityChecker._infoMap.isModelCompatible(compatLevel) ? 0 : 1);
}
Also used : CompatibilityReport(com.linkedin.restli.tools.compatibility.CompatibilityReport) ExtensionSchemaAnnotationHandler(com.linkedin.data.schema.annotation.ExtensionSchemaAnnotationHandler) GnuParser(org.apache.commons.cli.GnuParser) CompatibilityOptions(com.linkedin.data.schema.compatibility.CompatibilityOptions) CommandLine(org.apache.commons.cli.CommandLine) CompatibilityLevel(com.linkedin.restli.tools.idlcheck.CompatibilityLevel) CommandLineParser(org.apache.commons.cli.CommandLineParser) File(java.io.File)

Aggregations

ExtensionSchemaAnnotationHandler (com.linkedin.data.schema.annotation.ExtensionSchemaAnnotationHandler)2 PathSpec (com.linkedin.data.schema.PathSpec)1 AnnotationCompatibilityResult (com.linkedin.data.schema.annotation.SchemaAnnotationHandler.AnnotationCompatibilityResult)1 CompatibilityCheckContext (com.linkedin.data.schema.annotation.SchemaAnnotationHandler.CompatibilityCheckContext)1 CompatibilityOptions (com.linkedin.data.schema.compatibility.CompatibilityOptions)1 CompatibilityReport (com.linkedin.restli.tools.compatibility.CompatibilityReport)1 CompatibilityLevel (com.linkedin.restli.tools.idlcheck.CompatibilityLevel)1 File (java.io.File)1 CommandLine (org.apache.commons.cli.CommandLine)1 CommandLineParser (org.apache.commons.cli.CommandLineParser)1 GnuParser (org.apache.commons.cli.GnuParser)1 DataProvider (org.testng.annotations.DataProvider)1