3

I'm new to AVRO, trying to create a custom Logical Type which can validate AVRO data using Regular Expression just as the use cases from this question: Data validation in AVRO

var type = avro.parse({
  name: 'Example',
  type: 'record',
  fields: [
    {
      name: 'custId',
      type: 'string' // Normal (free-form) string.
    },
    {
      name: 'sessionId',
      type: {
        type: 'string',
        logicalType: 'validated-string',
        pattern: '^\\d{3}-\\d{4}-\\d{5}$' // Validation pattern.
      }
    },
  ]
}, {logicalTypes: {'validated-string': ValidatedString}});

type.isValid({custId: 'abc', sessionId: '123-1234-12345'}); // true
type.isValid({custId: 'abc', sessionId: 'foobar'}); // false

But the example is written in JS. However, how to implement it using Java, I finish reading this question:

How to define a LogicalType in Avro. (java)

Currently, I extend the custom Logical Type Class as the above answer:

The following JS code does in the demo answer could receive RegExp pattern from Schema.

function ValidatedString(attrs, opts) {
  avro.types.LogicalType.call(this, attrs, opts);
  this._pattern = new RegExp(attrs.pattern);
}

My question is how can I extend the Conversion/LogicalType Class like the JS code? From my understanding, I create the Conversion and Logical Type Class, but how can I use the RegExp pattern from a Schema AVRO file so as to validate the new data?

import org.apache.avro.LogicalType;

public class RegExpLogicalType extends LogicalType {
    //The key to use as a reference to the type
    public static final String REGEXP_LOGICAL_TYPE_NAME = "regexp";
    public String regexp_pattern;

    RegExpLogicalType() {
        super(REGEXP_LOGICAL_TYPE_NAME);
    }

    private RegExpLogicalType(String regexp_pattern) {
        super(REGEXP_LOGICAL_TYPE_NAME);
        this.regexp_pattern = regexp_pattern;
    }
}
public class RegExpConversion extends Conversion<ByteBuffer> {

    private static final RegExpConversion INSTANCE = new RegExpConversion();
    public static final RegExpConversion get(){ return INSTANCE; }
    private RegExpConversion(){ super(); }

    ...

    @Override
    public ByteBuffer fromBytes(ByteBuffer value, Schema schema, LogicalType type) {

        /* How can I get the RegExp pattern from the the Schema pre defined? */
        String regexp_pattern = ?????;
        /* So I can use the pattern to validate value in the following code */

        if (Pattern.matches(regexp_pattern, new String(value.array(), StandardCharsets.UTF_8))) {
            return value;
        }
        throw new IllegalArgumentException("Invalid pattern : " + value + " (must be ...)");

    }
}

Thanks a lot in advance.

zfz
  • 1,597
  • 1
  • 22
  • 45

0 Answers0