You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by cu...@apache.org on 2014/10/03 22:33:39 UTC

svn commit: r1629315 - in /avro/trunk: ./ lang/java/avro/src/main/java/org/apache/avro/generic/ lang/java/avro/src/test/java/org/apache/avro/ lang/java/avro/src/test/java/org/apache/avro/generic/ lang/java/ipc/src/test/java/org/apache/avro/

Author: cutting
Date: Fri Oct  3 20:33:39 2014
New Revision: 1629315

URL: http://svn.apache.org/r1629315
Log:
AVRO-997. Java: For enum values, no longer sometimes permit any Object whose toString() names an enum symbol, but rather always require use of distinct enum types.  Contributed by Sean Busbey.

Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java
    avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java
    avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericData.java
    avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericDatumWriter.java
    avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestCompare.java

Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1629315&r1=1629314&r2=1629315&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Fri Oct  3 20:33:39 2014
@@ -6,6 +6,10 @@ Trunk (not yet released)
 
     AVRO-1334. Java: Update versions of many dependencies. (scottcarey, cutting)
 
+    AVRO-997. Java: For enum values, no longer sometimes permit any
+    Object whose toString() names an enum symbol, but rather always
+    require use of distinct enum types. (Sean Busbey via cutting)
+
   NEW FEATURES
 
     AVRO-1555.  C#: Add support for RPC over HTTP. (Dmitry Kovalev via cutting)

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java?rev=1629315&r1=1629314&r2=1629315&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java Fri Oct  3 20:33:39 2014
@@ -328,6 +328,14 @@ public class GenericData {
       this.symbol = symbol;
     }
 
+    /**
+     * Maps existing Objects into an Avro enum
+     * by calling toString(), eg for Java Enums
+     */
+    public EnumSymbol(Schema schema, Object symbol) {
+      this(schema, symbol.toString());
+    }
+
     @Override public Schema getSchema() { return schema; }
 
     @Override
@@ -375,7 +383,7 @@ public class GenericData {
       }
       return true;
     case ENUM:
-      if (datum == null) return false;
+      if (!isEnum(datum)) return false;
       return schema.getEnumSymbols().contains(datum.toString());
     case ARRAY:
       if (!(isArray(datum))) return false;

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java?rev=1629315&r1=1629314&r2=1629315&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java Fri Oct  3 20:33:39 2014
@@ -121,6 +121,8 @@ public class GenericDatumWriter<D> imple
    * representations.*/
   protected void writeEnum(Schema schema, Object datum, Encoder out)
     throws IOException {
+    if (!data.isEnum(datum))
+      throw new AvroTypeException("Not an enum: "+datum);
     out.writeEnum(schema.getEnumOrdinal(datum.toString()));
   }
   

Modified: avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java?rev=1629315&r1=1629314&r2=1629315&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java (original)
+++ avro/trunk/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java Fri Oct  3 20:33:39 2014
@@ -541,15 +541,15 @@ public class TestSchemaCompatibility {
       // new DecodingTestCase(LONG_SCHEMA, 1L, INT_SCHEMA, 1),  // should work in best-effort!
 
       new DecodingTestCase(
-          ENUM1_AB_SCHEMA, "A",
+          ENUM1_AB_SCHEMA, new EnumSymbol(ENUM1_AB_SCHEMA, "A"),
           ENUM1_ABC_SCHEMA, new EnumSymbol(ENUM1_ABC_SCHEMA, "A")),
 
       new DecodingTestCase(
-          ENUM1_ABC_SCHEMA, "A",
+          ENUM1_ABC_SCHEMA, new EnumSymbol(ENUM1_ABC_SCHEMA, "A"),
           ENUM1_AB_SCHEMA, new EnumSymbol(ENUM1_AB_SCHEMA, "A")),
 
       new DecodingTestCase(
-          ENUM1_ABC_SCHEMA, "B",
+          ENUM1_ABC_SCHEMA, new EnumSymbol(ENUM1_ABC_SCHEMA, "B"),
           ENUM1_BC_SCHEMA, new EnumSymbol(ENUM1_BC_SCHEMA, "B")),
 
       new DecodingTestCase(

Modified: avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericData.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericData.java?rev=1629315&r1=1629314&r2=1629315&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericData.java (original)
+++ avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericData.java Fri Oct  3 20:33:39 2014
@@ -440,4 +440,19 @@ public class TestGenericData {
     assertFalse(GenericData.get().validate(schema, w));
     assertTrue(GenericData.get().validate(schema, null));
   }
+
+  private enum anEnum { ONE,TWO,THREE };
+  @Test
+  public void validateRequiresGenericSymbolForEnumSchema() {
+    final Schema schema = Schema.createEnum("my_enum", "doc", "namespace", Arrays.asList("ONE","TWO","THREE"));
+    final GenericData gd = GenericData.get();
+    
+    /* positive cases */
+    assertTrue(gd.validate(schema, new GenericData.EnumSymbol(schema, "ONE")));
+    assertTrue(gd.validate(schema, new GenericData.EnumSymbol(schema, anEnum.ONE)));
+
+    /* negative cases */
+    assertFalse("We don't expect GenericData to allow a String datum for an enum schema", gd.validate(schema, "ONE"));
+    assertFalse("We don't expect GenericData to allow a Java Enum for an enum schema", gd.validate(schema, anEnum.ONE));
+  }
 }

Modified: avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericDatumWriter.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericDatumWriter.java?rev=1629315&r1=1629314&r2=1629315&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericDatumWriter.java (original)
+++ avro/trunk/lang/java/avro/src/test/java/org/apache/avro/generic/TestGenericDatumWriter.java Fri Oct  3 20:33:39 2014
@@ -42,6 +42,7 @@ import org.apache.avro.io.DirectBinaryEn
 import org.apache.avro.io.Encoder;
 import org.apache.avro.io.EncoderFactory;
 import org.apache.avro.io.JsonDecoder;
+import org.apache.avro.AvroTypeException;
 import org.junit.Test;
 import org.apache.avro.util.Utf8;
 
@@ -211,4 +212,49 @@ public class TestGenericDatumWriter {
     @Override
     public void writeIndex(int unionIndex) throws IOException { e.writeIndex(unionIndex); }
   };
+
+  @Test(expected=AvroTypeException.class)
+  public void writeDoesNotAllowStringForGenericEnum() throws IOException {
+    final String json = "{\"type\": \"record\", \"name\": \"recordWithEnum\"," +
+      "\"fields\": [ " +
+        "{\"name\": \"field\", \"type\": " +
+          "{\"type\": \"enum\", \"name\": \"enum\", \"symbols\": " +
+            "[\"ONE\",\"TWO\",\"THREE\"] " +
+          "}" +
+        "}" +
+      "]}";
+    Schema schema = Schema.parse(json);
+    GenericRecord record = new GenericData.Record(schema);
+    record.put("field", "ONE");
+
+    ByteArrayOutputStream bao = new ByteArrayOutputStream();
+    GenericDatumWriter<GenericRecord> writer =
+      new GenericDatumWriter<GenericRecord>(schema);
+    Encoder encoder = EncoderFactory.get().jsonEncoder(schema, bao);
+
+    writer.write(record, encoder);
+  }
+
+  private enum AnEnum { ONE, TWO, THREE };
+  @Test(expected=AvroTypeException.class)
+  public void writeDoesNotAllowJavaEnumForGenericEnum() throws IOException {
+    final String json = "{\"type\": \"record\", \"name\": \"recordWithEnum\"," +
+      "\"fields\": [ " +
+        "{\"name\": \"field\", \"type\": " +
+          "{\"type\": \"enum\", \"name\": \"enum\", \"symbols\": " +
+            "[\"ONE\",\"TWO\",\"THREE\"] " +
+          "}" +
+        "}" +
+      "]}";
+    Schema schema = Schema.parse(json);
+    GenericRecord record = new GenericData.Record(schema);
+    record.put("field", AnEnum.ONE);
+
+    ByteArrayOutputStream bao = new ByteArrayOutputStream();
+    GenericDatumWriter<GenericRecord> writer =
+      new GenericDatumWriter<GenericRecord>(schema);
+    Encoder encoder = EncoderFactory.get().jsonEncoder(schema, bao);
+
+    writer.write(record, encoder);
+  }
 }

Modified: avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestCompare.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestCompare.java?rev=1629315&r1=1629314&r2=1629315&view=diff
==============================================================================
--- avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestCompare.java (original)
+++ avro/trunk/lang/java/ipc/src/test/java/org/apache/avro/TestCompare.java Fri Oct  3 20:33:39 2014
@@ -143,8 +143,12 @@ public class TestCompare {
 
   @Test
   public void testEnum() throws Exception {
-    check("{\"type\":\"enum\", \"name\":\"Test\",\"symbols\": [\"A\", \"B\"]}",
-          "A", "B");
+    String json =
+      "{\"type\":\"enum\", \"name\":\"Test\",\"symbols\": [\"A\", \"B\"]}";
+    Schema schema = Schema.parse(json);
+    check(json,
+          new GenericData.EnumSymbol(schema, "A"),
+          new GenericData.EnumSymbol(schema, "B"));
   }
 
   @Test