/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.avro.specific; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.ArrayList; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.apache.avro.FooBarSpecificRecord; import org.apache.avro.TypeEnum; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonParser; import org.codehaus.jackson.map.ObjectMapper; import org.junit.Test; import org.junit.Assert; import org.apache.avro.Schema; import org.apache.avro.generic.GenericData; import org.apache.avro.util.Utf8; import org.apache.avro.TestSchema; import org.apache.avro.test.TestRecord; import org.apache.avro.test.MD5; import org.apache.avro.test.Kind; import org.apache.avro.test.Reserved; import org.apache.avro.generic.GenericRecord; public class TestSpecificData { @Test /** Make sure that even with nulls, hashCode() doesn't throw NPE. */ public void testHashCode() { new TestRecord().hashCode(); SpecificData.get().hashCode(null, TestRecord.SCHEMA$); } @Test /** Make sure that even with nulls, toString() doesn't throw NPE. */ public void testToString() { new TestRecord().toString(); } private static class X { public Map<String,String> map; } @Test public void testGetMapSchema() throws Exception { SpecificData.get().getSchema(X.class.getField("map").getGenericType()); } @Test /** Test nesting of specific data within generic. */ public void testSpecificWithinGeneric() throws Exception { // define a record with a field that's a generated TestRecord Schema schema = Schema.createRecord("Foo", "", "x.y.z", false); List<Schema.Field> fields = new ArrayList<Schema.Field>(); fields.add(new Schema.Field("f", TestRecord.SCHEMA$, "", null)); schema.setFields(fields); // create a generic instance of this record TestRecord nested = new TestRecord(); nested.setName("foo"); nested.setKind(Kind.BAR); nested.setHash(new MD5(new byte[]{0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5})); GenericData.Record record = new GenericData.Record(schema); record.put("f", nested); // test that this instance can be written & re-read TestSchema.checkBinary(schema, record, new SpecificDatumWriter<Object>(), new SpecificDatumReader<Object>()); TestSchema.checkDirectBinary(schema, record, new SpecificDatumWriter<Object>(), new SpecificDatumReader<Object>()); TestSchema.checkBlockingBinary(schema, record, new SpecificDatumWriter<Object>(), new SpecificDatumReader<Object>()); } @Test public void testConvertGenericToSpecific() { GenericRecord generic = new GenericData.Record(TestRecord.SCHEMA$); generic.put("name", "foo"); generic.put("kind", new GenericData.EnumSymbol(Kind.SCHEMA$, "BAR")); generic.put("hash", new GenericData.Fixed (MD5.SCHEMA$, new byte[]{0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5})); TestRecord specific = (TestRecord)SpecificData.get().deepCopy(TestRecord.SCHEMA$, generic); } @Test public void testGetClassSchema() throws Exception { Assert.assertEquals(TestRecord.getClassSchema(), TestRecord.SCHEMA$); Assert.assertEquals(MD5.getClassSchema(), MD5.SCHEMA$); Assert.assertEquals(Kind.getClassSchema(), Kind.SCHEMA$); } @Test public void testSpecificRecordToString() throws IOException { FooBarSpecificRecord foo = FooBarSpecificRecord.newBuilder() .setId(123) .setName("foo") .setNicknames(Arrays.asList("bar")) .setRelatedids(Arrays.asList(1, 2, 3)) .setTypeEnum(TypeEnum.c) .build(); String json = foo.toString(); JsonFactory factory = new JsonFactory(); JsonParser parser = factory.createJsonParser(json); ObjectMapper mapper = new ObjectMapper(); // will throw exception if string is not parsable json mapper.readTree(parser); } @Test public void testExternalizeable() throws Exception { TestRecord before = new TestRecord(); before.setName("foo"); before.setKind(Kind.BAR); before.setHash(new MD5(new byte[]{0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5})); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bytes); out.writeObject(before); out.close(); ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray())); TestRecord after = (TestRecord)in.readObject(); Assert.assertEquals(before, after); } @Test public void testReservedEnumSymbol() throws Exception { Assert.assertEquals(Reserved.default$, SpecificData.get().createEnum("default", Reserved.SCHEMA$)); } }