summaryrefslogtreecommitdiffstats
path: root/node-admin/src/main/java/com
diff options
context:
space:
mode:
authorHåkon Hallingstad <hakon@yahooinc.com>2022-10-31 21:35:02 +0100
committerHåkon Hallingstad <hakon@yahooinc.com>2022-10-31 21:35:02 +0100
commit613464e11b5c9b478873014ccb1d629bd1ae91fe (patch)
treeb283d6a952b58653368898afce53dd06b1ede6ad /node-admin/src/main/java/com
parent42d67fa4e4fd247296b1e99bcfe44e1fdcb50834 (diff)
New cores client in node-admin
Diffstat (limited to 'node-admin/src/main/java/com')
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerClients.java4
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerException.java10
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/RealConfigServerClients.java9
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/StandardConfigServerResponse.java22
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoreDumpMetadata.java60
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/Cores.java16
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoresImpl.java37
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/bindings/ReportCoreDumpRequest.java27
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepository.java32
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/bindings/NodeMessageResponse.java18
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/package-info.java5
11 files changed, 197 insertions, 43 deletions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerClients.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerClients.java
index 4a9f761a72f..1bf4120c071 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerClients.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerClients.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.node.admin.configserver;
import com.yahoo.vespa.flags.FlagRepository;
+import com.yahoo.vespa.hosted.node.admin.configserver.cores.Cores;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository;
import com.yahoo.vespa.hosted.node.admin.configserver.orchestrator.Orchestrator;
import com.yahoo.vespa.hosted.node.admin.configserver.state.State;
@@ -24,5 +25,8 @@ public interface ConfigServerClients {
/** Get handle to the /flags/v1 REST API */
FlagRepository flagRepository();
+ /** Get handle to the /cores/v1 REST API */
+ Cores cores();
+
void stop();
}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerException.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerException.java
new file mode 100644
index 00000000000..369a1c93dc4
--- /dev/null
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/ConfigServerException.java
@@ -0,0 +1,10 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.configserver;
+
+/**
+ * @author hakonhall
+ */
+public class ConfigServerException extends RuntimeException {
+ public ConfigServerException(String message) { super(message); }
+ public ConfigServerException(String message, Throwable cause) { super(message, cause); }
+}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/RealConfigServerClients.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/RealConfigServerClients.java
index 6c650700432..4311a31816a 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/RealConfigServerClients.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/RealConfigServerClients.java
@@ -2,6 +2,8 @@
package com.yahoo.vespa.hosted.node.admin.configserver;
import com.yahoo.vespa.flags.FlagRepository;
+import com.yahoo.vespa.hosted.node.admin.configserver.cores.Cores;
+import com.yahoo.vespa.hosted.node.admin.configserver.cores.CoresImpl;
import com.yahoo.vespa.hosted.node.admin.configserver.flags.RealFlagRepository;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.RealNodeRepository;
@@ -22,6 +24,7 @@ public class RealConfigServerClients implements ConfigServerClients {
private final Orchestrator orchestrator;
private final State state;
private final RealFlagRepository flagRepository;
+ private final Cores cores;
/**
* @param configServerApi the backend API to use - will be closed at {@link #stop()}.
@@ -32,6 +35,7 @@ public class RealConfigServerClients implements ConfigServerClients {
orchestrator = new OrchestratorImpl(configServerApi);
state = new StateImpl(configServerApi);
flagRepository = new RealFlagRepository(configServerApi);
+ cores = new CoresImpl(configServerApi);
}
@Override
@@ -55,6 +59,11 @@ public class RealConfigServerClients implements ConfigServerClients {
}
@Override
+ public Cores cores() {
+ return cores;
+ }
+
+ @Override
public void stop() {
configServerApi.close();
}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/StandardConfigServerResponse.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/StandardConfigServerResponse.java
new file mode 100644
index 00000000000..0aa4af3fe22
--- /dev/null
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/StandardConfigServerResponse.java
@@ -0,0 +1,22 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.configserver;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Strings;
+
+/**
+ * @author hakonhall
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class StandardConfigServerResponse {
+ @JsonProperty("message") public String message;
+ @JsonProperty("error-code") public String errorCode;
+
+ public void throwOnError(String detail) {
+ if (!Strings.isNullOrEmpty(errorCode))
+ throw new ConfigServerException(detail + ": " + message + " " + errorCode);
+ }
+}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoreDumpMetadata.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoreDumpMetadata.java
new file mode 100644
index 00000000000..8ea39e37489
--- /dev/null
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoreDumpMetadata.java
@@ -0,0 +1,60 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.configserver.cores;
+
+import com.yahoo.component.Version;
+import com.yahoo.config.provision.DockerImage;
+
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author hakonhall
+ */
+public class CoreDumpMetadata {
+ private String binPath;
+ private List<String> backtrace;
+ private List<String> backtraceAllThreads;
+ private Path coreDumpPath;
+ private String kernelVersion;
+ private String cpuMicrocodeVersion;
+ private DockerImage dockerImage;
+ private String vespaVersion;
+
+ public CoreDumpMetadata() {}
+
+ public Optional<String> binPath() { return Optional.ofNullable(binPath); };
+ public Optional<List<String>> backtrace() { return Optional.ofNullable(backtrace); };
+ public Optional<List<String>> backtraceAllThreads() { return Optional.ofNullable(backtraceAllThreads); };
+ public Optional<Path> coredumpPath() { return Optional.ofNullable(coreDumpPath); };
+ public Optional<String> kernelVersion() { return Optional.ofNullable(kernelVersion); };
+ public Optional<String> cpuMicrocodeVersion() { return Optional.ofNullable(cpuMicrocodeVersion); };
+ public Optional<DockerImage> dockerImage() { return Optional.ofNullable(dockerImage); };
+ public Optional<String> vespaVersion() { return Optional.ofNullable(vespaVersion); };
+
+ public CoreDumpMetadata setBinPath(String binPath) { this.binPath = binPath; return this; };
+ public CoreDumpMetadata setBacktrace(List<String> backtrace) { this.backtrace = backtrace; return this; };
+ public CoreDumpMetadata setBacktraceAllThreads(List<String> backtraceAllThreads) { this.backtraceAllThreads = backtraceAllThreads; return this; };
+ public CoreDumpMetadata setCoreDumpPath(Path coreDumpPath) { this.coreDumpPath = coreDumpPath; return this; };
+ public CoreDumpMetadata setKernelVersion(String kernelVersion) { this.kernelVersion = kernelVersion; return this; };
+ public CoreDumpMetadata setCpuMicrocodeVersion(String cpuMicrocodeVersion) { this.cpuMicrocodeVersion = cpuMicrocodeVersion; return this; };
+ public CoreDumpMetadata setDockerImage(DockerImage dockerImage) { this.dockerImage = dockerImage; return this; };
+ public CoreDumpMetadata setVespaVersion(String vespaVersion) { this.vespaVersion = vespaVersion; return this; };
+
+ @Override
+ public String toString() {
+ return "CoreDumpMetadata{" +
+ "binPath=" + binPath +
+ ", backtrace=" + backtrace +
+ ", backtraceAllThreads=" + backtraceAllThreads +
+ ", coreDumpPath=" + coreDumpPath +
+ ", kernelVersion='" + kernelVersion + '\'' +
+ ", cpuMicrocodeVersion='" + cpuMicrocodeVersion + '\'' +
+ ", dockerImage=" + dockerImage +
+ ", vespaVersion=" + vespaVersion +
+ '}';
+ }
+
+ @Override public boolean equals(Object o) { throw new UnsupportedOperationException(); }
+ @Override public int hashCode() { throw new UnsupportedOperationException(); }
+}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/Cores.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/Cores.java
new file mode 100644
index 00000000000..6f72e4e9551
--- /dev/null
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/Cores.java
@@ -0,0 +1,16 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.configserver.cores;
+
+import com.yahoo.config.provision.HostName;
+
+/**
+ * @author hakonhall
+ */
+public interface Cores {
+ /**
+ * @param hostname Hostname of the node that produced the core.
+ * @param id The ID (aka UUID aka docid) of the core.
+ * @param metadata Core dump metadata.
+ */
+ void report(HostName hostname, String id, CoreDumpMetadata metadata);
+}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoresImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoresImpl.java
new file mode 100644
index 00000000000..f6393d3726c
--- /dev/null
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/CoresImpl.java
@@ -0,0 +1,37 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.configserver.cores;
+
+import com.yahoo.config.provision.HostName;
+import com.yahoo.vespa.hosted.node.admin.configserver.ConfigServerApi;
+import com.yahoo.vespa.hosted.node.admin.configserver.StandardConfigServerResponse;
+import com.yahoo.vespa.hosted.node.admin.configserver.cores.bindings.ReportCoreDumpRequest;
+
+import java.util.List;
+
+/**
+ * @author hakonhall
+ */
+public class CoresImpl implements Cores {
+ private final ConfigServerApi configServerApi;
+
+ public CoresImpl(ConfigServerApi configServerApi) {
+ this.configServerApi = configServerApi;
+ }
+
+ @Override
+ public void report(HostName hostname, String id, CoreDumpMetadata metadata) {
+ var request = new ReportCoreDumpRequest();
+ metadata.binPath().ifPresent(binPath -> request.bin_path = binPath);
+ metadata.backtrace().ifPresent(backtrace -> request.backtrace = List.copyOf(backtrace));
+ metadata.backtraceAllThreads().ifPresent(backtraceAllThreads -> request.backtrace_all_threads = List.copyOf(backtraceAllThreads));
+ metadata.coredumpPath().ifPresent(coredumpPath -> request.coredump_path = coredumpPath.toString());
+ metadata.kernelVersion().ifPresent(kernelVersion -> request.kernel_version = kernelVersion);
+ metadata.cpuMicrocodeVersion().ifPresent(cpuMicrocodeVersion -> request.cpu_microcode_version = cpuMicrocodeVersion);
+ metadata.dockerImage().ifPresent(dockerImage -> request.docker_image = dockerImage.asString());
+ metadata.vespaVersion().ifPresent(vespaVersion -> request.vespa_version = vespaVersion);
+
+ String uriPath = "/cores/v1/report/" + hostname.value() + "/" + id;
+ configServerApi.post(uriPath, request, StandardConfigServerResponse.class)
+ .throwOnError("Failed to report core dump at " + metadata.coredumpPath());
+ }
+}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/bindings/ReportCoreDumpRequest.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/bindings/ReportCoreDumpRequest.java
new file mode 100644
index 00000000000..f31c1e71bae
--- /dev/null
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/cores/bindings/ReportCoreDumpRequest.java
@@ -0,0 +1,27 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.node.admin.configserver.cores.bindings;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.util.List;
+
+/**
+ * Jackson class of JSON request, with names of fields verified in unit test.
+ *
+ * @author hakonhall
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ReportCoreDumpRequest {
+ public List<String> backtrace;
+ public List<String> backtrace_all_threads;
+ public String bin_path;
+ public String coredump_path;
+ public String cpu_microcode_version;
+ public String docker_image;
+ public String kernel_version;
+ public String vespa_version;
+
+ public ReportCoreDumpRequest() {}
+}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepository.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepository.java
index b70ce491c73..a4a047b524c 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepository.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/RealNodeRepository.java
@@ -2,7 +2,6 @@
package com.yahoo.vespa.hosted.node.admin.configserver.noderepository;
import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.base.Strings;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.DockerImage;
@@ -11,9 +10,9 @@ import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.host.FlavorOverrides;
import com.yahoo.vespa.hosted.node.admin.configserver.ConfigServerApi;
import com.yahoo.vespa.hosted.node.admin.configserver.HttpException;
+import com.yahoo.vespa.hosted.node.admin.configserver.StandardConfigServerResponse;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.bindings.GetAclResponse;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.bindings.GetNodesResponse;
-import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.bindings.NodeMessageResponse;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.bindings.NodeRepositoryNode;
import java.net.URI;
@@ -48,9 +47,8 @@ public class RealNodeRepository implements NodeRepository {
.map(RealNodeRepository::nodeRepositoryNodeFromAddNode)
.collect(Collectors.toList());
- NodeMessageResponse response = configServerApi.post("/nodes/v2/node", nodesToPost, NodeMessageResponse.class);
- if (Strings.isNullOrEmpty(response.errorCode)) return;
- throw new NodeRepositoryException("Failed to add nodes: " + response.message + " " + response.errorCode);
+ configServerApi.post("/nodes/v2/node", nodesToPost, StandardConfigServerResponse.class)
+ .throwOnError("Failed to add nodes");
}
@Override
@@ -119,26 +117,20 @@ public class RealNodeRepository implements NodeRepository {
@Override
public void updateNodeAttributes(String hostName, NodeAttributes nodeAttributes) {
- NodeMessageResponse response = configServerApi.patch(
- "/nodes/v2/node/" + hostName,
- nodeRepositoryNodeFromNodeAttributes(nodeAttributes),
- NodeMessageResponse.class);
-
- if (Strings.isNullOrEmpty(response.errorCode)) return;
- throw new NodeRepositoryException("Failed to update node attributes: " + response.message + " " + response.errorCode);
+ configServerApi.patch("/nodes/v2/node/" + hostName,
+ nodeRepositoryNodeFromNodeAttributes(nodeAttributes),
+ StandardConfigServerResponse.class)
+ .throwOnError("Failed to update node attributes");
}
@Override
public void setNodeState(String hostName, NodeState nodeState) {
String state = nodeState.name();
- NodeMessageResponse response = configServerApi.put(
- "/nodes/v2/state/" + state + "/" + hostName,
- Optional.empty(), /* body */
- NodeMessageResponse.class);
+ StandardConfigServerResponse response = configServerApi.put("/nodes/v2/state/" + state + "/" + hostName,
+ Optional.empty(), /* body */
+ StandardConfigServerResponse.class);
logger.info(response.message);
-
- if (Strings.isNullOrEmpty(response.errorCode)) return;
- throw new NodeRepositoryException("Failed to set node state: " + response.message + " " + response.errorCode);
+ response.throwOnError("Failed to set node state");
}
private static NodeSpec createNodeSpec(NodeRepositoryNode node) {
@@ -153,7 +145,7 @@ public class RealNodeRepository implements NodeRepository {
NodeReports reports = NodeReports.fromMap(Optional.ofNullable(node.reports).orElseGet(Map::of));
List<Event> events = node.history.stream()
.map(event -> new Event(event.agent, event.event, Optional.ofNullable(event.at).map(Instant::ofEpochMilli).orElse(Instant.EPOCH)))
- .collect(Collectors.toUnmodifiableList());
+ .toList();
List<TrustStoreItem> trustStore = Optional.ofNullable(node.trustStore).orElse(List.of()).stream()
.map(item -> new TrustStoreItem(item.fingerprint, Instant.ofEpochMilli(item.expiry)))
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/bindings/NodeMessageResponse.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/bindings/NodeMessageResponse.java
deleted file mode 100644
index f4c6181f219..00000000000
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/bindings/NodeMessageResponse.java
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.node.admin.configserver.noderepository.bindings;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * Response from PUT /nodes/v2/state/ call to node-repository.
- *
- * @author dybis
- */
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class NodeMessageResponse {
- @JsonProperty("message")
- public String message;
- @JsonProperty("error-code")
- public String errorCode;
-}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/package-info.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/package-info.java
deleted file mode 100644
index 6e529fe8d77..00000000000
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-@ExportPackage
-package com.yahoo.vespa.hosted.node.admin;
-
-import com.yahoo.osgi.annotation.ExportPackage;