diff --git a/avro-builder/tests/tests-allavro/src/test/java/com/linkedin/avroutil1/builder/SpecificRecordTest.java b/avro-builder/tests/tests-allavro/src/test/java/com/linkedin/avroutil1/builder/SpecificRecordTest.java index 58ee89c1d..d94729673 100644 --- a/avro-builder/tests/tests-allavro/src/test/java/com/linkedin/avroutil1/builder/SpecificRecordTest.java +++ b/avro-builder/tests/tests-allavro/src/test/java/com/linkedin/avroutil1/builder/SpecificRecordTest.java @@ -7,14 +7,10 @@ package com.linkedin.avroutil1.builder; import com.linkedin.avroutil1.compatibility.AvroCodecUtil; -import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroRecordUtil; -import com.linkedin.avroutil1.compatibility.CustomDecoder; import com.linkedin.avroutil1.compatibility.RandomRecordGenerator; import com.linkedin.avroutil1.compatibility.RecordGenerationConfig; import com.linkedin.avroutil1.compatibility.StringConverterUtil; - -import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; @@ -33,13 +29,9 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; - -import com.linkedin.avroutil1.compatibility.backports.SpecificRecordBaseExt; import noutf8.TestCollections; import org.apache.avro.AvroRuntimeException; import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.Decoder; -import org.apache.avro.io.Encoder; import org.apache.avro.util.Utf8; import org.testng.Assert; import org.testng.annotations.BeforeClass; @@ -2048,36 +2040,6 @@ public void testNoUtf8Encoding() throws IOException { Assert.assertTrue(instance.arOfMap.get(0).containsValue(strValue)); } - @DataProvider - private Object[][] customDecodeDataProvider() { - return new Object[][]{ - {vs19.MoneyRange.class}, - {vs110.MoneyRange.class}, - {vs111.MoneyRange.class} - }; - } - - @Test(dataProvider = "customDecodeDataProvider") - public void testCustomDecode(Class specificRecordClass) throws Exception { - RandomRecordGenerator generator = new RandomRecordGenerator(); - SpecificRecordBaseExt instance = generator.randomSpecific(specificRecordClass); - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - Encoder encoder = AvroCompatibilityHelper.newBinaryEncoder(outputStream); - Method customEncodeMethod = instance.getClass().getMethod("customEncode", Encoder.class); - customEncodeMethod.invoke(instance, encoder); - encoder.flush(); - - byte[] data = outputStream.toByteArray(); - Decoder binaryDecoder = AvroCompatibilityHelper.newBinaryDecoder(data); - CustomDecoder decoder = - (CustomDecoder) AvroCompatibilityHelper.newCachedResolvingDecoder( - instance.getSchema(), instance.getSchema(), binaryDecoder); - SpecificRecordBaseExt decodedInstance = specificRecordClass.getDeclaredConstructor().newInstance(); - decodedInstance.customDecode(decoder); - Assert.assertEquals(instance, decodedInstance); - } - @BeforeClass public void setup() { System.setProperty("org.apache.avro.specific.use_custom_coders", "true"); diff --git a/avro-codegen/src/main/java/com/linkedin/avroutil1/codegen/SpecificRecordClassGenerator.java b/avro-codegen/src/main/java/com/linkedin/avroutil1/codegen/SpecificRecordClassGenerator.java index 879c10bc0..5e5ca3b17 100644 --- a/avro-codegen/src/main/java/com/linkedin/avroutil1/codegen/SpecificRecordClassGenerator.java +++ b/avro-codegen/src/main/java/com/linkedin/avroutil1/codegen/SpecificRecordClassGenerator.java @@ -356,7 +356,7 @@ protected JavaFile generateSpecificRecord(AvroRecordSchema recordSchema, Specifi classBuilder.addSuperinterface(SpecificRecordGeneratorUtil.CLASSNAME_SPECIFIC_RECORD); // extends - classBuilder.superclass(SpecificRecordGeneratorUtil.CLASSNAME_SPECIFIC_RECORD_BASE_EXT); + classBuilder.superclass(SpecificRecordGeneratorUtil.CLASSNAME_SPECIFIC_RECORD_BASE); //add class-level doc from schema doc //file-level (top of file) comment is added to the file object later @@ -519,27 +519,9 @@ protected JavaFile generateSpecificRecord(AvroRecordSchema recordSchema, Specifi .addParameter(SpecificRecordGeneratorUtil.CLASSNAME_RESOLVING_DECODER, "in") .addException(IOException.class) .addModifiers(Modifier.PUBLIC); - addCustomDecodeMethod(customDecodeBuilder, recordSchema, config, classBuilder, sizeValCounter, false); + addCustomDecodeMethod(customDecodeBuilder, recordSchema, config, classBuilder, sizeValCounter); classBuilder.addMethod(customDecodeBuilder.build()); - //customDecode with CustomDecoder - MethodSpec.Builder methodBuilder = MethodSpec - .methodBuilder("customDecode") - .addParameter(SpecificRecordGeneratorUtil.CLASSNAME_CUSTOM_DECODER, "in") - .addException(IOException.class) - .addModifiers(Modifier.PUBLIC) - .addAnnotation(Override.class); - addCustomDecodeMethod(methodBuilder, recordSchema, config, classBuilder, sizeValCounter, true); - classBuilder.addMethod(methodBuilder.build()); - - MethodSpec.Builder isCustomDecodingEnabledMethod = MethodSpec - .methodBuilder("isCustomDecodingEnabled") - .addModifiers(Modifier.PUBLIC) - .returns(TypeName.BOOLEAN) - .addAnnotation(Override.class) - .addCode("return hasCustomCoders();"); - classBuilder.addMethod(isCustomDecodingEnabledMethod.build()); - // Builder TypeSpec.Builder recordBuilder = TypeSpec.classBuilder("Builder"); recordBuilder.addModifiers(Modifier.PUBLIC, Modifier.STATIC); @@ -963,13 +945,8 @@ private String getMethodNameForFieldWithPrefix(String prefix, String fieldName) } private void addCustomDecodeMethod(MethodSpec.Builder customDecodeBuilder, AvroRecordSchema recordSchema, - SpecificRecordGenerationConfig config, TypeSpec.Builder classBuilder, Counter sizeValCounter, boolean isCustomDecoder) { + SpecificRecordGenerationConfig config, TypeSpec.Builder classBuilder, Counter sizeValCounter) { int blockSize = 25, fieldCounter = 0, chunkCounter = 0; - - // Decoder class name. - ClassName decoderClassName = isCustomDecoder ? SpecificRecordGeneratorUtil.CLASSNAME_CUSTOM_DECODER : - SpecificRecordGeneratorUtil.CLASSNAME_RESOLVING_DECODER; - // reset var counter sizeValCounter.reset(); customDecodeBuilder.addStatement( @@ -982,7 +959,7 @@ private void addCustomDecodeMethod(MethodSpec.Builder customDecodeBuilder, AvroR customDecodeBuilder.addStatement(chunkMethodName + "(in)"); // create new method MethodSpec.Builder customDecodeChunkMethod = MethodSpec.methodBuilder(chunkMethodName) - .addParameter(decoderClassName, "in") + .addParameter(SpecificRecordGeneratorUtil.CLASSNAME_RESOLVING_DECODER, "in") .addException(IOException.class) .addModifiers(Modifier.PUBLIC); for (; fieldCounter < Math.min(blockSize * chunkCounter + blockSize, recordSchema.getFields().size()); @@ -1012,7 +989,7 @@ private void addCustomDecodeMethod(MethodSpec.Builder customDecodeBuilder, AvroR customDecodeBuilder.addStatement(chunkMethodName + "(in, fieldOrder)"); // create new method MethodSpec.Builder customDecodeChunkMethod = MethodSpec.methodBuilder(chunkMethodName) - .addParameter(decoderClassName, "in") + .addParameter(SpecificRecordGeneratorUtil.CLASSNAME_RESOLVING_DECODER, "in") .addParameter(ArrayTypeName.of(SpecificRecordGeneratorUtil.CLASSNAME_SCHEMA_FIELD), "fieldOrder") .addException(IOException.class) .addModifiers(Modifier.PUBLIC); diff --git a/avro-codegen/src/main/java/com/linkedin/avroutil1/codegen/SpecificRecordGeneratorUtil.java b/avro-codegen/src/main/java/com/linkedin/avroutil1/codegen/SpecificRecordGeneratorUtil.java index 6110aa4ba..e5eb32e57 100644 --- a/avro-codegen/src/main/java/com/linkedin/avroutil1/codegen/SpecificRecordGeneratorUtil.java +++ b/avro-codegen/src/main/java/com/linkedin/avroutil1/codegen/SpecificRecordGeneratorUtil.java @@ -51,11 +51,9 @@ public class SpecificRecordGeneratorUtil { public static final ClassName CLASSNAME_SPECIFIC_DATA = ClassName.get("org.apache.avro.specific", "SpecificData"); public static final ClassName CLASSNAME_SPECIFIC_RECORD = ClassName.get("org.apache.avro.specific", "SpecificRecord"); public static final ClassName CLASSNAME_SPECIFIC_RECORD_BASE = ClassName.get("org.apache.avro.specific", "SpecificRecordBase"); - public static final ClassName CLASSNAME_SPECIFIC_RECORD_BASE_EXT = ClassName.get("com.linkedin.avroutil1.compatibility.backports", "SpecificRecordBaseExt"); public static final ClassName CLASSNAME_SPECIFIC_DATUM_READER = ClassName.get("org.apache.avro.specific", "SpecificDatumReader"); public static final ClassName CLASSNAME_SPECIFIC_DATUM_WRITER = ClassName.get("org.apache.avro.specific", "SpecificDatumWriter"); public static final ClassName CLASSNAME_ENCODER = ClassName.get("org.apache.avro.io", "Encoder"); - public static final ClassName CLASSNAME_CUSTOM_DECODER = ClassName.get("com.linkedin.avroutil1.compatibility", "CustomDecoder"); public static final ClassName CLASSNAME_RESOLVING_DECODER = ClassName.get("org.apache.avro.io", "ResolvingDecoder"); public static final ClassName CLASSNAME_DATUM_READER = ClassName.get("org.apache.avro.io", "DatumReader"); public static final ClassName CLASSNAME_DATUM_WRITER = ClassName.get("org.apache.avro.io", "DatumWriter"); diff --git a/helper/helper-common/src/main/java/com/linkedin/avroutil1/compatibility/CustomDecoder.java b/helper/helper-common/src/main/java/com/linkedin/avroutil1/compatibility/CustomDecoder.java index 18a0be710..555a54751 100644 --- a/helper/helper-common/src/main/java/com/linkedin/avroutil1/compatibility/CustomDecoder.java +++ b/helper/helper-common/src/main/java/com/linkedin/avroutil1/compatibility/CustomDecoder.java @@ -17,7 +17,9 @@ /** * Interface that enables custom decoding of * {@link com.linkedin.avroutil1.compatibility.backports.SpecificRecordBaseExt} instances. + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public interface CustomDecoder { /** Returns the actual order in which the reader's fields will be diff --git a/helper/helper-common/src/main/java/com/linkedin/avroutil1/compatibility/backports/SpecificRecordBaseExt.java b/helper/helper-common/src/main/java/com/linkedin/avroutil1/compatibility/backports/SpecificRecordBaseExt.java index 05295864d..b7267f53d 100644 --- a/helper/helper-common/src/main/java/com/linkedin/avroutil1/compatibility/backports/SpecificRecordBaseExt.java +++ b/helper/helper-common/src/main/java/com/linkedin/avroutil1/compatibility/backports/SpecificRecordBaseExt.java @@ -13,7 +13,9 @@ /** * Extension of {@link SpecificRecordBase} that allows for custom decoding using a custom decoder. + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public abstract class SpecificRecordBaseExt extends SpecificRecordBase { /** diff --git a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/Avro110Adapter.java b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/Avro110Adapter.java index a3df729b3..b0e1d95e5 100644 --- a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/Avro110Adapter.java +++ b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/Avro110Adapter.java @@ -24,8 +24,6 @@ import com.linkedin.avroutil1.compatibility.SkipDecoder; import com.linkedin.avroutil1.compatibility.StringRepresentation; import com.linkedin.avroutil1.compatibility.avro110.backports.Avro110DefaultValuesCache; -import com.linkedin.avroutil1.compatibility.avro110.backports.GenericDatumReaderExt; -import com.linkedin.avroutil1.compatibility.avro110.backports.SpecificDatumReaderExt; import com.linkedin.avroutil1.compatibility.avro110.codec.AliasAwareSpecificDatumReader; import com.linkedin.avroutil1.compatibility.avro110.codec.BoundedMemoryDecoder; import com.linkedin.avroutil1.compatibility.avro110.codec.CachedResolvingDecoder; @@ -40,6 +38,7 @@ import org.apache.avro.Schema; import org.apache.avro.SchemaNormalization; import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericDatumReader; import org.apache.avro.generic.GenericDatumWriter; import org.apache.avro.io.Avro110BinaryDecoderAccessUtil; import org.apache.avro.io.BinaryDecoder; @@ -240,7 +239,7 @@ public DatumWriter newGenericDatumWriter(Schema writer, GenericData genericDa @Override public DatumReader newGenericDatumReader(Schema writer, Schema reader, GenericData genericData) { - return new GenericDatumReaderExt<>(writer, reader, genericData); + return new GenericDatumReader<>(writer, reader, genericData); } @Override @@ -250,7 +249,7 @@ public DatumWriter newSpecificDatumWriter(Schema writer, SpecificData specifi @Override public DatumReader newSpecificDatumReader(Schema writer, Schema reader, SpecificData specificData) { - return new SpecificDatumReaderExt<>(writer, reader, specificData); + return new SpecificDatumReader<>(writer, reader, specificData); } @Override diff --git a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/backports/GenericDatumReaderExt.java b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/backports/GenericDatumReaderExt.java index d4de9f5ec..36c53b994 100644 --- a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/backports/GenericDatumReaderExt.java +++ b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/backports/GenericDatumReaderExt.java @@ -25,7 +25,9 @@ * a specified {@link GenericData} instance under avro 1.10 * * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class GenericDatumReaderExt extends GenericDatumReader { public GenericDatumReaderExt(Schema writer, Schema reader, GenericData genericData) { diff --git a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/backports/SpecificDatumReaderExt.java b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/backports/SpecificDatumReaderExt.java index 9fe212158..3453f995e 100644 --- a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/backports/SpecificDatumReaderExt.java +++ b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/backports/SpecificDatumReaderExt.java @@ -28,7 +28,9 @@ * a specified {@link SpecificData} instance under avro 1.9. * * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class SpecificDatumReaderExt extends SpecificDatumReader { public SpecificDatumReaderExt(Schema writer, Schema reader, SpecificData specificData) { diff --git a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/codec/AliasAwareSpecificDatumReader.java b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/codec/AliasAwareSpecificDatumReader.java index 320d805a5..cceb502ec 100644 --- a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/codec/AliasAwareSpecificDatumReader.java +++ b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/codec/AliasAwareSpecificDatumReader.java @@ -6,7 +6,6 @@ package com.linkedin.avroutil1.compatibility.avro110.codec; -import com.linkedin.avroutil1.compatibility.avro110.backports.SpecificDatumReaderExt; import org.apache.avro.Schema; import org.apache.avro.specific.SpecificData; import org.apache.avro.specific.SpecificDatumReader; @@ -21,7 +20,7 @@ * * @param */ -public class AliasAwareSpecificDatumReader extends SpecificDatumReaderExt { +public class AliasAwareSpecificDatumReader extends SpecificDatumReader { public AliasAwareSpecificDatumReader() { this(null, null); @@ -41,12 +40,10 @@ public AliasAwareSpecificDatumReader(Schema writer, Schema reader) { } public AliasAwareSpecificDatumReader(Schema writer, Schema reader, SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } protected AliasAwareSpecificDatumReader(SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } } diff --git a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/codec/ResolvingDecoder.java b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/codec/ResolvingDecoder.java index 230a349d8..d6bd68173 100644 --- a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/codec/ResolvingDecoder.java +++ b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/codec/ResolvingDecoder.java @@ -39,7 +39,7 @@ import org.apache.avro.io.DecoderFactory; import org.apache.avro.util.Utf8; -public class ResolvingDecoder extends ValidatingDecoder implements CustomDecoder { +public class ResolvingDecoder extends ValidatingDecoder implements CustomDecoder { private Decoder backup; ResolvingDecoder(Schema writer, Schema reader, Decoder in) throws IOException { @@ -70,24 +70,6 @@ public final void drain() throws IOException { this.parser.processImplicitActions(); } - @Override - public int readInt() throws IOException { - Symbol actual = parser.advance(Symbol.INT); - - if (actual == Symbol.INT) { - return in.readInt(); - } else if (actual == Symbol.IntLongAdjustAction.INSTANCE) { - long value = in.readLong(); - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new AvroTypeException(value + " cannot be represented as int"); - } - - return (int) value; - } - - throw new AvroTypeException("Expected int but found " + actual); - } - public long readLong() throws IOException { Symbol actual = this.parser.advance(Symbol.LONG); if (actual == Symbol.INT) { @@ -244,10 +226,6 @@ public Symbol doAction(Symbol input, Symbol top) throws IOException { this.backup = this.in; this.in = DecoderFactory.get().binaryDecoder(dsa.contents, (BinaryDecoder)null); } else { - if (top == Symbol.IntLongAdjustAction.INSTANCE) { - return top; - } - if (top != Symbol.DEFAULT_END_ACTION) { throw new AvroTypeException("Unknown action: " + top); } diff --git a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/parsing/ResolvingGrammarGenerator.java b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/parsing/ResolvingGrammarGenerator.java index e7424366a..09aa81439 100644 --- a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/parsing/ResolvingGrammarGenerator.java +++ b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/parsing/ResolvingGrammarGenerator.java @@ -82,11 +82,6 @@ private Symbol generate(Resolver.Action action, Map seen, boolea return simpleGen(action.writer, seen, useFqcns); } else if (action instanceof Resolver.ErrorAction) { - // We should be able to selectively demote long to int if it fits within the range of int. - if (isLongToIntDemotion((Resolver.ErrorAction) action, false)) { - return Symbol.IntLongAdjustAction.INSTANCE; - } - return Symbol.error(action.toString()); } else if (action instanceof Resolver.Skip) { @@ -97,16 +92,6 @@ private Symbol generate(Resolver.Action action, Map seen, boolea } else if (action instanceof Resolver.ReaderUnion) { Resolver.ReaderUnion ru = (Resolver.ReaderUnion) action; - - // Check if we need to handle selective long-to-int demotion within unions. - if (ru.actualAction instanceof Resolver.ErrorAction) { - if (isLongToIntDemotion((Resolver.ErrorAction) ru.actualAction, true)) { - return Symbol.seq( - Symbol.unionAdjustAction(ru.firstMatch, Symbol.IntLongAdjustAction.INSTANCE), - Symbol.UNION); - } - } - Symbol s = generate(ru.actualAction, seen, useFqcns); return Symbol.seq(Symbol.unionAdjustAction(ru.firstMatch, s), Symbol.UNION); @@ -122,28 +107,18 @@ private Symbol generate(Resolver.Action action, Map seen, boolea if (((Resolver.WriterUnion) action).unionEquiv) { return simpleGen(action.writer, seen, useFqcns); } - - Resolver.WriterUnion wu = (Resolver.WriterUnion) action; - Resolver.Action[] branches = wu.actions; + Resolver.Action[] branches = ((Resolver.WriterUnion) action).actions; Symbol[] symbols = new Symbol[branches.length]; String[] oldLabels = new String[branches.length]; String[] newLabels = new String[branches.length]; - - for (int i = 0; i < branches.length; i++) { - // Check if this branch needs long-to-int conversion - if (branches[i] instanceof Resolver.ErrorAction && isLongToIntDemotion((Resolver.ErrorAction) branches[i], true)) { - symbols[i] = Symbol.seq( - Symbol.unionAdjustAction(i, Symbol.IntLongAdjustAction.INSTANCE), - Symbol.UNION); - } else { - symbols[i] = generate(branches[i], seen, useFqcns); - } - + int i = 0; + for (Resolver.Action branch : branches) { + symbols[i] = generate(branch, seen, useFqcns); Schema schema = action.writer.getTypes().get(i); oldLabels[i] = schema.getName(); newLabels[i] = schema.getFullName(); + i++; } - return Symbol.seq(Symbol.alt(symbols, oldLabels, newLabels, useFqcns), Symbol.WRITER_UNION_ACTION); } else if (action instanceof Resolver.EnumAdjust) { Resolver.EnumAdjust e = (Resolver.EnumAdjust) action; @@ -377,39 +352,6 @@ public static void encode(Encoder e, Schema s, JsonNode n) throws IOException { } } - private static boolean isLongToIntDemotion(Resolver.ErrorAction errorAction, boolean includeIntUnions) { - return isInt(errorAction.reader, includeIntUnions) - && errorAction.writer.getType() == Schema.Type.LONG - && isLongToIntDemotionError(errorAction, includeIntUnions); - } - - private static boolean isLongToIntDemotionError(Resolver.ErrorAction errorAction, boolean includeIntUnions) { - if (errorAction.error == Resolver.ErrorAction.ErrorType.INCOMPATIBLE_SCHEMA_TYPES) { - return true; - } - - return includeIntUnions && errorAction.error == Resolver.ErrorAction.ErrorType.NO_MATCHING_BRANCH; - } - - private static boolean isInt(Schema schema, boolean includeIntUnions) { - if (schema.getType() == Schema.Type.INT) { - return true; - } - - if (!includeIntUnions) { - return false; - } - - if (schema.getType() != Schema.Type.UNION) { - return false; - } - - List types = schema.getTypes(); - return (types.size() == 2 - && types.get(0).getType() == Schema.Type.NULL - && types.get(1).getType() == Schema.Type.INT); - } - /** * Clever trick which differentiates items put into * seen by {@link ValidatingGrammarGenerator validating()} diff --git a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/parsing/Symbol.java b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/parsing/Symbol.java index 9ba84b171..07ae5918c 100644 --- a/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/parsing/Symbol.java +++ b/helper/impls/helper-impl-110/src/main/java/com/linkedin/avroutil1/compatibility/avro110/parsing/Symbol.java @@ -615,10 +615,6 @@ public FieldAdjustAction(int rindex, String fname, Set aliases) { } } - public static class IntLongAdjustAction extends ImplicitAction { - public static final IntLongAdjustAction INSTANCE = new IntLongAdjustAction(); - } - public static FieldOrderAction fieldOrderAction(Schema.Field[] fields) { return new FieldOrderAction(fields); } diff --git a/helper/impls/helper-impl-110/src/main/java/org/apache/avro/generic/Avro110GenericDataAccessUtil.java b/helper/impls/helper-impl-110/src/main/java/org/apache/avro/generic/Avro110GenericDataAccessUtil.java index 1f2c62f21..3db2b83de 100644 --- a/helper/impls/helper-impl-110/src/main/java/org/apache/avro/generic/Avro110GenericDataAccessUtil.java +++ b/helper/impls/helper-impl-110/src/main/java/org/apache/avro/generic/Avro110GenericDataAccessUtil.java @@ -10,7 +10,9 @@ /** * this class exists to allow us access to package-private classes and methods on class {@link GenericData} + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class Avro110GenericDataAccessUtil { private Avro110GenericDataAccessUtil() { } diff --git a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/Avro111Adapter.java b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/Avro111Adapter.java index ebed681ab..c471aa6ce 100644 --- a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/Avro111Adapter.java +++ b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/Avro111Adapter.java @@ -24,8 +24,6 @@ import com.linkedin.avroutil1.compatibility.SkipDecoder; import com.linkedin.avroutil1.compatibility.StringRepresentation; import com.linkedin.avroutil1.compatibility.avro111.backports.Avro111DefaultValuesCache; -import com.linkedin.avroutil1.compatibility.avro111.backports.GenericDatumReaderExt; -import com.linkedin.avroutil1.compatibility.avro111.backports.SpecificDatumReaderExt; import com.linkedin.avroutil1.compatibility.avro111.codec.AliasAwareSpecificDatumReader; import com.linkedin.avroutil1.compatibility.avro111.codec.BoundedMemoryDecoder; import com.linkedin.avroutil1.compatibility.avro111.codec.CachedResolvingDecoder; @@ -40,6 +38,7 @@ import org.apache.avro.Schema; import org.apache.avro.SchemaNormalization; import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericDatumReader; import org.apache.avro.generic.GenericDatumWriter; import org.apache.avro.io.Avro111BinaryDecoderAccessUtil; import org.apache.avro.io.BinaryDecoder; @@ -240,7 +239,7 @@ public DatumWriter newGenericDatumWriter(Schema writer, GenericData genericDa @Override public DatumReader newGenericDatumReader(Schema writer, Schema reader, GenericData genericData) { - return new GenericDatumReaderExt<>(writer, reader, genericData); + return new GenericDatumReader<>(writer, reader, genericData); } @Override @@ -250,7 +249,7 @@ public DatumWriter newSpecificDatumWriter(Schema writer, SpecificData specifi @Override public DatumReader newSpecificDatumReader(Schema writer, Schema reader, SpecificData specificData) { - return new SpecificDatumReaderExt<>(writer, reader, specificData); + return new SpecificDatumReader<>(writer, reader, specificData); } @Override diff --git a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/backports/GenericDatumReaderExt.java b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/backports/GenericDatumReaderExt.java index 79ca35844..b46c27466 100644 --- a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/backports/GenericDatumReaderExt.java +++ b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/backports/GenericDatumReaderExt.java @@ -24,7 +24,9 @@ * a specified {@link GenericData} instance under avro 1.10 * * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class GenericDatumReaderExt extends GenericDatumReader { public GenericDatumReaderExt(Schema writer, Schema reader, GenericData genericData) { diff --git a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/backports/SpecificDatumReaderExt.java b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/backports/SpecificDatumReaderExt.java index 4515001f1..18a782d7e 100644 --- a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/backports/SpecificDatumReaderExt.java +++ b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/backports/SpecificDatumReaderExt.java @@ -27,7 +27,9 @@ * a specified {@link SpecificData} instance under avro 1.9. * * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class SpecificDatumReaderExt extends SpecificDatumReader { public SpecificDatumReaderExt(Schema writer, Schema reader, SpecificData specificData) { diff --git a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/codec/AliasAwareSpecificDatumReader.java b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/codec/AliasAwareSpecificDatumReader.java index 83aa085f0..854cb939a 100644 --- a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/codec/AliasAwareSpecificDatumReader.java +++ b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/codec/AliasAwareSpecificDatumReader.java @@ -6,7 +6,6 @@ package com.linkedin.avroutil1.compatibility.avro111.codec; -import com.linkedin.avroutil1.compatibility.avro111.backports.SpecificDatumReaderExt; import org.apache.avro.Schema; import org.apache.avro.specific.SpecificData; import org.apache.avro.specific.SpecificDatumReader; @@ -21,7 +20,7 @@ * * @param */ -public class AliasAwareSpecificDatumReader extends SpecificDatumReaderExt { +public class AliasAwareSpecificDatumReader extends SpecificDatumReader { public AliasAwareSpecificDatumReader() { this(null, null); @@ -41,12 +40,10 @@ public AliasAwareSpecificDatumReader(Schema writer, Schema reader) { } public AliasAwareSpecificDatumReader(Schema writer, Schema reader, SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } protected AliasAwareSpecificDatumReader(SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } } diff --git a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/codec/ResolvingDecoder.java b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/codec/ResolvingDecoder.java index 8e060fca9..d09ef7460 100644 --- a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/codec/ResolvingDecoder.java +++ b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/codec/ResolvingDecoder.java @@ -71,23 +71,6 @@ public final void drain() throws IOException { this.parser.processImplicitActions(); } - @Override - public int readInt() throws IOException { - Symbol actual = parser.advance(Symbol.INT); - if (actual == Symbol.INT) { - return in.readInt(); - } else if (actual == Symbol.IntLongAdjustAction.INSTANCE) { - long value = in.readLong(); - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new AvroTypeException(value + " cannot be represented as int"); - } - - return (int) value; - } - - throw new AvroTypeException("Expected int but found " + actual); - } - public long readLong() throws IOException { Symbol actual = this.parser.advance(Symbol.LONG); if (actual == Symbol.INT) { @@ -244,10 +227,6 @@ public Symbol doAction(Symbol input, Symbol top) throws IOException { this.backup = this.in; this.in = DecoderFactory.get().binaryDecoder(dsa.contents, (BinaryDecoder)null); } else { - if (top == Symbol.IntLongAdjustAction.INSTANCE) { - return top; - } - if (top != Symbol.DEFAULT_END_ACTION) { throw new AvroTypeException("Unknown action: " + top); } diff --git a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/parsing/ResolvingGrammarGenerator.java b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/parsing/ResolvingGrammarGenerator.java index 84a3db788..c2bfb6f5b 100644 --- a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/parsing/ResolvingGrammarGenerator.java +++ b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/parsing/ResolvingGrammarGenerator.java @@ -82,11 +82,6 @@ private Symbol generate(Resolver.Action action, Map seen, boolea return simpleGen(action.writer, seen, useFqcns); } else if (action instanceof Resolver.ErrorAction) { - // We should be able to selectively demote long to int if it fits within the range of int. - if (isLongToIntDemotion((Resolver.ErrorAction) action, false)) { - return Symbol.IntLongAdjustAction.INSTANCE; - } - return Symbol.error(action.toString()); } else if (action instanceof Resolver.Skip) { @@ -97,16 +92,6 @@ private Symbol generate(Resolver.Action action, Map seen, boolea } else if (action instanceof Resolver.ReaderUnion) { Resolver.ReaderUnion ru = (Resolver.ReaderUnion) action; - - // Check if we need to handle selective long-to-int demotion within unions. - if (ru.actualAction instanceof Resolver.ErrorAction) { - if (isLongToIntDemotion((Resolver.ErrorAction) ru.actualAction, true)) { - return Symbol.seq( - Symbol.unionAdjustAction(ru.firstMatch, Symbol.IntLongAdjustAction.INSTANCE), - Symbol.UNION); - } - } - Symbol s = generate(ru.actualAction, seen, useFqcns); return Symbol.seq(Symbol.unionAdjustAction(ru.firstMatch, s), Symbol.UNION); @@ -122,28 +107,18 @@ private Symbol generate(Resolver.Action action, Map seen, boolea if (((Resolver.WriterUnion) action).unionEquiv) { return simpleGen(action.writer, seen, useFqcns); } - - Resolver.WriterUnion wu = (Resolver.WriterUnion) action; - Resolver.Action[] branches = wu.actions; + Resolver.Action[] branches = ((Resolver.WriterUnion) action).actions; Symbol[] symbols = new Symbol[branches.length]; String[] oldLabels = new String[branches.length]; String[] newLabels = new String[branches.length]; - - for (int i = 0; i < branches.length; i++) { - // Check if this branch needs long-to-int conversion - if (branches[i] instanceof Resolver.ErrorAction && isLongToIntDemotion((Resolver.ErrorAction) branches[i], true)) { - symbols[i] = Symbol.seq( - Symbol.unionAdjustAction(i, Symbol.IntLongAdjustAction.INSTANCE), - Symbol.UNION); - } else { - symbols[i] = generate(branches[i], seen, useFqcns); - } - + int i = 0; + for (Resolver.Action branch : branches) { + symbols[i] = generate(branch, seen, useFqcns); Schema schema = action.writer.getTypes().get(i); oldLabels[i] = schema.getName(); newLabels[i] = schema.getFullName(); + i++; } - return Symbol.seq(Symbol.alt(symbols, oldLabels, newLabels, useFqcns), Symbol.WRITER_UNION_ACTION); } else if (action instanceof Resolver.EnumAdjust) { Resolver.EnumAdjust e = (Resolver.EnumAdjust) action; @@ -377,39 +352,6 @@ public static void encode(Encoder e, Schema s, JsonNode n) throws IOException { } } - private static boolean isLongToIntDemotion(Resolver.ErrorAction errorAction, boolean includeIntUnions) { - return isInt(errorAction.reader, includeIntUnions) - && errorAction.writer.getType() == Schema.Type.LONG - && isLongToIntDemotionError(errorAction, includeIntUnions); - } - - private static boolean isLongToIntDemotionError(Resolver.ErrorAction errorAction, boolean includeIntUnions) { - if (errorAction.error == Resolver.ErrorAction.ErrorType.INCOMPATIBLE_SCHEMA_TYPES) { - return true; - } - - return includeIntUnions && errorAction.error == Resolver.ErrorAction.ErrorType.NO_MATCHING_BRANCH; - } - - private static boolean isInt(Schema schema, boolean includeIntUnions) { - if (schema.getType() == Schema.Type.INT) { - return true; - } - - if (!includeIntUnions) { - return false; - } - - if (schema.getType() != Schema.Type.UNION) { - return false; - } - - List types = schema.getTypes(); - return (types.size() == 2 - && types.get(0).getType() == Schema.Type.NULL - && types.get(1).getType() == Schema.Type.INT); - } - /** * Clever trick which differentiates items put into * seen by {@link ValidatingGrammarGenerator validating()} diff --git a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/parsing/Symbol.java b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/parsing/Symbol.java index 62b0d6766..25d467bae 100644 --- a/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/parsing/Symbol.java +++ b/helper/impls/helper-impl-111/src/main/java/com/linkedin/avroutil1/compatibility/avro111/parsing/Symbol.java @@ -615,10 +615,6 @@ public FieldAdjustAction(int rindex, String fname, Set aliases) { } } - public static class IntLongAdjustAction extends ImplicitAction { - public static final IntLongAdjustAction INSTANCE = new IntLongAdjustAction(); - } - public static FieldOrderAction fieldOrderAction(Schema.Field[] fields) { return new FieldOrderAction(fields); } diff --git a/helper/impls/helper-impl-111/src/main/java/org/apache/avro/generic/Avro111GenericDataAccessUtil.java b/helper/impls/helper-impl-111/src/main/java/org/apache/avro/generic/Avro111GenericDataAccessUtil.java index 45e1ae846..c5e6541d2 100644 --- a/helper/impls/helper-impl-111/src/main/java/org/apache/avro/generic/Avro111GenericDataAccessUtil.java +++ b/helper/impls/helper-impl-111/src/main/java/org/apache/avro/generic/Avro111GenericDataAccessUtil.java @@ -10,7 +10,9 @@ /** * this class exists to allow us access to package-private classes and methods on class {@link GenericData} + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class Avro111GenericDataAccessUtil { private Avro111GenericDataAccessUtil() { } diff --git a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/Avro14Adapter.java b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/Avro14Adapter.java index 9693b1de5..d157eb835 100644 --- a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/Avro14Adapter.java +++ b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/Avro14Adapter.java @@ -25,9 +25,7 @@ import com.linkedin.avroutil1.compatibility.StringRepresentation; import com.linkedin.avroutil1.compatibility.avro14.backports.Avro14DefaultValuesCache; import com.linkedin.avroutil1.compatibility.avro14.backports.Avro18BufferedBinaryEncoder; -import com.linkedin.avroutil1.compatibility.avro14.backports.GenericDatumReaderExt; import com.linkedin.avroutil1.compatibility.avro14.backports.GenericDatumWriterExt; -import com.linkedin.avroutil1.compatibility.avro14.backports.SpecificDatumReaderExt; import com.linkedin.avroutil1.compatibility.avro14.backports.SpecificDatumWriterExt; import com.linkedin.avroutil1.compatibility.avro14.codec.AliasAwareSpecificDatumReader; import com.linkedin.avroutil1.compatibility.avro14.codec.BoundedMemoryDecoder; @@ -45,6 +43,7 @@ import org.apache.avro.AvroRuntimeException; import org.apache.avro.Schema; import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericDatumReader; import org.apache.avro.io.Avro14BinaryDecoderAccessUtil; import org.apache.avro.io.BinaryDecoder; import org.apache.avro.io.BinaryEncoder; @@ -230,7 +229,7 @@ public DatumWriter newGenericDatumWriter(Schema writer, GenericData genericDa @Override public DatumReader newGenericDatumReader(Schema writer, Schema reader, GenericData genericData) { // genericData not supported here - return new GenericDatumReaderExt<>(writer, reader); + return new GenericDatumReader<>(writer, reader); } @Override @@ -242,7 +241,7 @@ public DatumWriter newSpecificDatumWriter(Schema writer, SpecificData specifi public DatumReader newSpecificDatumReader(Schema writer, Schema reader, SpecificData specificData) { //SDRs in 1.4 do not allow for specifying an instance of SpecificData //TODO - get back here if we want to try backporting this to 1.4 - return new SpecificDatumReaderExt<>(writer, reader); + return new SpecificDatumReader<>(writer, reader); } @Override diff --git a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/backports/GenericDatumReaderExt.java b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/backports/GenericDatumReaderExt.java index fd18eaaa4..0f3e320a9 100644 --- a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/backports/GenericDatumReaderExt.java +++ b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/backports/GenericDatumReaderExt.java @@ -14,6 +14,10 @@ import java.io.IOException; +/** + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. + */ +@Deprecated public class GenericDatumReaderExt extends GenericDatumReader { private Schema writer; diff --git a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/backports/SpecificDatumReaderExt.java b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/backports/SpecificDatumReaderExt.java index 9a986aac7..2d3dfd249 100644 --- a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/backports/SpecificDatumReaderExt.java +++ b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/backports/SpecificDatumReaderExt.java @@ -14,6 +14,10 @@ import java.io.IOException; +/** + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. + */ +@Deprecated public class SpecificDatumReaderExt extends SpecificDatumReader { private Schema writer; diff --git a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/codec/AliasAwareSpecificDatumReader.java b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/codec/AliasAwareSpecificDatumReader.java index 31fe3aa11..38b3cda6a 100644 --- a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/codec/AliasAwareSpecificDatumReader.java +++ b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/codec/AliasAwareSpecificDatumReader.java @@ -6,7 +6,6 @@ package com.linkedin.avroutil1.compatibility.avro14.codec; -import com.linkedin.avroutil1.compatibility.avro14.backports.SpecificDatumReaderExt; import org.apache.avro.Schema; import org.apache.avro.specific.SpecificData; import org.apache.avro.specific.SpecificDatumReader; @@ -24,21 +23,20 @@ * * @param */ -public class AliasAwareSpecificDatumReader extends SpecificDatumReaderExt { +public class AliasAwareSpecificDatumReader extends SpecificDatumReader { //same idea as the one in SpecificData protected final static Map> CLASS_CACHE = new ConcurrentHashMap<>(); public AliasAwareSpecificDatumReader() { - this(null, null); } public AliasAwareSpecificDatumReader(Class c) { - this(SpecificData.get().getSchema(c)); + super(c); } public AliasAwareSpecificDatumReader(Schema schema) { - this(schema, schema); + super(schema); } public AliasAwareSpecificDatumReader(Schema writer, Schema reader) { diff --git a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/codec/ResolvingDecoder.java b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/codec/ResolvingDecoder.java index e18e67ca7..2079dc376 100644 --- a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/codec/ResolvingDecoder.java +++ b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/codec/ResolvingDecoder.java @@ -24,7 +24,6 @@ package com.linkedin.avroutil1.compatibility.avro14.codec; -import com.linkedin.avroutil1.compatibility.CustomDecoder; import com.linkedin.avroutil1.compatibility.avro14.parsing.ResolvingGrammarGenerator; import com.linkedin.avroutil1.compatibility.avro14.parsing.Symbol; import java.io.IOException; @@ -46,7 +45,7 @@ *

See the parser documentation for * information on how this works. */ -public class ResolvingDecoder extends ValidatingDecoder implements CustomDecoder { +public class ResolvingDecoder extends ValidatingDecoder { private Decoder backup; @@ -152,23 +151,6 @@ public final void drain() throws IOException { parser.processImplicitActions(); } - @Override - public int readInt() throws IOException { - Symbol actual = parser.advance(Symbol.INT); - if (actual == Symbol.INT) { - return in.readInt(); - } else if (actual == Symbol.IntLongAdjustAction.INSTANCE) { - long value = in.readLong(); - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new AvroTypeException(value + " cannot be represented as int"); - } - - return (int) value; - } - - throw new AvroTypeException("Expected int but found " + actual); - } - @Override public long readLong() throws IOException { Symbol actual = parser.advance(Symbol.LONG); @@ -245,8 +227,6 @@ public Symbol doAction(Symbol input, Symbol top) throws IOException { .createBinaryDecoder(dsa.contents, null); } else if (top == Symbol.DEFAULT_END_ACTION) { in = backup; - } else if (top == Symbol.IntLongAdjustAction.INSTANCE) { - return top; } else { throw new AvroTypeException("Unknown action: " + top); } diff --git a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/parsing/ResolvingGrammarGenerator.java b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/parsing/ResolvingGrammarGenerator.java index 479d527f7..1fb229e16 100644 --- a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/parsing/ResolvingGrammarGenerator.java +++ b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/parsing/ResolvingGrammarGenerator.java @@ -164,11 +164,7 @@ public Symbol generate( break; case NULL: case BOOLEAN: - break; case INT: - if (writerType == Schema.Type.LONG) { - return Symbol.IntLongAdjustAction.INSTANCE; - } case STRING: case FLOAT: case BYTES: @@ -453,11 +449,6 @@ private static int bestBranch(Schema r, Schema w) { } break; case LONG: - // We can selectively demote long and check that it fits inside int range - // when reading an int from a long writer schema. - if (b.getType() == Schema.Type.INT) { - return j; - } case FLOAT: switch (b.getType()) { case DOUBLE: diff --git a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/parsing/Symbol.java b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/parsing/Symbol.java index b7a2c6a34..d6406b37f 100644 --- a/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/parsing/Symbol.java +++ b/helper/impls/helper-impl-14/src/main/java/com/linkedin/avroutil1/compatibility/avro14/parsing/Symbol.java @@ -421,10 +421,6 @@ private ErrorAction(String msg) { } } - public static class IntLongAdjustAction extends ImplicitAction { - public static final IntLongAdjustAction INSTANCE = new IntLongAdjustAction(); - } - public static class IntCheckAction extends Symbol { public final int size; public IntCheckAction(int size) { diff --git a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/backports/GenericDatumReaderExt.java b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/backports/GenericDatumReaderExt.java index 9b373996e..cf6b394ba 100644 --- a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/backports/GenericDatumReaderExt.java +++ b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/backports/GenericDatumReaderExt.java @@ -6,14 +6,9 @@ package com.linkedin.avroutil1.compatibility.avro15.backports; -import com.linkedin.avroutil1.compatibility.avro15.codec.CachedResolvingDecoder; -import org.apache.avro.AvroRuntimeException; import org.apache.avro.Schema; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericDatumReader; -import org.apache.avro.io.Decoder; - -import java.io.IOException; /** @@ -23,132 +18,7 @@ */ public class GenericDatumReaderExt extends GenericDatumReader { - private Schema writer; - private Schema reader; - public GenericDatumReaderExt(Schema writer, Schema reader, GenericData genericData) { super(writer, reader, genericData); - this.writer = writer; - this.reader = reader; - } - - /** - * {@inheritDoc} - */ - @Override - public void setExpected(Schema reader) throws IOException { - super.setExpected(reader); - this.reader = reader; - } - - /** - * {@inheritDoc} - */ - @Override - public void setSchema(Schema writer) { - super.setSchema(writer); - this.writer = writer; - if (reader == null) { - this.reader = writer; - } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - @Override - public T read(T reuse, Decoder in) throws IOException { - CachedResolvingDecoder resolver = new CachedResolvingDecoder(Schema.applyAliases(writer, reader), reader, in); - resolver.init(in); - T result = (T) read(reuse, reader, resolver); - resolver.drain(); - return result; - } - - private Object read(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - switch (expected.getType()) { - case RECORD: - return readRecord(old, expected, in); - case ENUM: - return readEnum(expected, in); - case ARRAY: - return readArray(old, expected, in); - case MAP: - return readMap(old, expected, in); - case UNION: - return read(old, expected.getTypes().get(in.readIndex()), in); - case FIXED: - return readFixed(old, expected, in); - case STRING: - return readString(old, expected, in); - case BYTES: - return readBytes(old, in); - case INT: - return readInt(old, expected, in); - case LONG: - return in.readLong(); - case FLOAT: - return in.readFloat(); - case DOUBLE: - return in.readDouble(); - case BOOLEAN: - return in.readBoolean(); - case NULL: - in.readNull(); - return null; - default: - throw new AvroRuntimeException("Unknown type: " + expected); - } - } - - private Object readRecord(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - Object record = newRecord(old, expected); - final GenericData data = getData(); - - for (Schema.Field f : in.readFieldOrder()) { - int pos = f.pos(); - String name = f.name(); - Object oldDatum = (old != null) ? data.getField(record, name, pos) : null; - data.setField(record, name, pos, read(oldDatum, f.schema(), in)); - } - - return record; - } - - private Object readArray(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - Schema expectedType = expected.getElementType(); - long l = in.readArrayStart(); - long base = 0; - if (l > 0) { - Object array = newArray(old, (int) l, expected); - do { - for (long i = 0; i < l; i++) { - addToArray(array, base + i, read(peekArray(array), expectedType, in)); - } - base += l; - } while ((l = in.arrayNext()) > 0); - return array; - } else { - return newArray(old, 0, expected); - } - } - - private Object readMap(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - Schema eValue = expected.getValueType(); - long l = in.readMapStart(); - Object map = newMap(old, (int) l); - if (l > 0) { - do { - for (int i = 0; i < l; i++) { - addToMap(map, readString(null, in), read(null, eValue, in)); - } - } while ((l = in.mapNext()) > 0); - } - return map; } } diff --git a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/backports/SpecificDatumReaderExt.java b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/backports/SpecificDatumReaderExt.java index 5b01aba17..29d17ca15 100644 --- a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/backports/SpecificDatumReaderExt.java +++ b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/backports/SpecificDatumReaderExt.java @@ -6,16 +6,10 @@ package com.linkedin.avroutil1.compatibility.avro15.backports; -import com.linkedin.avroutil1.compatibility.avro15.codec.CachedResolvingDecoder; -import org.apache.avro.AvroRuntimeException; import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.io.Decoder; import org.apache.avro.specific.SpecificData; import org.apache.avro.specific.SpecificDatumReader; -import java.io.IOException; - /** * this class allows constructing a {@link SpecificDatumReader} with @@ -23,132 +17,7 @@ * @param */ public class SpecificDatumReaderExt extends SpecificDatumReader { - private Schema writer; - private Schema reader; - public SpecificDatumReaderExt(Schema writer, Schema reader, SpecificData specificData) { super(writer, reader, specificData); - this.writer = writer; - this.reader = reader; - } - - /** - * {@inheritDoc} - */ - @Override - public void setExpected(Schema reader) throws IOException { - super.setExpected(reader); - this.reader = reader; - } - - /** - * {@inheritDoc} - */ - @Override - public void setSchema(Schema writer) { - super.setSchema(writer); - this.writer = writer; - if (reader == null) { - this.reader = writer; - } - } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - @Override - public T read(T reuse, Decoder in) throws IOException { - CachedResolvingDecoder resolver = new CachedResolvingDecoder(Schema.applyAliases(writer, reader), reader, in); - resolver.init(in); - T result = (T) read(reuse, reader, resolver); - resolver.drain(); - return result; - } - - private Object read(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - switch (expected.getType()) { - case RECORD: - return readRecord(old, expected, in); - case ENUM: - return readEnum(expected, in); - case ARRAY: - return readArray(old, expected, in); - case MAP: - return readMap(old, expected, in); - case UNION: - return read(old, expected.getTypes().get(in.readIndex()), in); - case FIXED: - return readFixed(old, expected, in); - case STRING: - return readString(old, expected, in); - case BYTES: - return readBytes(old, in); - case INT: - return readInt(old, expected, in); - case LONG: - return in.readLong(); - case FLOAT: - return in.readFloat(); - case DOUBLE: - return in.readDouble(); - case BOOLEAN: - return in.readBoolean(); - case NULL: - in.readNull(); - return null; - default: - throw new AvroRuntimeException("Unknown type: " + expected); - } - } - - private Object readRecord(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - Object record = newRecord(old, expected); - final GenericData data = getData(); - - for (Schema.Field f : in.readFieldOrder()) { - int pos = f.pos(); - String name = f.name(); - Object oldDatum = (old != null) ? data.getField(record, name, pos) : null; - data.setField(record, name, pos, read(oldDatum, f.schema(), in)); - } - - return record; - } - - private Object readArray(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - Schema expectedType = expected.getElementType(); - long l = in.readArrayStart(); - long base = 0; - if (l > 0) { - Object array = newArray(old, (int) l, expected); - do { - for (long i = 0; i < l; i++) { - addToArray(array, base + i, read(peekArray(array), expectedType, in)); - } - base += l; - } while ((l = in.arrayNext()) > 0); - return array; - } else { - return newArray(old, 0, expected); - } - } - - private Object readMap(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - Schema eValue = expected.getValueType(); - long l = in.readMapStart(); - Object map = newMap(old, (int) l); - if (l > 0) { - do { - for (int i = 0; i < l; i++) { - addToMap(map, readString(null, in), read(null, eValue, in)); - } - } while ((l = in.mapNext()) > 0); - } - return map; } } diff --git a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/codec/AliasAwareSpecificDatumReader.java b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/codec/AliasAwareSpecificDatumReader.java index fc5586a02..4e4b6ddf2 100644 --- a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/codec/AliasAwareSpecificDatumReader.java +++ b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/codec/AliasAwareSpecificDatumReader.java @@ -6,7 +6,6 @@ package com.linkedin.avroutil1.compatibility.avro15.codec; -import com.linkedin.avroutil1.compatibility.avro15.backports.SpecificDatumReaderExt; import org.apache.avro.Schema; import org.apache.avro.specific.SpecificData; import org.apache.avro.specific.SpecificDatumReader; @@ -24,25 +23,24 @@ * * @param */ -public class AliasAwareSpecificDatumReader extends SpecificDatumReaderExt { +public class AliasAwareSpecificDatumReader extends SpecificDatumReader { //same idea as the one in SpecificData protected final static Map> CLASS_CACHE = new ConcurrentHashMap<>(); public AliasAwareSpecificDatumReader() { - this(null, null); } public AliasAwareSpecificDatumReader(Class c) { - this(SpecificData.get().getSchema(c)); + super(c); } public AliasAwareSpecificDatumReader(Schema schema) { - this(schema, schema); + super(schema); } public AliasAwareSpecificDatumReader(Schema writer, Schema reader) { - super(writer, reader, SpecificData.get()); + super(writer, reader); } @Override diff --git a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/codec/ResolvingDecoder.java b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/codec/ResolvingDecoder.java index dde1ac8e4..29c105648 100644 --- a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/codec/ResolvingDecoder.java +++ b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/codec/ResolvingDecoder.java @@ -24,7 +24,6 @@ package com.linkedin.avroutil1.compatibility.avro15.codec; -import com.linkedin.avroutil1.compatibility.CustomDecoder; import com.linkedin.avroutil1.compatibility.avro15.parsing.ResolvingGrammarGenerator; import com.linkedin.avroutil1.compatibility.avro15.parsing.Symbol; import java.io.IOException; @@ -46,7 +45,7 @@ *

See the parser documentation for * information on how this works. */ -public class ResolvingDecoder extends ValidatingDecoder implements CustomDecoder { +public class ResolvingDecoder extends ValidatingDecoder { private Decoder backup; @@ -157,23 +156,6 @@ public final void drain() throws IOException { parser.processImplicitActions(); } - @Override - public int readInt() throws IOException { - Symbol actual = parser.advance(Symbol.INT); - if (actual == Symbol.INT) { - return in.readInt(); - } else if (actual == Symbol.IntLongAdjustAction.INSTANCE) { - long value = in.readLong(); - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new AvroTypeException(value + " cannot be represented as int"); - } - - return (int) value; - } - - throw new AvroTypeException("Expected int but found " + actual); - } - @Override public long readLong() throws IOException { Symbol actual = parser.advance(Symbol.LONG); @@ -263,8 +245,6 @@ public Symbol doAction(Symbol input, Symbol top) throws IOException { .binaryDecoder(dsa.contents, null); } else if (top == Symbol.DEFAULT_END_ACTION) { in = backup; - } else if (top == Symbol.IntLongAdjustAction.INSTANCE) { - return top; } else { throw new AvroTypeException("Unknown action: " + top); } diff --git a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/parsing/ResolvingGrammarGenerator.java b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/parsing/ResolvingGrammarGenerator.java index 4c2f09597..1989baf4a 100644 --- a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/parsing/ResolvingGrammarGenerator.java +++ b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/parsing/ResolvingGrammarGenerator.java @@ -33,8 +33,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; -import java.util.Iterator; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -170,11 +170,7 @@ public Symbol generate( break; case NULL: case BOOLEAN: - break; case INT: - if (writerType == Schema.Type.LONG) { - return Symbol.IntLongAdjustAction.INSTANCE; - } case STRING: case BYTES: case ENUM: @@ -465,11 +461,6 @@ private static int bestBranch(Schema r, Schema w) { } break; case LONG: - // We can selectively demote long and check that it fits inside int range - // when reading an int from a long writer schema. - if (b.getType() == Schema.Type.INT) { - return j; - } case FLOAT: switch (b.getType()) { case DOUBLE: diff --git a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/parsing/Symbol.java b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/parsing/Symbol.java index 7b10e1871..f51addcc6 100644 --- a/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/parsing/Symbol.java +++ b/helper/impls/helper-impl-15/src/main/java/com/linkedin/avroutil1/compatibility/avro15/parsing/Symbol.java @@ -481,10 +481,6 @@ public FieldAdjustAction(int rindex, String fname) { } } - public static class IntLongAdjustAction extends ImplicitAction { - public static final IntLongAdjustAction INSTANCE = new IntLongAdjustAction(); - } - public static final class FieldOrderAction extends ImplicitAction { public final Schema.Field[] fields; public FieldOrderAction(Schema.Field[] fields) { diff --git a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/Avro16Adapter.java b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/Avro16Adapter.java index 5cb932fde..f80dac16e 100644 --- a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/Avro16Adapter.java +++ b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/Avro16Adapter.java @@ -27,7 +27,6 @@ import com.linkedin.avroutil1.compatibility.avro16.backports.Avro16DefaultValuesCache; import com.linkedin.avroutil1.compatibility.avro16.backports.GenericDatumReaderExt; import com.linkedin.avroutil1.compatibility.avro16.backports.GenericDatumWriterExt; -import com.linkedin.avroutil1.compatibility.avro16.backports.SpecificDatumReaderExt; import com.linkedin.avroutil1.compatibility.avro16.backports.SpecificDatumWriterExt; import com.linkedin.avroutil1.compatibility.avro16.codec.AliasAwareSpecificDatumReader; import com.linkedin.avroutil1.compatibility.avro16.codec.BoundedMemoryDecoder; @@ -246,7 +245,7 @@ public DatumWriter newSpecificDatumWriter(Schema writer, SpecificData specifi @Override public DatumReader newSpecificDatumReader(Schema writer, Schema reader, SpecificData specificData) { - return new SpecificDatumReaderExt<>(writer, reader, specificData); + return new SpecificDatumReader<>(writer, reader, specificData); } @Override diff --git a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/backports/GenericDatumReaderExt.java b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/backports/GenericDatumReaderExt.java index 479d1080f..7d6e494bc 100644 --- a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/backports/GenericDatumReaderExt.java +++ b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/backports/GenericDatumReaderExt.java @@ -6,14 +6,9 @@ package com.linkedin.avroutil1.compatibility.avro16.backports; -import com.linkedin.avroutil1.compatibility.avro16.codec.CachedResolvingDecoder; -import org.apache.avro.AvroRuntimeException; import org.apache.avro.Schema; import org.apache.avro.generic.GenericData; import org.apache.avro.generic.GenericDatumReader; -import org.apache.avro.io.Decoder; - -import java.io.IOException; /** @@ -26,105 +21,4 @@ public class GenericDatumReaderExt extends GenericDatumReader { public GenericDatumReaderExt(Schema writer, Schema reader, GenericData genericData) { super(writer, reader, genericData); } - - /** - * {@inheritDoc} - */ - @SuppressWarnings("unchecked") - @Override - public T read(T reuse, Decoder in) throws IOException { - final Schema reader = getExpected(); - final Schema writer = getSchema(); - CachedResolvingDecoder resolver = new CachedResolvingDecoder(Schema.applyAliases(writer, reader), reader, in); - resolver.configure(in); - T result = (T) read(reuse, reader, resolver); - resolver.drain(); - return result; - } - - private Object read(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - switch (expected.getType()) { - case RECORD: - return readRecord(old, expected, in); - case ENUM: - return readEnum(expected, in); - case ARRAY: - return readArray(old, expected, in); - case MAP: - return readMap(old, expected, in); - case UNION: - return read(old, expected.getTypes().get(in.readIndex()), in); - case FIXED: - return readFixed(old, expected, in); - case STRING: - return readString(old, expected, in); - case BYTES: - return readBytes(old, in); - case INT: - return readInt(old, expected, in); - case LONG: - return in.readLong(); - case FLOAT: - return in.readFloat(); - case DOUBLE: - return in.readDouble(); - case BOOLEAN: - return in.readBoolean(); - case NULL: - in.readNull(); - return null; - default: - throw new AvroRuntimeException("Unknown type: " + expected); - } - } - - private Object readRecord(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - final GenericData data = getData(); - Object r = data.newRecord(old, expected); - - for (Schema.Field f : in.readFieldOrder()) { - int pos = f.pos(); - String name = f.name(); - Object oldDatum = (old!=null) ? data.getField(r, name, pos) : null; - data.setField(r, name, pos, read(oldDatum, f.schema(), in)); - } - - return r; - } - - private Object readArray(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - Schema expectedType = expected.getElementType(); - long l = in.readArrayStart(); - long base = 0; - if (l > 0) { - Object array = newArray(old, (int) l, expected); - do { - for (long i = 0; i < l; i++) { - addToArray(array, base + i, read(peekArray(array), expectedType, in)); - } - base += l; - } while ((l = in.arrayNext()) > 0); - return array; - } else { - return newArray(old, 0, expected); - } - } - - private Object readMap(Object old, Schema expected, - CachedResolvingDecoder in) throws IOException { - Schema eValue = expected.getValueType(); - long l = in.readMapStart(); - Object map = newMap(old, (int) l); - if (l > 0) { - do { - for (int i = 0; i < l; i++) { - addToMap(map, readString(null, in), read(null, eValue, in)); - } - } while ((l = in.mapNext()) > 0); - } - return map; - } } diff --git a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/backports/SpecificDatumReaderExt.java b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/backports/SpecificDatumReaderExt.java index 4db31af34..8587b5572 100644 --- a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/backports/SpecificDatumReaderExt.java +++ b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/backports/SpecificDatumReaderExt.java @@ -21,7 +21,9 @@ * this class allows constructing a {@link SpecificDatumReader} with * a specified {@link SpecificData} instance under avro 1.6 * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class SpecificDatumReaderExt extends SpecificDatumReader { public SpecificDatumReaderExt(Schema writer, Schema reader, SpecificData specificData) { diff --git a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/codec/AliasAwareSpecificDatumReader.java b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/codec/AliasAwareSpecificDatumReader.java index 7f52b63fd..9258fe819 100644 --- a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/codec/AliasAwareSpecificDatumReader.java +++ b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/codec/AliasAwareSpecificDatumReader.java @@ -6,7 +6,6 @@ package com.linkedin.avroutil1.compatibility.avro16.codec; -import com.linkedin.avroutil1.compatibility.avro16.backports.SpecificDatumReaderExt; import org.apache.avro.Schema; import org.apache.avro.specific.SpecificData; import org.apache.avro.specific.SpecificDatumReader; @@ -24,7 +23,7 @@ * * @param */ -public class AliasAwareSpecificDatumReader extends SpecificDatumReaderExt { +public class AliasAwareSpecificDatumReader extends SpecificDatumReader { //same idea as the one in SpecificData protected final static Map> CLASS_CACHE = new ConcurrentHashMap<>(); @@ -46,7 +45,6 @@ public AliasAwareSpecificDatumReader(Schema writer, Schema reader) { } public AliasAwareSpecificDatumReader(Schema writer, Schema reader, SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } diff --git a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/codec/ResolvingDecoder.java b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/codec/ResolvingDecoder.java index ee8b6871f..e449e82f8 100644 --- a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/codec/ResolvingDecoder.java +++ b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/codec/ResolvingDecoder.java @@ -24,7 +24,6 @@ package com.linkedin.avroutil1.compatibility.avro16.codec; -import com.linkedin.avroutil1.compatibility.CustomDecoder; import com.linkedin.avroutil1.compatibility.avro16.parsing.ResolvingGrammarGenerator; import com.linkedin.avroutil1.compatibility.avro16.parsing.Symbol; import java.io.IOException; @@ -35,7 +34,7 @@ import org.apache.avro.io.Decoder; import org.apache.avro.io.DecoderFactory; -public class ResolvingDecoder extends ValidatingDecoder implements CustomDecoder { +public class ResolvingDecoder extends ValidatingDecoder { private Decoder backup; ResolvingDecoder(Schema writer, Schema reader, Decoder in) throws IOException { @@ -65,23 +64,6 @@ public final void drain() throws IOException { this.parser.processImplicitActions(); } - @Override - public int readInt() throws IOException { - Symbol actual = parser.advance(Symbol.INT); - if (actual == Symbol.INT) { - return in.readInt(); - } else if (actual == Symbol.IntLongAdjustAction.INSTANCE) { - long value = in.readLong(); - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new AvroTypeException(value + " cannot be represented as int"); - } - - return (int) value; - } - - throw new AvroTypeException("Expected int but found " + actual); - } - public long readLong() throws IOException { Symbol actual = this.parser.advance(Symbol.LONG); if (actual == Symbol.INT) { @@ -164,10 +146,6 @@ public Symbol doAction(Symbol input, Symbol top) throws IOException { throw new AvroTypeException(((Symbol.ErrorAction)top).msg); } - if (top == Symbol.IntLongAdjustAction.INSTANCE) { - return top; - } - if (top instanceof Symbol.DefaultStartAction) { Symbol.DefaultStartAction dsa = (Symbol.DefaultStartAction)top; this.backup = this.in; diff --git a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/parsing/ResolvingGrammarGenerator.java b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/parsing/ResolvingGrammarGenerator.java index e2e1d168f..94bb22273 100644 --- a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/parsing/ResolvingGrammarGenerator.java +++ b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/parsing/ResolvingGrammarGenerator.java @@ -170,11 +170,7 @@ public Symbol generate( break; case NULL: case BOOLEAN: - break; case INT: - if (writerType == Schema.Type.LONG) { - return Symbol.IntLongAdjustAction.INSTANCE; - } case STRING: case BYTES: case ENUM: @@ -465,11 +461,6 @@ private static int bestBranch(Schema r, Schema w) { } break; case LONG: - // We can selectively demote long and check that it fits inside int range - // when reading an int from a long writer schema. - if (b.getType() == Schema.Type.INT) { - return j; - } case FLOAT: switch (b.getType()) { case DOUBLE: diff --git a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/parsing/Symbol.java b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/parsing/Symbol.java index 8a0121fbe..3ad5e1b54 100644 --- a/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/parsing/Symbol.java +++ b/helper/impls/helper-impl-16/src/main/java/com/linkedin/avroutil1/compatibility/avro16/parsing/Symbol.java @@ -488,10 +488,6 @@ public FieldOrderAction(Schema.Field[] fields) { } } - public static class IntLongAdjustAction extends ImplicitAction { - public static final IntLongAdjustAction INSTANCE = new IntLongAdjustAction(); - } - public static class DefaultStartAction extends ImplicitAction { public final byte[] contents; public DefaultStartAction(byte[] contents) { diff --git a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/Avro17Adapter.java b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/Avro17Adapter.java index cf9fd1669..9da748762 100644 --- a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/Avro17Adapter.java +++ b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/Avro17Adapter.java @@ -23,8 +23,6 @@ import com.linkedin.avroutil1.compatibility.SkipDecoder; import com.linkedin.avroutil1.compatibility.StringRepresentation; import com.linkedin.avroutil1.compatibility.avro17.backports.Avro17DefaultValuesCache; -import com.linkedin.avroutil1.compatibility.avro17.backports.GenericDatumReaderExt; -import com.linkedin.avroutil1.compatibility.avro17.backports.SpecificDatumReaderExt; import com.linkedin.avroutil1.compatibility.avro17.backports.SpecificDatumWriterExt; import com.linkedin.avroutil1.compatibility.avro17.codec.AliasAwareSpecificDatumReader; import com.linkedin.avroutil1.compatibility.avro17.codec.BoundedMemoryDecoder; @@ -40,6 +38,7 @@ import org.apache.avro.Schema; import org.apache.avro.SchemaNormalization; import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericDatumReader; import org.apache.avro.generic.GenericDatumWriter; import org.apache.avro.io.Avro17BinaryDecoderAccessUtil; import org.apache.avro.io.BinaryDecoder; @@ -271,7 +270,7 @@ public DatumWriter newGenericDatumWriter(Schema writer, GenericData genericDa @Override public DatumReader newGenericDatumReader(Schema writer, Schema reader, GenericData genericData) { - return new GenericDatumReaderExt<>(writer, reader, genericData); + return new GenericDatumReader<>(writer, reader, genericData); } @Override @@ -281,7 +280,7 @@ public DatumWriter newSpecificDatumWriter(Schema writer, SpecificData specifi @Override public DatumReader newSpecificDatumReader(Schema writer, Schema reader, SpecificData specificData) { - return new SpecificDatumReaderExt<>(writer, reader, specificData); + return new SpecificDatumReader<>(writer, reader, specificData); } @Override diff --git a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/backports/GenericDatumReaderExt.java b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/backports/GenericDatumReaderExt.java index 82025d73c..6505ffe7e 100644 --- a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/backports/GenericDatumReaderExt.java +++ b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/backports/GenericDatumReaderExt.java @@ -20,7 +20,9 @@ * this class allows constructing a {@link GenericDatumReader} with * a specified {@link GenericData} instance under avro 1.7 * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class GenericDatumReaderExt extends GenericDatumReader { public GenericDatumReaderExt(Schema writer, Schema reader, GenericData genericData) { diff --git a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/backports/SpecificDatumReaderExt.java b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/backports/SpecificDatumReaderExt.java index c8445451d..49f31d475 100644 --- a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/backports/SpecificDatumReaderExt.java +++ b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/backports/SpecificDatumReaderExt.java @@ -21,7 +21,9 @@ * this class allows constructing a {@link SpecificDatumReader} with * a specified {@link SpecificData} instance under avro 1.7 * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class SpecificDatumReaderExt extends SpecificDatumReader { public SpecificDatumReaderExt(Schema writer, Schema reader, SpecificData specificData) { diff --git a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/codec/AliasAwareSpecificDatumReader.java b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/codec/AliasAwareSpecificDatumReader.java index 989b91001..5fbe2ba05 100644 --- a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/codec/AliasAwareSpecificDatumReader.java +++ b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/codec/AliasAwareSpecificDatumReader.java @@ -6,7 +6,6 @@ package com.linkedin.avroutil1.compatibility.avro17.codec; -import com.linkedin.avroutil1.compatibility.avro17.backports.SpecificDatumReaderExt; import org.apache.avro.Schema; import org.apache.avro.specific.SpecificData; import org.apache.avro.specific.SpecificDatumReader; @@ -25,7 +24,7 @@ * * @param */ -public class AliasAwareSpecificDatumReader extends SpecificDatumReaderExt { +public class AliasAwareSpecificDatumReader extends SpecificDatumReader { //same idea as the one in SpecificData protected final static Map> CLASS_CACHE = new ConcurrentHashMap<>(); @@ -48,12 +47,10 @@ public AliasAwareSpecificDatumReader(Schema writer, Schema reader) { } public AliasAwareSpecificDatumReader(Schema writer, Schema reader, SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } protected AliasAwareSpecificDatumReader(SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } diff --git a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/codec/ResolvingDecoder.java b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/codec/ResolvingDecoder.java index 5c9690061..1f85435d4 100644 --- a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/codec/ResolvingDecoder.java +++ b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/codec/ResolvingDecoder.java @@ -24,7 +24,6 @@ package com.linkedin.avroutil1.compatibility.avro17.codec; -import com.linkedin.avroutil1.compatibility.CustomDecoder; import com.linkedin.avroutil1.compatibility.avro17.parsing.ResolvingGrammarGenerator; import com.linkedin.avroutil1.compatibility.avro17.parsing.Symbol; import java.io.IOException; @@ -38,7 +37,7 @@ import org.apache.avro.io.DecoderFactory; import org.apache.avro.util.Utf8; -public class ResolvingDecoder extends ValidatingDecoder implements CustomDecoder { +public class ResolvingDecoder extends ValidatingDecoder { private Decoder backup; private static final Charset UTF8 = Charset.forName("UTF-8"); @@ -69,23 +68,6 @@ public final void drain() throws IOException { this.parser.processImplicitActions(); } - @Override - public int readInt() throws IOException { - Symbol actual = parser.advance(Symbol.INT); - if (actual == Symbol.INT) { - return in.readInt(); - } else if (actual == Symbol.IntLongAdjustAction.INSTANCE) { - long value = in.readLong(); - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new AvroTypeException(value + " cannot be represented as int"); - } - - return (int) value; - } - - throw new AvroTypeException("Expected int but found " + actual); - } - public long readLong() throws IOException { Symbol actual = this.parser.advance(Symbol.LONG); if (actual == Symbol.INT) { @@ -226,10 +208,6 @@ public Symbol doAction(Symbol input, Symbol top) throws IOException { throw new AvroTypeException(((Symbol.ErrorAction)top).msg); } - if (top == Symbol.IntLongAdjustAction.INSTANCE) { - return top; - } - if (top instanceof Symbol.DefaultStartAction) { Symbol.DefaultStartAction dsa = (Symbol.DefaultStartAction)top; this.backup = this.in; diff --git a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/parsing/ResolvingGrammarGenerator.java b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/parsing/ResolvingGrammarGenerator.java index 540230a6b..028cc5754 100644 --- a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/parsing/ResolvingGrammarGenerator.java +++ b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/parsing/ResolvingGrammarGenerator.java @@ -184,11 +184,7 @@ public Symbol generate( break; case NULL: case BOOLEAN: - break; case INT: - if (writerType == Schema.Type.LONG) { - return Symbol.IntLongAdjustAction.INSTANCE; - } case ENUM: case ARRAY: case MAP: @@ -479,11 +475,6 @@ private static int bestBranch(Schema r, Schema w) { } break; case LONG: - // We can selectively demote long and check that it fits inside int range - // when reading an int from a long writer schema. - if (b.getType() == Schema.Type.INT) { - return j; - } case FLOAT: switch (b.getType()) { case DOUBLE: diff --git a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/parsing/Symbol.java b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/parsing/Symbol.java index f25a40b92..832c780a9 100644 --- a/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/parsing/Symbol.java +++ b/helper/impls/helper-impl-17/src/main/java/com/linkedin/avroutil1/compatibility/avro17/parsing/Symbol.java @@ -551,10 +551,6 @@ public static final class FieldOrderAction extends ImplicitAction { } } - public static class IntLongAdjustAction extends ImplicitAction { - public static final IntLongAdjustAction INSTANCE = new IntLongAdjustAction(); - } - public static DefaultStartAction defaultStartAction(byte[] contents) { return new DefaultStartAction(contents); } diff --git a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/Avro18Adapter.java b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/Avro18Adapter.java index fc3b3e7ff..56a944fc1 100644 --- a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/Avro18Adapter.java +++ b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/Avro18Adapter.java @@ -23,8 +23,6 @@ import com.linkedin.avroutil1.compatibility.SkipDecoder; import com.linkedin.avroutil1.compatibility.StringRepresentation; import com.linkedin.avroutil1.compatibility.avro18.backports.Avro18DefaultValuesCache; -import com.linkedin.avroutil1.compatibility.avro18.backports.GenericDatumReaderExt; -import com.linkedin.avroutil1.compatibility.avro18.backports.SpecificDatumReaderExt; import com.linkedin.avroutil1.compatibility.avro18.codec.AliasAwareSpecificDatumReader; import com.linkedin.avroutil1.compatibility.avro18.codec.BoundedMemoryDecoder; import com.linkedin.avroutil1.compatibility.avro18.codec.CachedResolvingDecoder; @@ -38,6 +36,7 @@ import org.apache.avro.Schema; import org.apache.avro.SchemaNormalization; import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericDatumReader; import org.apache.avro.generic.GenericDatumWriter; import org.apache.avro.io.Avro18BinaryDecoderAccessUtil; import org.apache.avro.io.BinaryDecoder; @@ -233,7 +232,7 @@ public DatumWriter newGenericDatumWriter(Schema writer, GenericData genericDa @Override public DatumReader newGenericDatumReader(Schema writer, Schema reader, GenericData genericData) { - return new GenericDatumReaderExt<>(writer, reader, genericData); + return new GenericDatumReader<>(writer, reader, genericData); } @Override @@ -243,7 +242,7 @@ public DatumWriter newSpecificDatumWriter(Schema writer, SpecificData specifi @Override public DatumReader newSpecificDatumReader(Schema writer, Schema reader, SpecificData specificData) { - return new SpecificDatumReaderExt<>(writer, reader, specificData); + return new SpecificDatumReader<>(writer, reader, specificData); } @Override diff --git a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/backports/GenericDatumReaderExt.java b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/backports/GenericDatumReaderExt.java index 3a09719c3..da9d6aa4d 100644 --- a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/backports/GenericDatumReaderExt.java +++ b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/backports/GenericDatumReaderExt.java @@ -24,7 +24,9 @@ * a specified {@link GenericData} instance under avro 1.8 * * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class GenericDatumReaderExt extends GenericDatumReader { public GenericDatumReaderExt(Schema writer, Schema reader, GenericData genericData) { diff --git a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/backports/SpecificDatumReaderExt.java b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/backports/SpecificDatumReaderExt.java index 4b02fbd06..12d78301c 100644 --- a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/backports/SpecificDatumReaderExt.java +++ b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/backports/SpecificDatumReaderExt.java @@ -26,7 +26,9 @@ * a specified {@link SpecificData} instance under avro 1.8 * * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class SpecificDatumReaderExt extends SpecificDatumReader { public SpecificDatumReaderExt(Schema writer, Schema reader, SpecificData specificData) { diff --git a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/codec/AliasAwareSpecificDatumReader.java b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/codec/AliasAwareSpecificDatumReader.java index 04956f057..bae57cf7c 100644 --- a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/codec/AliasAwareSpecificDatumReader.java +++ b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/codec/AliasAwareSpecificDatumReader.java @@ -6,7 +6,6 @@ package com.linkedin.avroutil1.compatibility.avro18.codec; -import com.linkedin.avroutil1.compatibility.avro18.backports.SpecificDatumReaderExt; import org.apache.avro.Schema; import org.apache.avro.specific.SpecificData; import org.apache.avro.specific.SpecificDatumReader; @@ -21,7 +20,7 @@ * * @param */ -public class AliasAwareSpecificDatumReader extends SpecificDatumReaderExt { +public class AliasAwareSpecificDatumReader extends SpecificDatumReader { public AliasAwareSpecificDatumReader() { this(null, null); @@ -41,12 +40,10 @@ public AliasAwareSpecificDatumReader(Schema writer, Schema reader) { } public AliasAwareSpecificDatumReader(Schema writer, Schema reader, SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } protected AliasAwareSpecificDatumReader(SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } } diff --git a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/codec/ResolvingDecoder.java b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/codec/ResolvingDecoder.java index bf60440ce..1f47727d2 100644 --- a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/codec/ResolvingDecoder.java +++ b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/codec/ResolvingDecoder.java @@ -24,7 +24,6 @@ package com.linkedin.avroutil1.compatibility.avro18.codec; -import com.linkedin.avroutil1.compatibility.CustomDecoder; import com.linkedin.avroutil1.compatibility.avro18.parsing.ResolvingGrammarGenerator; import com.linkedin.avroutil1.compatibility.avro18.parsing.Symbol; import java.io.IOException; @@ -38,7 +37,7 @@ import org.apache.avro.io.DecoderFactory; import org.apache.avro.util.Utf8; -public class ResolvingDecoder extends ValidatingDecoder implements CustomDecoder { +public class ResolvingDecoder extends ValidatingDecoder { private Decoder backup; private static final Charset UTF8 = Charset.forName("UTF-8"); @@ -69,23 +68,6 @@ public final void drain() throws IOException { this.parser.processImplicitActions(); } - @Override - public int readInt() throws IOException { - Symbol actual = parser.advance(Symbol.INT); - if (actual == Symbol.INT) { - return in.readInt(); - } else if (actual == Symbol.IntLongAdjustAction.INSTANCE) { - long value = in.readLong(); - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new AvroTypeException(value + " cannot be represented as int"); - } - - return (int) value; - } - - throw new AvroTypeException("Expected int but found " + actual); - } - public long readLong() throws IOException { Symbol actual = this.parser.advance(Symbol.LONG); if (actual == Symbol.INT) { @@ -226,10 +208,6 @@ public Symbol doAction(Symbol input, Symbol top) throws IOException { throw new AvroTypeException(((Symbol.ErrorAction)top).msg); } - if (top == Symbol.IntLongAdjustAction.INSTANCE) { - return top; - } - if (top instanceof Symbol.DefaultStartAction) { Symbol.DefaultStartAction dsa = (Symbol.DefaultStartAction)top; this.backup = this.in; diff --git a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/parsing/ResolvingGrammarGenerator.java b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/parsing/ResolvingGrammarGenerator.java index d9348c643..fb1948a87 100644 --- a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/parsing/ResolvingGrammarGenerator.java +++ b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/parsing/ResolvingGrammarGenerator.java @@ -184,11 +184,7 @@ public Symbol generate( break; case NULL: case BOOLEAN: - break; case INT: - if (writerType == Schema.Type.LONG) { - return Symbol.IntLongAdjustAction.INSTANCE; - } case ENUM: case ARRAY: case MAP: @@ -520,11 +516,6 @@ private int bestBranch(Schema r, Schema w, Map seen, boolean useFq } break; case LONG: - // We can selectively demote long and check that it fits inside int range - // when reading an int from a long writer schema. - if (b.getType() == Schema.Type.INT) { - return j; - } case FLOAT: switch (b.getType()) { case DOUBLE: diff --git a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/parsing/Symbol.java b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/parsing/Symbol.java index d75392019..5be985f91 100644 --- a/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/parsing/Symbol.java +++ b/helper/impls/helper-impl-18/src/main/java/com/linkedin/avroutil1/compatibility/avro18/parsing/Symbol.java @@ -573,10 +573,6 @@ public static final class FieldOrderAction extends ImplicitAction { } } - public static class IntLongAdjustAction extends ImplicitAction { - public static final IntLongAdjustAction INSTANCE = new IntLongAdjustAction(); - } - public static DefaultStartAction defaultStartAction(byte[] contents) { return new DefaultStartAction(contents); } diff --git a/helper/impls/helper-impl-18/src/main/java/org/apache/avro/generic/Avro18GenericDataAccessUtil.java b/helper/impls/helper-impl-18/src/main/java/org/apache/avro/generic/Avro18GenericDataAccessUtil.java index b50f4b51f..0ec6d221e 100644 --- a/helper/impls/helper-impl-18/src/main/java/org/apache/avro/generic/Avro18GenericDataAccessUtil.java +++ b/helper/impls/helper-impl-18/src/main/java/org/apache/avro/generic/Avro18GenericDataAccessUtil.java @@ -10,7 +10,9 @@ /** * this class exists to allow us access to package-private classes and methods on class {@link GenericData} + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class Avro18GenericDataAccessUtil { private Avro18GenericDataAccessUtil() { } diff --git a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/Avro19Adapter.java b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/Avro19Adapter.java index 45b8bebca..0af84ff78 100644 --- a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/Avro19Adapter.java +++ b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/Avro19Adapter.java @@ -24,8 +24,6 @@ import com.linkedin.avroutil1.compatibility.SkipDecoder; import com.linkedin.avroutil1.compatibility.StringRepresentation; import com.linkedin.avroutil1.compatibility.avro19.backports.Avro19DefaultValuesCache; -import com.linkedin.avroutil1.compatibility.avro19.backports.GenericDatumReaderExt; -import com.linkedin.avroutil1.compatibility.avro19.backports.SpecificDatumReaderExt; import com.linkedin.avroutil1.compatibility.avro19.codec.AliasAwareSpecificDatumReader; import com.linkedin.avroutil1.compatibility.avro19.codec.BoundedMemoryDecoder; import com.linkedin.avroutil1.compatibility.avro19.codec.CachedResolvingDecoder; @@ -40,6 +38,7 @@ import org.apache.avro.Schema; import org.apache.avro.SchemaNormalization; import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericDatumReader; import org.apache.avro.generic.GenericDatumWriter; import org.apache.avro.io.Avro19BinaryDecoderAccessUtil; import org.apache.avro.io.BinaryDecoder; @@ -243,7 +242,7 @@ public DatumWriter newGenericDatumWriter(Schema writer, GenericData genericDa @Override public DatumReader newGenericDatumReader(Schema writer, Schema reader, GenericData genericData) { - return new GenericDatumReaderExt<>(writer, reader, genericData); + return new GenericDatumReader<>(writer, reader, genericData); } @Override @@ -253,7 +252,7 @@ public DatumWriter newSpecificDatumWriter(Schema writer, SpecificData specifi @Override public DatumReader newSpecificDatumReader(Schema writer, Schema reader, SpecificData specificData) { - return new SpecificDatumReaderExt<>(writer, reader, specificData); + return new SpecificDatumReader<>(writer, reader, specificData); } @Override diff --git a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/backports/GenericDatumReaderExt.java b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/backports/GenericDatumReaderExt.java index 06d714f1c..7c72f48d8 100644 --- a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/backports/GenericDatumReaderExt.java +++ b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/backports/GenericDatumReaderExt.java @@ -24,7 +24,9 @@ * a specified {@link GenericData} instance under avro 1.9 * * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class GenericDatumReaderExt extends GenericDatumReader { public GenericDatumReaderExt(Schema writer, Schema reader, GenericData genericData) { diff --git a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/backports/SpecificDatumReaderExt.java b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/backports/SpecificDatumReaderExt.java index eee2f73f7..61414975a 100644 --- a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/backports/SpecificDatumReaderExt.java +++ b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/backports/SpecificDatumReaderExt.java @@ -27,7 +27,9 @@ * a specified {@link SpecificData} instance under avro 1.9. * * @param + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class SpecificDatumReaderExt extends SpecificDatumReader { public SpecificDatumReaderExt(Schema writer, Schema reader, SpecificData specificData) { diff --git a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/AliasAwareSpecificDatumReader.java b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/AliasAwareSpecificDatumReader.java index d7a7ff9a0..35539178d 100644 --- a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/AliasAwareSpecificDatumReader.java +++ b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/AliasAwareSpecificDatumReader.java @@ -6,7 +6,6 @@ package com.linkedin.avroutil1.compatibility.avro19.codec; -import com.linkedin.avroutil1.compatibility.avro19.backports.SpecificDatumReaderExt; import org.apache.avro.Schema; import org.apache.avro.specific.SpecificData; import org.apache.avro.specific.SpecificDatumReader; @@ -21,7 +20,7 @@ * * @param */ -public class AliasAwareSpecificDatumReader extends SpecificDatumReaderExt { +public class AliasAwareSpecificDatumReader extends SpecificDatumReader { public AliasAwareSpecificDatumReader() { this(null, null); @@ -41,12 +40,10 @@ public AliasAwareSpecificDatumReader(Schema writer, Schema reader) { } public AliasAwareSpecificDatumReader(Schema writer, Schema reader, SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } protected AliasAwareSpecificDatumReader(SpecificData data) { - super(null, null, data); throw new UnsupportedOperationException("providing custom SpecificData not supported (yet?)"); } } diff --git a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/CachedResolvingDecoder.java b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/CachedResolvingDecoder.java index 2665a56af..7564fd3fc 100644 --- a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/CachedResolvingDecoder.java +++ b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/CachedResolvingDecoder.java @@ -10,7 +10,6 @@ import com.linkedin.avroutil1.compatibility.avro19.parsing.Symbol; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; - import org.apache.avro.Schema; import org.apache.avro.io.BinaryDecoder; import org.apache.avro.io.Decoder; diff --git a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/ResolvingDecoder.java b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/ResolvingDecoder.java index 0276a5bfa..a4292fbd6 100644 --- a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/ResolvingDecoder.java +++ b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/codec/ResolvingDecoder.java @@ -24,13 +24,12 @@ package com.linkedin.avroutil1.compatibility.avro19.codec; +import com.linkedin.avroutil1.compatibility.CustomDecoder; import com.linkedin.avroutil1.compatibility.avro19.parsing.ResolvingGrammarGenerator; import com.linkedin.avroutil1.compatibility.avro19.parsing.Symbol; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; - -import com.linkedin.avroutil1.compatibility.CustomDecoder; import org.apache.avro.AvroTypeException; import org.apache.avro.Schema; import org.apache.avro.io.Decoder; @@ -154,23 +153,6 @@ public final void drain() throws IOException { parser.processImplicitActions(); } - @Override - public int readInt() throws IOException { - Symbol actual = parser.advance(Symbol.INT); - if (actual == Symbol.INT) { - return in.readInt(); - } else if (actual == Symbol.IntLongAdjustAction.INSTANCE) { - long value = in.readLong(); - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new AvroTypeException(value + " cannot be represented as int"); - } - - return (int) value; - } - - throw new AvroTypeException("Expected int but found " + actual); - } - @Override public long readLong() throws IOException { Symbol actual = parser.advance(Symbol.LONG); @@ -326,8 +308,6 @@ public Symbol doAction(Symbol input, Symbol top) throws IOException { in = DecoderFactory.get().binaryDecoder(dsa.contents, null); } else if (top == Symbol.DEFAULT_END_ACTION) { in = backup; - } else if (top == Symbol.IntLongAdjustAction.INSTANCE) { - return top; } else { throw new AvroTypeException("Unknown action: " + top); } diff --git a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/parsing/ResolvingGrammarGenerator.java b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/parsing/ResolvingGrammarGenerator.java index efb37e6ef..3d13aa075 100644 --- a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/parsing/ResolvingGrammarGenerator.java +++ b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/parsing/ResolvingGrammarGenerator.java @@ -82,11 +82,6 @@ private Symbol generate(Resolver.Action action, Map seen, boolea return simpleGen(action.writer, seen, useFqcns); } else if (action instanceof Resolver.ErrorAction) { - // We should be able to selectively demote long to int if it fits within the range of int. - if (isLongToIntDemotion((Resolver.ErrorAction) action, false)) { - return Symbol.IntLongAdjustAction.INSTANCE; - } - return Symbol.error(action.toString()); } else if (action instanceof Resolver.Skip) { @@ -97,16 +92,6 @@ private Symbol generate(Resolver.Action action, Map seen, boolea } else if (action instanceof Resolver.ReaderUnion) { Resolver.ReaderUnion ru = (Resolver.ReaderUnion) action; - - // Check if we need to handle selective long-to-int demotion within unions. - if (ru.actualAction instanceof Resolver.ErrorAction) { - if (isLongToIntDemotion((Resolver.ErrorAction) ru.actualAction, true)) { - return Symbol.seq( - Symbol.unionAdjustAction(ru.firstMatch, Symbol.IntLongAdjustAction.INSTANCE), - Symbol.UNION); - } - } - Symbol s = generate(ru.actualAction, seen, useFqcns); return Symbol.seq(Symbol.unionAdjustAction(ru.firstMatch, s), Symbol.UNION); @@ -122,25 +107,17 @@ private Symbol generate(Resolver.Action action, Map seen, boolea if (((Resolver.WriterUnion) action).unionEquiv) { return simpleGen(action.writer, seen, useFqcns); } - Resolver.WriterUnion wu = (Resolver.WriterUnion) action; - Resolver.Action[] branches = wu.actions; + Resolver.Action[] branches = ((Resolver.WriterUnion) action).actions; Symbol[] symbols = new Symbol[branches.length]; String[] oldLabels = new String[branches.length]; String[] newLabels = new String[branches.length]; - - for (int i = 0; i < branches.length; i++) { - // Check if this branch needs long-to-int conversion - if (branches[i] instanceof Resolver.ErrorAction && isLongToIntDemotion((Resolver.ErrorAction) branches[i], true)) { - symbols[i] = Symbol.seq( - Symbol.unionAdjustAction(i, Symbol.IntLongAdjustAction.INSTANCE), - Symbol.UNION); - } else { - symbols[i] = generate(branches[i], seen, useFqcns); - } - + int i = 0; + for (Resolver.Action branch : branches) { + symbols[i] = generate(branch, seen, useFqcns); Schema schema = action.writer.getTypes().get(i); oldLabels[i] = schema.getName(); newLabels[i] = schema.getFullName(); + i++; } return Symbol.seq(Symbol.alt(symbols, oldLabels, newLabels, useFqcns), Symbol.WRITER_UNION_ACTION); } else if (action instanceof Resolver.EnumAdjust) { @@ -375,39 +352,6 @@ public static void encode(Encoder e, Schema s, JsonNode n) throws IOException { } } - private static boolean isLongToIntDemotion(Resolver.ErrorAction errorAction, boolean includeIntUnions) { - return isInt(errorAction.reader, includeIntUnions) - && errorAction.writer.getType() == Schema.Type.LONG - && isLongToIntDemotionError(errorAction, includeIntUnions); - } - - private static boolean isLongToIntDemotionError(Resolver.ErrorAction errorAction, boolean includeIntUnions) { - if (errorAction.error == Resolver.ErrorAction.ErrorType.INCOMPATIBLE_SCHEMA_TYPES) { - return true; - } - - return includeIntUnions && errorAction.error == Resolver.ErrorAction.ErrorType.NO_MATCHING_BRANCH; - } - - private static boolean isInt(Schema schema, boolean includeIntUnions) { - if (schema.getType() == Schema.Type.INT) { - return true; - } - - if (!includeIntUnions) { - return false; - } - - if (schema.getType() != Schema.Type.UNION) { - return false; - } - - List types = schema.getTypes(); - return (types.size() == 2 - && types.get(0).getType() == Schema.Type.NULL - && types.get(1).getType() == Schema.Type.INT); - } - /** * Clever trick which differentiates items put into * seen by {@link ValidatingGrammarGenerator validating()} diff --git a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/parsing/Symbol.java b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/parsing/Symbol.java index 4b8bbd4c2..ff50d07d8 100644 --- a/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/parsing/Symbol.java +++ b/helper/impls/helper-impl-19/src/main/java/com/linkedin/avroutil1/compatibility/avro19/parsing/Symbol.java @@ -633,10 +633,6 @@ public FieldOrderAction(Schema.Field[] fields) { } } - public static class IntLongAdjustAction extends ImplicitAction { - public static final IntLongAdjustAction INSTANCE = new IntLongAdjustAction(); - } - public static DefaultStartAction defaultStartAction(byte[] contents) { return new DefaultStartAction(contents); } diff --git a/helper/impls/helper-impl-19/src/main/java/org/apache/avro/generic/Avro19GenericDataAccessUtil.java b/helper/impls/helper-impl-19/src/main/java/org/apache/avro/generic/Avro19GenericDataAccessUtil.java index 9b486ecf8..7fbadae8b 100644 --- a/helper/impls/helper-impl-19/src/main/java/org/apache/avro/generic/Avro19GenericDataAccessUtil.java +++ b/helper/impls/helper-impl-19/src/main/java/org/apache/avro/generic/Avro19GenericDataAccessUtil.java @@ -10,7 +10,9 @@ /** * this class exists to allow us access to package-private classes and methods on class {@link GenericData} + * @deprecated DO NOT USE. This class was added to support long to int type demotion and is no longer needed. */ +@Deprecated public class Avro19GenericDataAccessUtil { private Avro19GenericDataAccessUtil() { } diff --git a/helper/tests/helper-tests-110/src/test/java/com/linkedin/avroutil1/compatibility/avro110/AvroCompatibilityHelperAvro110Test.java b/helper/tests/helper-tests-110/src/test/java/com/linkedin/avroutil1/compatibility/avro110/AvroCompatibilityHelperAvro110Test.java index 7d4150a20..b5226fb3a 100644 --- a/helper/tests/helper-tests-110/src/test/java/com/linkedin/avroutil1/compatibility/avro110/AvroCompatibilityHelperAvro110Test.java +++ b/helper/tests/helper-tests-110/src/test/java/com/linkedin/avroutil1/compatibility/avro110/AvroCompatibilityHelperAvro110Test.java @@ -6,33 +6,15 @@ package com.linkedin.avroutil1.compatibility.avro110; -import by110.IntRecord; -import by110.LongRecord; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.linkedin.avroutil1.Pojo; import com.linkedin.avroutil1.testcommon.TestUtil; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroVersion; - -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; import java.util.Map; - -import org.apache.avro.AvroTypeException; import org.apache.avro.JsonProperties; import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.BinaryDecoder; -import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; -import org.apache.avro.specific.SpecificData; -import org.apache.avro.specific.SpecificRecord; -import org.apache.avro.util.Utf8; import org.mockito.Mockito; import org.testng.Assert; import org.testng.annotations.Test; @@ -92,180 +74,4 @@ public void testCreateSchemaFieldWithProvidedDefaultValue() throws IOException { (List>) AvroCompatibilityHelper.createSchemaField("arrayOfArrayWithDefault", field.schema(), "", field.defaultVal()).defaultVal(); Assert.assertEquals(actualListValue.get(0).get(0), "dummyElement"); } - - @Test - public void testIntRoundtrip() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - IntRecord roundtrip = toSpecificRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(roundtrip.getField(), 42); - Assert.assertEquals(roundtrip.getUnionField().intValue(), 55); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongRoundtrip() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - LongRecord roundtrip = toSpecificRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(roundtrip.getField(), 42L); - Assert.assertEquals(roundtrip.getUnionField().longValue(), 55L); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testIntToLongPromotion() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - LongRecord longRecord = toSpecificRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(longRecord.getField(), 42L); - Assert.assertEquals(longRecord.getUnionField().longValue(), 55L); - Assert.assertEquals(longRecord.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(longRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(longRecord.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(longRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testLongToIntDemotion() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - IntRecord intRecord = toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(intRecord.getField(), 42); - Assert.assertEquals(intRecord.getUnionField().intValue(), 55); - Assert.assertEquals(intRecord.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(intRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(intRecord.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(intRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongToIntDemotionOutOfRange() throws IOException { - LongRecord longRecord = LongRecord.newBuilder().setField((long) Integer.MAX_VALUE + 1L).build(); - byte[] binary = toBinary(longRecord); - - LongRecord longRecord2 = LongRecord.newBuilder().setField(0L).setUnionField((long) Integer.MIN_VALUE - 1L).build(); - byte[] binary2 = toBinary(longRecord2); - - LongRecord longRecord3 = LongRecord.newBuilder().setField(0L).setArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary3 = toBinary(longRecord3); - - LongRecord longRecord4 = LongRecord.newBuilder().setField(0L).setMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary4 = toBinary(longRecord4); - - LongRecord longRecord5 = LongRecord.newBuilder().setField(0L).setUnionArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary5 = toBinary(longRecord5); - - LongRecord longRecord6 = LongRecord.newBuilder().setField(0L).setUnionMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary6 = toBinary(longRecord6); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - } - - private byte[] toBinary(IndexedRecord record) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryEncoder encoder = AvroCompatibilityHelper.newBinaryEncoder(baos); - GenericDatumWriter writer = new GenericDatumWriter<>(record.getSchema()); - writer.write(record, encoder); - encoder.flush(); - return baos.toByteArray(); - } - - private T toSpecificRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newSpecificDatumReader(writerSchema, readerSchema, SpecificData.get()); - return reader.read(null, decoder); - } - - private GenericRecord toGenericRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newGenericDatumReader(writerSchema, readerSchema, GenericData.get()); - return reader.read(null, decoder); - } } diff --git a/helper/tests/helper-tests-111/src/test/java/com/linkedin/avroutil1/compatibility/avro111/AvroCompatibilityHelperAvro111Test.java b/helper/tests/helper-tests-111/src/test/java/com/linkedin/avroutil1/compatibility/avro111/AvroCompatibilityHelperAvro111Test.java index 42b925547..e539da7ab 100644 --- a/helper/tests/helper-tests-111/src/test/java/com/linkedin/avroutil1/compatibility/avro111/AvroCompatibilityHelperAvro111Test.java +++ b/helper/tests/helper-tests-111/src/test/java/com/linkedin/avroutil1/compatibility/avro111/AvroCompatibilityHelperAvro111Test.java @@ -6,30 +6,11 @@ package com.linkedin.avroutil1.compatibility.avro111; -import by111.IntRecord; -import by111.LongRecord; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroVersion; -import org.apache.avro.AvroTypeException; -import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.BinaryDecoder; -import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; -import org.apache.avro.specific.SpecificData; -import org.apache.avro.specific.SpecificRecord; -import org.apache.avro.util.Utf8; import org.testng.Assert; import org.testng.annotations.Test; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - public class AvroCompatibilityHelperAvro111Test { @@ -46,180 +27,4 @@ public void testAvroCompilerVersionDetection() { AvroVersion detected = AvroCompatibilityHelper.getRuntimeAvroCompilerVersion(); Assert.assertEquals(detected, expected, "expected " + expected + ", got " + detected); } - - @Test - public void testIntRoundtrip() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - IntRecord roundtrip = toSpecificRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(roundtrip.getField(), 42); - Assert.assertEquals(roundtrip.getUnionField().intValue(), 55); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongRoundtrip() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - LongRecord roundtrip = toSpecificRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(roundtrip.getField(), 42L); - Assert.assertEquals(roundtrip.getUnionField().longValue(), 55L); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testIntToLongPromotion() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - LongRecord longRecord = toSpecificRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(longRecord.getField(), 42L); - Assert.assertEquals(longRecord.getUnionField().longValue(), 55L); - Assert.assertEquals(longRecord.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(longRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(longRecord.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(longRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testLongToIntDemotion() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - IntRecord intRecord = toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(intRecord.getField(), 42); - Assert.assertEquals(intRecord.getUnionField().intValue(), 55); - Assert.assertEquals(intRecord.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(intRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(intRecord.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(intRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongToIntDemotionOutOfRange() throws IOException { - LongRecord longRecord = LongRecord.newBuilder().setField((long) Integer.MAX_VALUE + 1L).build(); - byte[] binary = toBinary(longRecord); - - LongRecord longRecord2 = LongRecord.newBuilder().setField(0L).setUnionField((long) Integer.MIN_VALUE - 1L).build(); - byte[] binary2 = toBinary(longRecord2); - - LongRecord longRecord3 = LongRecord.newBuilder().setField(0L).setArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary3 = toBinary(longRecord3); - - LongRecord longRecord4 = LongRecord.newBuilder().setField(0L).setMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary4 = toBinary(longRecord4); - - LongRecord longRecord5 = LongRecord.newBuilder().setField(0L).setUnionArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary5 = toBinary(longRecord5); - - LongRecord longRecord6 = LongRecord.newBuilder().setField(0L).setUnionMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary6 = toBinary(longRecord6); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - } - - private byte[] toBinary(IndexedRecord record) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryEncoder encoder = AvroCompatibilityHelper.newBinaryEncoder(baos); - GenericDatumWriter writer = new GenericDatumWriter<>(record.getSchema()); - writer.write(record, encoder); - encoder.flush(); - return baos.toByteArray(); - } - - private T toSpecificRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newSpecificDatumReader(writerSchema, readerSchema, SpecificData.get()); - return reader.read(null, decoder); - } - - private GenericRecord toGenericRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newGenericDatumReader(writerSchema, readerSchema, GenericData.get()); - return reader.read(null, decoder); - } } diff --git a/helper/tests/helper-tests-111_0/src/test/java/com.linkedin.avroutil1.compatibility.avro111/AvroCompatibilityHelperAvro1110Test.java b/helper/tests/helper-tests-111_0/src/test/java/com.linkedin.avroutil1.compatibility.avro111/AvroCompatibilityHelperAvro1110Test.java index 4866a59f7..23addc6d6 100644 --- a/helper/tests/helper-tests-111_0/src/test/java/com.linkedin.avroutil1.compatibility.avro111/AvroCompatibilityHelperAvro1110Test.java +++ b/helper/tests/helper-tests-111_0/src/test/java/com.linkedin.avroutil1.compatibility.avro111/AvroCompatibilityHelperAvro1110Test.java @@ -6,30 +6,11 @@ package com.linkedin.avroutil1.compatibility.avro111; -import by111.IntRecord; -import by111.LongRecord; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroVersion; -import org.apache.avro.AvroTypeException; -import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.BinaryDecoder; -import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; -import org.apache.avro.specific.SpecificData; -import org.apache.avro.specific.SpecificRecord; -import org.apache.avro.util.Utf8; import org.testng.Assert; import org.testng.annotations.Test; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - // Tests version detection against Avro 1.11.0 public class AvroCompatibilityHelperAvro1110Test { @@ -47,180 +28,4 @@ public void testAvroCompilerVersionDetection() { AvroVersion detected = AvroCompatibilityHelper.getRuntimeAvroCompilerVersion(); Assert.assertEquals(detected, expected, "expected " + expected + ", got " + detected); } - - @Test - public void testIntRoundtrip() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - IntRecord roundtrip = toSpecificRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(roundtrip.getField(), 42); - Assert.assertEquals(roundtrip.getUnionField().intValue(), 55); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongRoundtrip() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - LongRecord roundtrip = toSpecificRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(roundtrip.getField(), 42L); - Assert.assertEquals(roundtrip.getUnionField().longValue(), 55L); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testIntToLongPromotion() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - LongRecord longRecord = toSpecificRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(longRecord.getField(), 42L); - Assert.assertEquals(longRecord.getUnionField().longValue(), 55L); - Assert.assertEquals(longRecord.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(longRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(longRecord.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(longRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testLongToIntDemotion() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - IntRecord intRecord = toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(intRecord.getField(), 42); - Assert.assertEquals(intRecord.getUnionField().intValue(), 55); - Assert.assertEquals(intRecord.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(intRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(intRecord.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(intRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongToIntDemotionOutOfRange() throws IOException { - LongRecord longRecord = LongRecord.newBuilder().setField((long) Integer.MAX_VALUE + 1L).build(); - byte[] binary = toBinary(longRecord); - - LongRecord longRecord2 = LongRecord.newBuilder().setField(0L).setUnionField((long) Integer.MIN_VALUE - 1L).build(); - byte[] binary2 = toBinary(longRecord2); - - LongRecord longRecord3 = LongRecord.newBuilder().setField(0L).setArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary3 = toBinary(longRecord3); - - LongRecord longRecord4 = LongRecord.newBuilder().setField(0L).setMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary4 = toBinary(longRecord4); - - LongRecord longRecord5 = LongRecord.newBuilder().setField(0L).setUnionArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary5 = toBinary(longRecord5); - - LongRecord longRecord6 = LongRecord.newBuilder().setField(0L).setUnionMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary6 = toBinary(longRecord6); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - } - - private byte[] toBinary(IndexedRecord record) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryEncoder encoder = AvroCompatibilityHelper.newBinaryEncoder(baos); - GenericDatumWriter writer = new GenericDatumWriter<>(record.getSchema()); - writer.write(record, encoder); - encoder.flush(); - return baos.toByteArray(); - } - - private T toSpecificRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newSpecificDatumReader(writerSchema, readerSchema, SpecificData.get()); - return reader.read(null, decoder); - } - - private GenericRecord toGenericRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newGenericDatumReader(writerSchema, readerSchema, GenericData.get()); - return reader.read(null, decoder); - } } \ No newline at end of file diff --git a/helper/tests/helper-tests-14/src/test/java/com/linkedin/avroutil1/compatibility/avro14/AvroCompatibilityHelperAvro14Test.java b/helper/tests/helper-tests-14/src/test/java/com/linkedin/avroutil1/compatibility/avro14/AvroCompatibilityHelperAvro14Test.java index 41a6ffe2e..0d6124ada 100644 --- a/helper/tests/helper-tests-14/src/test/java/com/linkedin/avroutil1/compatibility/avro14/AvroCompatibilityHelperAvro14Test.java +++ b/helper/tests/helper-tests-14/src/test/java/com/linkedin/avroutil1/compatibility/avro14/AvroCompatibilityHelperAvro14Test.java @@ -6,33 +6,15 @@ package com.linkedin.avroutil1.compatibility.avro14; -import by14.IntRecord; -import by14.LongRecord; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.linkedin.avroutil1.Pojo; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroVersion; import com.linkedin.avroutil1.testcommon.TestUtil; - -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; - -import org.apache.avro.AvroTypeException; import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.BinaryDecoder; -import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; -import org.apache.avro.specific.SpecificRecord; -import org.apache.avro.util.Utf8; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; @@ -97,197 +79,4 @@ public void testCreateSchemaFieldWithProvidedDefaultValue() throws IOException { List> actualListValue = mapper.convertValue(actualJsonNode, new TypeReference>>(){}); Assert.assertEquals(actualListValue.get(0).get(0), "dummyElement"); } - - @Test - public void testIntRoundtrip() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.field = 42; - intRecord.unionField = 55; - intRecord.arrayField = ImmutableList.of(100, -200); - intRecord.mapField = ImmutableMap.of("key1", 300, "key2", -400); - intRecord.unionArrayField = ImmutableList.of(99, -199); - intRecord.unionMapField = ImmutableMap.of("key1", 298, "key2", 355); - byte[] binary = toBinary(intRecord); - - IntRecord roundtrip = toSpecificRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(roundtrip.field, 42); - Assert.assertEquals(roundtrip.unionField.intValue(), 55); - Assert.assertEquals(roundtrip.arrayField, ImmutableList.of(100, -200)); - Assert.assertEquals(roundtrip.mapField, ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(roundtrip.unionArrayField, ImmutableList.of(99, -199)); - Assert.assertEquals(roundtrip.unionMapField, ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("arrayField")), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("unionArrayField")), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongRoundtrip() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.field = 42L; - longRecord.unionField = 55L; - longRecord.arrayField = ImmutableList.of(100L, -200L); - longRecord.mapField = ImmutableMap.of("key1", 300L, "key2", -400L); - longRecord.unionArrayField = ImmutableList.of(99L, -199L); - longRecord.unionMapField = ImmutableMap.of("key1", 298L, "key2", 355L); - byte[] binary = toBinary(longRecord); - - LongRecord roundtrip = toSpecificRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(roundtrip.field, 42L); - Assert.assertEquals(roundtrip.unionField.longValue(), 55L); - Assert.assertEquals(roundtrip.arrayField, ImmutableList.of(100L, -200L)); - Assert.assertEquals(roundtrip.mapField, ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(roundtrip.unionArrayField, ImmutableList.of(99L, -199L)); - Assert.assertEquals(roundtrip.unionMapField, ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("arrayField")), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("unionArrayField")), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testIntToLongPromotion() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.field = 42; - intRecord.unionField = 55; - intRecord.arrayField = ImmutableList.of(100, -200); - intRecord.mapField = ImmutableMap.of("key1", 300, "key2", -400); - intRecord.unionArrayField = ImmutableList.of(99, -199); - intRecord.unionMapField = ImmutableMap.of("key1", 298, "key2", 355); - byte[] binary = toBinary(intRecord); - - LongRecord longRecord = toSpecificRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(longRecord.field, 42L); - Assert.assertEquals(longRecord.unionField.longValue(), 55L); - Assert.assertEquals(longRecord.arrayField, ImmutableList.of(100L, -200L)); - Assert.assertEquals(longRecord.mapField, ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(longRecord.unionArrayField, ImmutableList.of(99L, -199L)); - Assert.assertEquals(longRecord.unionMapField, ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("arrayField")), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("unionArrayField")), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testLongToIntDemotion() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.field = 42L; - longRecord.unionField = 55L; - longRecord.arrayField = ImmutableList.of(100L, -200L); - longRecord.mapField = ImmutableMap.of("key1", 300L, "key2", -400L); - longRecord.unionArrayField = ImmutableList.of(99L, -199L); - longRecord.unionMapField = ImmutableMap.of("key1", 298L, "key2", 355L); - byte[] binary = toBinary(longRecord); - - IntRecord intRecord = toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(intRecord.field, 42); - Assert.assertEquals(intRecord.unionField.intValue(), 55); - Assert.assertEquals(intRecord.arrayField, ImmutableList.of(100, -200)); - Assert.assertEquals(intRecord.mapField, ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(intRecord.unionArrayField, ImmutableList.of(99, -199)); - Assert.assertEquals(intRecord.unionMapField, ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("arrayField")), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("unionArrayField")), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongToIntDemotionOutOfRange() throws IOException { - LongRecord longRecord = newLongRecord(); - longRecord.field = (long) Integer.MAX_VALUE + 1L; - byte[] binary = toBinary(longRecord); - - LongRecord longRecord2 = newLongRecord(); - longRecord2.unionField = (long) Integer.MIN_VALUE - 1L; - byte[] binary2 = toBinary(longRecord2); - - LongRecord longRecord3 = newLongRecord(); - longRecord3.arrayField = ImmutableList.of((long) Integer.MAX_VALUE + 1L); - byte[] binary3 = toBinary(longRecord3); - - LongRecord longRecord4 = newLongRecord(); - longRecord4.mapField = ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L); - byte[] binary4 = toBinary(longRecord4); - - LongRecord longRecord5 = newLongRecord(); - longRecord5.unionArrayField = ImmutableList.of((long) Integer.MAX_VALUE + 1L); - byte[] binary5 = toBinary(longRecord5); - - LongRecord longRecord6 = newLongRecord(); - longRecord6.unionMapField = ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L); - byte[] binary6 = toBinary(longRecord6); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - } - - private LongRecord newLongRecord() { - LongRecord longRecord = new LongRecord(); - longRecord.field = 0L; - longRecord.unionField = 0L; - longRecord.arrayField = ImmutableList.of(); - longRecord.mapField = ImmutableMap.of(); - longRecord.unionArrayField = ImmutableList.of(); - longRecord.unionMapField = ImmutableMap.of(); - return longRecord; - } - - private byte[] toBinary(IndexedRecord record) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryEncoder encoder = AvroCompatibilityHelper.newBinaryEncoder(baos); - GenericDatumWriter writer = new GenericDatumWriter<>(record.getSchema()); - writer.write(record, encoder); - encoder.flush(); - return baos.toByteArray(); - } - - private T toSpecificRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newSpecificDatumReader(writerSchema, readerSchema, null); - return reader.read(null, decoder); - } - - private GenericRecord toGenericRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newGenericDatumReader(writerSchema, readerSchema, null); - return reader.read(null, decoder); - } } diff --git a/helper/tests/helper-tests-15/src/test/java/com/linkedin/avroutil1/compatibility/avro15/AvroCompatibilityHelperAvro15Test.java b/helper/tests/helper-tests-15/src/test/java/com/linkedin/avroutil1/compatibility/avro15/AvroCompatibilityHelperAvro15Test.java index be3f0b395..585a4ad66 100644 --- a/helper/tests/helper-tests-15/src/test/java/com/linkedin/avroutil1/compatibility/avro15/AvroCompatibilityHelperAvro15Test.java +++ b/helper/tests/helper-tests-15/src/test/java/com/linkedin/avroutil1/compatibility/avro15/AvroCompatibilityHelperAvro15Test.java @@ -6,33 +6,15 @@ package com.linkedin.avroutil1.compatibility.avro15; -import by15.IntRecord; -import by15.LongRecord; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import org.apache.avro.AvroTypeException; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.BinaryDecoder; -import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; -import org.apache.avro.specific.SpecificData; -import org.apache.avro.specific.SpecificRecord; import com.linkedin.avroutil1.Pojo; import com.linkedin.avroutil1.testcommon.TestUtil; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroVersion; - -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.avro.Schema; -import org.apache.avro.util.Utf8; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; @@ -98,197 +80,4 @@ public void testCreateSchemaFieldWithProvidedDefaultValue() throws IOException { List> actualListValue = mapper.convertValue(actualJsonNode, new TypeReference>>(){}); Assert.assertEquals(actualListValue.get(0).get(0), "dummyElement"); } - - @Test - public void testIntRoundtrip() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.field = 42; - intRecord.unionField = 55; - intRecord.arrayField = ImmutableList.of(100, -200); - intRecord.mapField = ImmutableMap.of("key1", 300, "key2", -400); - intRecord.unionArrayField = ImmutableList.of(99, -199); - intRecord.unionMapField = ImmutableMap.of("key1", 298, "key2", 355); - byte[] binary = toBinary(intRecord); - - IntRecord roundtrip = toSpecificRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(roundtrip.field, 42); - Assert.assertEquals(roundtrip.unionField.intValue(), 55); - Assert.assertEquals(roundtrip.arrayField, ImmutableList.of(100, -200)); - Assert.assertEquals(roundtrip.mapField, ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(roundtrip.unionArrayField, ImmutableList.of(99, -199)); - Assert.assertEquals(roundtrip.unionMapField, ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("arrayField")), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("unionArrayField")), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongRoundtrip() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.field = 42L; - longRecord.unionField = 55L; - longRecord.arrayField = ImmutableList.of(100L, -200L); - longRecord.mapField = ImmutableMap.of("key1", 300L, "key2", -400L); - longRecord.unionArrayField = ImmutableList.of(99L, -199L); - longRecord.unionMapField = ImmutableMap.of("key1", 298L, "key2", 355L); - byte[] binary = toBinary(longRecord); - - LongRecord roundtrip = toSpecificRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(roundtrip.field, 42L); - Assert.assertEquals(roundtrip.unionField.longValue(), 55L); - Assert.assertEquals(roundtrip.arrayField, ImmutableList.of(100L, -200L)); - Assert.assertEquals(roundtrip.mapField, ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(roundtrip.unionArrayField, ImmutableList.of(99L, -199L)); - Assert.assertEquals(roundtrip.unionMapField, ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("arrayField")), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("unionArrayField")), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testIntToLongPromotion() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.field = 42; - intRecord.unionField = 55; - intRecord.arrayField = ImmutableList.of(100, -200); - intRecord.mapField = ImmutableMap.of("key1", 300, "key2", -400); - intRecord.unionArrayField = ImmutableList.of(99, -199); - intRecord.unionMapField = ImmutableMap.of("key1", 298, "key2", 355); - byte[] binary = toBinary(intRecord); - - LongRecord longRecord = toSpecificRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(longRecord.field, 42L); - Assert.assertEquals(longRecord.unionField.longValue(), 55L); - Assert.assertEquals(longRecord.arrayField, ImmutableList.of(100L, -200L)); - Assert.assertEquals(longRecord.mapField, ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(longRecord.unionArrayField, ImmutableList.of(99L, -199L)); - Assert.assertEquals(longRecord.unionMapField, ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("arrayField")), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("unionArrayField")), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testLongToIntDemotion() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.field = 42L; - longRecord.unionField = 55L; - longRecord.arrayField = ImmutableList.of(100L, -200L); - longRecord.mapField = ImmutableMap.of("key1", 300L, "key2", -400L); - longRecord.unionArrayField = ImmutableList.of(99L, -199L); - longRecord.unionMapField = ImmutableMap.of("key1", 298L, "key2", 355L); - byte[] binary = toBinary(longRecord); - - IntRecord intRecord = toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(intRecord.field, 42); - Assert.assertEquals(intRecord.unionField.intValue(), 55); - Assert.assertEquals(intRecord.arrayField, ImmutableList.of(100, -200)); - Assert.assertEquals(intRecord.mapField, ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(intRecord.unionArrayField, ImmutableList.of(99, -199)); - Assert.assertEquals(intRecord.unionMapField, ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("arrayField")), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(new ArrayList<>((GenericData.Array) genericRecord.get("unionArrayField")), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongToIntDemotionOutOfRange() throws IOException { - LongRecord longRecord = newLongRecord(); - longRecord.field = (long) Integer.MAX_VALUE + 1L; - byte[] binary = toBinary(longRecord); - - LongRecord longRecord2 = newLongRecord(); - longRecord2.unionField = (long) Integer.MIN_VALUE - 1L; - byte[] binary2 = toBinary(longRecord2); - - LongRecord longRecord3 = newLongRecord(); - longRecord3.arrayField = ImmutableList.of((long) Integer.MAX_VALUE + 1L); - byte[] binary3 = toBinary(longRecord3); - - LongRecord longRecord4 = newLongRecord(); - longRecord4.mapField = ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L); - byte[] binary4 = toBinary(longRecord4); - - LongRecord longRecord5 = newLongRecord(); - longRecord5.unionArrayField = ImmutableList.of((long) Integer.MAX_VALUE + 1L); - byte[] binary5 = toBinary(longRecord5); - - LongRecord longRecord6 = newLongRecord(); - longRecord6.unionMapField = ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L); - byte[] binary6 = toBinary(longRecord6); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - } - - private LongRecord newLongRecord() { - LongRecord longRecord = new LongRecord(); - longRecord.field = 0L; - longRecord.unionField = 0L; - longRecord.arrayField = ImmutableList.of(); - longRecord.mapField = ImmutableMap.of(); - longRecord.unionArrayField = ImmutableList.of(); - longRecord.unionMapField = ImmutableMap.of(); - return longRecord; - } - - private byte[] toBinary(IndexedRecord record) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryEncoder encoder = AvroCompatibilityHelper.newBinaryEncoder(baos); - GenericDatumWriter writer = new GenericDatumWriter<>(record.getSchema()); - writer.write(record, encoder); - encoder.flush(); - return baos.toByteArray(); - } - - private T toSpecificRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newSpecificDatumReader(writerSchema, readerSchema, SpecificData.get()); - return reader.read(null, decoder); - } - - private GenericRecord toGenericRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newGenericDatumReader(writerSchema, readerSchema, GenericData.get()); - return reader.read(null, decoder); - } } diff --git a/helper/tests/helper-tests-16/src/test/java/com/linkedin/avroutil1/compatibility/avro16/AvroCompatibilityHelperAvro16Test.java b/helper/tests/helper-tests-16/src/test/java/com/linkedin/avroutil1/compatibility/avro16/AvroCompatibilityHelperAvro16Test.java index 0925c70a8..5403bce5c 100644 --- a/helper/tests/helper-tests-16/src/test/java/com/linkedin/avroutil1/compatibility/avro16/AvroCompatibilityHelperAvro16Test.java +++ b/helper/tests/helper-tests-16/src/test/java/com/linkedin/avroutil1/compatibility/avro16/AvroCompatibilityHelperAvro16Test.java @@ -6,33 +6,15 @@ package com.linkedin.avroutil1.compatibility.avro16; -import by16.IntRecord; -import by16.LongRecord; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.linkedin.avroutil1.Pojo; import com.linkedin.avroutil1.testcommon.TestUtil; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroVersion; - -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; - -import org.apache.avro.AvroTypeException; import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.BinaryDecoder; -import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; -import org.apache.avro.specific.SpecificData; -import org.apache.avro.specific.SpecificRecord; -import org.apache.avro.util.Utf8; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; @@ -98,180 +80,4 @@ public void testCreateSchemaFieldWithProvidedDefaultValue() throws IOException { List> actualListValue = mapper.convertValue(actualJsonNode, new TypeReference>>(){}); Assert.assertEquals(actualListValue.get(0).get(0), "dummyElement"); } - - @Test - public void testIntRoundtrip() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - IntRecord roundtrip = toSpecificRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals((int) roundtrip.getField(), 42); - Assert.assertEquals(roundtrip.getUnionField().intValue(), 55); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongRoundtrip() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - LongRecord roundtrip = toSpecificRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals((long) roundtrip.getField(), 42L); - Assert.assertEquals(roundtrip.getUnionField().longValue(), 55L); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testIntToLongPromotion() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - LongRecord longRecord = toSpecificRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals((long) longRecord.getField(), 42L); - Assert.assertEquals(longRecord.getUnionField().longValue(), 55L); - Assert.assertEquals(longRecord.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(longRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(longRecord.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(longRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testLongToIntDemotion() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - IntRecord intRecord = toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals((int) intRecord.getField(), 42); - Assert.assertEquals(intRecord.getUnionField().intValue(), 55); - Assert.assertEquals(intRecord.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(intRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(intRecord.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(intRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongToIntDemotionOutOfRange() throws IOException { - LongRecord longRecord = LongRecord.newBuilder().setField((long) Integer.MAX_VALUE + 1L).build(); - byte[] binary = toBinary(longRecord); - - LongRecord longRecord2 = LongRecord.newBuilder().setField(0L).setUnionField((long) Integer.MIN_VALUE - 1L).build(); - byte[] binary2 = toBinary(longRecord2); - - LongRecord longRecord3 = LongRecord.newBuilder().setField(0L).setArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary3 = toBinary(longRecord3); - - LongRecord longRecord4 = LongRecord.newBuilder().setField(0L).setMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary4 = toBinary(longRecord4); - - LongRecord longRecord5 = LongRecord.newBuilder().setField(0L).setUnionArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary5 = toBinary(longRecord5); - - LongRecord longRecord6 = LongRecord.newBuilder().setField(0L).setUnionMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary6 = toBinary(longRecord6); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - } - - private byte[] toBinary(IndexedRecord record) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryEncoder encoder = AvroCompatibilityHelper.newBinaryEncoder(baos); - GenericDatumWriter writer = new GenericDatumWriter<>(record.getSchema()); - writer.write(record, encoder); - encoder.flush(); - return baos.toByteArray(); - } - - private T toSpecificRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newSpecificDatumReader(writerSchema, readerSchema, SpecificData.get()); - return reader.read(null, decoder); - } - - private GenericRecord toGenericRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newGenericDatumReader(writerSchema, readerSchema, GenericData.get()); - return reader.read(null, decoder); - } } diff --git a/helper/tests/helper-tests-17/src/test/java/com/linkedin/avroutil1/compatibility/avro17/AvroCompatibilityHelperAvro17Test.java b/helper/tests/helper-tests-17/src/test/java/com/linkedin/avroutil1/compatibility/avro17/AvroCompatibilityHelperAvro17Test.java index b8421155e..76b208bf3 100644 --- a/helper/tests/helper-tests-17/src/test/java/com/linkedin/avroutil1/compatibility/avro17/AvroCompatibilityHelperAvro17Test.java +++ b/helper/tests/helper-tests-17/src/test/java/com/linkedin/avroutil1/compatibility/avro17/AvroCompatibilityHelperAvro17Test.java @@ -6,33 +6,15 @@ package com.linkedin.avroutil1.compatibility.avro17; -import by17.IntRecord; -import by17.LongRecord; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.linkedin.avroutil1.Pojo; import com.linkedin.avroutil1.testcommon.TestUtil; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroVersion; - -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; - -import org.apache.avro.AvroTypeException; import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.BinaryDecoder; -import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; -import org.apache.avro.specific.SpecificData; -import org.apache.avro.specific.SpecificRecord; -import org.apache.avro.util.Utf8; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; @@ -115,180 +97,4 @@ public void testGetGenericDefaultValueCloningForEnums() throws IOException { // Then we should expect the clone and original to be equal Assert.assertEquals(field, clone); } - - @Test - public void testIntRoundtrip() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - IntRecord roundtrip = toSpecificRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals((int) roundtrip.getField(), 42); - Assert.assertEquals(roundtrip.getUnionField().intValue(), 55); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongRoundtrip() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - LongRecord roundtrip = toSpecificRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals((long) roundtrip.getField(), 42L); - Assert.assertEquals(roundtrip.getUnionField().longValue(), 55L); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testIntToLongPromotion() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - LongRecord longRecord = toSpecificRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals((long) longRecord.getField(), 42L); - Assert.assertEquals(longRecord.getUnionField().longValue(), 55L); - Assert.assertEquals(longRecord.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(longRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(longRecord.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(longRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testLongToIntDemotion() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - IntRecord intRecord = toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals((int) intRecord.getField(), 42); - Assert.assertEquals(intRecord.getUnionField().intValue(), 55); - Assert.assertEquals(intRecord.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(intRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(intRecord.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(intRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongToIntDemotionOutOfRange() throws IOException { - LongRecord longRecord = LongRecord.newBuilder().setField((long) Integer.MAX_VALUE + 1L).build(); - byte[] binary = toBinary(longRecord); - - LongRecord longRecord2 = LongRecord.newBuilder().setField(0L).setUnionField((long) Integer.MIN_VALUE - 1L).build(); - byte[] binary2 = toBinary(longRecord2); - - LongRecord longRecord3 = LongRecord.newBuilder().setField(0L).setArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary3 = toBinary(longRecord3); - - LongRecord longRecord4 = LongRecord.newBuilder().setField(0L).setMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary4 = toBinary(longRecord4); - - LongRecord longRecord5 = LongRecord.newBuilder().setField(0L).setUnionArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary5 = toBinary(longRecord5); - - LongRecord longRecord6 = LongRecord.newBuilder().setField(0L).setUnionMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary6 = toBinary(longRecord6); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - } - - private byte[] toBinary(IndexedRecord record) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryEncoder encoder = AvroCompatibilityHelper.newBinaryEncoder(baos); - GenericDatumWriter writer = new GenericDatumWriter<>(record.getSchema()); - writer.write(record, encoder); - encoder.flush(); - return baos.toByteArray(); - } - - private T toSpecificRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newSpecificDatumReader(writerSchema, readerSchema, SpecificData.get()); - return reader.read(null, decoder); - } - - private GenericRecord toGenericRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newGenericDatumReader(writerSchema, readerSchema, GenericData.get()); - return reader.read(null, decoder); - } } diff --git a/helper/tests/helper-tests-18/src/test/java/com/linkedin/avroutil1/compatibility/avro18/AvroCompatibilityHelperAvro18Test.java b/helper/tests/helper-tests-18/src/test/java/com/linkedin/avroutil1/compatibility/avro18/AvroCompatibilityHelperAvro18Test.java index b3b94ddf7..7034f7c89 100644 --- a/helper/tests/helper-tests-18/src/test/java/com/linkedin/avroutil1/compatibility/avro18/AvroCompatibilityHelperAvro18Test.java +++ b/helper/tests/helper-tests-18/src/test/java/com/linkedin/avroutil1/compatibility/avro18/AvroCompatibilityHelperAvro18Test.java @@ -6,33 +6,15 @@ package com.linkedin.avroutil1.compatibility.avro18; -import by18.IntRecord; -import by18.LongRecord; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.linkedin.avroutil1.Pojo; import com.linkedin.avroutil1.testcommon.TestUtil; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroVersion; - -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; - -import org.apache.avro.AvroTypeException; import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.BinaryDecoder; -import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; -import org.apache.avro.specific.SpecificData; -import org.apache.avro.specific.SpecificRecord; -import org.apache.avro.util.Utf8; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; @@ -98,180 +80,4 @@ public void testCreateSchemaFieldWithProvidedDefaultValue() throws IOException { List> actualListValue = mapper.convertValue(actualJsonNode, new TypeReference>>(){}); Assert.assertEquals(actualListValue.get(0).get(0), "dummyElement"); } - - @Test - public void testIntRoundtrip() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - IntRecord roundtrip = toSpecificRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals((int) roundtrip.getField(), 42); - Assert.assertEquals(roundtrip.getUnionField().intValue(), 55); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongRoundtrip() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - LongRecord roundtrip = toSpecificRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals((long) roundtrip.getField(), 42L); - Assert.assertEquals(roundtrip.getUnionField().longValue(), 55L); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testIntToLongPromotion() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - LongRecord longRecord = toSpecificRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals((long) longRecord.getField(), 42L); - Assert.assertEquals(longRecord.getUnionField().longValue(), 55L); - Assert.assertEquals(longRecord.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(longRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(longRecord.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(longRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testLongToIntDemotion() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - IntRecord intRecord = toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals((int) intRecord.getField(), 42); - Assert.assertEquals(intRecord.getUnionField().intValue(), 55); - Assert.assertEquals(intRecord.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(intRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(intRecord.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(intRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongToIntDemotionOutOfRange() throws IOException { - LongRecord longRecord = LongRecord.newBuilder().setField((long) Integer.MAX_VALUE + 1L).build(); - byte[] binary = toBinary(longRecord); - - LongRecord longRecord2 = LongRecord.newBuilder().setField(0L).setUnionField((long) Integer.MIN_VALUE - 1L).build(); - byte[] binary2 = toBinary(longRecord2); - - LongRecord longRecord3 = LongRecord.newBuilder().setField(0L).setArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary3 = toBinary(longRecord3); - - LongRecord longRecord4 = LongRecord.newBuilder().setField(0L).setMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary4 = toBinary(longRecord4); - - LongRecord longRecord5 = LongRecord.newBuilder().setField(0L).setUnionArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary5 = toBinary(longRecord5); - - LongRecord longRecord6 = LongRecord.newBuilder().setField(0L).setUnionMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary6 = toBinary(longRecord6); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - } - - private byte[] toBinary(IndexedRecord record) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryEncoder encoder = AvroCompatibilityHelper.newBinaryEncoder(baos); - GenericDatumWriter writer = new GenericDatumWriter<>(record.getSchema()); - writer.write(record, encoder); - encoder.flush(); - return baos.toByteArray(); - } - - private T toSpecificRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newSpecificDatumReader(writerSchema, readerSchema, SpecificData.get()); - return reader.read(null, decoder); - } - - private GenericRecord toGenericRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newGenericDatumReader(writerSchema, readerSchema, GenericData.get()); - return reader.read(null, decoder); - } } diff --git a/helper/tests/helper-tests-19/src/test/java/com/linkedin/avroutil1/compatibility/avro19/AvroCompatibilityHelperAvro19Test.java b/helper/tests/helper-tests-19/src/test/java/com/linkedin/avroutil1/compatibility/avro19/AvroCompatibilityHelperAvro19Test.java index 67f9d3fd3..10c9c70fd 100644 --- a/helper/tests/helper-tests-19/src/test/java/com/linkedin/avroutil1/compatibility/avro19/AvroCompatibilityHelperAvro19Test.java +++ b/helper/tests/helper-tests-19/src/test/java/com/linkedin/avroutil1/compatibility/avro19/AvroCompatibilityHelperAvro19Test.java @@ -6,33 +6,15 @@ package com.linkedin.avroutil1.compatibility.avro19; -import by19.IntRecord; -import by19.LongRecord; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.linkedin.avroutil1.Pojo; import com.linkedin.avroutil1.compatibility.AvroCompatibilityHelper; import com.linkedin.avroutil1.compatibility.AvroVersion; import com.linkedin.avroutil1.testcommon.TestUtil; - -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; import java.util.Map; - -import org.apache.avro.AvroTypeException; import org.apache.avro.JsonProperties; import org.apache.avro.Schema; -import org.apache.avro.generic.GenericData; -import org.apache.avro.generic.GenericDatumWriter; -import org.apache.avro.generic.GenericRecord; -import org.apache.avro.generic.IndexedRecord; -import org.apache.avro.io.BinaryDecoder; -import org.apache.avro.io.BinaryEncoder; -import org.apache.avro.io.DatumReader; -import org.apache.avro.specific.SpecificData; -import org.apache.avro.specific.SpecificRecord; -import org.apache.avro.util.Utf8; import org.mockito.Mockito; import org.testng.Assert; import org.testng.annotations.Test; @@ -93,179 +75,4 @@ public void testCreateSchemaFieldWithProvidedDefaultValue() throws IOException { Assert.assertEquals(actualListValue.get(0).get(0), "dummyElement"); } - @Test - public void testIntRoundtrip() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - IntRecord roundtrip = toSpecificRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(roundtrip.getField(), 42); - Assert.assertEquals(roundtrip.getUnionField().intValue(), 55); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongRoundtrip() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - LongRecord roundtrip = toSpecificRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(roundtrip.getField(), 42L); - Assert.assertEquals(roundtrip.getUnionField().longValue(), 55L); - Assert.assertEquals(roundtrip.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(roundtrip.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(roundtrip.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(roundtrip.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testIntToLongPromotion() throws IOException { - IntRecord intRecord = new IntRecord(); - intRecord.setField(42); - intRecord.setUnionField(55); - intRecord.setArrayField(ImmutableList.of(100, -200)); - intRecord.setMapField(ImmutableMap.of("key1", 300, "key2", -400)); - intRecord.setUnionArrayField(ImmutableList.of(99, -199)); - intRecord.setUnionMapField(ImmutableMap.of("key1", 298, "key2", 355)); - byte[] binary = toBinary(intRecord); - - LongRecord longRecord = toSpecificRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(longRecord.getField(), 42L); - Assert.assertEquals(longRecord.getUnionField().longValue(), 55L); - Assert.assertEquals(longRecord.getArrayField(), ImmutableList.of(100L, -200L)); - Assert.assertEquals(longRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(longRecord.getUnionArrayField(), ImmutableList.of(99L, -199L)); - Assert.assertEquals(longRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - - GenericRecord genericRecord = toGenericRecord(binary, IntRecord.SCHEMA$, LongRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42L); - Assert.assertEquals(genericRecord.get("unionField"), 55L); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100L, -200L)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300L, new Utf8("key2"), -400L)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99L, -199L)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298L, new Utf8("key2"), 355L)); - } - - @Test - public void testLongToIntDemotion() throws IOException { - LongRecord longRecord = new LongRecord(); - longRecord.setField(42L); - longRecord.setUnionField(55L); - longRecord.setArrayField(ImmutableList.of(100L, -200L)); - longRecord.setMapField(ImmutableMap.of("key1", 300L, "key2", -400L)); - longRecord.setUnionArrayField(ImmutableList.of(99L, -199L)); - longRecord.setUnionMapField(ImmutableMap.of("key1", 298L, "key2", 355L)); - byte[] binary = toBinary(longRecord); - - IntRecord intRecord = toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(intRecord.getField(), 42); - Assert.assertEquals(intRecord.getUnionField().intValue(), 55); - Assert.assertEquals(intRecord.getArrayField(), ImmutableList.of(100, -200)); - Assert.assertEquals(intRecord.getMapField(), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(intRecord.getUnionArrayField(), ImmutableList.of(99, -199)); - Assert.assertEquals(intRecord.getUnionMapField(), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - - GenericRecord genericRecord = toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$); - Assert.assertEquals(genericRecord.get("field"), 42); - Assert.assertEquals(genericRecord.get("unionField"), 55); - Assert.assertEquals(genericRecord.get("arrayField"), ImmutableList.of(100, -200)); - Assert.assertEquals(genericRecord.get("mapField"), ImmutableMap.of(new Utf8("key1"), 300, new Utf8("key2"), -400)); - Assert.assertEquals(genericRecord.get("unionArrayField"), ImmutableList.of(99, -199)); - Assert.assertEquals(genericRecord.get("unionMapField"), ImmutableMap.of(new Utf8("key1"), 298, new Utf8("key2"), 355)); - } - - @Test - public void testLongToIntDemotionOutOfRange() throws IOException { - LongRecord longRecord = LongRecord.newBuilder().setField((long) Integer.MAX_VALUE + 1L).build(); - byte[] binary = toBinary(longRecord); - - LongRecord longRecord2 = LongRecord.newBuilder().setField(0L).setUnionField((long) Integer.MIN_VALUE - 1L).build(); - byte[] binary2 = toBinary(longRecord2); - - LongRecord longRecord3 = LongRecord.newBuilder().setField(0L).setArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary3 = toBinary(longRecord3); - - LongRecord longRecord4 = LongRecord.newBuilder().setField(0L).setMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary4 = toBinary(longRecord4); - - LongRecord longRecord5 = LongRecord.newBuilder().setField(0L).setUnionArrayField(ImmutableList.of((long) Integer.MAX_VALUE + 1L)).build(); - byte[] binary5 = toBinary(longRecord5); - - LongRecord longRecord6 = LongRecord.newBuilder().setField(0L).setUnionMapField(ImmutableMap.of("haha", (long) Integer.MIN_VALUE - 1L)).build(); - byte[] binary6 = toBinary(longRecord6); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary2, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary3, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary4, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary5, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - - Assert.assertThrows(AvroTypeException.class, () -> toSpecificRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - Assert.assertThrows(AvroTypeException.class, () -> toGenericRecord(binary6, LongRecord.SCHEMA$, IntRecord.SCHEMA$)); - } - - private byte[] toBinary(IndexedRecord record) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BinaryEncoder encoder = AvroCompatibilityHelper.newBinaryEncoder(baos); - GenericDatumWriter writer = new GenericDatumWriter<>(record.getSchema()); - writer.write(record, encoder); - encoder.flush(); - return baos.toByteArray(); - } - - private T toSpecificRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newSpecificDatumReader(writerSchema, readerSchema, SpecificData.get()); - return reader.read(null, decoder); - } - - private GenericRecord toGenericRecord(byte[] binary, - Schema writerSchema, - Schema readerSchema) throws IOException { - BinaryDecoder decoder = AvroCompatibilityHelper.newBinaryDecoder(binary); - DatumReader reader = AvroCompatibilityHelper.newGenericDatumReader(writerSchema, readerSchema, GenericData.get()); - return reader.read(null, decoder); - } }