From 9a81b4c1c8d856491f7b9efdb4294b9cd0089dc5 Mon Sep 17 00:00:00 2001 From: Steve Hawkins Date: Fri, 26 Apr 2024 11:17:46 -0400 Subject: [PATCH] fix: updating the kubernetesserializer handling of time types closes: #5960 Signed-off-by: Steve Hawkins --- CHANGELOG.md | 2 ++ .../crd/generator/types/TypeMappingsTest.java | 20 +++++++++---------- .../client/utils/KubernetesSerialization.java | 3 +++ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e788acd514..c56abe8fa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### 6.13-SNAPSHOT #### Bugs +* Fix #5960: The serialization of time related types should be string * Fix #5866: Addressed cycle in crd generation with Java 19+ and ZonedDateTime #### Improvements @@ -17,6 +18,7 @@ #### New Features #### _**Note**_: Breaking changes +* Fix #5960: The KubernetesSerializer will now by default serialize time related types to strings - rather than object, integer, number, or arrays of integer / number. If you are using these types in a custom object and were not including JsonFormat annotations to adjust the serialization they were likely being serialized in a non-standard way that would not be usable other Kubernetes clients, nor match the generated custom resource definition if one was being produced. Please open an issue if you need the previous behavior for whatever reason - there is a workaround by creating a customized KubernetesSerializer. ### 6.12.1 (2024-04-18) diff --git a/crd-generator/test/src/test/java/io/fabric8/crd/generator/types/TypeMappingsTest.java b/crd-generator/test/src/test/java/io/fabric8/crd/generator/types/TypeMappingsTest.java index 5eda53475f..c8ba310005 100644 --- a/crd-generator/test/src/test/java/io/fabric8/crd/generator/types/TypeMappingsTest.java +++ b/crd-generator/test/src/test/java/io/fabric8/crd/generator/types/TypeMappingsTest.java @@ -52,17 +52,17 @@ void targetType(String propertyName, String expectedType) { private static Stream targetTypeCases() { return Stream.of( Arguments.of("date", "string"), - Arguments.of("localDate", "array"), // to review - Arguments.of("localDateTime", "array"), // to review - Arguments.of("zonedDateTime", "number"), // to review - Arguments.of("offsetDateTime", "number"), // to review - Arguments.of("offsetTime", "array"), // to review - Arguments.of("yearMonth", "array"), // to review - Arguments.of("monthDay", "array"), // to review - Arguments.of("instant", "number"), // to review - Arguments.of("duration", "integer"), // to review + Arguments.of("localDate", "string"), + Arguments.of("localDateTime", "string"), + Arguments.of("zonedDateTime", "string"), + Arguments.of("offsetDateTime", "string"), + Arguments.of("offsetTime", "string"), + Arguments.of("yearMonth", "string"), + Arguments.of("monthDay", "string"), + Arguments.of("instant", "string"), + Arguments.of("duration", "string"), Arguments.of("period", "string"), - Arguments.of("timestamp", "integer"), // to review + Arguments.of("timestamp", "string"), // to review // Arguments.of("aShort", "integer"), // TODO: Not even present in the CRD Arguments.of("aShortObj", "integer"), Arguments.of("aInt", "integer"), diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/KubernetesSerialization.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/KubernetesSerialization.java index 609bf20a0e..db04df0247 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/KubernetesSerialization.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/KubernetesSerialization.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.KeyDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.cfg.HandlerInstantiator; import com.fasterxml.jackson.databind.cfg.MapperConfig; import com.fasterxml.jackson.databind.introspect.Annotated; @@ -90,6 +91,8 @@ public KubernetesSerialization(ObjectMapper mapper, boolean searchClassloaders) protected void configureMapper(ObjectMapper mapper) { mapper.registerModules(new JavaTimeModule(), unmatchedFieldTypeModule); mapper.disable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + mapper.disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS); // omit null fields, but keep null map values mapper.setDefaultPropertyInclusion(JsonInclude.Value.construct(Include.NON_NULL, Include.ALWAYS)); HandlerInstantiator instanciator = mapper.getDeserializationConfig().getHandlerInstantiator();