Skip to content

Commit 6b58e9b

Browse files
Add logical types for JSON to Avro converters (#187)
* add logical types for json to avro converter and avro to json converters #148 * reformat avro
1 parent 557fdaa commit 6b58e9b

File tree

5 files changed

+537
-176
lines changed

5 files changed

+537
-176
lines changed

kstreamplify-core/src/main/java/com/michelin/kstreamplify/converter/AvroToJsonConverter.java

Lines changed: 90 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,19 @@
1919

2020
import com.google.gson.Gson;
2121
import com.google.gson.GsonBuilder;
22+
import com.google.gson.JsonDeserializationContext;
23+
import com.google.gson.JsonDeserializer;
24+
import com.google.gson.JsonElement;
25+
import com.google.gson.JsonParseException;
26+
import com.google.gson.JsonPrimitive;
27+
import com.google.gson.JsonSerializationContext;
28+
import com.google.gson.JsonSerializer;
29+
import java.lang.reflect.Type;
2230
import java.time.Instant;
31+
import java.time.LocalDate;
32+
import java.time.LocalDateTime;
33+
import java.time.LocalTime;
34+
import java.time.format.DateTimeFormatter;
2335
import java.util.HashMap;
2436
import java.util.List;
2537
import java.util.Map;
@@ -35,8 +47,11 @@ private AvroToJsonConverter() {
3547
}
3648

3749
private static final Gson gson = new GsonBuilder()
38-
.setPrettyPrinting()
39-
.create();
50+
.registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter())
51+
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter())
52+
.registerTypeAdapter(LocalTime.class, new LocalTimeTypeAdapter())
53+
.setPrettyPrinting()
54+
.create();
4055

4156
/**
4257
* Convert the record from avro format to json format.
@@ -66,15 +81,15 @@ private static Map<String, Object> recordAsMap(GenericRecord inputRecord) {
6681

6782
if (recordValue instanceof List<?> recordValueAsList) {
6883
recordValue = recordValueAsList
69-
.stream()
70-
.map(value -> {
71-
if (value instanceof GenericRecord genericRecord) {
72-
return recordAsMap(genericRecord);
73-
} else {
74-
return value.toString();
75-
}
76-
})
77-
.toList();
84+
.stream()
85+
.map(value -> {
86+
if (value instanceof GenericRecord genericRecord) {
87+
return recordAsMap(genericRecord);
88+
} else {
89+
return value.toString();
90+
}
91+
})
92+
.toList();
7893
}
7994

8095
if (recordValue instanceof Map<?, ?> recordValueAsMap) {
@@ -99,4 +114,68 @@ private static Map<String, Object> recordAsMap(GenericRecord inputRecord) {
99114

100115
return recordMapping;
101116
}
117+
118+
private static class LocalDateTypeAdapter implements JsonSerializer<LocalDate>, JsonDeserializer<LocalDate> {
119+
120+
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
121+
122+
@Override
123+
public JsonElement serialize(final LocalDate date, final Type typeOfSrc,
124+
final JsonSerializationContext context) {
125+
return new JsonPrimitive(date.format(formatter));
126+
}
127+
128+
@Override
129+
public LocalDate deserialize(JsonElement json, Type typeOfT,
130+
JsonDeserializationContext context) throws JsonParseException {
131+
return LocalDate.parse(json.getAsString(), formatter);
132+
}
133+
}
134+
135+
private static class LocalDateTimeTypeAdapter implements JsonSerializer<LocalDateTime>,
136+
JsonDeserializer<LocalDateTime> {
137+
138+
private static final DateTimeFormatter formatter =
139+
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
140+
private static final DateTimeFormatter formatterNano =
141+
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS");
142+
143+
@Override
144+
public JsonElement serialize(LocalDateTime localDateTime, Type srcType,
145+
JsonSerializationContext context) {
146+
if (localDateTime.toString().length() == 29) {
147+
return new JsonPrimitive(formatterNano.format(localDateTime));
148+
}
149+
return new JsonPrimitive(formatter.format(localDateTime));
150+
}
151+
152+
@Override
153+
public LocalDateTime deserialize(JsonElement json, Type typeOfT,
154+
JsonDeserializationContext context) throws JsonParseException {
155+
return LocalDateTime.parse(json.getAsString(), formatter);
156+
}
157+
}
158+
159+
private static class LocalTimeTypeAdapter implements JsonSerializer<LocalTime>, JsonDeserializer<LocalTime> {
160+
161+
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
162+
private static final DateTimeFormatter formatterNano = DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSS");
163+
164+
@Override
165+
public JsonElement serialize(LocalTime localTime, Type srcType,
166+
JsonSerializationContext context) {
167+
if (localTime.toString().length() == 15) {
168+
return new JsonPrimitive(formatterNano.format(localTime));
169+
}
170+
return new JsonPrimitive(formatter.format(localTime));
171+
}
172+
173+
@Override
174+
public LocalTime deserialize(JsonElement json, Type typeOfT,
175+
JsonDeserializationContext context) throws JsonParseException {
176+
177+
return LocalTime.parse(json.getAsString(), formatter);
178+
}
179+
}
180+
102181
}

0 commit comments

Comments
 (0)