summaryrefslogtreecommitdiffstats
path: root/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java
Publish
Diffstat (limited to 'config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java')
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java124
1 files changed, 124 insertions, 0 deletions
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java b/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java
new file mode 100644
index 00000000000..1bf690749bb
--- /dev/null
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterMembership.java
@@ -0,0 +1,124 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.config.provision;
+
+import java.util.Optional;
+
+/**
+ * A node's membership in a cluster.
+ * This is a value object.
+ *
+ * @author bratseth
+ */
+public class ClusterMembership {
+
+ private ClusterSpec cluster; // final
+ private int index; // final
+ private boolean retired; // final
+ private String stringValue; // final
+
+ protected ClusterMembership() {}
+
+ private ClusterMembership(String stringValue, Optional<String> dockerImage) {
+ String restValue;
+ if (stringValue.endsWith("/retired")) {
+ retired = true;
+ restValue = stringValue.substring(0, stringValue.length() - "/retired".length());
+ }
+ else {
+ retired = false;
+ restValue = stringValue;
+ }
+
+ String[] components = restValue.split("/");
+
+ if ( components.length == 3)
+ initWithoutGroup(components, dockerImage);
+ else if (components.length == 4)
+ initWithGroup(components, dockerImage);
+ else
+ throw new RuntimeException("Could not parse '" + stringValue + "' to a cluster membership. " +
+ "Expected 'id/type.index[/group]'");
+
+ this.stringValue = toStringValue();
+ }
+
+ private ClusterMembership(ClusterSpec cluster, int index, boolean retired) {
+ this.cluster = cluster;
+ this.index = index;
+ this.retired = retired;
+ this.stringValue = toStringValue();
+ }
+
+ private void initWithoutGroup(String[] components, Optional<String> dockerImage) {
+ this.cluster = ClusterSpec.from(ClusterSpec.Type.valueOf(components[0]), ClusterSpec.Id.from(components[1]),
+ Optional.empty(), dockerImage);
+ this.index = Integer.parseInt(components[2]);
+ }
+
+ private void initWithGroup(String[] components, Optional<String> dockerImage) {
+ this.cluster = ClusterSpec.from(ClusterSpec.Type.valueOf(components[0]), ClusterSpec.Id.from(components[1]),
+ Optional.of(ClusterSpec.Group.from(components[2])), dockerImage);
+ this.index = Integer.parseInt(components[3]);
+ }
+
+ protected String toStringValue() {
+ return cluster.type().name() + "/" + cluster.id().value() +
+ ( cluster.group().isPresent() ? "/" + cluster.group().get().value() : "") + "/" + index +
+ ( retired ? "/retired" : "");
+ }
+
+ /** Returns the cluster this node is a member of */
+ public ClusterSpec cluster() { return cluster; }
+
+ /** Returns the index of this node within the cluster */
+ public int index() { return index; }
+
+ /** Returns whether the cluster should prepare for this node to be removed */
+ public boolean retired() { return retired; }
+
+ /** Returns a copy of this which is retired */
+ public ClusterMembership retire() {
+ return new ClusterMembership(cluster, index, true);
+ }
+
+ /** Returns a copy of this node which is not retired */
+ public ClusterMembership unretire() {
+ return new ClusterMembership(cluster, index, false);
+ }
+
+ public ClusterMembership changeCluster(ClusterSpec newCluster) {
+ return new ClusterMembership(newCluster, index, retired);
+ }
+
+ /**
+ * Returns all the information in this as a string which can be used to construct the same ClusterMembership
+ * instance using {@link #from}. This string is currently stored in ZooKeeper on running instances.
+ */
+ public String stringValue() { return stringValue; }
+
+ @Override
+ public int hashCode() { return stringValue().hashCode(); }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == this) return true;
+ if ( ! (other instanceof ClusterMembership)) return false;
+ return ((ClusterMembership)other).stringValue().equals(stringValue());
+ }
+
+ @Override
+ public String toString() { return stringValue(); }
+
+ public static ClusterMembership from(String stringValue, Optional<String> dockerImage) {
+ return new ClusterMembership(stringValue, dockerImage);
+ }
+
+ public static ClusterMembership from(ClusterSpec cluster, int index) {
+ return new ClusterMembership(cluster, index, false);
+ }
+
+ public static ClusterMembership retiredFrom(ClusterSpec cluster, int index) {
+ return new ClusterMembership(cluster, index, true);
+ }
+
+}