简体   繁体   中英

Can I have an Avro Schema with an enum that includes values as enum members?

This is the Java enum that I want to transform into an Avro Schema:

public enum ApplicationCode {
    APP_A("MY-APP-A"),
    APP_B("MY-APP-B");


    private final String code;

    ApplicationCode(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }
}

Since enums are generally available as Types in Avro, I came up with following:

{
  "type" : "enum",
  "name" : "ApplicationCode",
  "namespace" : "com.example",
  "symbols" : [ "APP_A", "APP_B" ]
}

And referenced it in my main Avro like this:

"fields": [
    {
      "name": "masterApplicationCode",
      "type": "ApplicationCode"
    }, 

It works like that but unfortunately I am losing the Application Codes (eg "MY-APP-A") using this approach. I'm looking for something, that allows me to include both, the code and the label. Something like

{
  "type" : "enum",
  "name" : "ApplicationCode",
  "namespace" : "com.example",
  "symbols" : [ "APP_A("MY-APP-A")", "APP_B("MY-APP-B")" ]
}

Is it even possible to have this kind of complex enums or is there any workaround to achieve this?

I believe the avro schema is internally transforming it into a JSON String. So, I think the question is more about serializing enums. Reference from here - https://www.baeldung.com/jackson-serialize-enums

I think it should return the code if you use JsonFormat annotation like this -

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum ApplicationCode {

Otherwise you will need to add a Custom Serializer for enum.

I solved my problem by writing custom serializer / deserializer that map an object with complex typed fields to one that is being sent with eg Strings instead of enums.

Here an example of the custom serializer:

public class CustomSerializer implements Serializer<ApplicationObject> {

    @Override
    public byte[] serialize(String topic, ApplicationObject ApplicationObjectDto) {
        com.example.avro.ApplicationObject applicationObject = com.example.avro.ApplicationObject.newBuilder()
                .setApplicationCode(ApplicationObjectDto.getApplicationCode().getCode())
                .build();
        return SerializationUtils.serialize(applicationObject);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM