Uploaded image for project: 'Apache Avro'
  1. Apache Avro
  2. AVRO-2493

Unable to register Logical Type for custom Conversion class

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.9.0
    • 1.10.0
    • java, logical types
    • None

    Description

      I have created a custom conversion class for Java's (1.8) java.time.OffsetDateTime.

      public class OffsetDateTimeConversion extends Conversion<OffsetDateTime> {
          private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.nnnnnnZZZZZ");
      
          @Override
          public Class<OffsetDateTime> getConvertedType() {
              return OffsetDateTime.class;
          }
      
          @Override
          public String getLogicalTypeName() {
              return "offset-date-time";
          }
      
          @Override
          public OffsetDateTime fromCharSequence(CharSequence value, Schema schema, LogicalType type) {
              return OffsetDateTime.parse(value, DATE_TIME_FORMATTER);
          }
      
          @Override
          public CharSequence toCharSequence(OffsetDateTime value, Schema schema, LogicalType type) {
              return value.format(DATE_TIME_FORMATTER);
          }
      }
      

       And my simple schema to test (including a field that uses the built-in "time-millis" converter in Avro 1.9 for testing purposes):

      TimeTest.avsc

       

      {
         "type": "record",
         "name": "TimeTest",
         "namespace": "time.test",
         "fields": [
            {
                 "name": "createTime",
                 "type": {
                     "type": "int",
                     "logicalType": "time-millis"
                 }
            },
            {
                 "name": "createDateTime",
                 "type": {
                     "type": "string",
                     "logicalType": "offset-date-time"
                 }
            }
         ]
      }
      

       

      I've also created a LogicalType for my conversion field that I need to register:

       

      public class OffsetDateTimeLogicalType extends LogicalType {
          public static final String LOGICAL_DATE_TIME_NAME = "offset-date-time";
      
          public OffsetDateTimeLogicalType() {
              super(LOGICAL_DATE_TIME_NAME);
          }
      
          @Override
          public void validate(Schema schema) {
              super.validate(schema);
              if (schema.getType() != Schema.Type.STRING) {
                  throw new IllegalArgumentException("Logical type 'offset-date-time' must be of type string");
              }
          }
      }

       

      I've been debugging the avro-maven-plugin and have been able to pinpoint where my issue is occurring while parsing the schema:

       

      // parse logical type if present
      result.logicalType = LogicalTypes.fromSchemaIgnoreInvalid(result);
      

       

      The schema's "logicalType" property is being set to null because it's not a registered logical type.

      The code I need to execute is:

       

      LogicalTypes.register(getLogicalTypeName(), schema -> new OffsetDateTimeLogicalType());
      

      Without modifying the plugin code, I see no way to execute this register so that the Schema.parse method (which is called before the conversion class is executed) will recognize this LogicalType.

       

      The plugin has a config property <enableDecimalLogicalType> to allow for registering the Decimal logical types but nothing to enable other logical types.

      Am I missing something or is this a real issue?

      Attachments

        Issue Links

          Activity

            People

              pavel.likin Pavel Likin
              trav017 Travis Yocum
              Votes:
              3 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: