package com.yammer.breakerbox.turbine.config; import java.util.Collections; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import javax.validation.Valid; import javax.validation.constraints.NotNull; import com.fasterxml.jackson.annotation.JsonUnwrapped; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.net.HostAndPort; import com.netflix.turbine.discovery.Instance; import com.yammer.breakerbox.turbine.TurbineInstanceDiscovery; public class YamlInstanceConfiguration { @JsonUnwrapped @Valid private ImmutableMap<String, Cluster> clusters = ImmutableMap.of( "breakerbox", Cluster.withInstances(HostAndPort.fromParts("localhost", 8080)), "production", Cluster.withClusters("breakerbox")); @NotNull private String urlSuffix = TurbineInstanceDiscovery.DEFAULT_URL_SUFFIX; public ImmutableMap<String, Cluster> getClusters() { return clusters; } public void setClusters(ImmutableMap<String, Cluster> clusters) { this.clusters = clusters; } public Set<Instance> getAllInstances() { final ImmutableSet.Builder<Instance> builder = ImmutableSet.builder(); for (Map.Entry<String, Cluster> entry : clusters.entrySet()) { final String clusterName = entry.getKey(); addCluster(builder, entry.getValue(), clusterName, ImmutableSet.of(clusterName)); } return builder.build(); } private void addCluster(ImmutableSet.Builder<Instance> acc, Cluster cluster, String clusterName, ImmutableSet<String> visited) { acc.addAll(cluster.getInstances().stream() .map(hostAndPort -> { final Instance instance = new Instance(hostAndPort.toString(), clusterName, true); instance.getAttributes().put(TurbineInstanceDiscovery.BREAKERBOX_INSTANCE_ID, hostAndPort.toString()); return instance; }) .collect(Collectors.toList())); cluster.getClusters() .stream() .filter(name -> !visited.contains(name)) .forEach(notVisitedClusterName -> addCluster(acc, clusters.get(notVisitedClusterName), clusterName, ImmutableSet.<String>builder().addAll(visited).add(notVisitedClusterName).build())); } public String getUrlSuffix() { return urlSuffix; } public void setUrlSuffix(String urlSuffix) { this.urlSuffix = urlSuffix; } @Override public int hashCode() { return Objects.hash(clusters, urlSuffix); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } final YamlInstanceConfiguration other = (YamlInstanceConfiguration) obj; return Objects.equals(this.clusters, other.clusters) && Objects.equals(this.urlSuffix, other.urlSuffix); } @Override public String toString() { return "YamlInstanceConfiguration{" + "clusters=" + clusters + ", urlSuffix='" + urlSuffix + '\'' + '}'; } public static class Cluster { @Valid private Set<HostAndPort> instances = Collections.emptySet(); private Set<String> clusters = Collections.emptySet(); public Cluster() { /* Jackson */ } public Cluster(Set<HostAndPort> instances, Set<String> clusters) { this.instances = instances; this.clusters = clusters; } public Set<HostAndPort> getInstances() { return instances; } public Set<String> getClusters() { return clusters; } public void setInstances(Set<HostAndPort> instances) { this.instances = instances; } public void setClusters(Set<String> clusters) { this.clusters = clusters; } public static Cluster withInstances(HostAndPort... hostAndPorts) { return new Cluster(ImmutableSet.copyOf(hostAndPorts), Collections.<String>emptySet()); } public static Cluster withClusters(String... clusters) { return new Cluster(Collections.<HostAndPort>emptySet(), ImmutableSet.copyOf(clusters)); } @Override public int hashCode() { return Objects.hash(instances, clusters); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } final Cluster other = (Cluster) obj; return Objects.equals(this.instances, other.instances) && Objects.equals(this.clusters, other.clusters); } @Override public String toString() { return "Cluster{" + "instances=" + instances + ", clusters=" + clusters + '}'; } } }