stratos-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From im...@apache.org
Subject [07/12] stratos git commit: Migrating Kubernetes API client to Fabric8
Date Mon, 15 Jun 2015 12:43:12 GMT
http://git-wip-us.apache.org/repos/asf/stratos/blob/3414e7ce/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/KubernetesHelper.java
----------------------------------------------------------------------
diff --git a/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/KubernetesHelper.java b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/KubernetesHelper.java
new file mode 100644
index 0000000..360c0a5
--- /dev/null
+++ b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/KubernetesHelper.java
@@ -0,0 +1,1724 @@
+/**
+ * Copyright 2005-2014 Red Hat, Inc.
+ *
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.  See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package io.fabric8.kubernetes.api;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import io.fabric8.kubernetes.api.model.KubernetesResource;
+import io.fabric8.kubernetes.api.extensions.Templates;
+import io.fabric8.kubernetes.api.model.Container;
+import io.fabric8.kubernetes.api.model.ContainerPort;
+import io.fabric8.kubernetes.api.model.ContainerState;
+import io.fabric8.kubernetes.api.model.ContainerStateRunning;
+import io.fabric8.kubernetes.api.model.ContainerStateTerminated;
+import io.fabric8.kubernetes.api.model.ContainerStateWaiting;
+import io.fabric8.kubernetes.api.model.ContainerStatus;
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.fabric8.kubernetes.api.model.KubernetesList;
+import io.fabric8.kubernetes.api.model.ObjectMeta;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.PodList;
+import io.fabric8.kubernetes.api.model.PodSpec;
+import io.fabric8.kubernetes.api.model.PodStatus;
+import io.fabric8.kubernetes.api.model.PodTemplateSpec;
+import io.fabric8.kubernetes.api.model.ReplicationController;
+import io.fabric8.kubernetes.api.model.ReplicationControllerList;
+import io.fabric8.kubernetes.api.model.ReplicationControllerSpec;
+import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.api.model.Service;
+import io.fabric8.kubernetes.api.model.ServiceList;
+import io.fabric8.kubernetes.api.model.ServicePort;
+import io.fabric8.kubernetes.api.model.ServiceSpec;
+import io.fabric8.kubernetes.api.model.util.IntOrString;
+import io.fabric8.openshift.api.model.DeploymentConfig;
+import io.fabric8.openshift.api.model.DeploymentConfigSpec;
+import io.fabric8.openshift.api.model.OAuthClient;
+import io.fabric8.openshift.api.model.Route;
+import io.fabric8.openshift.api.model.RouteSpec;
+import io.fabric8.openshift.api.model.template.Parameter;
+import io.fabric8.openshift.api.model.template.Template;
+import io.fabric8.utils.Files;
+import io.fabric8.utils.Filter;
+import io.fabric8.utils.Filters;
+import io.fabric8.utils.Objects;
+import io.fabric8.utils.Strings;
+import io.fabric8.utils.Systems;
+import io.fabric8.utils.cxf.TrustEverythingSSLTrustManager;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xbill.DNS.*;
+
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLKeyException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLProtocolException;
+import javax.net.ssl.SSLSocketFactory;
+import javax.ws.rs.WebApplicationException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import static io.fabric8.utils.Lists.notNullList;
+import static io.fabric8.utils.Strings.isNullOrBlank;
+
+/**
+ * Kubernetes utility methods.
+ */
+public final class KubernetesHelper {
+    public static final int INTORSTRING_KIND_INT = 0;
+    public static final int INTORSTRING_KIND_STRING = 1;
+    private static final transient Logger LOG = LoggerFactory.getLogger(KubernetesHelper.class);
+
+    public static final String DEFAULT_DOCKER_HOST = "tcp://localhost:2375";
+    protected static SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
+    private static ObjectMapper objectMapper = KubernetesFactory.createObjectMapper();
+
+    public static final String defaultApiVersion = "v1beta3";
+    public static final String defaultOsApiVersion = "v1beta3";
+
+    private static final String HOST_SUFFIX = "_SERVICE_HOST";
+    private static final String PORT_SUFFIX = "_SERVICE_PORT";
+    private static final String PROTO_SUFFIX = "_TCP_PROTO";
+    public static final String DEFAULT_PROTO = "tcp";
+
+    /**
+     * Returns the ID of the given object
+     */
+    public static String getObjectId(Object object) {
+        if (object instanceof HasMetadata) {
+            return getName((HasMetadata) object);
+        } else {
+            return object != null ? object.toString() : null;
+        }
+    }
+
+    public static ObjectMeta getOrCreateMetadata(HasMetadata entity) {
+        ObjectMeta metadata = entity.getMetadata();
+        if (metadata == null) {
+            metadata = new ObjectMeta();
+            entity.setMetadata(metadata);
+        }
+        return metadata;
+    }
+
+    /**
+     * Returns the resource version for the entity or null if it does not have one
+     */
+    public static String getResourceVersion(HasMetadata entity) {
+        if (entity != null) {
+            ObjectMeta metadata = entity.getMetadata();
+            if (metadata != null) {
+                String resourceVersion = metadata.getResourceVersion();
+                if (Strings.isNotBlank(resourceVersion)) {
+                    return resourceVersion;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns true if this entity has a valid non blank resourceVersion in its metadata
+     */
+    public static boolean hasResourceVersion(HasMetadata entity) {
+        return getResourceVersion(entity) != null;
+    }
+
+    public static String getName(ObjectMeta entity) {
+        if (entity != null) {
+            return Strings.firstNonBlank(entity.getName(),
+                    getAdditionalPropertyText(entity.getAdditionalProperties(), "id"),
+                    entity.getUid());
+        } else {
+            return null;
+        }
+    }
+
+
+    /**
+     * Returns the kind of the entity
+     */
+    public static String getKind(HasMetadata entity) {
+        if (entity != null) {
+            // TODO use reflection to find the kind?
+            if (entity instanceof KubernetesList) {
+                return "List";
+            } else {
+                return entity.getClass().getSimpleName();
+            }
+        } else {
+            return null;
+        }
+    }
+
+    public static String getName(HasMetadata entity) {
+        if (entity != null) {
+            return getName(entity.getMetadata());
+        } else {
+            return null;
+        }
+    }
+
+    public static void setName(HasMetadata entity, String name) {
+        getOrCreateMetadata(entity).setName(name);
+    }
+
+    public static void setName(HasMetadata entity, String namespace, String name) {
+        ObjectMeta metadata = getOrCreateMetadata(entity);
+        metadata.setNamespace(namespace);
+        metadata.setName(name);
+    }
+
+    public static void setNamespace(HasMetadata entity, String namespace) {
+        getOrCreateMetadata(entity).setNamespace(namespace);
+    }
+
+    public static String getNamespace(ObjectMeta entity) {
+        if (entity != null) {
+            return entity.getNamespace();
+        } else {
+            return null;
+        }
+    }
+
+    public static String getNamespace(HasMetadata entity) {
+        if (entity != null) {
+            return getNamespace(entity.getMetadata());
+        } else {
+            return null;
+        }
+    }
+
+    public static Map<String, String> getOrCreateAnnotations(HasMetadata entity) {
+        ObjectMeta metadata = getOrCreateMetadata(entity);
+        Map<String, String> answer = metadata.getAnnotations();
+        if (answer == null) {
+            // use linked so the annotations can be in the FIFO order
+            answer = new LinkedHashMap<>();
+            metadata.setAnnotations(answer);
+        }
+        return answer;
+    }
+
+    public static Map<String, String> getOrCreateLabels(HasMetadata entity) {
+        ObjectMeta metadata = getOrCreateMetadata(entity);
+        Map<String, String> answer = metadata.getLabels();
+        if (answer == null) {
+            // use linked so the annotations can be in the FIFO order
+            answer = new LinkedHashMap<>();
+            metadata.setLabels(answer);
+        }
+        return answer;
+    }
+
+    /**
+     * Returns the labels of the given metadata object or an empty map if the metadata or labels are null
+     */
+    @SuppressWarnings("unchecked")
+    public static Map<String, String> getLabels(ObjectMeta metadata) {
+        if (metadata != null) {
+            Map<String, String> labels = metadata.getLabels();
+            if (labels != null) {
+                return labels;
+            }
+        }
+        return Collections.EMPTY_MAP;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static Map<String, String> getLabels(HasMetadata entity) {
+        if (entity != null) {
+            return getLabels(entity.getMetadata());
+        }
+        return Collections.EMPTY_MAP;
+    }
+
+    public static ServiceSpec getOrCreateSpec(Service entity) {
+        ServiceSpec spec = entity.getSpec();
+        if (spec == null) {
+            spec = new ServiceSpec();
+            entity.setSpec(spec);
+        }
+        return spec;
+    }
+
+    public static String getPortalIP(Service entity) {
+        String answer = null;
+        if (entity != null) {
+            ServiceSpec spec = getOrCreateSpec(entity);
+            return spec.getPortalIP();
+        }
+        return answer;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static Map<String, String> getSelector(Service entity) {
+        Map<String, String> answer = null;
+        if (entity != null) {
+            ServiceSpec spec = getOrCreateSpec(entity);
+            answer = spec.getSelector();
+        }
+        return answer != null ? answer : Collections.EMPTY_MAP;
+    }
+
+    public static void setSelector(Service entity, Map<String, String> labels) {
+        ServiceSpec spec = getOrCreateSpec(entity);
+        spec.setSelector(labels);
+    }
+
+    public static Set<Integer> getPorts(Service entity) {
+        Set<Integer> answer = new HashSet<>();
+        if (entity != null) {
+            ServiceSpec spec = getOrCreateSpec(entity);
+            for (ServicePort port : spec.getPorts()) {
+                answer.add(port.getPort());
+            }
+        }
+        return answer;
+    }
+
+    protected static String getAdditionalPropertyText(Map<String, Object> additionalProperties, String name) {
+        if (additionalProperties != null) {
+            Object value = additionalProperties.get(name);
+            if (value != null) {
+                return value.toString();
+            }
+        }
+        return null;
+    }
+
+    protected static Map<String, Object> getMetadata(Map<String, Object> additionalProperties, boolean create) {
+        Map<String, Object> answer = getAdditionalPropertyMap(additionalProperties, "metadata");
+        if (answer == null) {
+            answer = new LinkedHashMap<>();
+            if (create) {
+                additionalProperties.put("metadata", answer);
+            }
+        }
+        return answer;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected static Map<String, Object> getAdditionalPropertyMap(Map<String, Object> additionalProperties, String name) {
+        if (additionalProperties != null) {
+            Object value = additionalProperties.get(name);
+            if (value instanceof Map) {
+                return (Map<String, Object>) value;
+            }
+        }
+        return null;
+    }
+
+    public static String getDockerIp() {
+        String url = resolveDockerHost();
+        int idx = url.indexOf("://");
+        if (idx > 0) {
+            url = url.substring(idx + 3);
+        }
+        idx = url.indexOf(":");
+        if (idx > 0) {
+            url = url.substring(0, idx);
+        }
+        return url;
+    }
+
+    public static String resolveDockerHost() {
+        String dockerHost = System.getenv("DOCKER_HOST");
+        if (isNullOrBlank(dockerHost)) {
+            dockerHost = System.getProperty("docker.host");
+        }
+        if (isNullOrBlank(dockerHost)) {
+            return DEFAULT_DOCKER_HOST;
+        } else {
+            return dockerHost;
+        }
+    }
+
+    public static String toJson(Object dto) throws JsonProcessingException {
+        Class<?> clazz = dto.getClass();
+        return objectMapper.writerWithType(clazz).writeValueAsString(dto);
+    }
+
+    /**
+     * Returns the given json data as a DTO such as
+     * {@link Pod}, {@link ReplicationController} or
+     * {@link io.fabric8.kubernetes.api.model.Service}
+     * from the Kubernetes REST API
+     */
+    public static Object loadJson(File file) throws IOException {
+        byte[] data = Files.readBytes(file);
+        return loadJson(data);
+    }
+
+    /**
+     * Returns the given json data as a DTO such as
+     * {@link Pod}, {@link ReplicationController} or
+     * {@link io.fabric8.kubernetes.api.model.Service}
+     * from the Kubernetes REST API
+     */
+    public static Object loadJson(InputStream in) throws IOException {
+        byte[] data = Files.readBytes(in);
+        return loadJson(data);
+    }
+
+    public static Object loadJson(String json) throws IOException {
+        byte[] data = json.getBytes();
+        return loadJson(data);
+    }
+
+    /**
+     * Returns the given json data as a DTO such as
+     * {@link Pod}, {@link ReplicationController} or
+     * {@link io.fabric8.kubernetes.api.model.Service}
+     * from the Kubernetes REST API
+     */
+    public static Object loadJson(byte[] json) throws IOException {
+        if (json != null && json.length > 0) {
+            return objectMapper.reader(KubernetesResource.class).readValue(json);
+        }
+        return null;
+    }
+
+    /**
+     * Loads the YAML file for the given DTO class
+     */
+    public static <T> T loadYaml(InputStream in, Class<T> clazz) throws IOException {
+        byte[] data = Files.readBytes(in);
+        return loadYaml(data, clazz);
+    }
+
+    /**
+     * Loads the YAML file for the given DTO class
+     */
+    public static <T> T loadYaml(File file, Class<T> clazz) throws IOException {
+        byte[] data = Files.readBytes(file);
+        return loadYaml(data, clazz);
+    }
+
+    /**
+     * Loads the YAML file for the given DTO class
+     */
+    public static <T> T loadYaml(byte[] data, Class<T> clazz) throws IOException {
+        ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
+        return mapper.readValue(data, clazz);
+    }
+
+    /**
+     * Loads the Kubernetes JSON and converts it to a list of entities
+     */
+    @SuppressWarnings("unchecked")
+    public static List<HasMetadata> toItemList(Object entity) throws IOException {
+        if (entity instanceof List) {
+            return (List<HasMetadata>) entity;
+        } else if (entity instanceof HasMetadata[]) {
+            HasMetadata[] array = (HasMetadata[]) entity;
+            return Arrays.asList(array);
+        } else if (entity instanceof KubernetesList) {
+            KubernetesList config = (KubernetesList) entity;
+            return config.getItems();
+        } else if (entity instanceof Template) {
+            Template objects = (Template) entity;
+            return objects.getObjects();
+        } else {
+            List<HasMetadata> answer = new ArrayList<>();
+            if (entity instanceof HasMetadata) {
+                answer.add((HasMetadata) entity);
+            }
+            return answer;
+        }
+    }
+
+    /**
+     * Saves the json object to the given file
+     */
+    public static void saveJson(File json, Object object) throws IOException {
+        objectMapper.writer().writeValue(json, object);
+    }
+
+    /**
+     * Returns a map indexed by pod id of the pods
+     */
+    public static Map<String, Pod> toPodMap(PodList podSchema) {
+        return toFilteredPodMap(podSchema, Filters.<Pod>trueFilter());
+    }
+
+    protected static Map<String, Pod> toFilteredPodMap(PodList podSchema, Filter<Pod> filter) {
+        List<Pod> list = podSchema != null ? podSchema.getItems() : null;
+        List<Pod> filteredList = Filters.filter(list, filter);
+        return toPodMap(filteredList);
+    }
+
+    /**
+     * Returns a map indexed by pod id of the pods
+     */
+    public static Map<String, Pod> toPodMap(List<Pod> pods) {
+        List<Pod> list = notNullList(pods);
+        Map<String, Pod> answer = new HashMap<>();
+        for (Pod pod : list) {
+            String id = getName(pod);
+            if (Strings.isNotBlank(id)) {
+                answer.put(id, pod);
+            }
+        }
+        return answer;
+    }
+
+    /**
+     * Returns a map indexed by service id of the services
+     */
+    public static Map<String, Service> toServiceMap(ServiceList serviceSchema) {
+        return toServiceMap(serviceSchema != null ? serviceSchema.getItems() : null);
+    }
+
+    /**
+     * Returns a map indexed by service id of the services
+     */
+    public static Map<String, Service> toServiceMap(List<Service> services) {
+        List<Service> list = notNullList(services);
+        Map<String, Service> answer = new HashMap<>();
+        for (Service service : list) {
+            String id = getName(service);
+            if (Strings.isNotBlank(id)) {
+                answer.put(id, service);
+            }
+        }
+        return answer;
+    }
+
+    public static Map<String, Service> toFilteredServiceMap(ServiceList serviceList, Filter<Service> filter) {
+        List<Service> list = serviceList != null ? serviceList.getItems() : null;
+        List<Service> filteredList = Filters.filter(list, filter);
+        return toServiceMap(filteredList);
+    }
+
+    /**
+     * Returns a map indexed by replicationController id of the replicationControllers
+     */
+    public static Map<String, ReplicationController> toReplicationControllerMap(ReplicationControllerList replicationControllerSchema) {
+        Filter<ReplicationController> filter = createReplicationControllerFilter((String) null);
+        return toFilteredReplicationControllerMap(replicationControllerSchema, filter);
+    }
+
+    protected static Map<String, ReplicationController> toFilteredReplicationControllerMap(ReplicationControllerList replicationControllerSchema, Filter<ReplicationController> filter) {
+        List<ReplicationController> list = replicationControllerSchema != null ? replicationControllerSchema.getItems() : null;
+        List<ReplicationController> filteredList = Filters.filter(list, filter);
+        return toReplicationControllerMap(filteredList);
+    }
+
+    /**
+     * Returns a map indexed by replicationController id of the replicationControllers
+     */
+    public static Map<String, ReplicationController> toReplicationControllerMap(List<ReplicationController> replicationControllers) {
+        List<ReplicationController> list = notNullList(replicationControllers);
+        Map<String, ReplicationController> answer = new HashMap<>();
+        for (ReplicationController replicationControllerSchema : list) {
+            String id = getName(replicationControllerSchema);
+            if (Strings.isNotBlank(id)) {
+                answer.put(id, replicationControllerSchema);
+            }
+        }
+        return answer;
+    }
+
+    public static Map<String, Pod> getPodMap(Kubernetes kubernetes) {
+        return getPodMap(kubernetes, Kubernetes.NAMESPACE_ALL);
+    }
+
+    public static Map<String, Pod> getPodMap(Kubernetes kubernetes, String namespace) {
+        PodList pods = null;
+        try {
+            pods = kubernetes.getPods(namespace);
+        } catch (WebApplicationException e) {
+            if (e.getResponse().getStatus() == 404) {
+                // ignore not found
+            } else {
+                throw e;
+            }
+        }
+        return toPodMap(pods);
+    }
+
+    public static Map<String, Pod> getSelectedPodMap(Kubernetes kubernetes, String selector) {
+        return getSelectedPodMap(kubernetes, Kubernetes.NAMESPACE_ALL, selector);
+    }
+
+    public static Map<String, Pod> getSelectedPodMap(Kubernetes kubernetes, String namespace, String selector) {
+        Filter<Pod> filter = createPodFilter(selector);
+        return getFilteredPodMap(kubernetes, namespace, filter);
+    }
+
+    public static Map<String, Pod> getFilteredPodMap(Kubernetes kubernetes, Filter<Pod> filter) {
+        return getFilteredPodMap(kubernetes, Kubernetes.NAMESPACE_ALL, filter);
+    }
+
+    public static Map<String, Pod> getFilteredPodMap(Kubernetes kubernetes, String namespace, Filter<Pod> filter) {
+        PodList podSchema = kubernetes.getPods(namespace);
+        return toFilteredPodMap(podSchema, filter);
+    }
+
+    public static Map<String, Service> getServiceMap(Kubernetes kubernetes) {
+        return getServiceMap(kubernetes, Kubernetes.NAMESPACE_ALL);
+    }
+
+    public static Map<String, Service> getServiceMap(Kubernetes kubernetes, String namespace) {
+        return toServiceMap(kubernetes.getServices(namespace));
+    }
+
+    public static Map<String, ReplicationController> getReplicationControllerMap(Kubernetes kubernetes) {
+        return getReplicationControllerMap(kubernetes, Kubernetes.NAMESPACE_ALL);
+    }
+
+    public static Map<String, ReplicationController> getReplicationControllerMap(Kubernetes kubernetes, String namespace) {
+        return toReplicationControllerMap(kubernetes.getReplicationControllers(namespace));
+    }
+
+    public static Map<String, ReplicationController> getSelectedReplicationControllerMap(Kubernetes kubernetes, String selector) {
+        return getSelectedReplicationControllerMap(kubernetes, Kubernetes.NAMESPACE_ALL, selector);
+    }
+
+    public static Map<String, ReplicationController> getSelectedReplicationControllerMap(Kubernetes kubernetes, String namespace, String selector) {
+        Filter<ReplicationController> filter = createReplicationControllerFilter(selector);
+        return toFilteredReplicationControllerMap(kubernetes.getReplicationControllers(namespace), filter);
+    }
+
+    /**
+     * Removes empty pods returned by Kubernetes
+     */
+    public static void removeEmptyPods(PodList podSchema) {
+        List<Pod> list = notNullList(podSchema.getItems());
+
+        List<Pod> removeItems = new ArrayList<Pod>();
+
+        for (Pod pod : list) {
+            if (StringUtils.isEmpty(getName(pod))) {
+                removeItems.add(pod);
+
+            }
+        }
+        list.removeAll(removeItems);
+    }
+
+    /**
+     * Returns the pod id for the given container id
+     */
+    public static String containerNameToPodId(String containerName) {
+        // TODO use prefix?
+        return containerName;
+    }
+
+    /**
+     * Returns a string for the labels using "," to separate values
+     */
+    public static String toLabelsString(Map<String, String> labelMap) {
+        StringBuilder buffer = new StringBuilder();
+        if (labelMap != null) {
+            Set<Map.Entry<String, String>> entries = labelMap.entrySet();
+            for (Map.Entry<String, String> entry : entries) {
+                if (buffer.length() > 0) {
+                    buffer.append(",");
+                }
+                buffer.append(entry.getKey());
+                buffer.append("=");
+                buffer.append(entry.getValue());
+            }
+        }
+        return buffer.toString();
+    }
+
+    public static Map<String, String> toLabelsMap(String labels) {
+        Map<String, String> map = new HashMap<>();
+        if (labels != null && !labels.isEmpty()) {
+            String[] elements = labels.split(",");
+            if (elements.length > 0) {
+                for (String str : elements) {
+                    String[] keyValue = str.split("=");
+                    if (keyValue.length == 2) {
+                        String key = keyValue[0];
+                        String value = keyValue[1];
+                        if (key != null && value != null) {
+                            map.put(key.trim(), value.trim());
+                        }
+                    }
+                }
+            }
+        }
+        return map;
+    }
+
+    /**
+     * Creates a filter on a pod using the given text string
+     */
+    public static Filter<Pod> createPodFilter(final String textFilter) {
+        if (isNullOrBlank(textFilter)) {
+            return Filters.<Pod>trueFilter();
+        } else {
+            return new Filter<Pod>() {
+                public String toString() {
+                    return "PodFilter(" + textFilter + ")";
+                }
+
+                public boolean matches(Pod entity) {
+                    return filterMatchesIdOrLabels(textFilter, getName(entity), entity.getMetadata().getLabels());
+                }
+            };
+        }
+    }
+
+    /**
+     * Creates a filter on a pod using the given set of labels
+     */
+    public static Filter<Pod> createPodFilter(final Map<String, String> labelSelector) {
+        if (labelSelector == null || labelSelector.isEmpty()) {
+            return Filters.<Pod>trueFilter();
+        } else {
+            return new Filter<Pod>() {
+                public String toString() {
+                    return "PodFilter(" + labelSelector + ")";
+                }
+
+                public boolean matches(Pod entity) {
+                    return filterLabels(labelSelector, entity.getMetadata().getLabels());
+                }
+            };
+        }
+    }
+
+    /**
+     * Creates a filter on a pod annotations using the given set of attribute values
+     */
+    public static Filter<Pod> createPodAnnotationFilter(final Map<String, String> annotationSelector) {
+        if (annotationSelector == null || annotationSelector.isEmpty()) {
+            return Filters.<Pod>trueFilter();
+        } else {
+            return new Filter<Pod>() {
+                public String toString() {
+                    return "PodAnnotationFilter(" + annotationSelector + ")";
+                }
+
+                public boolean matches(Pod entity) {
+                    return filterLabels(annotationSelector, entity.getMetadata().getAnnotations());
+                }
+            };
+        }
+    }
+
+    /**
+     * Creates a filter on a service using the given text string
+     */
+    public static Filter<Service> createServiceFilter(final String textFilter) {
+        if (isNullOrBlank(textFilter)) {
+            return Filters.<Service>trueFilter();
+        } else {
+            return new Filter<Service>() {
+                public String toString() {
+                    return "ServiceFilter(" + textFilter + ")";
+                }
+
+                public boolean matches(Service entity) {
+                    return filterMatchesIdOrLabels(textFilter, getName(entity), entity.getMetadata().getLabels());
+                }
+            };
+        }
+    }
+
+    /**
+     * Creates a filter on a service if it matches the given namespace
+     */
+    public static Filter<Service> createNamespaceServiceFilter(final String namespace) {
+        if (isNullOrBlank(namespace)) {
+            return Filters.<Service>trueFilter();
+        } else {
+            return new Filter<Service>() {
+                public String toString() {
+                    return "NamespaceServiceFilter(" + namespace + ")";
+                }
+
+                public boolean matches(Service entity) {
+                    return Objects.equal(namespace, getNamespace(entity.getMetadata()));
+                }
+            };
+        }
+    }
+
+    /**
+     * Creates a filter on a service using the given text string
+     */
+    public static Filter<Service> createServiceFilter(final Map<String, String> labelSelector) {
+        if (labelSelector == null || labelSelector.isEmpty()) {
+            return Filters.<Service>trueFilter();
+        } else {
+            return new Filter<Service>() {
+                public String toString() {
+                    return "ServiceFilter(" + labelSelector + ")";
+                }
+
+                public boolean matches(Service entity) {
+                    return filterLabels(labelSelector, entity.getMetadata().getLabels());
+                }
+            };
+        }
+    }
+
+    /**
+     * Creates a filter on a replicationController using the given text string
+     */
+    public static Filter<ReplicationController> createReplicationControllerFilter(final String textFilter) {
+        if (isNullOrBlank(textFilter)) {
+            return Filters.<ReplicationController>trueFilter();
+        } else {
+            return new Filter<ReplicationController>() {
+                public String toString() {
+                    return "ReplicationControllerFilter(" + textFilter + ")";
+                }
+
+                public boolean matches(ReplicationController entity) {
+                    return filterMatchesIdOrLabels(textFilter, getName(entity), entity.getMetadata().getLabels());
+                }
+            };
+        }
+    }
+
+    /**
+     * Creates a filter on a replicationController using the given text string
+     */
+    public static Filter<ReplicationController> createReplicationControllerFilter(final Map<String, String> labelSelector) {
+        if (labelSelector == null || labelSelector.isEmpty()) {
+            return Filters.<ReplicationController>trueFilter();
+        } else {
+            return new Filter<ReplicationController>() {
+                public String toString() {
+                    return "ReplicationControllerFilter(" + labelSelector + ")";
+                }
+
+                public boolean matches(ReplicationController entity) {
+                    return filterLabels(labelSelector, entity.getMetadata().getLabels());
+                }
+            };
+        }
+    }
+
+    /**
+     * Returns true if the given textFilter matches either the id or the labels
+     */
+    public static boolean filterMatchesIdOrLabels(String textFilter, String id, Map<String, String> labels) {
+        String text = toLabelsString(labels);
+        boolean result = (text != null && text.contains(textFilter)) || (id != null && id.contains(textFilter));
+        if (!result) {
+            //labels can be in different order to selector
+            Map<String, String> selectorMap = toLabelsMap(textFilter);
+
+            if (!selectorMap.isEmpty() && labels != null && !labels.isEmpty()) {
+                result = true;
+                for (Map.Entry<String, String> entry : selectorMap.entrySet()) {
+                    String value = labels.get(entry.getKey());
+                    if (value == null || !value.matches(entry.getValue())) {
+                        result = false;
+                        break;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns true if the given filterLabels matches the actual labels
+     */
+    public static boolean filterLabels(Map<String, String> filterLabels, Map<String, String> labels) {
+        if (labels == null) {
+            return false;
+        }
+        Set<Map.Entry<String, String>> entries = filterLabels.entrySet();
+        for (Map.Entry<String, String> entry : entries) {
+            String key = entry.getKey();
+            String expectedValue = entry.getValue();
+            String actualValue = labels.get(key);
+            if (!Objects.equal(expectedValue, actualValue)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * For positive non-zero values return the text of the number or return blank
+     */
+    public static String toPositiveNonZeroText(Integer port) {
+        if (port != null) {
+            int value = port;
+            if (value > 0) {
+                return "" + value;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * Returns all the containers from the given pod
+     */
+    @SuppressWarnings("unchecked")
+    public static List<Container> getContainers(Pod pod) {
+        if (pod != null) {
+            PodSpec podSpec = pod.getSpec();
+            return getContainers(podSpec);
+
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Returns all the containers from the given Replication Controller
+     */
+    @SuppressWarnings("unchecked")
+    public static List<Container> getContainers(ReplicationController replicationController) {
+        if (replicationController != null) {
+            ReplicationControllerSpec replicationControllerSpec = replicationController.getSpec();
+            return getContainers(replicationControllerSpec);
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Returns all the containers from the given Replication Controller's replicationControllerSpec
+     */
+    @SuppressWarnings("unchecked")
+    public static List<Container> getContainers(ReplicationControllerSpec replicationControllerSpec) {
+        if (replicationControllerSpec != null) {
+            PodTemplateSpec podTemplateSpec = replicationControllerSpec.getTemplate();
+            return getContainers(podTemplateSpec);
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static List<Container> getContainers(PodSpec podSpec) {
+        if (podSpec != null) {
+            return podSpec.getContainers();
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static List<Container> getContainers(PodTemplateSpec podTemplateSpec) {
+        if (podTemplateSpec != null) {
+            return getContainers(podTemplateSpec.getSpec());
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Returns all the containers from the given Replication Controller
+     */
+    @SuppressWarnings("unchecked")
+    public static List<Container> getCurrentContainers(ReplicationController replicationController) {
+        if (replicationController != null) {
+            // TODO
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Returns all the current containers from the given currentState
+     */
+    @SuppressWarnings("unchecked")
+    public static Map<String, ContainerStatus> getCurrentContainers(Pod pod) {
+        if (pod != null) {
+            PodStatus currentStatus = pod.getStatus();
+            return getCurrentContainers(currentStatus);
+
+        }
+        return Collections.EMPTY_MAP;
+    }
+
+    /**
+     * Returns all the current containers from the given podStatus
+     */
+    @SuppressWarnings("unchecked")
+    public static Map<String, ContainerStatus> getCurrentContainers(PodStatus podStatus) {
+        if (podStatus != null) {
+            List<ContainerStatus> containerStatuses = podStatus.getContainerStatuses();
+            Map<String, ContainerStatus> info = new Hashtable<>(containerStatuses.size());
+            for (ContainerStatus status : containerStatuses) {
+                info.put(status.getContainerID(), status);
+            }
+            return info;
+        }
+        return Collections.EMPTY_MAP;
+    }
+
+    /**
+     * Returns the host of the pod
+     */
+    public static String getHost(Pod pod) {
+        if (pod != null) {
+            PodStatus currentState = pod.getStatus();
+            if (currentState != null) {
+                return currentState.getHostIP();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the container port number for the given service
+     */
+    @SuppressWarnings("unchecked")
+    public static Set<Integer> getContainerPorts(Service service) {
+        Set<Integer> answer = Collections.EMPTY_SET;
+        String id = getName(service);
+        ServiceSpec spec = service.getSpec();
+        if (spec != null) {
+            List<ServicePort> servicePorts = spec.getPorts();
+            Objects.notNull(servicePorts, "servicePorts for service " + id);
+
+            answer = new HashSet<>(servicePorts.size());
+            String message = "service " + id;
+
+            for (ServicePort port : servicePorts) {
+                IntOrString intOrStringValue = port.getTargetPort();
+                Integer intValue = intOrStringToInteger(intOrStringValue, message);
+                if (intValue != null) {
+                    answer.add(intValue);
+                }
+            }
+        }
+        return answer;
+    }
+
+    /**
+     * Returns the IntOrString converted to an Integer value or throws an exception with the given message
+     */
+    public static Integer intOrStringToInteger(IntOrString intOrStringValue, String message) {
+        Integer intValue = intOrStringValue.getIntVal();
+        if (intValue == null) {
+            String containerPortText = intOrStringValue.getStrVal();
+            if (Strings.isNullOrBlank(containerPortText)) {
+                throw new IllegalArgumentException("No port for " +
+                        message);
+            }
+            try {
+                intValue = Integer.parseInt(containerPortText);
+            } catch (NumberFormatException e) {
+                throw new IllegalStateException("Invalid servicePorts expression " + containerPortText + " for " +
+                        message + ". " + e, e);
+            }
+        }
+        return intValue;
+    }
+
+    /**
+     * Returns the container port number for the given service
+     */
+    @SuppressWarnings("unchecked")
+    public static Set<String> getContainerPortsStrings(Service service) {
+        Set<String> answer = Collections.EMPTY_SET;
+        String id = getName(service);
+        ServiceSpec spec = service.getSpec();
+        if (spec != null) {
+            List<ServicePort> servicePorts = spec.getPorts();
+            Objects.notNull(servicePorts, "servicePorts for service " + id);
+
+            answer = new HashSet<>(servicePorts.size());
+
+            for (ServicePort port : servicePorts) {
+                IntOrString intOrStringValue = port.getTargetPort();
+                Integer intValue = intOrStringValue.getIntVal();
+                if (intValue != null) {
+                    answer.add(intValue.toString());
+                } else {
+                    String containerPortText = intOrStringValue.getStrVal();
+                    if (Strings.isNullOrBlank(containerPortText)) {
+                        throw new IllegalArgumentException("No servicePorts for service " + id);
+                    }
+                    answer.add(containerPortText);
+                }
+            }
+        }
+        return answer;
+    }
+
+    /**
+     * Combines the JSON objects into a config object
+     */
+    public static Object combineJson(Object... objects) throws IOException {
+        KubernetesList list = findOrCreateList(objects);
+        List<HasMetadata> items = list.getItems();
+        if (items == null) {
+            items = new ArrayList<>();
+            list.setItems(items);
+        }
+        for (Object object : objects) {
+            if (object != list) {
+                addObjectsToItemArray(items, object);
+            }
+        }
+        moveServicesToFrontOfArray(items);
+        removeDuplicates(items);
+        Object answer = Templates.combineTemplates(list, items);
+        items = toItemList(answer);
+        removeDuplicates(items);
+        return answer;
+    }
+
+    /**
+     * Lets move all Service resources before any other to avoid ordering issues creating things
+     */
+    public static void moveServicesToFrontOfArray(List<HasMetadata> list) {
+        int size = list.size();
+        int lastNonService = -1;
+        for (int i = 0; i < size; i++) {
+            HasMetadata item = list.get(i);
+            if (item instanceof Service) {
+                if (lastNonService >= 0) {
+                    HasMetadata nonService = list.get(lastNonService);
+                    list.set(i, nonService);
+                    list.set(lastNonService, item);
+                    lastNonService++;
+                }
+            } else if (lastNonService < 0) {
+                lastNonService = i;
+            }
+        }
+    }
+
+    /**
+     * Remove any duplicate resources using the kind and id
+     */
+    protected static void removeDuplicates(List<HasMetadata> itemArray) {
+        int size = itemArray.size();
+        int lastNonService = -1;
+        Set<String> keys = new HashSet<>();
+        for (int i = 0; i < size; i++) {
+            HasMetadata item = itemArray.get(i);
+            if (item == null) {
+                itemArray.remove(i);
+                i--;
+                size--;
+            } else {
+                String id = getObjectId(item);
+                String kind = item.getClass().getSimpleName();
+                if (Strings.isNotBlank(id)) {
+                    String key = kind + ":" + id;
+                    if (!keys.add(key)) {
+                        // lets remove this one
+                        itemArray.remove(i);
+                        i--;
+                        size--;
+                    }
+                }
+
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    protected static void addObjectsToItemArray(List destinationList, Object object) throws IOException {
+        if (object instanceof KubernetesList) {
+            KubernetesList kubernetesList = (KubernetesList) object;
+            List<HasMetadata> items = kubernetesList.getItems();
+            if (items != null) {
+                destinationList.addAll(items);
+            }
+        } else if (object instanceof Collection) {
+            Collection collection = (Collection) object;
+            destinationList.addAll(collection);
+        } else {
+            destinationList.add(object);
+        }
+    }
+
+    protected static KubernetesList findOrCreateList(Object[] objects) {
+        KubernetesList list = null;
+        for (Object object : objects) {
+            if (object instanceof KubernetesList) {
+                list = (KubernetesList) object;
+                break;
+            }
+        }
+        if (list == null) {
+            list = new KubernetesList();
+        }
+        return list;
+    }
+
+    /**
+     * Returns the URL to access the service; using the service portalIP and port
+     */
+    public static String getServiceURL(Service service) {
+        if (service != null) {
+            ServiceSpec spec = service.getSpec();
+            if (spec != null) {
+                String portalIP = spec.getPortalIP();
+                if (portalIP != null) {
+                    Integer port = spec.getPorts().iterator().next().getPort();
+                    if (port != null && port > 0) {
+                        portalIP += ":" + port;
+                    }
+                    String protocol = "http://";
+                    if (KubernetesHelper.isServiceSsl(spec.getPortalIP(), port, Boolean.valueOf(System.getenv(KubernetesFactory.KUBERNETES_TRUST_ALL_CERIFICATES)))) {
+                        protocol = "https://";
+                    }
+                    return protocol + portalIP;
+                }
+            }
+        }
+        return null;
+    }
+
+    public static String serviceToHost(String id) {
+        return Systems.getEnvVarOrSystemProperty(toEnvVariable(id + HOST_SUFFIX), "");
+    }
+
+    public static String serviceToPort(String id) {
+        return Systems.getEnvVarOrSystemProperty(toEnvVariable(id + PORT_SUFFIX), "");
+    }
+
+    public static String serviceToProtocol(String id, String servicePort) {
+        return Systems.getEnvVarOrSystemProperty(toEnvVariable(id + PORT_SUFFIX + "_" + servicePort + PROTO_SUFFIX), DEFAULT_PROTO);
+    }
+
+    public static String toEnvVariable(String str) {
+        return str.toUpperCase().replaceAll("-", "_");
+    }
+
+    /**
+     * Returns the port for the given port number on the pod
+     */
+    public static ContainerPort findContainerPort(Pod pod, Integer portNumber) {
+        List<Container> containers = KubernetesHelper.getContainers(pod);
+        for (Container container : containers) {
+            List<ContainerPort> ports = container.getPorts();
+            for (ContainerPort port : ports) {
+                if (Objects.equal(portNumber, port.getContainerPort())) {
+                    return port;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the port for the given port name
+     */
+    public static ContainerPort findContainerPortByName(Pod pod, String name) {
+        List<Container> containers = KubernetesHelper.getContainers(pod);
+        for (Container container : containers) {
+            List<ContainerPort> ports = container.getPorts();
+            for (ContainerPort port : ports) {
+                if (Objects.equal(name, port.getName())) {
+                    return port;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the port for the given port number or name
+     */
+    public static ContainerPort findContainerPortByNumberOrName(Pod pod, String numberOrName) {
+        Integer portNumber = toOptionalNumber(numberOrName);
+        if (portNumber != null) {
+            return findContainerPort(pod, portNumber);
+        } else {
+            return findContainerPortByName(pod, numberOrName);
+        }
+    }
+
+    /**
+     * Returns the number if it can be parsed or null
+     */
+    protected static Integer toOptionalNumber(String text) {
+        if (Strings.isNotBlank(text)) {
+            try {
+                return Integer.parseInt(text);
+            } catch (NumberFormatException e) {
+                // ignore parse errors
+            }
+        }
+        return null;
+    }
+
+    public static PodStatusType getPodStatus(Pod pod) {
+        String text = getPodStatusText(pod);
+        if (Strings.isNotBlank(text)) {
+            text = text.toLowerCase();
+            if (text.startsWith("run")) {
+                return PodStatusType.OK;
+            } else if (text.startsWith("wait")) {
+                return PodStatusType.WAIT;
+            } else {
+                return PodStatusType.ERROR;
+            }
+        }
+        return PodStatusType.WAIT;
+    }
+
+    /**
+     * Returns true if the pod is running
+     */
+    public static boolean isPodRunning(Pod pod) {
+        PodStatusType status = getPodStatus(pod);
+        return Objects.equal(status, PodStatusType.OK);
+    }
+
+    public static String getPodStatusText(Pod pod) {
+        if (pod != null) {
+            PodStatus podStatus = pod.getStatus();
+            if (podStatus != null) {
+                return podStatus.getPhase();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the pods for the given replication controller
+     */
+    @SuppressWarnings("unchecked")
+    public static List<Pod> getPodsForReplicationController(ReplicationController replicationController, Iterable<Pod> pods) {
+        ReplicationControllerSpec replicationControllerSpec = replicationController.getSpec();
+        if (replicationControllerSpec == null) {
+            LOG.warn("Cannot instantiate replication controller: " + getName(replicationController) + " due to missing ReplicationController.Spec!");
+        } else {
+            Map<String, String> replicaSelector = replicationControllerSpec.getSelector();
+            Filter<Pod> podFilter = KubernetesHelper.createPodFilter(replicaSelector);
+            return Filters.filter(pods, podFilter);
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Returns the pods for the given service
+     */
+    public static List<Pod> getPodsForService(Service service, Iterable<Pod> pods) {
+        Map<String, String> selector = getSelector(service);
+        Filter<Pod> podFilter = KubernetesHelper.createPodFilter(selector);
+        return Filters.filter(pods, podFilter);
+    }
+
+    /**
+     * Looks up the service endpoints in DNS.
+     *
+     * Endpoints are registered as SRV records in DNS so this method returns
+     * endpoints in the format "host:port". This is a list as SRV records are ordered
+     * by priority & weight before being returned to the client.
+     *
+     * See https://github.com/GoogleCloudPlatform/kubernetes/blob/master/cluster/addons/dns/README.md
+     */
+    public static List<String> lookupServiceEndpointsInDns(String serviceName) throws IllegalArgumentException, UnknownHostException {
+        try {
+            Lookup l = new Lookup(serviceName, Type.SRV);
+            Record[] records = l.run();
+            if (l.getResult() == Lookup.SUCCESSFUL) {
+
+                SRVRecord[] srvRecords = Arrays.copyOf(records, records.length, SRVRecord[].class);
+                Arrays.sort(srvRecords, new Comparator<SRVRecord>() {
+                    @Override
+                    public int compare(SRVRecord a, SRVRecord b) {
+                        int ret = Integer.compare(b.getPriority(), a.getPriority());
+                        if (ret == 0) {
+                            ret = Integer.compare(b.getWeight(), a.getWeight());
+                        }
+                        return ret;
+                    }
+                });
+
+                List<String> endpointAddresses = new ArrayList<>(srvRecords.length);
+                for (SRVRecord srvRecord : srvRecords) {
+                    endpointAddresses.add(srvRecord.getTarget().toString(true).concat(":").concat(String.valueOf(srvRecord.getPort())));
+                }
+                return endpointAddresses;
+            } else {
+                LOG.warn("Lookup {} result: {}", serviceName, l.getErrorString());
+            }
+        } catch (TextParseException e) {
+            LOG.error("Unparseable service name: {}", serviceName, e);
+        } catch (ClassCastException e) {
+            LOG.error("Invalid response from DNS server - should have been A records", e);
+        }
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Looks up the service in DNS.
+     * If this is a headless service, this call returns the endpoint IPs from DNS.
+     * If this is a non-headless service, this call returns the service IP only.
+     * <p/>
+     * See https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/services.md#headless-services
+     */
+    public static Set<String> lookupServiceInDns(String serviceName) throws IllegalArgumentException, UnknownHostException {
+        try {
+            Lookup l = new Lookup(serviceName);
+            Record[] records = l.run();
+            if (l.getResult() == Lookup.SUCCESSFUL) {
+                Set<String> endpointAddresses = new HashSet<>(records.length);
+                for (int i = 0; i < records.length; i++) {
+                    ARecord aRecord = (ARecord) records[i];
+                    endpointAddresses.add(aRecord.getAddress().getHostAddress());
+                }
+                return endpointAddresses;
+            } else {
+                LOG.warn("Lookup {} result: {}", serviceName, l.getErrorString());
+            }
+        } catch (TextParseException e) {
+            LOG.error("Unparseable service name: {}", serviceName, e);
+        } catch (ClassCastException e) {
+            LOG.error("Invalid response from DNS server - should have been A records", e);
+        }
+        return Collections.EMPTY_SET;
+    }
+
+    public static boolean isServiceSsl(String host, int port, boolean trustAllCerts) {
+        try {
+            SSLSocketFactory sslsocketfactory;
+            if (trustAllCerts) {
+                sslsocketfactory = TrustEverythingSSLTrustManager.getTrustingSSLSocketFactory();
+            } else {
+                sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+            }
+
+            Socket socket = sslsocketfactory.createSocket();
+
+            // Connect, with an explicit timeout value
+            socket.connect(new InetSocketAddress(host, port), 1 * 1000);
+            try {
+
+                InputStream in = socket.getInputStream();
+                OutputStream out = socket.getOutputStream();
+
+                // Write a test byte to get a reaction :)
+                out.write(1);
+
+                while (in.available() > 0) {
+                    System.out.print(in.read());
+                }
+
+                return true;
+            } finally {
+                socket.close();
+            }
+        } catch (SSLHandshakeException e) {
+            LOG.error("SSL handshake failed - this probably means that you need to trust the kubernetes root SSL certificate or set the environment variable " + KubernetesFactory.KUBERNETES_TRUST_ALL_CERIFICATES, e);
+        } catch (SSLProtocolException e) {
+            LOG.error("SSL protocol error", e);
+        } catch (SSLKeyException e) {
+            LOG.error("Bad SSL key", e);
+        } catch (SSLPeerUnverifiedException e) {
+            LOG.error("Could not verify server", e);
+        } catch (SSLException e) {
+            LOG.debug("Address does not appear to be SSL-enabled - falling back to http", e);
+        } catch (IOException e) {
+            LOG.debug("Failed to validate service", e);
+        }
+        return false;
+    }
+
+    /**
+     * Validates that the given value is valid according to the kubernetes ID parsing rules, throwing an exception if not.
+     */
+    public static String validateKubernetesId(String currentValue, String description) throws IllegalArgumentException {
+        if (isNullOrBlank(currentValue)) {
+            throw new IllegalArgumentException("No " + description + " is specified!");
+        }
+        int size = currentValue.length();
+        for (int i = 0; i < size; i++) {
+            char ch = currentValue.charAt(i);
+            if (Character.isUpperCase(ch)) {
+                throw new IllegalArgumentException("Invalid upper case letter '" + ch + "' at index " + i + " for " + description + " value: " + currentValue);
+            }
+        }
+        return currentValue;
+    }
+
+    public static Date parseDate(String text) {
+        try {
+            return dateTimeFormat.parse(text);
+        } catch (ParseException e) {
+            LOG.warn("Failed to parse date: " + text + ". Reason: " + e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns a short summary text message for the given kubernetes resource
+     */
+    public static String summaryText(Object object) {
+        if (object instanceof Route) {
+            return summaryText((Route) object);
+        } else if (object instanceof Service) {
+            return summaryText((Service) object);
+        } else if (object instanceof ReplicationController) {
+            return summaryText((ReplicationController) object);
+        } else if (object instanceof Pod) {
+            return summaryText((Pod) object);
+        } else if (object instanceof Template) {
+            return summaryText((Template) object);
+        } else if (object instanceof DeploymentConfig) {
+            return summaryText((DeploymentConfig) object);
+        } else if (object instanceof OAuthClient) {
+            return summaryText((OAuthClient) object);
+        } else if (object instanceof String) {
+            return object.toString();
+        }
+        return "";
+    }
+
+    /**
+     * Returns a short summary text message for the given kubernetes resource
+     */
+    public static String summaryText(Route entity) {
+        RouteSpec spec = entity.getSpec();
+        if (spec == null) {
+            return "No spec!";
+        }
+        return "host: " + spec.getHost();
+    }
+
+    /**
+     * Returns a short summary text message for the given kubernetes resource
+     */
+    public static String summaryText(ContainerState entity) {
+        ContainerStateRunning running = entity.getRunning();
+        if (running != null) {
+            return "Running";
+        }
+        ContainerStateWaiting waiting = entity.getWaiting();
+        if (waiting != null) {
+            return "Waiting";
+        }
+        ContainerStateTerminated termination = entity.getTermination();
+        if (termination != null) {
+            return "Terminated";
+        }
+        return "Unknown";
+    }
+
+    /**
+     * Returns a short summary text message for the given kubernetes resource
+     */
+    public static String summaryText(Template entity) {
+        StringBuilder buffer = new StringBuilder();
+        List<Parameter> parameters = entity.getParameters();
+        if (parameters != null) {
+            for (Parameter parameter : parameters) {
+                String name = parameter.getName();
+                appendText(buffer, name);
+            }
+        }
+        return "parameters: " + buffer;
+    }
+
+    /**
+     * Returns a short summary text message for the given kubernetes resource
+     */
+    public static String summaryText(OAuthClient entity) {
+        return "redirectURIs: " + entity.getRedirectURIs();
+    }
+
+    /**
+     * Returns a short summary text message for the given kubernetes resource
+     */
+    public static String summaryText(Service entity) {
+        StringBuilder portText = new StringBuilder();
+        ServiceSpec spec = entity.getSpec();
+        if (spec == null) {
+            return "No spec";
+        } else {
+            List<ServicePort> ports = spec.getPorts();
+            if (ports != null) {
+                for (ServicePort port : ports) {
+                    Integer number = port.getPort();
+                    if (number != null) {
+                        if (portText.length() > 0) {
+                            portText.append(", ");
+                        }
+                        portText.append("").append(number);
+                    }
+                }
+
+            }
+            return "selector: " + spec.getSelector() + " ports: " + portText;
+        }
+    }
+
+    /**
+     * Returns a short summary text message for the given kubernetes resource
+     */
+    public static String summaryText(ReplicationController entity) {
+        StringBuilder buffer = new StringBuilder();
+        ReplicationControllerSpec spec = entity.getSpec();
+        if (spec != null) {
+            buffer.append("replicas: ").append(spec.getReplicas());
+            PodTemplateSpec podTemplateSpec = spec.getTemplate();
+            if (podTemplateSpec != null) {
+                appendSummaryText(buffer, podTemplateSpec);
+            }
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Returns a short summary text message for the given kubernetes resource
+     */
+    public static String summaryText(DeploymentConfig entity) {
+        StringBuilder buffer = new StringBuilder();
+        DeploymentConfigSpec spec = entity.getSpec();
+        if (spec != null) {
+            buffer.append("replicas: " + spec.getReplicas());
+            PodTemplateSpec podTemplateSpec = spec.getTemplate();
+            if (podTemplateSpec != null) {
+                appendSummaryText(buffer, podTemplateSpec);
+            }
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Returns a short summary text message for the given kubernetes resource
+     */
+    public static String summaryText(Pod entity) {
+        StringBuilder buffer = new StringBuilder();
+        PodSpec podSpec = entity.getSpec();
+        appendSummaryText(buffer, podSpec);
+        return buffer.toString();
+    }
+
+    protected static void appendSummaryText(StringBuilder buffer, PodTemplateSpec podTemplateSpec) {
+        if (podTemplateSpec != null) {
+            appendSummaryText(buffer, podTemplateSpec.getSpec());
+        }
+    }
+
+    protected static void appendSummaryText(StringBuilder buffer, PodSpec podSpec) {
+        if (podSpec != null) {
+            List<Container> containers = podSpec.getContainers();
+            if (containers != null) {
+                for (Container container : containers) {
+                    String image = container.getImage();
+                    appendText(buffer, "image: " + image);
+                }
+            }
+        }
+    }
+
+    protected static void appendText(StringBuilder buffer, String text) {
+        if (buffer.length() > 0) {
+            buffer.append(", ");
+        }
+        buffer.append(text);
+    }
+
+    /**
+     * Creates an IntOrString from the given string which could be a number or a name
+     */
+    public static IntOrString createIntOrString(int intVal) {
+        IntOrString answer = new IntOrString();
+        answer.setIntVal(intVal);
+        answer.setKind(INTORSTRING_KIND_INT);
+        return answer;
+    }
+
+    /**
+     * Creates an IntOrString from the given string which could be a number or a name
+     */
+    public static IntOrString createIntOrString(String nameOrNumber) {
+        if (isNullOrBlank(nameOrNumber)) {
+            return null;
+        } else {
+            IntOrString answer = new IntOrString();
+            Integer intVal = null;
+            try {
+                intVal = Integer.parseInt(nameOrNumber);
+            } catch (Exception e) {
+                // ignore invalid number
+            }
+            if (intVal != null) {
+                answer.setIntVal(intVal);
+                answer.setKind(INTORSTRING_KIND_INT);
+            } else {
+                answer.setStrVal(nameOrNumber);
+                answer.setKind(INTORSTRING_KIND_STRING);
+            }
+            return answer;
+        }
+    }
+
+    public static String getStatusText(PodStatus podStatus) {
+        String status;
+        List<String> statusList = new ArrayList<>();
+        List<ContainerStatus> containerStatuses = podStatus.getContainerStatuses();
+        for (ContainerStatus containerStatus : containerStatuses) {
+            ContainerState state = containerStatus.getState();
+            String statusText = summaryText(state);
+            if (statusText != null) {
+                statusList.add(statusText);
+            }
+        }
+        if (statusList.size() == 1) {
+            status = statusList.get(0);
+        } else {
+            status = statusList.toString();
+        }
+        return status;
+    }
+
+    public static Secret validateSecretExists(KubernetesClient kubernetes, String namespace, String secretName) {
+        Secret secret = null;
+        try {
+            secret = kubernetes.getSecret(secretName, namespace);
+        } catch (WebApplicationException e) {
+            if (e.getResponse().getStatus() == 404) {
+                // does not exist
+            } else {
+                throw e;
+            }
+        }
+        if (secret == null) {
+            throw new IllegalArgumentException("No secret named: " + secretName +
+                    " for namespace " + namespace + " is available on Kubernetes at address " + kubernetes.getAddress() +
+                    ". For how to create secrets see: http://fabric8.io/guide/fabric8OnOpenShift.html#requirements ");
+        } else {
+            return secret;
+        }
+    }
+
+    /**
+     * Converts the DTO loaded from JSON to a {@link KubernetesList} assuming its not a {@link Template}
+     */
+    public static KubernetesList asKubernetesList(Object dto) throws IOException {
+        if (dto instanceof KubernetesList) {
+            return (KubernetesList) dto;
+        } else {
+            KubernetesList answer = new KubernetesList();
+            List<HasMetadata> items = toItemList(dto);
+            answer.setItems(items);
+            return answer;
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/3414e7ce/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/PodStatusType.java
----------------------------------------------------------------------
diff --git a/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/PodStatusType.java b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/PodStatusType.java
new file mode 100644
index 0000000..19a1bd7
--- /dev/null
+++ b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/PodStatusType.java
@@ -0,0 +1,25 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fabric8.kubernetes.api;
+
+/**
+ * Represents the status of the pod
+ */
+public enum PodStatusType {
+    WAIT, OK, ERROR
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3414e7ce/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/ServiceNames.java
----------------------------------------------------------------------
diff --git a/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/ServiceNames.java b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/ServiceNames.java
new file mode 100644
index 0000000..e453153
--- /dev/null
+++ b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/ServiceNames.java
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fabric8.kubernetes.api;
+
+/**
+ * Defines some standard service names for common services in fabric8
+ */
+public class ServiceNames {
+
+    // Management
+    //-------------------------------------------------------------------------
+
+    /**
+     * The fabric8 console
+     */
+    public static final String FABRIC8_CONSOLE = "fabric8";
+
+    public static final String ELASTICSEARCH = "elasticsearch";
+    public static final String KIBANA = "kibana";
+    public static final String INFLUXDB = "influxdb";
+    public static final String GRAFANA = "grafana";
+
+    public static final String KEYCLOAK = "keycloak";
+
+    // Continuous Delivery
+    //-------------------------------------------------------------------------
+    public static final String GOGS = "fabric8";
+    public static final String JENKINS = "jenkins";
+    public static final String NEXUS = "nexus";
+    public static final String GERRIT = "gerrit";
+    public static final String SONARQUBE = "sonarqube";
+
+    /**
+     * used for jBPM workflows with CD
+     */
+    public static final String CDELIVERY_API = "cdelivery";
+
+    // Social
+    //-------------------------------------------------------------------------
+
+    public static final String HUBOT = "hubot";
+    public static final String LETSCHAT = "letschat";
+    public static final String TAIGA = "taiga";
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3414e7ce/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/UserConfigurationCompare.java
----------------------------------------------------------------------
diff --git a/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/UserConfigurationCompare.java b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/UserConfigurationCompare.java
new file mode 100644
index 0000000..a04c900
--- /dev/null
+++ b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/UserConfigurationCompare.java
@@ -0,0 +1,201 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fabric8.kubernetes.api;
+
+import io.fabric8.kubernetes.api.model.ObjectMeta;
+import io.fabric8.kubernetes.api.support.KindToClassMapping;
+import io.fabric8.utils.Objects;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.validation.constraints.NotNull;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Helper methods to compare the user configuration on entities
+ */
+public class UserConfigurationCompare {
+    private static final transient Logger LOG = LoggerFactory.getLogger(UserConfigurationCompare.class);
+
+    protected static final Set<String> ignoredProperties = new HashSet<>(Arrays.asList("status"));
+
+
+    /**
+     * This method detects if the user has changed the configuration of an entity.
+     * <p/>
+     * It compares the <b>user</b> configuration of 2 object trees ignoring any
+     * runtime status or timestamp information.
+     *
+     * @return true if the configurations are equal.
+     */
+    public static boolean configEqual(Object entity1, Object entity2) {
+        if (entity1 == entity2) {
+            return true;
+        } else if (entity1 == null || entity2 == null) {
+            return false;
+        } else if (entity1 instanceof Map) {
+            return configEqualMap((Map) entity1, castTo(Map.class, entity2));
+        } else if (entity2 instanceof Map) {
+            return configEqualMap((Map) entity1, castTo(Map.class, entity2));
+        } else if (entity2 instanceof ObjectMeta) {
+            return configEqualObjectMeta((ObjectMeta) entity1, castTo(ObjectMeta.class, entity2));
+        } else {
+            Set<Class<?>> classes = new HashSet<>(KindToClassMapping.getKindToClassMap().values());
+            Class<?> aClass = entity1.getClass();
+            if (classes.contains(aClass)) {
+                Object castEntity2 = castTo(aClass, entity2);
+                if (castEntity2 == null) {
+                    return false;
+                } else {
+                    return configEqualKubernetesDTO(entity1, entity2, aClass);
+                }
+            } else {
+                return Objects.equal(entity1, entity2);
+            }
+        }
+    }
+
+
+    /**
+     * Compares 2 instances of the given Kubernetes DTO class to see if the user has changed their configuration.
+     * <p/>
+     * This method will ignore properties {@link #ignoredProperties} such as status or timestamp properties
+     */
+    protected static boolean configEqualKubernetesDTO(@NotNull Object entity1, @NotNull Object entity2, @NotNull Class<?> clazz) {
+        // lets iterate through the objects making sure we've not
+        BeanInfo beanInfo = null;
+        try {
+            beanInfo = Introspector.getBeanInfo(clazz);
+        } catch (IntrospectionException e) {
+            LOG.warn("Failed to get beanInfo for " + clazz.getName() + ". " + e, e);
+            return false;
+        }
+        try {
+            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
+            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
+                String name = propertyDescriptor.getName();
+                if (ignoredProperties.contains(name)) {
+                    continue;
+                }
+                Method readMethod = propertyDescriptor.getReadMethod();
+                if (readMethod != null) {
+                    Object value1 = invokeMethod(entity1, readMethod);
+                    Object value2 = invokeMethod(entity2, readMethod);
+                    if (!configEqual(value1, value2)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    protected static Object invokeMethod(@NotNull Object entity, Method readMethod) throws InvocationTargetException, IllegalAccessException {
+        try {
+            return readMethod.invoke(entity);
+        } catch (Exception e) {
+            LOG.warn("Failed to invoke method " + readMethod + " on " + entity + ". " + e, e);
+            throw e;
+        }
+    }
+
+    protected static boolean configEqualObjectMeta(ObjectMeta entity1, ObjectMeta entity2) {
+        if (entity1 == entity2) {
+            return true;
+        } else if (entity1 == null || entity2 == null) {
+            return false;
+        }
+        // TODO should we ignore annotations?
+        return Objects.equal(entity1.getName(), entity2.getName()) &&
+                Objects.equal(entity1.getNamespace(), entity2.getNamespace()) &&
+                configEqualMap(entity1.getLabels(), entity2.getLabels()) &&
+                configEqualMap(entity1.getAnnotations(), entity2.getAnnotations());
+    }
+
+    protected static <T> T castTo(Class<T> clazz, Object entity) {
+        if (clazz.isInstance(entity)) {
+            return clazz.cast(entity);
+        } else {
+            if (entity != null) {
+                LOG.warn("Invalid class " + entity.getClass().getName() + " when expecting " + clazz.getName() + " for instance: " + entity);
+            }
+            return null;
+        }
+    }
+
+    protected static boolean configEqualMap(Map entity1, Map entity2) {
+        if (entity1 == entity2) {
+            return true;
+        } else if (entity1 == null || entity2 == null) {
+            return false;
+        }
+        int size1 = size(entity1);
+        int size2 = size(entity2);
+        if (size1 != size2) {
+            return false;
+        }
+        Set<Map.Entry> entries = entity1.entrySet();
+        for (Map.Entry entry : entries) {
+            Object key = entry.getKey();
+            Object value = entry.getValue();
+            Object value2 = entity2.get(key);
+            if (!configEqual(value, value2)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    protected static boolean configEqualList(List v1, List v2) {
+        int size1 = size(v1);
+        int size2 = size(v2);
+        if (size1 != size2) {
+            return false;
+        }
+        int idx = 0;
+        for (Object value : v1) {
+            Object value2 = v2.get(idx++);
+            if (!configEqual(value, value2)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    protected static int size(Map map) {
+        return (map == null) ? 0 : map.size();
+    }
+
+    protected static int size(Collection coll) {
+        return (coll == null) ? 0 : coll.size();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3414e7ce/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/Watcher.java
----------------------------------------------------------------------
diff --git a/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/Watcher.java b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/Watcher.java
new file mode 100644
index 0000000..a6447ce
--- /dev/null
+++ b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/Watcher.java
@@ -0,0 +1,13 @@
+package io.fabric8.kubernetes.api;
+
+import io.fabric8.kubernetes.api.model.HasMetadata;
+
+public interface Watcher<T extends HasMetadata> {
+
+    enum Action {
+        ADDED, MODIFIED, DELETED, ERROR
+    }
+
+    void eventReceived(Action action, T object);
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3414e7ce/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builders/ListEnvVarBuilder.java
----------------------------------------------------------------------
diff --git a/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builders/ListEnvVarBuilder.java b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builders/ListEnvVarBuilder.java
new file mode 100644
index 0000000..e97ec01
--- /dev/null
+++ b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builders/ListEnvVarBuilder.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fabric8.kubernetes.api.builders;
+
+import io.fabric8.kubernetes.api.model.EnvVar;
+import io.fabric8.utils.Strings;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A little helper class to build a <code>List<EnvVar></code> object
+ */
+public class ListEnvVarBuilder {
+    private List<EnvVar> envVars = new ArrayList<>();
+
+    public void withEnvVar(String name, String value) {
+        if (Strings.isNotBlank(name) && value != null) {
+            EnvVar envVar = new EnvVar();
+            envVar.setName(name);
+            envVar.setValue(value);
+            envVars.add(envVar);
+        }
+    }
+
+    public List<EnvVar> build() {
+        return envVars;
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3414e7ce/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builds/BuildFinishedEvent.java
----------------------------------------------------------------------
diff --git a/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builds/BuildFinishedEvent.java b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builds/BuildFinishedEvent.java
new file mode 100644
index 0000000..071979c
--- /dev/null
+++ b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builds/BuildFinishedEvent.java
@@ -0,0 +1,64 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fabric8.kubernetes.api.builds;
+
+import io.fabric8.openshift.api.model.Build;
+
+/**
+ */
+public class BuildFinishedEvent {
+    private final String uid;
+    private final Build build;
+    private final boolean loading;
+    private final String buildLink;
+
+    public BuildFinishedEvent(String uid, Build build, boolean loading, String buildLink) {
+        this.uid = uid;
+        this.build = build;
+        this.loading = loading;
+        this.buildLink = buildLink;
+    }
+
+    public String getUid() {
+        return uid;
+    }
+
+    public Build getBuild() {
+        return build;
+    }
+
+    public String getBuildLink() {
+        return buildLink;
+    }
+
+    public boolean isLoading() {
+        return loading;
+    }
+
+    public String getStatus() {
+        return build.getStatus().getPhase();
+    }
+
+    public String getConfigName() {
+        return Builds.getBuildConfigName(build);
+    }
+
+    public String getNamespace() {
+        return Builds.getNamespace(build);
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/3414e7ce/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builds/BuildListener.java
----------------------------------------------------------------------
diff --git a/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builds/BuildListener.java b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builds/BuildListener.java
new file mode 100644
index 0000000..3edf170
--- /dev/null
+++ b/dependencies/fabric8/kubernetes-api/src/main/java/io/fabric8/kubernetes/api/builds/BuildListener.java
@@ -0,0 +1,30 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.fabric8.kubernetes.api.builds;
+
+/**
+ * A strategy for processing completed builds
+ */
+public interface BuildListener {
+    /**
+     * The build that has completed (successfully or not) and the flag indicating whether or not
+     * this is the first time the watcher is being started up (so you should check if you've already
+     * received and processed this event before).
+     */
+    void onBuildFinished(BuildFinishedEvent event);
+}


Mime
View raw message