Skip to content

Commit f895bd7

Browse files
committed
Merge pull request #14 from yammer/issue-13
Add ability to specify meta clusters in yml
2 parents 8301d89 + 3bc4910 commit f895bd7

File tree

13 files changed

+72
-31
lines changed

13 files changed

+72
-31
lines changed

breakerbox-service/breakerbox.yml

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ database:
1313
checkConnectionWhileIdle: true
1414
validationInterval: 30s
1515

16+
metaClusters:
17+
- production
18+
- stage
19+
- staging
20+
1621
tenacityClient:
1722
connectionTimeout: 500ms
1823
timeout: 1000ms

breakerbox-service/src/main/java/com/yammer/breakerbox/service/BreakerboxService.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.google.common.collect.ImmutableList;
44
import com.google.common.collect.ImmutableMap;
5+
import com.google.common.collect.Sets;
56
import com.netflix.turbine.init.TurbineInit;
67
import com.netflix.turbine.streaming.servlet.TurbineStreamServlet;
78
import com.yammer.breakerbox.azure.AzureStore;
@@ -52,6 +53,7 @@
5253
import org.slf4j.LoggerFactory;
5354

5455
import java.util.Map;
56+
import java.util.Set;
5557
import java.util.concurrent.ScheduledExecutorService;
5658
import java.util.concurrent.TimeUnit;
5759

@@ -126,11 +128,16 @@ public void run(final BreakerboxServiceConfiguration configuration, final Enviro
126128
.build()),
127129
breakerboxStore);
128130

131+
Set<String> metaClusters = Sets.newHashSet();
132+
for (String cluster : configuration.getMetaClusters()) {
133+
metaClusters.add(cluster.toUpperCase());
134+
}
135+
129136
environment.servlets().addServlet("turbine.stream", new TurbineStreamServlet()).addMapping("/turbine.stream");
130137

131138
environment.jersey().register(new ArchaiusResource(configuration.getArchaiusOverride(), breakerboxStore));
132-
environment.jersey().register(new ConfigureResource(breakerboxStore, tenacityPropertyKeysStore, syncComparator));
133-
environment.jersey().register(new DashboardResource(new DashboardViewFactory(configuration.getBreakerboxHostAndPort()), configuration.getDefaultDashboard()));
139+
environment.jersey().register(new ConfigureResource(breakerboxStore, tenacityPropertyKeysStore, syncComparator, metaClusters));
140+
environment.jersey().register(new DashboardResource(new DashboardViewFactory(configuration.getBreakerboxHostAndPort()), configuration.getDefaultDashboard(), metaClusters));
134141
environment.jersey().register(new InSyncResource(syncComparator, tenacityPropertyKeysStore));
135142

136143
final ScheduledExecutorService scheduledExecutorService = environment

breakerbox-service/src/main/java/com/yammer/breakerbox/service/config/BreakerboxServiceConfiguration.java

+8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
import javax.validation.Valid;
1717
import javax.validation.constraints.NotNull;
18+
import java.util.Collections;
19+
import java.util.List;
1820
import java.util.Objects;
1921

2022
public class BreakerboxServiceConfiguration extends Configuration {
@@ -43,6 +45,8 @@ public class BreakerboxServiceConfiguration extends Configuration {
4345
@NotNull @UnwrapValidatedValue(false) @Valid @JsonProperty("database")
4446
private Optional<JdbiConfiguration> jdbiConfiguration = Optional.absent();
4547

48+
private List<String> metaClusters = Collections.emptyList();
49+
4650
/* Useful if you are Breakerbox is behind a proxy and not at localhost:8080 */
4751
@NotNull @Valid
4852
private HostAndPort breakerboxHostAndPort;
@@ -127,6 +131,10 @@ public String getDefaultDashboard() {
127131
return defaultDashboard;
128132
}
129133

134+
public List<String> getMetaClusters() {
135+
return metaClusters;
136+
}
137+
130138
@Override
131139
public int hashCode() {
132140
return Objects.hash(azure, tenacityClient, breakerboxServicesPropertyKeys, breakerboxServicesConfiguration, breakerboxConfiguration, ldapConfiguration, archaiusOverride, jdbiConfiguration, breakerboxHostAndPort, defaultDashboard);

breakerbox-service/src/main/java/com/yammer/breakerbox/service/core/Instances.java

+5-12
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import javax.annotation.Nullable;
1616
import java.net.URI;
17-
import java.net.URISyntaxException;
17+
import java.util.Set;
1818

1919
import static com.google.common.base.Preconditions.checkNotNull;
2020

@@ -30,19 +30,12 @@ public String apply(Instance input) {
3030
};
3131
}
3232

33-
private static Predicate<Instance> pruneMetaClusters() {
33+
private static Predicate<Instance> pruneMetaClusters(final Set<String> specifiedMetaClusters) {
3434
return new Predicate<Instance>() {
3535
@Override
3636
public boolean apply(@Nullable Instance input) {
3737
if (input != null) {
38-
switch (input.getCluster().toUpperCase()) {
39-
case "PRODUCTION":
40-
case "STAGE":
41-
case "STAGING":
42-
return false;
43-
default:
44-
return true;
45-
}
38+
return !specifiedMetaClusters.contains(input.getCluster().toUpperCase());
4639
}
4740
return false;
4841
}
@@ -84,9 +77,9 @@ public static ImmutableSet<String> clusters() {
8477
.toSortedSet(Ordering.natural());
8578
}
8679

87-
public static ImmutableSet<String> noMetaClusters() {
80+
public static ImmutableSet<String> noMetaClusters(final Set<String> specifiedMetaClusters) {
8881
return rawInstances()
89-
.filter(pruneMetaClusters())
82+
.filter(pruneMetaClusters(specifiedMetaClusters))
9083
.transform(toClusterName())
9184
.toSortedSet(Ordering.natural());
9285
}

breakerbox-service/src/main/java/com/yammer/breakerbox/service/core/SyncComparator.java

+2
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ private ImmutableList<InstanceConfiguration> fetch(ServiceId serviceId, Dependen
7373
}
7474

7575
public ImmutableList<SyncServiceHostState> inSync(ServiceId serviceId, DependencyId dependencyId) {
76+
// fetch from services
7677
final ImmutableList<InstanceConfiguration> configurations = fetch(serviceId, dependencyId);
78+
7779
final Optional<DependencyModel> entityOptional = breakerboxStore.retrieveLatest(dependencyId, serviceId);
7880
if (entityOptional.isPresent()) {
7981

breakerbox-service/src/main/java/com/yammer/breakerbox/service/resources/ConfigureResource.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,24 @@
3434
import javax.ws.rs.core.MediaType;
3535
import javax.ws.rs.core.Response;
3636
import java.net.URI;
37+
import java.util.Set;
3738

3839
@Path("/configure/{service}")
3940
public class ConfigureResource {
4041
private static final Logger LOG = LoggerFactory.getLogger(ConfigureResource.class);
4142
private final BreakerboxStore breakerboxStore;
4243
private final TenacityPropertyKeysStore tenacityPropertyKeysStore;
4344
private final SyncComparator syncComparator;
45+
private final Set<String> specifiedMetaClusters;
4446

4547
public ConfigureResource(BreakerboxStore breakerboxStore,
4648
TenacityPropertyKeysStore tenacityPropertyKeysStore,
47-
SyncComparator syncComparator) {
49+
SyncComparator syncComparator,
50+
Set<String> specifiedMetaClusters) {
4851
this.breakerboxStore = breakerboxStore;
4952
this.tenacityPropertyKeysStore = tenacityPropertyKeysStore;
5053
this.syncComparator = syncComparator;
54+
this.specifiedMetaClusters = specifiedMetaClusters;
5155
}
5256

5357
@GET @Timed @Produces(MediaType.TEXT_HTML)
@@ -59,7 +63,7 @@ public View render(@PathParam("service") String serviceName) {
5963
if (firstDependencyKey.isPresent()) {
6064
return create(serviceId, DependencyId.from(firstDependencyKey.get()), Optional.<Long>absent());
6165
} else {
62-
return new NoPropertyKeysView(serviceId);
66+
return new NoPropertyKeysView(serviceId, specifiedMetaClusters);
6367
}
6468
}
6569

@@ -80,7 +84,8 @@ private ConfigureView create(ServiceId serviceId,
8084
serviceId,
8185
syncComparator.allInSync(serviceId, propertyKeys),
8286
getConfiguration(dependencyId, version, serviceId),
83-
getDependencyVersionNameList(dependencyEntities));
87+
getDependencyVersionNameList(dependencyEntities),
88+
specifiedMetaClusters);
8489
}
8590

8691
private TenacityConfiguration getConfiguration(DependencyId dependencyId, Optional<Long> version, ServiceId serviceId) {

breakerbox-service/src/main/java/com/yammer/breakerbox/service/resources/DashboardResource.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,22 @@
1010
import javax.ws.rs.Produces;
1111
import javax.ws.rs.QueryParam;
1212
import javax.ws.rs.core.MediaType;
13+
import java.util.Set;
1314

1415
@Path("/")
1516
public class DashboardResource {
1617
private final String defaultDashboard;
1718
private final DashboardViewFactory viewFactory;
18-
19-
public DashboardResource(DashboardViewFactory viewFactory, String defaultDashboard) {
19+
private final Set<String> specifiedMetaClusters;
20+
21+
public DashboardResource(DashboardViewFactory viewFactory, String defaultDashboard, Set<String> specifiedMetaClusters) {
2022
this.viewFactory = viewFactory;
2123
this.defaultDashboard = defaultDashboard;
24+
this.specifiedMetaClusters = specifiedMetaClusters;
2225
}
2326

2427
@GET @Timed @Produces(MediaType.TEXT_HTML)
2528
public DashboardView render(@QueryParam("cluster") Optional<String> clusterName) {
26-
return viewFactory.create(clusterName.or(defaultDashboard));
29+
return viewFactory.create(clusterName.or(defaultDashboard), specifiedMetaClusters);
2730
}
2831
}

breakerbox-service/src/main/java/com/yammer/breakerbox/service/views/ConfigureView.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import com.yammer.breakerbox.store.ServiceId;
77
import com.yammer.tenacity.core.config.TenacityConfiguration;
88

9+
import java.util.Set;
10+
911
public class ConfigureView extends NavbarView {
1012
private final ServiceId serviceId;
1113
private final Iterable<SyncPropertyKeyState> syncPropertyKeyStates;
@@ -15,8 +17,9 @@ public class ConfigureView extends NavbarView {
1517
public ConfigureView(ServiceId serviceId,
1618
Iterable<SyncPropertyKeyState> syncPropertyKeyStates,
1719
TenacityConfiguration tenacityConfiguration,
18-
ImmutableList<OptionItem> dependencyEntities) {
19-
super("/templates/configure/configure.mustache");
20+
ImmutableList<OptionItem> dependencyEntities,
21+
Set<String> specifiedMetaClusters) {
22+
super("/templates/configure/configure.mustache", specifiedMetaClusters);
2023
this.serviceId = serviceId;
2124
this.syncPropertyKeyStates = syncPropertyKeyStates;
2225
this.tenacityConfiguration = tenacityConfiguration;

breakerbox-service/src/main/java/com/yammer/breakerbox/service/views/DashboardView.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
import com.google.common.net.HostAndPort;
44
import com.google.common.net.UrlEscapers;
55

6+
import java.util.Set;
7+
68
public class DashboardView extends NavbarView {
79
private final String clusterName;
810
private final HostAndPort breakerboxHostAndPort;
911

10-
public DashboardView(String clusterName, HostAndPort breakerboxHostAndPort) {
11-
super("/templates/dashboard/dashboard.mustache");
12+
public DashboardView(String clusterName, HostAndPort breakerboxHostAndPort, Set<String> specifiedMetaClusters) {
13+
super("/templates/dashboard/dashboard.mustache", specifiedMetaClusters);
1214
this.clusterName = clusterName;
1315
this.breakerboxHostAndPort = breakerboxHostAndPort;
1416
}

breakerbox-service/src/main/java/com/yammer/breakerbox/service/views/DashboardViewFactory.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22

33
import com.google.common.net.HostAndPort;
44

5+
import java.util.Set;
6+
57
public class DashboardViewFactory {
68
private final HostAndPort breakerboxHostAndPort;
79

810
public DashboardViewFactory(HostAndPort breakerboxHostAndPort) {
911
this.breakerboxHostAndPort = breakerboxHostAndPort;
1012
}
1113

12-
public DashboardView create(String clusterName) {
13-
return new DashboardView(clusterName, breakerboxHostAndPort);
14+
public DashboardView create(String clusterName, Set<String> specifiedMetaClusters) {
15+
return new DashboardView(clusterName, breakerboxHostAndPort, specifiedMetaClusters);
1416
}
1517
}

breakerbox-service/src/main/java/com/yammer/breakerbox/service/views/NavbarView.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@
33
import com.yammer.breakerbox.service.core.Instances;
44
import io.dropwizard.views.View;
55

6+
import java.util.Set;
7+
68
public abstract class NavbarView extends View {
7-
protected NavbarView(String templateName) {
9+
10+
private Set<String> specifiedMetaClusters;
11+
12+
protected NavbarView(String templateName, Set<String> specifiedMetaClusters) {
813
super(templateName);
14+
this.specifiedMetaClusters = specifiedMetaClusters;
915
}
1016

1117
public Iterable<String> getClusters() {
1218
return Instances.clusters();
1319
}
1420

1521
public Iterable<String> getNoMetaClusters() {
16-
return Instances.noMetaClusters();
22+
return Instances.noMetaClusters(specifiedMetaClusters);
1723
}
1824
}

breakerbox-service/src/main/java/com/yammer/breakerbox/service/views/NoPropertyKeysView.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
import com.yammer.breakerbox.store.ServiceId;
44

5+
import java.util.Set;
6+
57
public class NoPropertyKeysView extends NavbarView {
68
private final ServiceId serviceId;
79

8-
public NoPropertyKeysView(ServiceId serviceId) {
9-
super("/templates/errors/nopropertykeys.mustache");
10+
public NoPropertyKeysView(ServiceId serviceId, Set<String> specifiedMetaClusters) {
11+
super("/templates/errors/nopropertykeys.mustache", specifiedMetaClusters);
1012
this.serviceId = serviceId;
1113
}
1214

breakerbox-service/src/test/java/com/yammer/breakerbox/service/core/tests/InstancesTest.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.yammer.breakerbox.service.core.tests;
22

33
import com.google.common.collect.ImmutableSet;
4+
import com.google.common.collect.Sets;
45
import com.google.common.io.Resources;
56
import com.netflix.turbine.discovery.Instance;
67
import com.yammer.breakerbox.service.core.Instances;
@@ -11,6 +12,7 @@
1112
import java.io.File;
1213
import java.io.FileInputStream;
1314
import java.net.URI;
15+
import java.util.Set;
1416

1517
import static org.assertj.core.api.Assertions.assertThat;
1618

@@ -29,7 +31,8 @@ public void clusters() {
2931

3032
@Test
3133
public void instances() {
32-
assertThat(Instances.noMetaClusters())
34+
Set<String> specifiedMetaClusters = Sets.newHashSet("PRODUCTION");
35+
assertThat(Instances.noMetaClusters(specifiedMetaClusters))
3336
.isEqualTo(ImmutableSet.of("mock"));
3437
}
3538

0 commit comments

Comments
 (0)