Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fully addressing static deserialization issues #4662

Merged
merged 1 commit into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
import io.fabric8.kubernetes.client.http.HttpClient.Factory;
import io.fabric8.kubernetes.client.http.StandardHttpClientBuilder;
import io.fabric8.kubernetes.client.utils.HttpClientUtils;
import io.fabric8.kubernetes.client.utils.Serialization;

import java.io.InputStream;

/**
* Class for Default Kubernetes Client implementing KubernetesClient interface.
Expand All @@ -36,14 +33,6 @@ public class DefaultKubernetesClient extends NamespacedKubernetesClientAdapter<N

public static final String KUBERNETES_VERSION_ENDPOINT = "version";

public static DefaultKubernetesClient fromConfig(String config) {
return new DefaultKubernetesClient(Serialization.unmarshal(config, Config.class));
}

public static DefaultKubernetesClient fromConfig(InputStream is) {
return new DefaultKubernetesClient(Serialization.unmarshal(is, Config.class));
}

public DefaultKubernetesClient() {
this(new ConfigBuilder().build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@
import io.fabric8.kubernetes.client.dsl.NamespaceableResource;
import io.fabric8.kubernetes.client.dsl.NetworkAPIGroupDSL;
import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
import io.fabric8.kubernetes.client.dsl.ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable;
import io.fabric8.kubernetes.client.dsl.PodResource;
import io.fabric8.kubernetes.client.dsl.PolicyAPIGroupDSL;
import io.fabric8.kubernetes.client.dsl.RbacAPIGroupDSL;
Expand All @@ -91,6 +90,7 @@
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElectorBuilder;
import io.fabric8.kubernetes.client.extended.run.RunOperations;
import io.fabric8.kubernetes.client.informers.SharedInformerFactory;
import io.fabric8.kubernetes.client.utils.KubernetesSerialization;

import java.io.InputStream;
import java.util.Collection;
Expand Down Expand Up @@ -300,15 +300,15 @@ MixedOperation<GenericKubernetesResource, GenericKubernetesResourceList, Resourc
* @param is the input stream containing JSON/YAML content
* @return an operation instance to work on the list of Kubernetes Resource objects
*/
ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> load(InputStream is);
NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> load(InputStream is);

/**
* Load a Kubernetes list object
*
* @param s kubernetes list as string
* @return an operation instance to work on the deserialized KubernetesList objects
*/
ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> resourceList(String s);
NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> resourceList(String s);

/**
* KubernetesResourceList operations
Expand Down Expand Up @@ -543,4 +543,9 @@ NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> resourc
* @param visitor
*/
void visitResources(ApiVisitor visitor);

/**
* @return the {@link KubernetesSerialization} used by this client
*/
KubernetesSerialization getKubernetesSerialization();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@

package io.fabric8.kubernetes.client;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.fabric8.kubernetes.client.http.HttpClient;
import io.fabric8.kubernetes.client.informers.ResourceEventHandler;
import io.fabric8.kubernetes.client.utils.HttpClientUtils;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.kubernetes.client.utils.KubernetesSerialization;
import io.fabric8.kubernetes.client.utils.Utils;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -47,6 +49,7 @@ default void onClose(Executor executor) {
private Class<KubernetesClient> clazz;
private ExecutorSupplier executorSupplier;
private Consumer<HttpClient.Builder> builderConsumer;
private KubernetesSerialization kubernetesSerialization = new KubernetesSerialization(new ObjectMapper());

public KubernetesClientBuilder() {
// basically the same logic as in KubernetesResourceUtil for finding list types
Expand Down Expand Up @@ -75,8 +78,9 @@ public KubernetesClient build() {
this.factory = HttpClientUtils.getHttpClientFactory();
}
HttpClient client = getHttpClient();
return clazz.getConstructor(HttpClient.class, Config.class, ExecutorSupplier.class).newInstance(client, config,
executorSupplier);
return clazz.getConstructor(HttpClient.class, Config.class, ExecutorSupplier.class, KubernetesSerialization.class)
.newInstance(client, config,
executorSupplier, kubernetesSerialization);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
throw KubernetesClientException.launderThrowable(e);
Expand All @@ -96,13 +100,18 @@ public KubernetesClientBuilder withConfig(Config config) {
return this;
}

public KubernetesClientBuilder withKubernetesSerialization(KubernetesSerialization kubernetesSerialization) {
this.kubernetesSerialization = Utils.checkNotNull(kubernetesSerialization, "kubernetesSerialization must not be null");
return this;
}

public KubernetesClientBuilder withConfig(String config) {
this.config = Serialization.unmarshal(config, Config.class);
this.config = kubernetesSerialization.unmarshal(config, Config.class);
return this;
}

public KubernetesClientBuilder withConfig(InputStream config) {
this.config = Serialization.unmarshal(config, Config.class);
this.config = kubernetesSerialization.unmarshal(config, Config.class);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
import io.fabric8.kubernetes.client.dsl.NamespaceableResource;
import io.fabric8.kubernetes.client.dsl.NetworkAPIGroupDSL;
import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
import io.fabric8.kubernetes.client.dsl.ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable;
import io.fabric8.kubernetes.client.dsl.PodResource;
import io.fabric8.kubernetes.client.dsl.PolicyAPIGroupDSL;
import io.fabric8.kubernetes.client.dsl.RbacAPIGroupDSL;
Expand All @@ -93,6 +92,7 @@
import io.fabric8.kubernetes.client.extended.run.RunOperations;
import io.fabric8.kubernetes.client.extension.ClientAdapter;
import io.fabric8.kubernetes.client.informers.SharedInformerFactory;
import io.fabric8.kubernetes.client.utils.KubernetesSerialization;

import java.io.InputStream;
import java.util.Collection;
Expand Down Expand Up @@ -255,12 +255,12 @@ public NonNamespaceOperation<ComponentStatus, ComponentStatusList, Resource<Comp
}

@Override
public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> load(InputStream is) {
public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> load(InputStream is) {
return getClient().load(is);
}

@Override
public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> resourceList(String s) {
public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata> resourceList(String s) {
return getClient().resourceList(s);
}

Expand Down Expand Up @@ -425,4 +425,9 @@ public String raw(String uri, String method, Object payload) {
return getClient().raw(uri, method, payload);
}

@Override
public KubernetesSerialization getKubernetesSerialization() {
return getClient().getKubernetesSerialization();
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.kubernetes.client.utils.KubernetesSerialization;

import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -42,6 +42,7 @@ public class ReducedStateItemStore<V extends HasMetadata> implements ItemStore<V
private final List<String[]> fields = new ArrayList<>();
private final Class<V> typeClass;
private final KeyState keyState;
private KubernetesSerialization serialization;

public static class KeyState {

Expand Down Expand Up @@ -101,7 +102,8 @@ public KeyState(Function<HasMetadata, String> keyFunction, Function<String, Stri
* @param typeClass the expected type
* @param valueFields the additional fields to save
*/
public ReducedStateItemStore(KeyState keyState, Class<V> typeClass, String... valueFields) {
public ReducedStateItemStore(KeyState keyState, Class<V> typeClass, KubernetesSerialization serialization,
String... valueFields) {
this.keyState = keyState;
fields.add(new String[] { METADATA, "resourceVersion" });
if (valueFields != null) {
Expand All @@ -110,13 +112,14 @@ public ReducedStateItemStore(KeyState keyState, Class<V> typeClass, String... va
}
}
this.typeClass = typeClass;
this.serialization = serialization;
}

Object[] store(V value) {
if (value == null) {
return null;
}
Map<String, Object> raw = Serialization.jsonMapper().convertValue(value, Map.class);
Map<String, Object> raw = serialization.convertValue(value, Map.class);
return fields.stream().map(f -> GenericKubernetesResource.get(raw, (Object[]) f)).toArray();
}

Expand All @@ -129,7 +132,7 @@ V restore(String key, Object[] values) {
String[] keyParts = this.keyState.keyFieldFunction.apply(key);
applyFields(keyParts, raw, this.keyState.keyFields);

return Serialization.jsonMapper().convertValue(raw, typeClass);
return serialization.convertValue(raw, typeClass);
}

private static void applyFields(Object[] values, Map<String, Object> raw, List<String[]> fields) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/
package io.fabric8.kubernetes.client.utils;

import io.fabric8.kubernetes.api.model.HasMetadata;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.fabric8.kubernetes.client.http.BasicBuilder;
import io.fabric8.kubernetes.client.http.HttpRequest;
import io.fabric8.kubernetes.client.http.HttpRequest.Builder;
Expand Down Expand Up @@ -165,19 +166,18 @@ public CompletableFuture<Boolean> afterFailure(Builder builder, HttpResponse<?>

HttpRequest request = response.request();
if (request.bodyString() != null && !request.method().equalsIgnoreCase(PATCH)) {
Object object = Serialization.unmarshal(request.bodyString());
if (object instanceof HasMetadata) {
HasMetadata h = (HasMetadata) object;
h.setApiVersion(target.group + "/" + target.version);
JsonNode object = Serialization.unmarshal(request.bodyString(), JsonNode.class);
if (object.get("apiVersion") != null) {
((ObjectNode) object).put("apiVersion", target.group + "/" + target.version);
switch (request.method()) {
case "POST":
builder.post(JSON, Serialization.asJson(h));
builder.post(JSON, Serialization.asJson(object));
break;
case "PUT":
builder.put(JSON, Serialization.asJson(h));
builder.put(JSON, Serialization.asJson(object));
break;
case "DELETE":
builder.delete(JSON, Serialization.asJson(h));
builder.delete(JSON, Serialization.asJson(object));
break;
default:
return CompletableFuture.completedFuture(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.fabric8.kubernetes.client.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.BufferedReader;
Expand Down Expand Up @@ -64,6 +65,10 @@ private static void copy(Reader reader, Writer writer) throws IOException {
}
}

/**
* @deprecated will be removed in future versions
*/
@Deprecated
public static boolean isJSONValid(String json) {
try {
ObjectMapper objectMapper = Serialization.jsonMapper();
Expand All @@ -74,10 +79,18 @@ public static boolean isJSONValid(String json) {
return true;
}

/**
* @deprecated will be removed in future versions
*/
@Deprecated
public static String convertYamlToJson(String yaml) {
return Serialization.asJson(Serialization.unmarshal(yaml, Object.class));
return Serialization.asJson(Serialization.unmarshal(yaml, JsonNode.class));
}

/**
* @deprecated will be removed in future versions
*/
@Deprecated
public static String convertToJson(String jsonOrYaml) {
if (isJSONValid(jsonOrYaml)) {
return jsonOrYaml;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package io.fabric8.kubernetes.client.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.fabric8.kubernetes.api.builder.VisitableBuilder;
import io.fabric8.kubernetes.api.model.DefaultKubernetesResourceList;
import io.fabric8.kubernetes.api.model.EnvVar;
Expand Down Expand Up @@ -383,7 +382,7 @@ public static List<EnvVar> convertMapToEnvVarList(Map<String, String> envVarMap)
* Check whether a Kubernetes resource is Ready or not. Applicable only to
* Deployment, ReplicaSet, Pod, ReplicationController, Endpoints, Node and
* StatefulSet
*
*
* @param item item which needs to be checked
* @return boolean value indicating it's status
*/
Expand All @@ -393,7 +392,7 @@ public static boolean isResourceReady(HasMetadata item) {

/**
* Calculates age of a kubernetes resource
*
*
* @param kubernetesResource
* @return a positive duration indicating age of the kubernetes resource
*/
Expand Down Expand Up @@ -432,10 +431,9 @@ private static Class<?> loadRelated(Class<?> type, String suffix, Class<?> defau
* secret's default name : "container-image-registry-secret" is the default name for secret
* @return an object of Secret
*/
public static Secret createDockerRegistrySecret(String dockerServer, String username, String password)
throws JsonProcessingException {
public static Secret createDockerRegistrySecret(String dockerServer, String username, String password) {
Map<String, Object> dockerConfigMap = createDockerRegistryConfigMap(dockerServer, username, password);
String dockerConfigAsStr = Serialization.jsonMapper().writeValueAsString(dockerConfigMap);
String dockerConfigAsStr = Serialization.asJson(dockerConfigMap);

return createDockerSecret(DEFAULT_CONTAINER_IMAGE_REGISTRY_SECRET_NAME, dockerConfigAsStr);
}
Expand All @@ -449,10 +447,9 @@ public static Secret createDockerRegistrySecret(String dockerServer, String user
* @param secretName secretName that needs to be used during secret creation
* @return an object of Secret
*/
public static Secret createDockerRegistrySecret(String dockerServer, String username, String password, String secretName)
throws JsonProcessingException {
public static Secret createDockerRegistrySecret(String dockerServer, String username, String password, String secretName) {
Map<String, Object> dockerConfigMap = createDockerRegistryConfigMap(dockerServer, username, password);
String dockerConfigAsStr = Serialization.jsonMapper().writeValueAsString(dockerConfigMap);
String dockerConfigAsStr = Serialization.asJson(dockerConfigMap);

return createDockerSecret(secretName, dockerConfigAsStr);
}
Expand Down
Loading