|
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