I have lib class Dimension3D which contains 3 fields and I want to convert
it as one avro filed.

My definition of logical type connected classes:
public class Dim3AvroLogicalType {

  public static final String LOGICAL_TYPE_NAME = "dim3";

  public static class Dim3LogicalType extends LogicalType {

    Dim3LogicalType() {
      super(LOGICAL_TYPE_NAME);
    }

    @Override
    public void validate(Schema schema) {
      super.validate(schema);
      if (schema.getType() != Schema.Type.MAP) {
        throw new IllegalArgumentException(
            String.format("Logical type '%s' must be backed by Map",
LOGICAL_TYPE_NAME));
      }
    }
  }

  public static class Dim3Factory implements
LogicalTypes.LogicalTypeFactory {

    @Override
    public LogicalType fromSchema(Schema schema) {
      return new Dim3LogicalType();
    }

    @Override
    public String getTypeName() {
      return LOGICAL_TYPE_NAME;
    }
  }

  public static class Dim3Conversion extends Conversion<Dimension3D> {

    @Override
    public Class<Dimension3D> getConvertedType() {
      return Dimension3D.class;
    }

    @Override
    public String getLogicalTypeName() {
      return LOGICAL_TYPE_NAME;
    }

    @Override
    public Dimension3D fromMap(Map<?, ?> value, Schema schema, LogicalType
type) {
      return Dimension3D.of(
          Length.of(new BigDecimal(value.get("length").toString())),
          Length.of(new BigDecimal(value.get("width").toString())),
          Length.of(new BigDecimal(value.get("height").toString()))
      );
    }

    @Override
    public Map<?, ?> toMap(Dimension3D dimension3D, Schema schema,
LogicalType type) {
      return Map.of(
          "length", dimension3D.getLength().toDecimal().toString(),
          "width", dimension3D.getWidth().toDecimal().toString(),
          "height", dimension3D.getHeight().toDecimal().toString()
      );
    }
  }
}

interesting part of avro definition:
          {
            "name": "dimension",
            "type": {
              "type": "map",
              "logicalType": "dim3",
              "values": "string"
            }
          }

after executing maven task I got:

public java.util.Map<java.lang.String,java.lang.String> getDimension().
Moreover there is no proper converter added to MODEL$ while other
converters are added correctly.

I'm using:
      <plugin>
        <groupId>org.apache.avro</groupId>
        <artifactId>avro-maven-plugin</artifactId>
        <version>1.11.3</version>

proper customLogicalTypeFactory & customConversion are added into
configuration.

How to properly use logical type with map backing type?

Reply via email to