Skip to content

Commit da74291

Browse files
authored
Implement improvements wrt #422 (#545)
1 parent 3244175 commit da74291

File tree

5 files changed

+88
-11
lines changed

5 files changed

+88
-11
lines changed

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/schema/AvroSchemaHelper.java

+21-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.apache.avro.JsonProperties;
1111
import org.apache.avro.Schema;
1212
import org.apache.avro.Schema.Parser;
13+
import org.apache.avro.SchemaParseException;
1314
import org.apache.avro.reflect.AvroAlias;
1415
import org.apache.avro.reflect.Stringable;
1516
import org.apache.avro.specific.SpecificData;
@@ -269,13 +270,27 @@ public static Schema parseJsonSchema(String json) {
269270
* @param values List of enum names
270271
* @return An {@link org.apache.avro.Schema.Type#ENUM ENUM} schema.
271272
*/
272-
public static Schema createEnumSchema(BeanDescription bean, List<String> values) {
273+
public static Schema createEnumSchema(BeanDescription bean, List<String> values)
274+
{
273275
final JavaType enumType = bean.getType();
274-
return addAlias(Schema.createEnum(
275-
getName(enumType),
276-
bean.findClassDescription(),
277-
getNamespace(enumType, bean.getClassInfo()), values
278-
), bean);
276+
final Schema avroSchema;
277+
278+
try {
279+
avroSchema = Schema.createEnum(
280+
getName(enumType),
281+
bean.findClassDescription(),
282+
getNamespace(enumType, bean.getClassInfo()),
283+
values);
284+
} catch (SchemaParseException spe) {
285+
final String msg = String.format("Problem generating Avro `Schema` for Enum type %s: %s",
286+
ClassUtil.getTypeDescription(enumType), spe.getMessage());
287+
288+
// 05-Jan-2025, tatu: SHOULD be able to throw like so but
289+
// `SchemaBuilder` does not expose checked exceptions so need to
290+
// throw InvalidDefinitionException.from((JsonParser) null, msg);
291+
throw new IllegalArgumentException(msg, spe);
292+
}
293+
return addAlias(avroSchema, bean);
279294
}
280295

281296
/**

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/schema/EnumVisitor.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package com.fasterxml.jackson.dataformat.avro.schema;
22

3+
import java.util.ArrayList;
4+
import java.util.Set;
5+
36
import com.fasterxml.jackson.databind.BeanDescription;
47
import com.fasterxml.jackson.databind.JavaType;
58
import com.fasterxml.jackson.databind.SerializerProvider;
69
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;
710

811
import org.apache.avro.Schema;
912

10-
import java.util.ArrayList;
11-
import java.util.Set;
12-
1313
/**
1414
* Specific visitor for Java Enum types that are to be exposed as
1515
* Avro Enums. Used unless Java Enums are to be mapped to Avro Strings.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.fasterxml.jackson.dataformat.avro.schema;
2+
3+
import org.junit.Test;
4+
5+
import com.fasterxml.jackson.annotation.JsonValue;
6+
7+
import com.fasterxml.jackson.dataformat.avro.AvroMapper;
8+
import com.fasterxml.jackson.dataformat.avro.AvroTestBase;
9+
10+
// For [dataformats-binary#422]
11+
public class EnumSchema422Test extends AvroTestBase
12+
{
13+
enum EnumType422 {
14+
CARD_S("CARD-S");
15+
16+
private final String value;
17+
18+
EnumType422(String value) {
19+
this.value = value;
20+
}
21+
22+
@JsonValue
23+
public String value() {
24+
return this.value;
25+
}
26+
}
27+
28+
static class Wrapper422 {
29+
public EnumType422 contract;
30+
}
31+
32+
private final AvroMapper MAPPER = newMapper();
33+
34+
// For [dataformats-binary#422]
35+
@Test
36+
public void testEnumSchemaGeneration422() throws Exception
37+
{
38+
// First, failure due to invalid enum value (when generating as Enum)
39+
AvroSchemaGenerator gen = new AvroSchemaGenerator()
40+
.enableLogicalTypes();
41+
try {
42+
MAPPER.acceptJsonFormatVisitor(Wrapper422.class, gen);
43+
fail("Expected failure");
44+
} catch (IllegalArgumentException e) { // in 2.x
45+
verifyException(e, "Problem generating Avro `Schema` for Enum type");
46+
verifyException(e, "Illegal character in");
47+
}
48+
49+
// But then success when configuring to produce Strings for Enum types
50+
51+
gen = new AvroSchemaGenerator()
52+
.enableLogicalTypes()
53+
.enableWriteEnumAsString();
54+
MAPPER.acceptJsonFormatVisitor(Wrapper422.class, gen);
55+
56+
org.apache.avro.Schema avroSchema = gen.getGeneratedSchema().getAvroSchema();
57+
String avroSchemaInJSON = avroSchema.toString(true);
58+
assertNotNull(avroSchemaInJSON);
59+
}
60+
}

avro/src/test/java/com/fasterxml/jackson/dataformat/avro/schema/Enum_schemaCreationTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
import org.apache.avro.specific.SpecificData;
1111
import org.junit.Test;
1212

13-
public class Enum_schemaCreationTest extends AvroTestBase {
14-
13+
public class Enum_schemaCreationTest extends AvroTestBase
14+
{
1515
static enum NumbersEnum {
1616
ONE, TWO, THREE
1717
}

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ Active maintainers:
1919
#308: (avro) Incorrect serialization for `LogicalType.Decimal` (Java `BigDecimal`)
2020
(reported by Idan S)
2121
(fix contributed by Michal F)
22+
#422: Avro generation failed with enums containing values with special characters
23+
(reported by @pfr-enedis)
2224
#535: (avro) AvroSchemaGenerator: logicalType(s) never set for non-date classes
2325
(reported by Cormac R)
2426
(fix contributed by Michal F)

0 commit comments

Comments
 (0)