Skip to content

Commit

Permalink
Implement improvements wrt #422 (#545)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder authored Jan 6, 2025
1 parent 3244175 commit da74291
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.apache.avro.JsonProperties;
import org.apache.avro.Schema;
import org.apache.avro.Schema.Parser;
import org.apache.avro.SchemaParseException;
import org.apache.avro.reflect.AvroAlias;
import org.apache.avro.reflect.Stringable;
import org.apache.avro.specific.SpecificData;
Expand Down Expand Up @@ -269,13 +270,27 @@ public static Schema parseJsonSchema(String json) {
* @param values List of enum names
* @return An {@link org.apache.avro.Schema.Type#ENUM ENUM} schema.
*/
public static Schema createEnumSchema(BeanDescription bean, List<String> values) {
public static Schema createEnumSchema(BeanDescription bean, List<String> values)
{
final JavaType enumType = bean.getType();
return addAlias(Schema.createEnum(
getName(enumType),
bean.findClassDescription(),
getNamespace(enumType, bean.getClassInfo()), values
), bean);
final Schema avroSchema;

try {
avroSchema = Schema.createEnum(
getName(enumType),
bean.findClassDescription(),
getNamespace(enumType, bean.getClassInfo()),
values);
} catch (SchemaParseException spe) {
final String msg = String.format("Problem generating Avro `Schema` for Enum type %s: %s",
ClassUtil.getTypeDescription(enumType), spe.getMessage());

// 05-Jan-2025, tatu: SHOULD be able to throw like so but
// `SchemaBuilder` does not expose checked exceptions so need to
// throw InvalidDefinitionException.from((JsonParser) null, msg);
throw new IllegalArgumentException(msg, spe);
}
return addAlias(avroSchema, bean);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.fasterxml.jackson.dataformat.avro.schema;

import java.util.ArrayList;
import java.util.Set;

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor;

import org.apache.avro.Schema;

import java.util.ArrayList;
import java.util.Set;

/**
* Specific visitor for Java Enum types that are to be exposed as
* Avro Enums. Used unless Java Enums are to be mapped to Avro Strings.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.fasterxml.jackson.dataformat.avro.schema;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonValue;

import com.fasterxml.jackson.dataformat.avro.AvroMapper;
import com.fasterxml.jackson.dataformat.avro.AvroTestBase;

// For [dataformats-binary#422]
public class EnumSchema422Test extends AvroTestBase
{
enum EnumType422 {
CARD_S("CARD-S");

private final String value;

EnumType422(String value) {
this.value = value;
}

@JsonValue
public String value() {
return this.value;
}
}

static class Wrapper422 {
public EnumType422 contract;
}

private final AvroMapper MAPPER = newMapper();

// For [dataformats-binary#422]
@Test
public void testEnumSchemaGeneration422() throws Exception
{
// First, failure due to invalid enum value (when generating as Enum)
AvroSchemaGenerator gen = new AvroSchemaGenerator()
.enableLogicalTypes();
try {
MAPPER.acceptJsonFormatVisitor(Wrapper422.class, gen);
fail("Expected failure");
} catch (IllegalArgumentException e) { // in 2.x
verifyException(e, "Problem generating Avro `Schema` for Enum type");
verifyException(e, "Illegal character in");
}

// But then success when configuring to produce Strings for Enum types

gen = new AvroSchemaGenerator()
.enableLogicalTypes()
.enableWriteEnumAsString();
MAPPER.acceptJsonFormatVisitor(Wrapper422.class, gen);

org.apache.avro.Schema avroSchema = gen.getGeneratedSchema().getAvroSchema();
String avroSchemaInJSON = avroSchema.toString(true);
assertNotNull(avroSchemaInJSON);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import org.apache.avro.specific.SpecificData;
import org.junit.Test;

public class Enum_schemaCreationTest extends AvroTestBase {

public class Enum_schemaCreationTest extends AvroTestBase
{
static enum NumbersEnum {
ONE, TWO, THREE
}
Expand Down
2 changes: 2 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Active maintainers:
#308: (avro) Incorrect serialization for `LogicalType.Decimal` (Java `BigDecimal`)
(reported by Idan S)
(fix contributed by Michal F)
#422: Avro generation failed with enums containing values with special characters
(reported by @pfr-enedis)
#535: (avro) AvroSchemaGenerator: logicalType(s) never set for non-date classes
(reported by Cormac R)
(fix contributed by Michal F)
Expand Down

0 comments on commit da74291

Please sign in to comment.