summaryrefslogtreecommitdiffstats
path: root/clustercontroller-core
diff options
context:
space:
mode:
authorGeir Storli <geirst@oath.com>2018-03-23 15:52:23 +0100
committerGeir Storli <geirst@oath.com>2018-03-23 15:52:23 +0100
commit2b4d47665326701622f55ebe8352a71643b2129f (patch)
tree30401192fd59303f97647d4c1837a9d8456fb506 /clustercontroller-core
parent53b11524f83b30d11a5c6d690a60ab34fdac1804 (diff)
Add information about derived bucket space state in cluster state history.
Diffstat (limited to 'clustercontroller-core')
-rw-r--r--clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/ClusterStateHistoryEntry.java15
-rw-r--r--clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/StateVersionTracker.java2
-rw-r--r--clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/status/LegacyIndexPageRequestHandler.java70
-rw-r--r--clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateVersionTrackerTest.java5
4 files changed, 71 insertions, 21 deletions
diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/ClusterStateHistoryEntry.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/ClusterStateHistoryEntry.java
index e0aefe8a90a..65c0f210fd5 100644
--- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/ClusterStateHistoryEntry.java
+++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/ClusterStateHistoryEntry.java
@@ -3,20 +3,27 @@ package com.yahoo.vespa.clustercontroller.core;
import com.yahoo.vdslib.state.ClusterState;
+import java.util.Map;
import java.util.Objects;
+import java.util.stream.Collectors;
public class ClusterStateHistoryEntry {
- private final ClusterState state;
+ private final ClusterStateBundle state;
private final long time;
- ClusterStateHistoryEntry(final ClusterState state, final long time) {
+ ClusterStateHistoryEntry(final ClusterStateBundle state, final long time) {
this.state = state;
this.time = time;
}
- public ClusterState state() {
- return state;
+ public ClusterState getBaselineState() {
+ return state.getBaselineClusterState();
+ }
+
+ public Map<String, ClusterState> getDerivedBucketSpaceStates() {
+ return state.getDerivedBucketSpaceStates().entrySet().stream()
+ .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue().getClusterState()));
}
public long time() {
diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/StateVersionTracker.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/StateVersionTracker.java
index 0673a10c282..177efe31766 100644
--- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/StateVersionTracker.java
+++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/StateVersionTracker.java
@@ -141,7 +141,7 @@ public class StateVersionTracker {
private void recordCurrentStateInHistoryAtTime(final long currentTimeMs) {
clusterStateHistory.addFirst(new ClusterStateHistoryEntry(
- currentClusterState.getBaselineClusterState(), currentTimeMs));
+ currentClusterState, currentTimeMs));
while (clusterStateHistory.size() > maxHistoryEntryCount) {
clusterStateHistory.removeLast();
}
diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/status/LegacyIndexPageRequestHandler.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/status/LegacyIndexPageRequestHandler.java
index e85623f068c..07195d05aa8 100644
--- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/status/LegacyIndexPageRequestHandler.java
+++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/status/LegacyIndexPageRequestHandler.java
@@ -3,12 +3,12 @@ package com.yahoo.vespa.clustercontroller.core.status;
import com.yahoo.vdslib.state.ClusterState;
import com.yahoo.vespa.clustercontroller.core.*;
+import com.yahoo.vespa.clustercontroller.core.Timer;
import com.yahoo.vespa.clustercontroller.core.status.statuspage.StatusPageResponse;
import com.yahoo.vespa.clustercontroller.core.status.statuspage.StatusPageServer;
import com.yahoo.vespa.clustercontroller.core.status.statuspage.VdsClusterHtmlRendrer;
-import java.util.Iterator;
-import java.util.TimeZone;
+import java.util.*;
/**
* @author Haakon Humberset
@@ -106,6 +106,7 @@ public class LegacyIndexPageRequestHandler implements StatusPageServer.RequestHa
}
sb.append("<table border=\"1\" cellspacing=\"0\"><tr>\n")
.append(" <th>Creation date (").append(tz.getDisplayName(false, TimeZone.SHORT)).append(")</th>\n")
+ .append(" <th>Bucket space</th>\n")
.append(" <th>Cluster state</th>\n")
.append("</tr>\n");
// Write cluster state history in reverse order (newest on top)
@@ -113,7 +114,7 @@ public class LegacyIndexPageRequestHandler implements StatusPageServer.RequestHa
ClusterStateHistoryEntry current = null;
while (stateIterator.hasNext()) {
ClusterStateHistoryEntry nextEntry = stateIterator.next();
- if (nextEntry.state().isOfficial() || showLocal) {
+ if (nextEntry.getBaselineState().isOfficial() || showLocal) {
if (current != null) writeClusterStateEntry(current, nextEntry, sb, tz);
current = nextEntry;
}
@@ -125,21 +126,64 @@ public class LegacyIndexPageRequestHandler implements StatusPageServer.RequestHa
private static void writeClusterStates(StringBuilder sb, ClusterStateBundle clusterStates) {
sb.append("<p>Baseline cluster state:<br><code>").append(clusterStates.getBaselineClusterState().toString()).append("</code></p>\n");
- clusterStates.getDerivedBucketSpaceStates().entrySet().forEach(entry -> {
- String bucketSpace = entry.getKey();
- ClusterState clusterState = entry.getValue().getClusterState();
- sb.append("<p>" + bucketSpace + " cluster state:<br><code>").append(clusterState.toString()).append("</code></p>\n");
+ clusterStates.getDerivedBucketSpaceStates().forEach((bucketSpace, state) -> {
+ sb.append("<p>" + bucketSpace + " cluster state:<br><code>").append(state.getClusterState().toString()).append("</code></p>\n");
});
}
private void writeClusterStateEntry(ClusterStateHistoryEntry entry, ClusterStateHistoryEntry last, StringBuilder sb, TimeZone tz) {
- sb.append("<tr><td>").append(RealTimer.printDate(entry.time(), tz))
- .append("</td><td>").append(entry.state().isOfficial() ? "" : "<font color=\"grey\">");
- sb.append(entry.state());
- if (last != null) {
- sb.append("<br><b>Diff</b>: ").append(last.state().getHtmlDifference(entry.state()));
+ List<ClusterStateTransition> derivedTransitions = calculateDerivedClusterStateTransitions(entry, last);
+ sb.append("<tr><td rowspan=\"" + (derivedTransitions.size() + 1) + "\">").append(RealTimer.printDate(entry.time(), tz)).append("</td>");
+ writeClusterStateTransition(ClusterStateTransition.forBaseline(entry.getBaselineState(),
+ (last != null ? last.getBaselineState() : null)), entry.getBaselineState().isOfficial(), sb);
+ derivedTransitions.forEach(transition -> {
+ sb.append("<tr>");
+ writeClusterStateTransition(transition, entry.getBaselineState().isOfficial(), sb);
+ });
+ }
+
+ private void writeClusterStateTransition(ClusterStateTransition transition, boolean isOfficial, StringBuilder sb) {
+ sb.append("<td align=\"center\">").append(transition.bucketSpace).append("</td>");
+ sb.append("<td>").append(isOfficial ? "" : "<font color=\"grey\">");
+ sb.append(transition.current);
+ if (transition.last != null) {
+ sb.append("<br><b>Diff</b>: ").append(transition.last.getHtmlDifference(transition.current));
+ }
+ sb.append(isOfficial ? "" : "</font>").append("</td></tr>\n");
+ }
+
+ private List<ClusterStateTransition> calculateDerivedClusterStateTransitions(ClusterStateHistoryEntry currentEntry,
+ ClusterStateHistoryEntry lastEntry) {
+ List<ClusterStateTransition> result = new ArrayList<>();
+ currentEntry.getDerivedBucketSpaceStates().forEach((bucketSpace, currentState) -> {
+ ClusterState lastState = (lastEntry != null ? lastEntry.getDerivedBucketSpaceStates().get(bucketSpace) : null);
+ if ((!currentState.equals(currentEntry.getBaselineState())) ||
+ ((lastState != null) && (!lastState.equals(lastEntry.getBaselineState())))) {
+ result.add(ClusterStateTransition.forBucketSpace(currentState, lastState, bucketSpace));
+ }
+ });
+ return result;
+ }
+
+ private static class ClusterStateTransition {
+ public final ClusterState current;
+ public final ClusterState last;
+ public final String bucketSpace;
+
+ private ClusterStateTransition(ClusterState current, ClusterState last, String bucketSpace) {
+ this.current = current;
+ this.last = last;
+ this.bucketSpace = bucketSpace;
+ }
+
+ public static ClusterStateTransition forBaseline(ClusterState current, ClusterState last) {
+ return new ClusterStateTransition(current, last, "-");
+ }
+
+ public static ClusterStateTransition forBucketSpace(ClusterState current, ClusterState last, String bucketSpace) {
+ return new ClusterStateTransition(current, last, bucketSpace);
}
- sb.append(entry.state().isOfficial() ? "" : "</font>").append("</td></tr>\n");
+
}
}
diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateVersionTrackerTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateVersionTrackerTest.java
index 1cb09fcf2d1..2a3be1e7194 100644
--- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateVersionTrackerTest.java
+++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateVersionTrackerTest.java
@@ -24,8 +24,7 @@ import static org.mockito.Mockito.when;
public class StateVersionTrackerTest {
private static AnnotatedClusterState stateWithoutAnnotations(String stateStr) {
- final ClusterState state = ClusterState.stateFromString(stateStr);
- return new AnnotatedClusterState(state, Optional.empty(), AnnotatedClusterState.emptyNodeStateReasons());
+ return AnnotatedClusterState.withoutAnnotations(ClusterState.stateFromString(stateStr));
}
private static ClusterStateBundle stateBundleWithoutAnnotations(String stateStr) {
@@ -184,7 +183,7 @@ public class StateVersionTrackerTest {
}
private static ClusterStateHistoryEntry historyEntry(final String state, final long time) {
- return new ClusterStateHistoryEntry(ClusterState.stateFromString(state), time);
+ return new ClusterStateHistoryEntry(stateBundleWithoutAnnotations(state), time);
}
@Test