Skip to content

Commit

Permalink
fix #4662: refining the client to not use static deserialization logic
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed May 19, 2023
1 parent b81e146 commit 33c9005
Show file tree
Hide file tree
Showing 69 changed files with 901 additions and 1,005 deletions.
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 Down Expand Up @@ -300,15 +299,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
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 Down Expand Up @@ -255,12 +254,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

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 @@ -75,7 +76,7 @@ public static boolean isJSONValid(String json) {
}

public static String convertYamlToJson(String yaml) {
return Serialization.asJson(Serialization.unmarshal(yaml, Object.class));
return Serialization.asJson(Serialization.unmarshal(yaml, JsonNode.class));
}

public static String convertToJson(String 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

0 comments on commit 33c9005

Please sign in to comment.