package org.arquillian.cube.kubernetes.impl.enricher; import com.fasterxml.jackson.databind.DeserializationFeature; import io.fabric8.kubernetes.clnt.v2_2.KubernetesClient; import io.fabric8.kubernetes.clnt.v2_2.utils.Serialization; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.arquillian.cube.kubernetes.annotations.Named; import org.arquillian.cube.kubernetes.impl.DefaultSession; import org.jboss.arquillian.core.api.Instance; import org.jboss.arquillian.core.api.annotation.Inject; import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider; public abstract class AbstractKubernetesResourceProvider implements ResourceProvider { private static final String JAVAX_INJECT_NAMED = "javax.inject.Named"; private static final String VALUE = "value"; private static final Object[] NO_ARGS = new Object[0]; private static final String VERSION_PACKAGE_PATTERN = ".v\\d+_\\d+"; private static final String CLNT = "clnt"; private static final String CLIENT = "client"; @Inject private Instance<KubernetesClient> client; @Inject private Instance<DefaultSession> seesion; protected String getName(Annotation... qualifiers) { for (Annotation annotation : qualifiers) { Class<? extends Annotation> type = annotation.annotationType(); if (annotation instanceof Named) { return ((Named) annotation).value(); } else if (type.getName().equals(JAVAX_INJECT_NAMED)) { return getAnnotationValue(annotation); } } return null; } protected String internalToUserType(String fqn) { return fqn.replaceAll(VERSION_PACKAGE_PATTERN, "").replaceAll(CLNT, CLIENT); } protected <I,O> O toUsersResource(I input) { return toUsersResource(input, internalToUserType(input.getClass().getCanonicalName())); } protected <I,O> O toUsersResource(I input, String className) { String json = Serialization.asJson(input); try { return (O) Serialization.jsonMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .readValue(json, loadClass(className)); } catch (IOException e) { throw new IllegalStateException("Failed to deserialize json into an object of class:["+className+"]."); } } /** * Try to load a class using the current classloader (the one that loaded this class) * or the thread context class loader. * @param className The name of the class. * @return The class of throws IllegalStateException. */ protected Class loadClass(String className) { try { return getClass().getClassLoader().loadClass(className); } catch (Exception e) { //ignore and fallback to TCCL } try { if (Thread.currentThread().getContextClassLoader() != null) return Thread.currentThread().getContextClassLoader().loadClass(className); } catch (Exception e) { //ignore and fallback to TCCL } throw new IllegalStateException("Failed to load class: ["+className+"]."); } /** * Get the value() from the specified annotation using reflection. * * @param annotation * The annotation. */ private String getAnnotationValue(Annotation annotation) { Class<? extends Annotation> type = annotation.annotationType(); try { Method method = type.getDeclaredMethod(VALUE); return String.valueOf(method.invoke(annotation, NO_ARGS)); } catch (NoSuchMethodException e) { return null; } catch (InvocationTargetException e) { return null; } catch (IllegalAccessException e) { return null; } } protected KubernetesClient getClient() { return client.get(); } public DefaultSession getSession() { return seesion.get(); } }