package com.at.avro.config; import java.math.BigDecimal; import java.util.Date; import java.util.function.BiConsumer; import java.util.function.Function; import com.at.avro.AvroSchema; import schemacrawler.schema.Table; /** * Configuration that allows avro model tweaking. Model is then used to generate schemas. * * @author [email protected] */ public class AvroConfig { private boolean representEnumsAsStrings = false; private boolean nullableTrueByDefault = false; private boolean allFieldsDefaultNull = false; private Class<?> decimalTypeClass = BigDecimal.class; private Class<?> dateTypeClass = Date.class; private final String namespace; private Function<String, String> schemaNameMapper = tableName -> tableName; private Function<String, String> fieldNameMapper = columnName -> columnName; private Function<String, String> unknownTypeResolver = dbType -> { throw new IllegalArgumentException("unknown data type: " + dbType); }; private BiConsumer<AvroSchema, Table> avroSchemaPostProcessor = (schema, table) -> {}; public AvroConfig(String namespace) { this.namespace = namespace; } /** * Provide custom schema name resolver function which takes DB table name as an input. * Table name is used by default. */ public AvroConfig setSchemaNameMapper(Function<String, String> schemaNameMapper) { this.schemaNameMapper = schemaNameMapper; return this; } public Function<String, String> getSchemaNameMapper() { return schemaNameMapper; } /** * Provide custom field names resolver function which takes DB column name as an input. * Column name is used by default. */ public AvroConfig setFieldNameMapper(Function<String, String> fieldNameMapper) { this.fieldNameMapper = fieldNameMapper; return this; } public Function<String, String> getFieldNameMapper() { return fieldNameMapper; } /** * Resolve 'enum' type to 'string' instead of 'enum'. */ public AvroConfig setRepresentEnumsAsStrings(boolean representEnumsAsStrings) { this.representEnumsAsStrings = representEnumsAsStrings; return this; } public boolean representEnumsAsStrings() { return representEnumsAsStrings; } /** * Set to true to make all fields default to null. DB column definition is used by default. */ public AvroConfig setAllFieldsDefaultNull(boolean allFieldsDefaultNull) { this.allFieldsDefaultNull = allFieldsDefaultNull; return this; } public boolean isAllFieldsDefaultNull() { return allFieldsDefaultNull; } public String getNamespace() { return namespace; } /** * Set to true to make all fields nullable in avro schema. DB column definition is used by default. */ public AvroConfig setNullableTrueByDefault(boolean nullableTrueByDefault) { this.nullableTrueByDefault = nullableTrueByDefault; return this; } public boolean isNullableTrueByDefault() { return nullableTrueByDefault; } /** * Sets a "java-class" property in this fields definition. * This might be used by avro java code generator to use the class you want for dates. */ public AvroConfig setDateTypeClass(Class<?> dateTypeClass) { this.dateTypeClass = dateTypeClass; return this; } public Class<?> getDateTypeClass() { return dateTypeClass; } /** * Sets a "java-class" property in this fields definition. * This might be used by avro java code generator to use the class you want for decimals. */ public AvroConfig setDecimalTypeClass(Class<?> decimalTypeClass) { this.decimalTypeClass = decimalTypeClass; return this; } public Class<?> getDecimalTypeClass() { return decimalTypeClass; } /** * Provide mapper for unknown db types. Throws IllegalArgumentException by default. * For example, if you want to default all unknown types to string: * <code> * avroConfig.setUnknownTypeResolver(type -> "string") * </code> * IllegalArgumentException is thrown by default. **/ public AvroConfig setUnknownTypeResolver(Function<String, String> unknownTypeResolver) { this.unknownTypeResolver = unknownTypeResolver; return this; } public Function<String, String> getUnknownTypeResolver() { return unknownTypeResolver; } /** * Set a callback that will be called after avro model was built. * Schema model is ready by this point, but you can still modify it by adding custom properties. */ public AvroConfig setAvroSchemaPostProcessor(BiConsumer<AvroSchema, Table> avroSchemaPostProcessor) { this.avroSchemaPostProcessor = avroSchemaPostProcessor; return this; } public BiConsumer<AvroSchema, Table> getAvroSchemaPostProcessor() { return avroSchemaPostProcessor; } }