From 0f7da0a4b9ad8d0b3b8b5a09e6ef16c876837056 Mon Sep 17 00:00:00 2001 From: Steve Hawkins Date: Thu, 8 Dec 2022 10:58:38 -0500 Subject: [PATCH] fix #3972: removing the need for parameter processing in Serialization --- CHANGELOG.md | 4 ++ .../client/dsl/ParameterMixedOperation.java | 9 +-- ...ServerGetDeleteRecreateWaitApplicable.java | 9 +++ .../client/dsl/Parameterizable.java | 7 +++ .../client/utils/Serialization.java | 61 +++++++++++-------- ...ializationSingleDocumentUnmarshalTest.java | 5 +- 6 files changed, 60 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cd908d5bc1..9334e31c8ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,7 +55,11 @@ * Fix #4515: files located at the root of jars named model.properties, e.g. core.properties, have been removed * Fix #4579: the implicit registration of resource and list types that happens when using the resource(class) methods has been removed. This makes the behavior of the client more predictable as that was an undocumented side-effect. If you expect to see instances of a custom type from an untyped api call - typically KubernetesClient.load, KubernetesClient.resourceList, KubernetesClient.resource(InputStream|String), then you must either create a META-INF/services/io.fabric8.kubernetes.api.model.KubernetesResource file (see above #3923), or make calls to KubernetesDeserializer.registerCustomKind - however since KubernetesDeserializer is an internal class that mechanism is not preferred. * Fix #4597: remove the deprecated support for `javax.validation.constraints.NotNull` in the `crd-generator`, to mark a property as `required` it needs to be annotated with `io.fabric8.generator.annotation.Required` +<<<<<<< HEAD * Fix #4363: deprecated existing ResourceCompare methods such as compareKubernetesResource as they are not for general use +======= +* Fix #3973: removed support for Parameterizable - that was only needed as a workaround for non-string parameters. You should instead include those parameter values in the map passed to processLocally. +>>>>>>> b8f6fb444 (Fix #3972: removing the need for parameter processing in Serialization) ### 6.2.0 (2022-10-20) diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ParameterMixedOperation.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ParameterMixedOperation.java index 3213b4c47b0..33b362fceaf 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ParameterMixedOperation.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ParameterMixedOperation.java @@ -17,12 +17,13 @@ package io.fabric8.kubernetes.client.dsl; /** - * A {@link Parameterizable} {@link MixedOperation} + * It is no longer necessary to associate parameters prior to deserialization. + *

+ * reference {@link MixedOperation} instead * - * @param The Kubernetes resource type. - * @param The list variant of the Kubernetes resource type. - * @param The resource operations. + * @param */ +@Deprecated public interface ParameterMixedOperation> extends MixedOperation, Parameterizable> { } diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable.java index f8c39a58fbc..0929eaeed10 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable.java @@ -16,6 +16,15 @@ package io.fabric8.kubernetes.client.dsl; +/** + * It is no longer necessary to associate parameters prior to deserialization. + *

+ * reference {@link NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable} instead + * + * + * @param + */ +@Deprecated public interface ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable extends NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable, Parameterizable> { diff --git a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/Parameterizable.java b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/Parameterizable.java index 3dfdd74d083..faf22d43113 100644 --- a/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/Parameterizable.java +++ b/kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/dsl/Parameterizable.java @@ -17,6 +17,13 @@ import java.util.Map; +/** + * It is no longer necessary to associate parameters prior to deserialization. Please + * provide the parameters to one of the process methods instead + * + * @param + */ +@Deprecated public interface Parameterizable { T withParameters(Map parameters); 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 a5ffeb936b5..d747ee3f099 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 @@ -35,7 +35,6 @@ import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type; @@ -180,17 +179,13 @@ public static T unmarshal(InputStream is) { * @param parameters A {@link Map} with parameters for placeholder substitution. * @param The target type. * @return returns returns de-serialized object + * + * @deprecated please directly apply {@link Utils#interpolateString(String, Map)} instead of passing parameters here */ + @Deprecated @SuppressWarnings("unchecked") public static T unmarshal(InputStream is, Map parameters) { - String specFile = readSpecFileFromInputStream(is); - if (containsMultipleDocuments(specFile)) { - return (T) getKubernetesResourceList(parameters, specFile); - } else if (specFile.contains(DOCUMENT_DELIMITER)) { - specFile = specFile.replaceAll("^---([ \\t].*?)?\\r?\\n", ""); - specFile = specFile.replaceAll("\\n---([ \\t].*?)?\\r?\\n?$", "\n"); - } - return unmarshal(new ByteArrayInputStream(specFile.getBytes()), JSON_MAPPER, parameters); + return unmarshal(is, JSON_MAPPER, parameters); } /** @@ -217,9 +212,27 @@ public static T unmarshal(InputStream is, ObjectMapper mapper) { * @param parameters A {@link Map} with parameters for placeholder substitution. * @param The target type. * @return returns de-serialized object + * + * @deprecated please directly apply {@link Utils#interpolateString(String, Map)} instead of passing parameters here */ + @Deprecated public static T unmarshal(InputStream is, ObjectMapper mapper, Map parameters) { - return unmarshal(is, mapper, new TypeReference() { + // it's not well documented which Serialization methods are aware of input that can contain + // multiple docs + String specFile; + try { + specFile = IOHelpers.readFully(is); + } catch (IOException e1) { + throw new RuntimeException("Could not read stream"); + } + if (containsMultipleDocuments(specFile)) { + return (T) getKubernetesResourceList(Collections.emptyMap(), specFile); + } else if (specFile.contains(DOCUMENT_DELIMITER)) { + specFile = specFile.replaceAll("^---([ \\t].*?)?\\r?\\n", ""); + specFile = specFile.replaceAll("\\n---([ \\t].*?)?\\r?\\n?$", "\n"); + } + + return unmarshal(new ByteArrayInputStream(specFile.getBytes(StandardCharsets.UTF_8)), mapper, new TypeReference() { @Override public Type getType() { return KubernetesResource.class; @@ -228,9 +241,8 @@ public Type getType() { } private static T unmarshal(InputStream is, ObjectMapper mapper, TypeReference type, Map parameters) { - try ( - InputStream wrapped = parameters != null && !parameters.isEmpty() ? ReplaceValueStream.replaceValues(is, parameters) - : is; + try (InputStream wrapped = parameters != null && !parameters.isEmpty() ? ReplaceValueStream.replaceValues(is, parameters) + : is; BufferedInputStream bis = new BufferedInputStream(wrapped)) { bis.mark(-1); int intch; @@ -296,7 +308,10 @@ public static T unmarshal(String str, final Class type) { * @param parameters A hashmap containing parameters * * @return returns de-serialized object + * + * @deprecated please directly apply {@link Utils#interpolateString(String, Map)} instead of passing parameters here */ + @Deprecated public static T unmarshal(String str, final Class type, Map parameters) { try (InputStream is = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8))) { return unmarshal(is, new TypeReference() { @@ -330,7 +345,10 @@ public static T unmarshal(InputStream is, final Class type) { * @param parameters A {@link Map} with parameters for placeholder substitution. * @param Template argument denoting type * @return returns de-serialized object + * + * @deprecated please directly apply {@link Utils#interpolateString(String, Map)} instead of passing parameters here */ + @Deprecated public static T unmarshal(InputStream is, final Class type, Map parameters) { return unmarshal(is, new TypeReference() { @Override @@ -361,7 +379,10 @@ public static T unmarshal(InputStream is, TypeReference type) { * @param Template argument denoting type * * @return returns de-serialized object + * + * @deprecated please directly apply {@link Utils#interpolateString(String, Map)} instead of passing parameters here */ + @Deprecated public static T unmarshal(InputStream is, TypeReference type, Map parameters) { return unmarshal(is, JSON_MAPPER, type, parameters); } @@ -401,20 +422,6 @@ private static boolean validate(String document) { return !document.isEmpty() && keyValueMatcher.find(); } - private static String readSpecFileFromInputStream(InputStream inputStream) { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int length; - try { - while ((length = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, length); - } - return outputStream.toString(); - } catch (IOException e) { - throw new RuntimeException("Unable to read InputStream." + e); - } - } - /** * Create a copy of the resource via serialization. * diff --git a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/SerializationSingleDocumentUnmarshalTest.java b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/SerializationSingleDocumentUnmarshalTest.java index d8bf77536ef..936a85fa64b 100644 --- a/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/SerializationSingleDocumentUnmarshalTest.java +++ b/kubernetes-client-api/src/test/java/io/fabric8/kubernetes/client/utils/SerializationSingleDocumentUnmarshalTest.java @@ -21,8 +21,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import java.util.Collections; - import static org.assertj.core.api.Assertions.assertThat; class SerializationSingleDocumentUnmarshalTest { @@ -36,8 +34,7 @@ class SerializationSingleDocumentUnmarshalTest { void unmarshalWithSingleDocumentWithDocumentDelimiterShouldReturnKubernetesResource(String arg) { // When final KubernetesResource result = Serialization.unmarshal( - SerializationTest.class.getResourceAsStream(String.format("/serialization/%s", arg)), - Collections.emptyMap()); + SerializationTest.class.getResourceAsStream(String.format("/serialization/%s", arg))); // Then assertThat(result) .asInstanceOf(InstanceOfAssertFactories.type(Service.class))