|
24 | 24 | import io.gsonfire.GsonFireBuilder;
|
25 | 25 | import io.gsonfire.TypeSelector;
|
26 | 26 |
|
| 27 | +import io.kubernetes.client.gson.V1MetadataExclusionStrategy; |
| 28 | +import io.kubernetes.client.gson.V1StatusPreProcessor; |
| 29 | +import io.kubernetes.client.openapi.models.V1Status; |
27 | 30 | import okio.ByteString;
|
28 | 31 |
|
29 | 32 | import java.io.IOException;
|
|
38 | 41 | import java.time.LocalDate;
|
39 | 42 | import java.time.OffsetDateTime;
|
40 | 43 | import java.time.format.DateTimeFormatter;
|
| 44 | +import java.time.format.DateTimeFormatterBuilder; |
| 45 | +import java.time.format.DateTimeParseException; |
| 46 | +import java.time.temporal.ChronoField; |
41 | 47 | import java.util.Date;
|
42 | 48 | import java.util.Locale;
|
43 | 49 | import java.util.Map;
|
|
52 | 58 | public class JSON {
|
53 | 59 | private static Gson gson;
|
54 | 60 | private static boolean isLenientOnJson = false;
|
| 61 | + |
| 62 | + private static final DateTimeFormatter RFC3339MICRO_FORMATTER = |
| 63 | + new DateTimeFormatterBuilder() |
| 64 | + .parseDefaulting(ChronoField.OFFSET_SECONDS, 0) |
| 65 | + .append(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")) |
| 66 | + .optionalStart() |
| 67 | + .appendFraction(ChronoField.NANO_OF_SECOND, 6, 6, true) |
| 68 | + .optionalEnd() |
| 69 | + .appendLiteral("Z") |
| 70 | + .toFormatter(); |
| 71 | + |
55 | 72 | private static DateTypeAdapter dateTypeAdapter = new DateTypeAdapter();
|
56 | 73 | private static SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
|
57 |
| - private static OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(); |
| 74 | + private static OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(RFC3339MICRO_FORMATTER); |
58 | 75 | private static LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
|
59 | 76 | private static ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();
|
60 | 77 |
|
61 | 78 | @SuppressWarnings("unchecked")
|
62 | 79 | public static GsonBuilder createGson() {
|
63 | 80 | GsonFireBuilder fireBuilder = new GsonFireBuilder()
|
64 | 81 | ;
|
65 |
| - GsonBuilder builder = fireBuilder.createGsonBuilder(); |
66 |
| - return builder; |
| 82 | + GsonBuilder builder = |
| 83 | + fireBuilder |
| 84 | + .registerPreProcessor(V1Status.class, new V1StatusPreProcessor()) |
| 85 | + .createGsonBuilder(); |
| 86 | + return builder.setExclusionStrategies(new V1MetadataExclusionStrategy()); |
67 | 87 | }
|
68 | 88 |
|
69 | 89 | private static String getDiscriminatorValue(JsonElement readElement, String discriminatorField) {
|
@@ -884,11 +904,14 @@ public static class ByteArrayAdapter extends TypeAdapter<byte[]> {
|
884 | 904 |
|
885 | 905 | @Override
|
886 | 906 | public void write(JsonWriter out, byte[] value) throws IOException {
|
| 907 | + boolean oldHtmlSafe = out.isHtmlSafe(); |
| 908 | + out.setHtmlSafe(false); |
887 | 909 | if (value == null) {
|
888 | 910 | out.nullValue();
|
889 | 911 | } else {
|
890 | 912 | out.value(ByteString.of(value).base64());
|
891 | 913 | }
|
| 914 | + out.setHtmlSafe(oldHtmlSafe); |
892 | 915 | }
|
893 | 916 |
|
894 | 917 | @Override
|
@@ -944,7 +967,12 @@ public OffsetDateTime read(JsonReader in) throws IOException {
|
944 | 967 | if (date.endsWith("+0000")) {
|
945 | 968 | date = date.substring(0, date.length()-5) + "Z";
|
946 | 969 | }
|
947 |
| - return OffsetDateTime.parse(date, formatter); |
| 970 | + try { |
| 971 | + return OffsetDateTime.parse(date, formatter); |
| 972 | + } catch (DateTimeParseException e) { |
| 973 | + // backward-compatibility for ISO8601 timestamp format |
| 974 | + return OffsetDateTime.parse(date, DateTimeFormatter.ISO_OFFSET_DATE_TIME); |
| 975 | + } |
948 | 976 | }
|
949 | 977 | }
|
950 | 978 | }
|
|
0 commit comments