Skip to content

Commit

Permalink
Fix fabric8io#2066: Separated Kubernetes and OpenShift Handler interf…
Browse files Browse the repository at this point in the history
…aces to avoid collission in uberjar
  • Loading branch information
rohanKanojia committed May 7, 2020
1 parent 9069bb5 commit a2eda82
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### 4.10-SNAPSHOT
#### Bugs
* Fix #2066: Separated Kubernetes and OpenShift Handler interfaces to avoid collission in uberjar

#### Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public HasMetadata waitUntilCondition(Predicate<HasMetadata> condition, long amo
}


private static HasMetadata acceptVisitors(HasMetadata item, List<Visitor> visitors) {
protected HasMetadata acceptVisitors(HasMetadata item, List<Visitor> visitors) {
ResourceHandler<HasMetadata, HasMetadataVisitiableBuilder> h = handlerOf(item);
VisitableBuilder<HasMetadata, ?> builder = h.edit(item);

Expand All @@ -267,7 +267,7 @@ private static HasMetadata acceptVisitors(HasMetadata item, List<Visitor> visito
return builder.build();
}

private static List<HasMetadata> acceptVisitors(List<HasMetadata> list, List<Visitor> visitors) {
protected List<HasMetadata> acceptVisitors(List<HasMetadata> list, List<Visitor> visitors) {
List<HasMetadata> result = new ArrayList<>();
for (HasMetadata item : list) {
ResourceHandler<HasMetadata, HasMetadataVisitiableBuilder> h = handlerOf(item);
Expand All @@ -282,7 +282,7 @@ private static List<HasMetadata> acceptVisitors(List<HasMetadata> list, List<Vis
return result;
}

private static <T> HasMetadata asHasMetadata(T item) {
protected <T> HasMetadata asHasMetadata(T item) {
if (item instanceof HasMetadata) {
return (HasMetadata) item;
} else if (item instanceof String) {
Expand All @@ -295,7 +295,7 @@ private static <T> HasMetadata asHasMetadata(T item) {
throw new IllegalArgumentException("Item needs to be an instance of HasMetadata or String.");
}

private static <T> ResourceHandler handlerOf(T item) {
protected <T> ResourceHandler handlerOf(T item) {
if (item instanceof HasMetadata) {
return Handlers.<HasMetadata, HasMetadataVisitiableBuilder>get(((HasMetadata) item).getKind(), ((HasMetadata) item).getApiVersion());
} else if (item instanceof KubernetesList) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ public List<HasMetadata> get() {
}
}

private static List<HasMetadata> acceptVisitors(List<HasMetadata> list, List<Visitor> visitors) {
public List<HasMetadata> acceptVisitors(List<HasMetadata> list, List<Visitor> visitors) {
List<HasMetadata> result = new ArrayList<>();
for (HasMetadata item : list) {
ResourceHandler<HasMetadata, HasMetadataVisitiableBuilder> h = handlerOf(item);
Expand Down Expand Up @@ -410,7 +410,7 @@ private static <T> List<HasMetadata> asHasMetadata(T item, Boolean enableProcces
return result;
}

private static <T> ResourceHandler handlerOf(T item) {
public <T> ResourceHandler handlerOf(T item) {
if (item instanceof HasMetadata) {
return Handlers.<HasMetadata, HasMetadataVisitiableBuilder>get(((HasMetadata) item).getKind(), ((HasMetadata) item).getApiVersion());
} else if (item instanceof KubernetesList) {
Expand Down
2 changes: 1 addition & 1 deletion openshift-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
<Bundle-Activator>${osgi.activator}</Bundle-Activator>
<Export-Service>${osgi.export.service}</Export-Service>
<Include-Resource>
/META-INF/services/io.fabric8.kubernetes.client.ResourceHandler=target/classes/META-INF/services/io.fabric8.kubernetes.client.ResourceHandler
/META-INF/services/io.fabric8.openshift.client.OpenShiftResourceHandler=target/classes/META-INF/services/io.fabric8.openshift.client.OpenShiftResourceHandler
</Include-Resource>
</instructions>
<classifier>bundle</classifier>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
value = {
@VelocityTransformation("/resource-operation.vm"),
@VelocityTransformation("/resource-handler.vm"),
@VelocityTransformation(value = "/resource-handler-services.vm", gather = true, outputPath = "META-INF/services/io.fabric8.kubernetes.client.ResourceHandler")
@VelocityTransformation(value = "/resource-handler-services.vm", gather = true, outputPath = "META-INF/services/io.fabric8.openshift.client.OpenShiftResourceHandler")
},
resources = {
@ResourceSelector("openshift.properties")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
*/
package io.fabric8.openshift.client;

import io.fabric8.kubernetes.api.builder.Visitor;
import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.api.model.DoneableBinding;
import io.fabric8.kubernetes.api.model.DoneableComponentStatus;
import io.fabric8.kubernetes.api.model.DoneableConfigMap;
import io.fabric8.kubernetes.api.model.DoneableEndpoints;
import io.fabric8.kubernetes.api.model.KubernetesListBuilder;
import io.fabric8.kubernetes.api.model.events.DoneableEvent;
import io.fabric8.kubernetes.api.model.DoneableLimitRange;
import io.fabric8.kubernetes.api.model.DoneableNamespace;
Expand Down Expand Up @@ -129,6 +131,7 @@
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Collection;
import java.util.HashMap;
Expand All @@ -138,7 +141,7 @@
import java.util.concurrent.ForkJoinPool;

/**
* Class for Default Openshift Client implementing KubernetesClient interface.
* Class for Default OpenShift Client implementing KubernetesClient interface.
* It is thread safe.
*/
public class DefaultOpenShiftClient extends BaseClient implements NamespacedOpenShiftClient {
Expand Down Expand Up @@ -235,37 +238,42 @@ public MixedOperation<ComponentStatus, ComponentStatusList, DoneableComponentSta

@Override
public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata, Boolean> load(InputStream is) {
return delegate.load(is);
return new OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<>(), is, null, true, DeletionPropagation.BACKGROUND) {
};
}

@Override
public NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable<HasMetadata, Boolean> resource(HasMetadata item) {
return delegate.resource(item);
return new OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<Visitor>(), item, -1, DeletionPropagation.BACKGROUND, true) {
};
}

@Override
public NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicable<HasMetadata, Boolean> resource(String s) {
return delegate.resource(s);
return new OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<Visitor>(), s, -1, DeletionPropagation.BACKGROUND, true) {
};
}

@Override
public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata, Boolean> resourceList(KubernetesResourceList is) {
return delegate.resourceList(is);
public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata, Boolean> resourceList(KubernetesResourceList item) {
return new OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<Visitor>(), item, null, null, -1, DeletionPropagation.BACKGROUND, true) {
};
}

@Override
public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata, Boolean> resourceList(HasMetadata... items) {
return delegate.resourceList(items);
return resourceList(new KubernetesListBuilder().withItems(items).build());
}

@Override
public NamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata, Boolean> resourceList(Collection<HasMetadata> items) {
return delegate.resourceList(items);
return resourceList(new KubernetesListBuilder().withItems(new ArrayList<HasMetadata>(items)).build());
}

@Override
public ParameterNamespaceListVisitFromServerGetDeleteRecreateWaitApplicable<HasMetadata, Boolean> resourceList(String s) {
return delegate.resourceList(s);
return new OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl(httpClient, getConfiguration(), getNamespace(), null, false, false, new ArrayList<Visitor>(), s, null, null, -1, DeletionPropagation.BACKGROUND, true) {
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package io.fabric8.openshift.client;

import io.fabric8.kubernetes.api.builder.VisitableBuilder;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.Handlers;
import io.fabric8.kubernetes.client.ResourceHandler;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.function.Predicate;

public final class OpenShiftHandlers {

private static final Set<ClassLoader> CLASS_LOADERS = new HashSet<>();
private static final Map<ResourceHandler.Key, ResourceHandler> RESOURCE_HANDLER_MAP = new HashMap<>();
static {
// Register Kubernetes Handlers
discoverHandlers(ResourceHandler.class.getClassLoader());

// Register OpenShift Handlers
discoverHandlers(OpenShiftResourceHandler.class.getClassLoader());
}

public static <T extends HasMetadata, V extends VisitableBuilder<T, V>> void register(ResourceHandler<T,V> handler) {
RESOURCE_HANDLER_MAP.put(new ResourceHandler.Key(handler.getKind().toLowerCase(Locale.ROOT), handler.getApiVersion()), handler);
}

public static <T extends HasMetadata, V extends VisitableBuilder<T, V>> void unregister(ResourceHandler<T,V> handler) {
RESOURCE_HANDLER_MAP.remove(new ResourceHandler.Key(handler.getKind().toLowerCase(Locale.ROOT), handler.getApiVersion()));
}

public static <T extends HasMetadata, V extends VisitableBuilder<T, V>> ResourceHandler<T, V> get(String kind, String apiVersion) {
return get(kind, apiVersion, Thread.currentThread().getContextClassLoader());
}

public static <T extends HasMetadata, V extends VisitableBuilder<T, V>> ResourceHandler<T, V> get(String kind, String apiVersion, ClassLoader classLoader) {
return get(new ResourceHandler.Key(kind.toLowerCase(Locale.ROOT), apiVersion), classLoader);
}

public static <T extends HasMetadata, V extends VisitableBuilder<T, V>> ResourceHandler<T, V> get(ResourceHandler.Key key) {
return get(key, Thread.currentThread().getContextClassLoader());
}

public static <T extends HasMetadata, V extends VisitableBuilder<T, V>> ResourceHandler<T, V> get(ResourceHandler.Key key, ClassLoader classLoader) {
if (RESOURCE_HANDLER_MAP.containsKey(key)) {
return RESOURCE_HANDLER_MAP.get(key);
} else {
// Check for Kubernetes
ResourceHandler resourceHandler = getResourceHandlerForClass(key, ResourceHandler.class, classLoader);
if (resourceHandler != null) {
return resourceHandler;
}

// Check for OpenShift
resourceHandler = getResourceHandlerForClass(key, OpenShiftResourceHandler.class, classLoader);
return resourceHandler;
}
}

private static <T extends HasMetadata, V extends VisitableBuilder<T, V>> ResourceHandler<T, V> fetchResourceHandlerFromServiceLoader(Class<ResourceHandler> handlerClass, ClassLoader classLoader, Predicate<ResourceHandler<T, V>> condition) {
for (ResourceHandler handler : ServiceLoader.load(handlerClass, classLoader)) {
if (condition.test(handler)) {
return handler;
}
}
return null;
}

private static <T extends HasMetadata, V extends VisitableBuilder<T, V>> ResourceHandler<T, V> getResourceHandlerForClass(ResourceHandler.Key key, Class className, ClassLoader classLoader) {
//1st pass: match kind and apiVersion
ResourceHandler handler = fetchResourceHandlerFromServiceLoader(className, classLoader, h -> h.getKind().toLowerCase(Locale.ROOT).equals(key.getKind()) && h.getApiVersion().equals(key.getApiVersion()));
if (handler != null) {
return handler;
}


//2nd pass: match kind.
handler = fetchResourceHandlerFromServiceLoader(className, classLoader, h -> h.getKind().toLowerCase(Locale.ROOT).equals(key.getKind()));
return handler;
}

protected static void discoverHandlers(ClassLoader classLoader) {
if (classLoader != null && CLASS_LOADERS.add(classLoader)) {
for (ResourceHandler handler : ServiceLoader.load(ResourceHandler.class, classLoader)) {
register(handler);
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.fabric8.openshift.client;

import io.fabric8.kubernetes.api.builder.VisitableBuilder;
import io.fabric8.kubernetes.client.ResourceHandler;

public interface OpenShiftResourceHandler<T, V extends VisitableBuilder<T, V>> extends ResourceHandler<T, V> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.fabric8.openshift.client.dsl.internal;

import io.fabric8.kubernetes.api.builder.Visitor;
import io.fabric8.kubernetes.api.model.DeletionPropagation;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesList;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.HasMetadataVisitiableBuilder;
import io.fabric8.kubernetes.client.ResourceHandler;
import io.fabric8.kubernetes.client.dsl.internal.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl;
import io.fabric8.kubernetes.client.handlers.KubernetesListHandler;
import io.fabric8.openshift.client.OpenShiftHandlers;
import okhttp3.OkHttpClient;

import java.util.List;

public class OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl extends NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl {

public OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableImpl(OkHttpClient client, Config config, String namespace, String explicitNamespace, Boolean fromServer, Boolean deletingExisting, List<Visitor> visitors, Object item, long gracePeriodSeconds, DeletionPropagation propagationPolicy, Boolean cascading) {
super(client, config, namespace, explicitNamespace, fromServer, deletingExisting, visitors, item, gracePeriodSeconds, propagationPolicy, cascading);
}

@Override
public <T> ResourceHandler handlerOf(T item) {
if (item instanceof HasMetadata) {
return OpenShiftHandlers.<HasMetadata, HasMetadataVisitiableBuilder>get(((HasMetadata) item).getKind(), ((HasMetadata) item).getApiVersion());
} else if (item instanceof KubernetesList) {
return new KubernetesListHandler();
} else {
throw new IllegalArgumentException("Could not find a registered handler for item: [" + item + "].");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.fabric8.openshift.client.dsl.internal;

import io.fabric8.kubernetes.api.builder.Visitor;
import io.fabric8.kubernetes.api.model.DeletionPropagation;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesList;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.HasMetadataVisitiableBuilder;
import io.fabric8.kubernetes.client.ResourceHandler;
import io.fabric8.kubernetes.client.dsl.internal.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl;
import io.fabric8.kubernetes.client.handlers.KubernetesListHandler;
import io.fabric8.openshift.client.OpenShiftHandlers;
import okhttp3.OkHttpClient;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

public class OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl extends NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl {
public OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl(OkHttpClient client, Config config, String namespace, String explicitNamespace, Boolean fromServer, Boolean deletingExisting, List<Visitor> visitors, InputStream is, Map<String, String> parameters, Boolean cascading, DeletionPropagation propagationPolicy) {
super(client, config, namespace, explicitNamespace, fromServer, deletingExisting, visitors, is, parameters, cascading, propagationPolicy);
}

public OpenShiftNamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl(OkHttpClient client, Config config, String namespace, String explicitNamespace, Boolean fromServer, Boolean deletingExisting, List<Visitor> visitors, Object item, InputStream inputStream, Map<String, String> parameters, long gracePeriodSeconds, DeletionPropagation propagationPolicy, Boolean cascading) {
super(client, config, namespace, explicitNamespace, fromServer, deletingExisting, visitors, item, inputStream, parameters, gracePeriodSeconds, propagationPolicy, cascading);
}

@Override
public <T> ResourceHandler handlerOf(T item) {
if (item instanceof HasMetadata) {
return OpenShiftHandlers.<HasMetadata, HasMetadataVisitiableBuilder>get(((HasMetadata) item).getKind(), ((HasMetadata) item).getApiVersion());
} else if (item instanceof KubernetesList) {
return new KubernetesListHandler();
} else {
throw new IllegalArgumentException("Could not find a registered handler for item: [" + item + "].");
}
}
}
4 changes: 2 additions & 2 deletions openshift-client/src/main/resources/resource-handler.vm
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import java.util.function.Predicate;

import io.fabric8.kubernetes.client.Config;
import io.fabric8.openshift.client.OpenShiftConfig;
import io.fabric8.kubernetes.client.ResourceHandler;
import io.fabric8.openshift.client.OpenShiftResourceHandler;
import io.fabric8.kubernetes.client.Watch;
import io.fabric8.kubernetes.client.Watcher;
import io.fabric8.openshift.client.dsl.internal.${model.name}OperationsImpl;
Expand All @@ -64,7 +64,7 @@ import ${model.fullyQualifiedName}Builder;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

public class ${model.name}Handler implements ResourceHandler<${model.name}, ${model.name}Builder> {
public class ${model.name}Handler implements OpenShiftResourceHandler<${model.name}, ${model.name}Builder> {

@Override
public String getKind() {
Expand Down
Loading

0 comments on commit a2eda82

Please sign in to comment.