|
1 | 1 | package com.fasterxml.jackson.dataformat.avro; |
2 | 2 |
|
| 3 | +import java.util.Set; |
3 | 4 | import java.util.concurrent.atomic.AtomicReference; |
4 | 5 |
|
5 | 6 | import org.apache.avro.Schema; |
| 7 | +import org.apache.avro.Schema.Type; |
6 | 8 | import org.apache.avro.SchemaCompatibility; |
7 | 9 | import org.apache.avro.SchemaCompatibility.SchemaCompatibilityType; |
8 | 10 | import org.apache.avro.SchemaCompatibility.SchemaPairCompatibility; |
@@ -75,21 +77,50 @@ public AvroSchema withReaderSchema(AvroSchema readerSchema) |
75 | 77 | w = Schema.applyAliases(w, r); |
76 | 78 |
|
77 | 79 | // and then use Avro std lib to validate compatibility |
| 80 | + |
| 81 | + // 16-Jun-2017, tatu: First, a very common case is for Record names not |
| 82 | + // to match; so let's check that first |
| 83 | + if (r.getType() == w.getType()) { |
| 84 | + if (!_schemaNamesEqual(w, r)) { |
| 85 | + throw new JsonMappingException(null, String.format( |
| 86 | +"Incompatible writer/reader schemas: root %ss have different names (\"%s\" vs \"%s\"), no match via aliases", |
| 87 | +r.getType().getName(), w.getFullName(), r.getFullName())); |
| 88 | + } |
| 89 | + } |
| 90 | + |
78 | 91 | SchemaPairCompatibility comp; |
79 | 92 | try { |
80 | 93 | comp = SchemaCompatibility.checkReaderWriterCompatibility(r, w); |
81 | 94 | } catch (Exception e) { |
82 | 95 | throw new JsonMappingException(null, String.format( |
83 | | - "Failed to resolve given reader/writer schemas, problem: (%s) %s", |
| 96 | + "Failed to resolve given writer/reader schemas, problem: (%s) %s", |
84 | 97 | e.getClass().getName(), e.getMessage())); |
85 | 98 | } |
86 | 99 | if (comp.getType() != SchemaCompatibilityType.COMPATIBLE) { |
87 | | - throw new JsonMappingException(null, String.format("Incompatible reader/writer schema: %s", |
| 100 | + throw new JsonMappingException(null, String.format("Incompatible writer/reader schemas: %s", |
88 | 101 | comp.getDescription())); |
89 | 102 | } |
90 | 103 | return Resolving.create(w, r); |
91 | 104 | } |
92 | 105 |
|
| 106 | + private boolean _schemaNamesEqual(Schema w, Schema r) |
| 107 | + { |
| 108 | + final String wname = w.getFullName(); |
| 109 | + final String rname = r.getFullName(); |
| 110 | + |
| 111 | + if ((wname == rname) || |
| 112 | + ((wname != null) && wname.equals(rname))) { |
| 113 | + return true; |
| 114 | + } |
| 115 | + |
| 116 | + // but may also have alias. NOTE! Avro lib itself does this, and we rely |
| 117 | + // on it, but basically only `NamedSchema` do NOT throw exception. But |
| 118 | + // we have no way of checking -- need to trust other cases bail out before |
| 119 | + // this (which they do). Unclean but... that's avrolib for you. |
| 120 | + Set<String> aliases = r.getAliases(); |
| 121 | + return aliases.contains(wname); |
| 122 | + } |
| 123 | + |
93 | 124 | /** |
94 | 125 | * Similar to {@link #withReaderSchema} but will NOT verify compatibility of schemas: |
95 | 126 | * this means that certain problems (such as missing default value for a newly added |
|
0 commit comments