Le dernier compilateur Avro (1.8.2) génère Java sources pour types logiques de dates avec Joda-Time implémentations basées. Comment puis-je configurer Avro compilateur pour produire des sources utilisant Java 8 API date-heure?
Actuellement (avro 1.8.2) ce n'est pas possible. Il est codé en dur pour générer des classes de date/heure Joda.
La branche master
actuelle est passée à Java 8 et il y a problème ouvert (avec Pull Request ) à ajouter la possibilité de générer des classes avec Java.time.*
les types.
Je n'ai aucune idée de tout type de calendrier de sortie pour ce qui est actuellement dans master
malheureusement. Si vous vous sentez aventureux, vous pouvez appliquer le patch à 1.8.2
, car en théorie, tout devrait être compatible. Les types de base sous-jacents lors de la sérialisation/désérialisation sont toujours des nombres entiers et longs.
Vous devez créer votre propre Conversion s pour prendre en charge l'API date-heure Java-8, voici une conversion pour Java.time.LocalDate
:
class Java8LocalDateConversion extends Conversion<LocalDate> {
@Override
public Class<LocalDate> getConvertedType() {
return LocalDate.class;
}
@Override
public String getLogicalTypeName() {
// v--- reuse the logical type `date`
return "date";
}
@Override
// convert LocalDate to Integer
public Integer toInt(LocalDate value, Schema schema, LogicalType type) {
return (int) value.toEpochDay();
}
@Override
// parse LocalDate from Integer
public LocalDate fromInt(Integer value, Schema schema, LogicalType type) {
return LocalDate.ofEpochDay(value);
}
}
Les types logiques peuvent être réutilisés dans avro, vous pouvez donc utiliser le type logique date
existant, par exemple:
Schema schema = LogicalTypes.date().addToSchema(Schema.create(Type.INT));
Pour la sérialisation et la désérialisation, vous devez définir le GenericData
qui trouvera votre propre conversion, par exemple:
//serializing
DatumWriter<T> out = new SpecificDatumWriter<>(schema, data());
// deserializing
DatumReader<T> in = new SpecificDatumReader<>(schema, schema, data());
private SpecificData data() {
SpecificData it = new SpecificData();
it.addLogicalTypeConversion(new Java8LocalDateConversion());
return it;
}
Si vous ne souhaitez pas configurer le GenericData
à chaque fois, vous pouvez utiliser le global GenericData
à la place, par exemple:
// register the conversion globally ---v
SpecificData.get().addLogicalTypeConversion(new Java8LocalDateConversion());
Avec avro 1.9.2, vous pouvez utiliser par exemple date pour LocalDate
:
{
"name": "Transaction",
"type": "record",
"fields": [
{
"name": "time",
"type": {
"type": "int",
"logicalType": "date"
}
},
Voir Types logiques pour les autres types.