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

org.arquillian.cube.impl.util.AutoStartOrderUtil Maven / Gradle / Ivy

package org.arquillian.cube.impl.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.arquillian.cube.impl.client.CubeConfiguration;

public class AutoStartOrderUtil {

    public static List getAutoStopOrder(CubeConfiguration config) {
        List autoStartOrder = getAutoStartOrder(config);
        Collections.reverse(autoStartOrder);
        return autoStartOrder;
    }

    public static List getAutoStartOrder(CubeConfiguration config) {
        List sorted = new ArrayList<>();
        List steps = sort(from(config));
        for(Step step : steps) {
            sorted.add(step.getIDs());
        }
        return sorted;
    }

    static List sort(Set nodes) {
        List steps = new ArrayList<>();

        List remaining = new ArrayList<>(nodes);
        int previousSize = remaining.size();
        while(!remaining.isEmpty()) {
            Step step = new Step();
            for(int i = 0; i < remaining.size(); i++) {
                Node node = remaining.get(i);
                if(!node.hasParent() || nodesInStep(steps, node.getParents())) {
                    step.add(node);
                    remaining.remove(i);
                    --i;
                }
            }
            if(previousSize == remaining.size()) {
                throw new IllegalArgumentException("Could not resolve autoStart order. " + nodes);
            }
            previousSize = remaining.size();
            steps.add(step);
        }
        return steps;
    }

    static Set from(CubeConfiguration config) {
        Map nodes = new HashMap<>();
        String[] autoStartContainers = config.getAutoStartContainers();
        Map containerDefinitions = config.getDockerContainersContent();

        for(String autoStart : autoStartContainers) {
            if(containerDefinitions.containsKey(autoStart)) {
                nodes.put(autoStart, Node.from(autoStart));
            }
        }

        Map autoStartNodes = new HashMap<>(nodes);
        for(Map.Entry node : autoStartNodes.entrySet()) {
            addAll(nodes, config, node.getKey());
        }

        return new HashSet<>(nodes.values());
    }

    private static boolean nodesInStep(List steps, Set nodes) {
        for(Node node: nodes) {
            if(!nodeInStep(steps, node)) {
                return false;
            }
        }
        return true;
    }

    private static boolean nodeInStep(List steps, Node node) {
        for(Step step : steps) {
            if(step.contains(node)) {
                return true;
            }
        }
        return false;
    }

    @SuppressWarnings("unchecked")
    private static void addAll(Map nodes, CubeConfiguration config, String id) {
        Map content = (Map)config.getDockerContainersContent().get(id);
        if(content == null) {
            return;
        }
        Node parent = nodes.get(id);
        if(content.containsKey("links")) {
            List links = (List)content.get("links");
            for(String link : links) {
                String[] parsed = link.split(":");
                String name = parsed[0];

                if(config.getDockerContainersContent().containsKey(name)) {
                    Node child = nodes.get(name);
                    if(child == null) {
                        child = Node.from(name);
                        nodes.put(name, child);
                    }
                    // Only continue recursively if this was a new found child
                    if(child.addAsChildOf(parent)) {
                        addAll(nodes, config, name);
                    }
                }
            }
        }
    }

    public static class Node {
        private String id;
        private Set parents;
        private Set children;

        private Node(String id) {
            this.id = id;
            this.parents = new HashSet<>();
            this.children = new HashSet<>();
        }

        public String getId() {
            return id;
        }

        public boolean addAsParentOf(Node node) {
            if(!this.parents.contains(node)) {
                this.parents.add(node);
                node.addAsChildOf(this);
                return true;
            }
            return false;
        }

        public boolean addAsChildOf(Node node) {
            if(!this.children.contains(node)) {
                this.children.add(node);
                node.addAsParentOf(this);
                return true;
            }
            return false;
        }

        public Set getParents() {
            return parents;
        }

        public boolean hasParent() {
            return this.parents.size() > 0;
        }

        public static Node from(String id) {
            return new Node(id);
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("Node [id=" + id);
            if(!parents.isEmpty()) {
                sb.append(", parents=" + nodeList(parents));
            }
            if(!children.isEmpty()) {
                sb.append(", children="+ nodeList(children));
            }
            sb.append("]");
            return sb.toString();
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((id == null) ? 0 : id.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Node other = (Node) obj;
            if (id == null) {
                if (other.id != null)
                    return false;
            } else if (!id.equals(other.id))
                return false;
            return true;
        }
    }

    public static class Step {
        private Set nodes;

        private Step() {
            this.nodes = new HashSet<>();
        }

        public boolean contains(Node node) {
            return this.nodes.contains(node);
        }

        public void add(Node node) {
            if(!this.nodes.contains(node)) {
                this.nodes.add(node);
            }
        }

        public String[] getIDs() {
            String[] ids = new String[this.nodes.size()];
            Node[] nodes = this.nodes.toArray(new Node[]{});
            for(int i = 0; i < nodes.length; i++) {
                ids[i] = nodes[i].getId();
            }
            return ids;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("Step [ids=" + nodeList(nodes));
            sb.append("]");
            return sb.toString();
        }
    }

    private static String nodeList(Set nodes) {
        StringBuilder sb = new StringBuilder();
        Node[] array = nodes.toArray(new Node[]{});
        for(int i = 0; i < array.length; i++) {
            sb.append(array[i].getId());
            if(i < array.length-1) {
                sb.append(",");
            }
        }
        return sb.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy