summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2019-10-04 12:48:01 +0200
committerMartin Polden <mpolden@mpolden.no>2019-10-07 13:59:40 +0200
commitd6be7f2e2696d2cc00518cd1593d8381692439c2 (patch)
tree6da3d82084c0821e0ece567a63dd8cf752078bb5
parentfe1e65cf69f88f6bb2965cbaa3ec7b003f315333 (diff)
Extract NodeVersionSerializer
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/NodeVersionSerializer.java61
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializer.java24
2 files changed, 68 insertions, 17 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/NodeVersionSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/NodeVersionSerializer.java
new file mode 100644
index 00000000000..088808f5942
--- /dev/null
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/NodeVersionSerializer.java
@@ -0,0 +1,61 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.persistence;
+
+import com.yahoo.component.Version;
+import com.yahoo.config.provision.HostName;
+import com.yahoo.slime.ArrayTraverser;
+import com.yahoo.slime.Cursor;
+import com.yahoo.slime.Inspector;
+import com.yahoo.vespa.hosted.controller.versions.NodeVersion;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Serializer for {@link com.yahoo.vespa.hosted.controller.versions.NodeVersion}.
+ *
+ * @author mpolden
+ */
+public class NodeVersionSerializer {
+
+ // WARNING: Since there are multiple servers in a ZooKeeper cluster and they upgrade one by one
+ // (and rewrite all nodes on startup), changes to the serialized format must be made
+ // such that what is serialized on version N+1 can be read by version N:
+ // - ADDING FIELDS: Always ok
+ // - REMOVING FIELDS: Stop reading the field first. Stop writing it on a later version.
+ // - CHANGING THE FORMAT OF A FIELD: Don't do it bro.
+
+ private static final String hostnameField = "hostname";
+ private static final String currentVersionField = "currentVersion";
+ private static final String wantedVersionField = "wantedVersion";
+ private static final String changedAtField = "changedAt";
+
+ public void nodeVersionsToSlime(Collection<NodeVersion> nodeVersions, Cursor array, boolean writeCurrentVersion) {
+ for (var nodeVersion : nodeVersions) {
+ var nodeVersionObject = array.addObject();
+ nodeVersionObject.setString(hostnameField, nodeVersion.hostname().value());
+ if (writeCurrentVersion) {
+ nodeVersionObject.setString(currentVersionField, nodeVersion.currentVersion().toFullString());
+ }
+ nodeVersionObject.setString(wantedVersionField, nodeVersion.wantedVersion().toFullString());
+ nodeVersionObject.setLong(changedAtField, nodeVersion.changedAt().toEpochMilli());
+ }
+ }
+
+ public List<NodeVersion> nodeVersionsFromSlime(Inspector object, Optional<Version> version) {
+ var nodeVersions = new ArrayList<NodeVersion>();
+ object.traverse((ArrayTraverser) (i, entry) -> {
+ var hostname = HostName.from(entry.field(hostnameField).asString());
+ var currentVersion = version.orElseGet(() -> Version.fromString(entry.field(currentVersionField).asString()));
+ var wantedVersion = Version.fromString(entry.field(wantedVersionField).asString());
+ var changedAt = Instant.ofEpochMilli(entry.field(changedAtField).asLong());
+ nodeVersions.add(new NodeVersion(hostname, currentVersion, wantedVersion, changedAt));
+ });
+ return Collections.unmodifiableList(nodeVersions);
+ }
+
+}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializer.java
index 5061f32da68..62fca7a419b 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializer.java
@@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
/**
@@ -53,17 +54,14 @@ public class VersionStatusSerializer {
// NodeVersions fields
private static final String nodeVersionsField = "nodeVersions";
- // NodeVersion fields
- private static final String hostnameField = "hostname";
- private static final String wantedVersionField = "wantedVersion";
- private static final String changedAtField = "changedAt";
-
// DeploymentStatistics fields
private static final String versionField = "version";
private static final String failingField = "failing";
private static final String productionField = "production";
private static final String deployingField = "deploying";
+ private final NodeVersionSerializer nodeVersionSerializer = new NodeVersionSerializer();
+
public Slime toSlime(VersionStatus status) {
Slime slime = new Slime();
Cursor root = slime.setObject();
@@ -93,12 +91,7 @@ public class VersionStatusSerializer {
}
private void nodeVersionsToSlime(NodeVersions nodeVersions, Cursor array) {
- for (NodeVersion nodeVersion : nodeVersions.asMap().values()) {
- var nodeVersionObject = array.addObject();
- nodeVersionObject.setString(hostnameField, nodeVersion.hostname().value());
- nodeVersionObject.setString(wantedVersionField, nodeVersion.wantedVersion().toFullString());
- nodeVersionObject.setLong(changedAtField, nodeVersion.changedAt().toEpochMilli());
- }
+ nodeVersionSerializer.nodeVersionsToSlime(nodeVersions.asMap().values(), array, false);
}
// TODO(mpolden): Remove after October 2019
@@ -140,12 +133,9 @@ public class VersionStatusSerializer {
var nodeVersions = ImmutableMap.<HostName, NodeVersion>builder();
var nodeVersionsRoot = root.field(nodeVersionsField);
if (nodeVersionsRoot.valid()) {
- nodeVersionsRoot.traverse((ArrayTraverser) (i, entry) -> {
- var hostname = HostName.from(entry.field(hostnameField).asString());
- var wantedVersion = Version.fromString(entry.field(wantedVersionField).asString());
- var changedAt = Instant.ofEpochMilli(entry.field(changedAtField).asLong());
- nodeVersions.put(hostname, new NodeVersion(hostname, version, wantedVersion, changedAt));
- });
+ for (var nodeVersion : nodeVersionSerializer.nodeVersionsFromSlime(nodeVersionsRoot, Optional.of(version))) {
+ nodeVersions.put(nodeVersion.hostname(), nodeVersion);
+ }
} else {
// TODO(mpolden): Remove after October 2019
var configServerHostnames = configServersFromSlime(root.field(configServersField));