diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/Serialization.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/Serialization.java index 4182c9e9201..dc994ca3a42 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/Serialization.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/Serialization.java @@ -25,7 +25,7 @@ import io.fabric8.kubernetes.api.model.GenericKubernetesResource; import io.fabric8.kubernetes.api.model.KubernetesResource; import io.fabric8.kubernetes.client.KubernetesClientException; -import io.fabric8.kubernetes.client.utils.serialization.UnmatchedFieldTypeModule; +import io.fabric8.kubernetes.model.jackson.UnmatchedFieldTypeModule; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.SafeConstructor; @@ -419,17 +419,8 @@ public static T clone(T resource) { // if full serialization seems too expensive, there is also //return (T) JSON_MAPPER.convertValue(resource, resource.getClass()); try { - return JSON_MAPPER.readValue( - JSON_MAPPER.writeValueAsString(resource), new TypeReference() { - @Override - public Type getType() { - if (resource instanceof KubernetesResource) { - // Force KubernetesResource so that the KubernetesDeserializer takes over any resource configured deserializer - return resource instanceof GenericKubernetesResource ? resource.getClass() : KubernetesResource.class; - } - return resource.getClass(); - } - }); + return (T) JSON_MAPPER.readValue( + JSON_MAPPER.writeValueAsString(resource), resource.getClass()); } catch (JsonProcessingException e) { throw new IllegalStateException(e); } diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/serialization/SettableBeanPropertyDelegateTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/model/jackson/SettableBeanPropertyDelegateTest.java similarity index 83% rename from kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/serialization/SettableBeanPropertyDelegateTest.java rename to kubernetes-client-api/src/test/java/io/fabric8/kubernetes/model/jackson/SettableBeanPropertyDelegateTest.java index fe1b0243784..07184e9cf09 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/serialization/SettableBeanPropertyDelegateTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/model/jackson/SettableBeanPropertyDelegateTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.fabric8.kubernetes.client.utils.serialization; +package io.fabric8.kubernetes.model.jackson; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.deser.SettableAnyProperty; @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -41,12 +42,14 @@ class SettableBeanPropertyDelegateTest { private SettableBeanProperty delegateMock; private SettableAnyProperty anySetterMock; private SettableBeanPropertyDelegate settableBeanPropertyDelegate; + private AtomicBoolean useAnySetter = new AtomicBoolean(); @BeforeEach void setUp() { delegateMock = mock(SettableBeanProperty.class, RETURNS_DEEP_STUBS); anySetterMock = mock(SettableAnyProperty.class); - settableBeanPropertyDelegate = new SettableBeanPropertyDelegate(delegateMock, anySetterMock, () -> false); + useAnySetter.set(false); + settableBeanPropertyDelegate = new SettableBeanPropertyDelegate(delegateMock, anySetterMock, () -> useAnySetter.get()); } @Test @@ -58,10 +61,10 @@ void withValueDeserializer() { final SettableBeanProperty result = settableBeanPropertyDelegate.withValueDeserializer(null); // Then assertThat(result) - .isInstanceOf(SettableBeanPropertyDelegate.class) - .isNotSameAs(settableBeanPropertyDelegate) - .hasFieldOrPropertyWithValue("anySetter", anySetterMock) - .hasFieldOrPropertyWithValue("delegate", delegateMock); + .isInstanceOf(SettableBeanPropertyDelegate.class) + .isNotSameAs(settableBeanPropertyDelegate) + .hasFieldOrPropertyWithValue("anySetter", anySetterMock) + .hasFieldOrPropertyWithValue("delegate", delegateMock); } @Test @@ -73,10 +76,10 @@ void withName() { final SettableBeanProperty result = settableBeanPropertyDelegate.withName(null); // Then assertThat(result) - .isInstanceOf(SettableBeanPropertyDelegate.class) - .isNotSameAs(settableBeanPropertyDelegate) - .hasFieldOrPropertyWithValue("anySetter", anySetterMock) - .hasFieldOrPropertyWithValue("delegate", delegateMock); + .isInstanceOf(SettableBeanPropertyDelegate.class) + .isNotSameAs(settableBeanPropertyDelegate) + .hasFieldOrPropertyWithValue("anySetter", anySetterMock) + .hasFieldOrPropertyWithValue("delegate", delegateMock); } @Test @@ -88,10 +91,10 @@ void withNullProvider() { final SettableBeanProperty result = settableBeanPropertyDelegate.withNullProvider(null); // Then assertThat(result) - .isInstanceOf(SettableBeanPropertyDelegate.class) - .isNotSameAs(settableBeanPropertyDelegate) - .hasFieldOrPropertyWithValue("anySetter", anySetterMock) - .hasFieldOrPropertyWithValue("delegate", delegateMock); + .isInstanceOf(SettableBeanPropertyDelegate.class) + .isNotSameAs(settableBeanPropertyDelegate) + .hasFieldOrPropertyWithValue("anySetter", anySetterMock) + .hasFieldOrPropertyWithValue("delegate", delegateMock); } @Test @@ -186,9 +189,10 @@ void deserializeSetAndReturnWithException() throws IOException { final Object instance = new Object(); when(delegateMock.getName()).thenReturn("the-property"); when(delegateMock.deserializeSetAndReturn(any(), any(), eq(instance))) - .thenThrow(MismatchedInputException.from(null, Integer.class, "The Mocked Exception")); + .thenThrow(MismatchedInputException.from(null, Integer.class, "The Mocked Exception")); doThrow(MismatchedInputException.from(null, Integer.class, "The Mocked Exception")) - .when(delegateMock).deserializeAndSet(any(), any(), eq(instance)); + .when(delegateMock).deserializeAndSet(any(), any(), eq(instance)); + useAnySetter.set(true); // When final Object result = settableBeanPropertyDelegate.deserializeSetAndReturn(mock(JsonParser.class), null, instance); // Then diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/serialization/UnmatchedFieldTypeModuleTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/model/jackson/UnmatchedFieldTypeModuleTest.java similarity index 99% rename from kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/serialization/UnmatchedFieldTypeModuleTest.java rename to kubernetes-client-api/src/test/java/io/fabric8/kubernetes/model/jackson/UnmatchedFieldTypeModuleTest.java index 6b4deb70ec4..40aebdddcfc 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/serialization/UnmatchedFieldTypeModuleTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/model/jackson/UnmatchedFieldTypeModuleTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.fabric8.kubernetes.client.utils.serialization; +package io.fabric8.kubernetes.model.jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/kubernetes-model-generator/kubernetes-model-common/pom.xml b/kubernetes-model-generator/kubernetes-model-common/pom.xml index ac5cdb37b36..f03cb6849b3 100644 --- a/kubernetes-model-generator/kubernetes-model-common/pom.xml +++ b/kubernetes-model-generator/kubernetes-model-common/pom.xml @@ -33,6 +33,10 @@ com.fasterxml.jackson.core jackson-databind + + org.slf4j + slf4j-api + diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/serialization/BeanPropertyWriterDelegate.java b/kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/BeanPropertyWriterDelegate.java similarity index 88% rename from kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/serialization/BeanPropertyWriterDelegate.java rename to kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/BeanPropertyWriterDelegate.java index 0a4d61c1584..7f73c2a76bc 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/serialization/BeanPropertyWriterDelegate.java +++ b/kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/BeanPropertyWriterDelegate.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.fabric8.kubernetes.client.utils.serialization; +package io.fabric8.kubernetes.model.jackson; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; @@ -29,10 +29,12 @@ * Variant of {@link BeanPropertyWriter} which prevents property values present in the {@link AnnotatedMember} anyGetter * to be serialized twice. * - *

Any property that's present in the anyGetter is ignored upon serialization. The values present in the anyGetter + *

+ * Any property that's present in the anyGetter is ignored upon serialization. The values present in the anyGetter * take precedence over those stored in the Bean's fields. * - *

This BeanPropertyWriter implementation is intended to be used in combination with + *

+ * This BeanPropertyWriter implementation is intended to be used in combination with * the {@link SettableBeanPropertyDelegate} to allow the propagation of deserialized properties that don't match the * target field types. */ @@ -64,7 +66,7 @@ public void serializeAsField(Object bean, JsonGenerator gen, SerializerProvider delegate.serializeAsField(bean, gen, prov); } else if (Boolean.TRUE.equals(logDuplicateWarning.get())) { logger.warn("Value in field '{}' ignored in favor of value in additionalProperties ({}) for {}", - delegate.getName(), valueInAnyGetter, bean.getClass().getName()); + delegate.getName(), valueInAnyGetter, bean.getClass().getName()); } } } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/serialization/SettableBeanPropertyDelegate.java b/kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/SettableBeanPropertyDelegate.java similarity index 80% rename from kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/serialization/SettableBeanPropertyDelegate.java rename to kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/SettableBeanPropertyDelegate.java index 13c86bf66f9..d93881617ab 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/serialization/SettableBeanPropertyDelegate.java +++ b/kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/SettableBeanPropertyDelegate.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.fabric8.kubernetes.client.utils.serialization; +package io.fabric8.kubernetes.model.jackson; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationConfig; @@ -25,29 +25,29 @@ import com.fasterxml.jackson.databind.deser.SettableBeanProperty; import com.fasterxml.jackson.databind.exc.MismatchedInputException; import com.fasterxml.jackson.databind.introspect.AnnotatedMember; -import io.fabric8.kubernetes.internal.KubernetesDeserializer; import java.io.IOException; import java.lang.annotation.Annotation; -import java.util.function.Supplier; +import java.util.function.BooleanSupplier; /** * This concrete sub-class encapsulates a {@link SettableBeanProperty} delegate that is always tried first. * - *

A fall-back mechanism is implemented in the deserializeAndSet methods to allow field values that don't match the + *

+ * A fall-back mechanism is implemented in the deserializeAndSet methods to allow field values that don't match the * target type to be preserved in the anySetter method if exists. */ public class SettableBeanPropertyDelegate extends SettableBeanProperty { private final SettableBeanProperty delegate; private final SettableAnyProperty anySetter; - private final transient Supplier restrictToTemplates; + private final transient BooleanSupplier useAnySetter; - SettableBeanPropertyDelegate(SettableBeanProperty delegate, SettableAnyProperty anySetter, Supplier restrictToTemplates) { + SettableBeanPropertyDelegate(SettableBeanProperty delegate, SettableAnyProperty anySetter, BooleanSupplier useAnySetter) { super(delegate); this.delegate = delegate; this.anySetter = anySetter; - this.restrictToTemplates = restrictToTemplates; + this.useAnySetter = useAnySetter; } /** @@ -55,7 +55,7 @@ public class SettableBeanPropertyDelegate extends SettableBeanProperty { */ @Override public SettableBeanProperty withValueDeserializer(JsonDeserializer deser) { - return new SettableBeanPropertyDelegate(delegate.withValueDeserializer(deser), anySetter, restrictToTemplates); + return new SettableBeanPropertyDelegate(delegate.withValueDeserializer(deser), anySetter, useAnySetter); } /** @@ -63,7 +63,7 @@ public SettableBeanProperty withValueDeserializer(JsonDeserializer deser) { */ @Override public SettableBeanProperty withName(PropertyName newName) { - return new SettableBeanPropertyDelegate(delegate.withName(newName), anySetter, restrictToTemplates); + return new SettableBeanPropertyDelegate(delegate.withName(newName), anySetter, useAnySetter); } /** @@ -71,7 +71,7 @@ public SettableBeanProperty withName(PropertyName newName) { */ @Override public SettableBeanProperty withNullProvider(NullValueProvider nva) { - return new SettableBeanPropertyDelegate(delegate.withNullProvider(nva), anySetter, restrictToTemplates); + return new SettableBeanPropertyDelegate(delegate.withNullProvider(nva), anySetter, useAnySetter); } /** @@ -117,13 +117,16 @@ public boolean isIgnorable() { /** * Method called to deserialize appropriate value, given parser (and context), and set it using appropriate mechanism. * - *

Deserialization is first tried through the delegate. In case a {@link MismatchedInputException} is caught, + *

+ * Deserialization is first tried through the delegate. In case a {@link MismatchedInputException} is caught, * the field is stored in the bean's {@link SettableAnyProperty} anySetter field if it exists. * - *

This allows deserialization processes propagate values that initially don't match the target bean type for the + *

+ * This allows deserialization processes propagate values that initially don't match the target bean type for the * applicable field. * - *

An example use-case is the use of placeholders (e.g. {@code ${aValue}}) in a field. + *

+ * An example use-case is the use of placeholders (e.g. {@code ${aValue}}) in a field. */ @Override public void deserializeAndSet(JsonParser p, DeserializationContext ctxt, Object instance) throws IOException { @@ -171,9 +174,6 @@ private boolean shouldUseAnySetter() { if (anySetter == null) { return false; } - if (Boolean.TRUE.equals(restrictToTemplates.get()) ) { - return KubernetesDeserializer.isInTemplate(); - } - return true; + return useAnySetter.getAsBoolean(); } } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/serialization/UnmatchedFieldTypeModule.java b/kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/UnmatchedFieldTypeModule.java similarity index 72% rename from kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/serialization/UnmatchedFieldTypeModule.java rename to kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/UnmatchedFieldTypeModule.java index 6df84461d8b..83d28f72d91 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/utils/serialization/UnmatchedFieldTypeModule.java +++ b/kubernetes-model-generator/kubernetes-model-common/src/main/java/io/fabric8/kubernetes/model/jackson/UnmatchedFieldTypeModule.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.fabric8.kubernetes.client.utils.serialization; +package io.fabric8.kubernetes.model.jackson; import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.DeserializationConfig; @@ -40,6 +40,8 @@ public class UnmatchedFieldTypeModule extends SimpleModule { private boolean logWarnings; private boolean restrictToTemplates; + private static final ThreadLocal IN_TEMPLATE = ThreadLocal.withInitial(() -> false); + public UnmatchedFieldTypeModule() { this(true, true); } @@ -50,19 +52,22 @@ public UnmatchedFieldTypeModule(boolean logWarnings, boolean restrictToTemplates setDeserializerModifier(new BeanDeserializerModifier() { @Override - public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BeanDescription beanDesc, BeanDeserializerBuilder builder) { - builder.getProperties().forEachRemaining(p -> - builder.addOrReplaceProperty(new SettableBeanPropertyDelegate(p, builder.getAnySetter(), UnmatchedFieldTypeModule.this::isRestrictToTemplates) { - }, true)); + public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BeanDescription beanDesc, + BeanDeserializerBuilder builder) { + builder.getProperties().forEachRemaining(p -> builder.addOrReplaceProperty( + new SettableBeanPropertyDelegate(p, builder.getAnySetter(), UnmatchedFieldTypeModule.this::useAnySetter) { + }, true)); return builder; } }); setSerializerModifier(new BeanSerializerModifier() { @Override - public BeanSerializerBuilder updateBuilder(SerializationConfig config, BeanDescription beanDesc, BeanSerializerBuilder builder) { - builder.setProperties(builder.getProperties().stream().map(p -> - new BeanPropertyWriterDelegate(p, builder.getBeanDescription().findAnyGetter(), UnmatchedFieldTypeModule.this::isLogWarnings)) - .collect(Collectors.toList())); + public BeanSerializerBuilder updateBuilder(SerializationConfig config, BeanDescription beanDesc, + BeanSerializerBuilder builder) { + builder.setProperties(builder.getProperties().stream() + .map(p -> new BeanPropertyWriterDelegate(p, builder.getBeanDescription().findAnyGetter(), + UnmatchedFieldTypeModule.this::isLogWarnings)) + .collect(Collectors.toList())); return builder; } }); @@ -85,6 +90,10 @@ boolean isRestrictToTemplates() { return restrictToTemplates; } + boolean useAnySetter() { + return !restrictToTemplates || isInTemplate(); + } + /** * Sets if the DeserializerModifier should only be applied to Templates or object trees contained in Templates. * @@ -93,4 +102,17 @@ boolean isRestrictToTemplates() { public void setRestrictToTemplates(boolean restrictToTemplates) { this.restrictToTemplates = restrictToTemplates; } + + public static boolean isInTemplate() { + return Boolean.TRUE.equals(IN_TEMPLATE.get()); + } + + public static void setInTemplate() { + IN_TEMPLATE.set(true); + } + + public static void removeInTemplate() { + IN_TEMPLATE.remove(); + } + } diff --git a/kubernetes-model-generator/kubernetes-model-core/src/main/java/io/fabric8/kubernetes/internal/KubernetesDeserializer.java b/kubernetes-model-generator/kubernetes-model-core/src/main/java/io/fabric8/kubernetes/internal/KubernetesDeserializer.java index a7e22cf3aa1..b1fabbfe3e4 100644 --- a/kubernetes-model-generator/kubernetes-model-core/src/main/java/io/fabric8/kubernetes/internal/KubernetesDeserializer.java +++ b/kubernetes-model-generator/kubernetes-model-core/src/main/java/io/fabric8/kubernetes/internal/KubernetesDeserializer.java @@ -76,18 +76,11 @@ public boolean equals(Object obj) { } - private static final String TEMPLATE_CLASS_NAME = "io.fabric8.openshift.api.model.Template"; private static final String KIND = "kind"; private static final String API_VERSION = "apiVersion"; private static final Mapping mapping = new Mapping(); - private static final ThreadLocal IN_TEMPLATE = ThreadLocal.withInitial(() -> false); - - public static boolean isInTemplate() { - return IN_TEMPLATE.get(); - } - @Override public KubernetesResource deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { JsonNode node = jp.readValueAsTree(); @@ -121,18 +114,7 @@ private static KubernetesResource fromObjectNode(JsonParser jp, JsonNode node) t if (resourceType == null) { return jp.getCodec().treeToValue(node, GenericKubernetesResource.class); } else if (KubernetesResource.class.isAssignableFrom(resourceType)) { - boolean inTemplate = false; - if (TEMPLATE_CLASS_NAME.equals(resourceType.getName())) { - inTemplate = true; - IN_TEMPLATE.set(true); - } - try { - return jp.getCodec().treeToValue(node, resourceType); - } finally { - if (inTemplate) { - IN_TEMPLATE.remove(); - } - } + return jp.getCodec().treeToValue(node, resourceType); } throw new JsonMappingException(jp, String.format( "There's a class loading issue, %s is registered as a KubernetesResource, but is not an instance of KubernetesResource", diff --git a/kubernetes-model-generator/openshift-model/cmd/generate/generate.go b/kubernetes-model-generator/openshift-model/cmd/generate/generate.go index ae248eafc27..cc9e3c5cc1f 100644 --- a/kubernetes-model-generator/openshift-model/cmd/generate/generate.go +++ b/kubernetes-model-generator/openshift-model/cmd/generate/generate.go @@ -198,6 +198,18 @@ func main() { fmt.Fprintf(os.Stderr, "An error occurred: %v", err) return } + + serdes := map[string]*schemagen.JavaSerDeDescriptor{ + "os_template_Template": &schemagen.JavaSerDeDescriptor{ + Deserializer: "io.fabric8.openshift.api.model.TemplateDeserializer.class", + }, + } + + for definitionKey, descriptor := range serdes { + val := schema.Definitions[definitionKey] + val.JavaSerDeDescriptor = descriptor + schema.Definitions[definitionKey] = val + } args := os.Args[1:] if len(args) < 1 || args[0] != "validation" { diff --git a/kubernetes-model-generator/openshift-model/src/generated/java/io/fabric8/openshift/api/model/Template.java b/kubernetes-model-generator/openshift-model/src/generated/java/io/fabric8/openshift/api/model/Template.java index 56f9ae58551..1f3ccfa07a6 100644 --- a/kubernetes-model-generator/openshift-model/src/generated/java/io/fabric8/openshift/api/model/Template.java +++ b/kubernetes-model-generator/openshift-model/src/generated/java/io/fabric8/openshift/api/model/Template.java @@ -34,7 +34,7 @@ import lombok.ToString; import lombok.experimental.Accessors; -@JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None.class) +@JsonDeserialize(using = io.fabric8.openshift.api.model.TemplateDeserializer.class) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "apiVersion", diff --git a/kubernetes-model-generator/openshift-model/src/main/java/io/fabric8/openshift/api/model/TemplateDeserializer.java b/kubernetes-model-generator/openshift-model/src/main/java/io/fabric8/openshift/api/model/TemplateDeserializer.java new file mode 100644 index 00000000000..3198f698ada --- /dev/null +++ b/kubernetes-model-generator/openshift-model/src/main/java/io/fabric8/openshift/api/model/TemplateDeserializer.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2015 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fabric8.openshift.api.model; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.deser.BeanDeserializer; +import com.fasterxml.jackson.databind.deser.ResolvableDeserializer; +import io.fabric8.kubernetes.model.jackson.UnmatchedFieldTypeModule; + +import java.io.IOException; + +/** + * Essentially wraps a {@link BeanDeserializer} to allow for unmatched fields + */ +public class TemplateDeserializer extends JsonDeserializer