All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.bazhenov.docker.DockerAnnotationsInspector Maven / Gradle / Ivy

There is a newer version: 1.6.2
Show newest version
package me.bazhenov.docker;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

/**
 * Performs inspection of test classes using {@link Container} annotations as well as {@link AfterContainerStart} and
 * {@link ContainerPort}.
 * 

* All collected information is accessible through getters of this class. */ @SuppressWarnings("WeakerAccess") public class DockerAnnotationsInspector { private Map, ContainerNamespace> namespaces = new HashMap<>(); /** * Creates and saves container namespace for future use. *

* All saved namespaces accessible using {@link #getAllNamespaces()} * * @param clazz test case class * @return set of containers accessible from given test case */ public ContainerNamespace createNamespace(Class clazz) { ContainerNamespace existingNamespace = namespaces.get(clazz); if (existingNamespace != null) { return existingNamespace; } Container[] local = clazz.getAnnotationsByType(Container.class); ContainersFrom imports = clazz.getAnnotation(ContainersFrom.class); if (local.length <= 0 && imports == null) { return null; } Map result = new HashMap<>(); for (Container a : local) { ContainerDefinition def = createContainerDefinitionFromAnnotation(a); if (result.containsKey(a.name())) throw new IllegalStateException("Duplicating container name: " + a.name() + " for test: " + clazz); result.put(a.name(), def); } List importNamespaces = new ArrayList<>(); if (imports != null) { for (Class aClass : imports.value()) { importNamespaces.add(createNamespace(aClass)); } } ContainerNamespace namespace = new ContainerNamespace(result, importNamespaces); namespaces.put(clazz, namespace); return namespace; } private static ContainerDefinition createContainerDefinitionFromAnnotation(Container annotation) { ContainerDefinition def = new ContainerDefinition(annotation.image(), annotation.command()); fillPublishedPorts(annotation, def); fillEnvironmentVariables(annotation, def); fillCustomOptions(annotation, def); fillVolumes(annotation, def); def.setRemoveAfterCompletion(annotation.removeAfterCompletion()); def.setWaitForAllExposedPortsToBeOpen(annotation.waitForAllExposedPorts()); if (!annotation.workingDir().isEmpty()) { def.setWorkingDirectory(annotation.workingDir()); } return def; } private static void fillVolumes(Container annotation, ContainerDefinition def) { for (Volume volume : annotation.volumes()) { def.addVolume(volume.value(), volume.atHost()); } } private static void fillEnvironmentVariables(Container annotation, ContainerDefinition def) { for (String value : annotation.environment()) { String[] parts = value.split("=", 2); def.addEnvironment(parts[0], parts[1]); } } private static void fillPublishedPorts(Container annotation, ContainerDefinition def) { for (Port port : annotation.publish()) def.addPublishedPort(port.value(), port.atHost()); } private static void fillCustomOptions(Container annotation, ContainerDefinition def) { for (String option : annotation.options()) def.addCustomOption(option); } public Collection getAllNamespaces() { return namespaces.values(); } /** * Retrieves method marked with {@link AfterContainerStart} annotations and build notification method object * used to pass container ports to a test before start * * @param clazz test object type * @return notification method definition */ public Optional resolveNotificationMethod(Class clazz) { ContainerNamespace namespace = namespaces.get(clazz); if (namespace == null) { return Optional.empty(); } for (Method method : clazz.getDeclaredMethods()) { if (method.getAnnotation(AfterContainerStart.class) == null) continue; ensureParameterTypes(method); List portReferences = new ArrayList<>(method.getParameterCount()); for (Annotation[] args : method.getParameterAnnotations()) { ContainerPort portRef = retrieveAnnotation(args); if (portRef == null) { throw new IllegalStateException("All parameters should be marked with @ContainerPort: " + method); } portReferences.add(new PortRef(namespace.getDefinition(portRef.name()), portRef.port())); } return Optional.of(new NotificationMethod(namespace, method, portReferences)); } return Optional.empty(); } private ContainerPort retrieveAnnotation(Annotation[] args) { for (Annotation a : args) { if (a instanceof ContainerPort) return (ContainerPort) a; } return null; } private static void ensureParameterTypes(Method method) { for (Class type : method.getParameterTypes()) { if (type != int.class) throw new IllegalStateException("All method parameters should be of type int: " + method); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy