Repository: avro Updated Branches: refs/heads/master 0a74e1e0f -> 8ecb2f130
AVRO-1932: Java: Allow setting the SchemaStore on generated classes. Project: http://git-wip-us.apache.org/repos/asf/avro/repo Commit: http://git-wip-us.apache.org/repos/asf/avro/commit/8ecb2f13 Tree: http://git-wip-us.apache.org/repos/asf/avro/tree/8ecb2f13 Diff: http://git-wip-us.apache.org/repos/asf/avro/diff/8ecb2f13 Branch: refs/heads/master Commit: 8ecb2f130fdb1f730e1e8df667ab99bd31af15b2 Parents: 0a74e1e Author: Niels Basjes <nbas...@bol.com> Authored: Mon Oct 10 13:04:06 2016 +0200 Committer: Niels Basjes <nielsbas...@apache.org> Committed: Sun Oct 16 07:43:26 2016 +0200 ---------------------------------------------------------------------- CHANGES.txt | 3 + .../avro/message/BinaryMessageDecoder.java | 2 +- .../specific/templates/java/classic/record.vm | 16 ++++ .../avro/message/TestCustomSchemaStore.java | 79 ++++++++++++++++++++ .../avro/examples/baseball/Player.java | 16 ++++ .../tools/src/test/compiler/output/Player.java | 16 ++++ share/test/schemas/schemaevolution.avdl | 55 ++++++++++++++ 7 files changed, 186 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/avro/blob/8ecb2f13/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index f2d01ed..5d231f9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,6 +13,9 @@ Trunk (not yet released) AVRO-1884: Java: Add method to set the compiler output suffix. (shijinkui via blue) + AVRO-1932: Java: Allow setting the SchemaStore on generated classes. + (Niels Basjes) + OPTIMIZATIONS IMPROVEMENTS http://git-wip-us.apache.org/repos/asf/avro/blob/8ecb2f13/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageDecoder.java ---------------------------------------------------------------------- diff --git a/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageDecoder.java b/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageDecoder.java index af8b8c1..bcdec0f 100644 --- a/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageDecoder.java +++ b/lang/java/avro/src/main/java/org/apache/avro/message/BinaryMessageDecoder.java @@ -160,7 +160,7 @@ public class BinaryMessageDecoder<D> extends MessageDecoder.BaseDecoder<D> { if (BinaryMessageEncoder.V1_HEADER[0] != header[0] || BinaryMessageEncoder.V1_HEADER[1] != header[1]) { throw new BadHeaderException(String.format( - "Unrecognized header bytes: 0x%h%h", + "Unrecognized header bytes: 0x%02X 0x%02X", header[0], header[1])); } http://git-wip-us.apache.org/repos/asf/avro/blob/8ecb2f13/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm ---------------------------------------------------------------------- diff --git a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm index d5ace4d..85c5e9d 100644 --- a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm +++ b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm @@ -23,6 +23,7 @@ import org.apache.avro.specific.SpecificData; #if (!$schema.isError()) import org.apache.avro.message.BinaryMessageEncoder; import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; #end @SuppressWarnings("all") @@ -47,6 +48,21 @@ public class ${this.mangle($schema.getName())}#if ($schema.isError()) extends or private static final BinaryMessageDecoder<${this.mangle($schema.getName())}> DECODER = new BinaryMessageDecoder<${this.mangle($schema.getName())}>(MODEL$, SCHEMA$); + /** + * Return the BinaryMessageDecoder instance used by this class. + */ + public static BinaryMessageDecoder<${this.mangle($schema.getName())}> getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + */ + public static BinaryMessageDecoder<${this.mangle($schema.getName())}> createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder<${this.mangle($schema.getName())}>(MODEL$, SCHEMA$, resolver); + } + /** Serializes this ${schema.getName()} to a ByteBuffer. */ public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { return ENCODER.encode(this); http://git-wip-us.apache.org/repos/asf/avro/blob/8ecb2f13/lang/java/ipc/src/test/java/org/apache/avro/message/TestCustomSchemaStore.java ---------------------------------------------------------------------- diff --git a/lang/java/ipc/src/test/java/org/apache/avro/message/TestCustomSchemaStore.java b/lang/java/ipc/src/test/java/org/apache/avro/message/TestCustomSchemaStore.java new file mode 100644 index 0000000..ba96044 --- /dev/null +++ b/lang/java/ipc/src/test/java/org/apache/avro/message/TestCustomSchemaStore.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.avro.message; + +import org.apache.avro.Schema; +import org.apache.avro.compiler.schema.evolve.NestedEvolve1; +import org.apache.avro.compiler.schema.evolve.NestedEvolve2; +import org.apache.avro.compiler.schema.evolve.NestedEvolve3; +import org.apache.avro.compiler.schema.evolve.TestRecord2; +import org.apache.avro.compiler.schema.evolve.TestRecord3; +import org.junit.Test; + +import java.nio.ByteBuffer; + +import static org.junit.Assert.assertEquals; + +public class TestCustomSchemaStore { + + static class CustomSchemaStore implements SchemaStore { + Cache cache; + CustomSchemaStore() { + cache = new Cache(); + cache.addSchema(NestedEvolve1.getClassSchema()); + cache.addSchema(NestedEvolve2.getClassSchema()); + } + + @Override + public Schema findByFingerprint(long fingerprint) { + return cache.findByFingerprint(fingerprint); + } + } + + private BinaryMessageDecoder<NestedEvolve1> decoder = NestedEvolve1.createDecoder(new CustomSchemaStore()); + + @Test + public void testCompatibleReadWithSchemaFromSchemaStore() throws Exception { + // Create and encode a NestedEvolve2 record. + NestedEvolve2.Builder rootBuilder = NestedEvolve2.newBuilder().setRootName("RootName"); + rootBuilder.setNested(TestRecord2.newBuilder().setName("Name").setValue(1).setData("Data").build()); + ByteBuffer nestedEvolve2Buffer = rootBuilder.build().toByteBuffer(); + + // Decode it + NestedEvolve1 nestedEvolve1 = decoder.decode(nestedEvolve2Buffer); + + // Should work + assertEquals(nestedEvolve1.getRootName(), "RootName"); + assertEquals(nestedEvolve1.getNested().getName(), "Name"); + assertEquals(nestedEvolve1.getNested().getValue(), Long.valueOf(1)); + } + + @Test(expected = MissingSchemaException.class) + public void testIncompatibleReadWithSchemaFromSchemaStore() throws Exception { + // Create and encode a NestedEvolve3 record. + NestedEvolve3.Builder rootBuilder = NestedEvolve3.newBuilder().setRootName("RootName"); + rootBuilder.setNested(TestRecord3.newBuilder().setName("Name").setData("Data").build()); + ByteBuffer nestedEvolve3Buffer = rootBuilder.build().toByteBuffer(); + + // Decode it ... should fail because schema for 'NestedEvolve3' is not available in the SchemaStore + decoder.decode(nestedEvolve3Buffer); + } + +} http://git-wip-us.apache.org/repos/asf/avro/blob/8ecb2f13/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/Player.java ---------------------------------------------------------------------- diff --git a/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/Player.java b/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/Player.java index eaefb12..ffd083b 100644 --- a/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/Player.java +++ b/lang/java/tools/src/test/compiler/output-string/avro/examples/baseball/Player.java @@ -8,6 +8,7 @@ package avro.examples.baseball; import org.apache.avro.specific.SpecificData; import org.apache.avro.message.BinaryMessageEncoder; import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; @SuppressWarnings("all") /** é¸æ is Japanese for player. */ @@ -25,6 +26,21 @@ public class Player extends org.apache.avro.specific.SpecificRecordBase implemen private static final BinaryMessageDecoder<Player> DECODER = new BinaryMessageDecoder<Player>(MODEL$, SCHEMA$); + /** + * Return the BinaryMessageDecoder instance used by this class. + */ + public static BinaryMessageDecoder<Player> getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + */ + public static BinaryMessageDecoder<Player> createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder<Player>(MODEL$, SCHEMA$, resolver); + } + /** Serializes this Player to a ByteBuffer. */ public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { return ENCODER.encode(this); http://git-wip-us.apache.org/repos/asf/avro/blob/8ecb2f13/lang/java/tools/src/test/compiler/output/Player.java ---------------------------------------------------------------------- diff --git a/lang/java/tools/src/test/compiler/output/Player.java b/lang/java/tools/src/test/compiler/output/Player.java index d870e79..ce8c84c 100644 --- a/lang/java/tools/src/test/compiler/output/Player.java +++ b/lang/java/tools/src/test/compiler/output/Player.java @@ -8,6 +8,7 @@ package avro.examples.baseball; import org.apache.avro.specific.SpecificData; import org.apache.avro.message.BinaryMessageEncoder; import org.apache.avro.message.BinaryMessageDecoder; +import org.apache.avro.message.SchemaStore; @SuppressWarnings("all") /** é¸æ is Japanese for player. */ @@ -25,6 +26,21 @@ public class Player extends org.apache.avro.specific.SpecificRecordBase implemen private static final BinaryMessageDecoder<Player> DECODER = new BinaryMessageDecoder<Player>(MODEL$, SCHEMA$); + /** + * Return the BinaryMessageDecoder instance used by this class. + */ + public static BinaryMessageDecoder<Player> getDecoder() { + return DECODER; + } + + /** + * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}. + * @param resolver a {@link SchemaStore} used to find schemas by fingerprint + */ + public static BinaryMessageDecoder<Player> createDecoder(SchemaStore resolver) { + return new BinaryMessageDecoder<Player>(MODEL$, SCHEMA$, resolver); + } + /** Serializes this Player to a ByteBuffer. */ public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException { return ENCODER.encode(this); http://git-wip-us.apache.org/repos/asf/avro/blob/8ecb2f13/share/test/schemas/schemaevolution.avdl ---------------------------------------------------------------------- diff --git a/share/test/schemas/schemaevolution.avdl b/share/test/schemas/schemaevolution.avdl new file mode 100644 index 0000000..bfb14c5 --- /dev/null +++ b/share/test/schemas/schemaevolution.avdl @@ -0,0 +1,55 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A few simple test schemas for testing schema evolution the IDL generated classes + */ +@namespace("org.apache.avro.compiler.schema.evolve") +protocol SchemaEvolveTesting { + record TestRecord1 { + string name; + long value; + } + + record TestRecord2 { + string name; + long value; + string data; + } + + record TestRecord3 { + string name; + string data; + } + + record NestedEvolve1 { + string rootName; + TestRecord1 nested; + } + + record NestedEvolve2 { + string rootName; + TestRecord2 nested; + } + + record NestedEvolve3 { + string rootName; + TestRecord3 nested; + } + +}