summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java6
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java8
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java8
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java202
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java12
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/filedistribution/FileDistributionAndUrlDownload.java32
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/filedistribution/UrlDownloadRpcServer.java (renamed from config-proxy/src/main/java/com/yahoo/vespa/config/proxy/UrlDownloadRpcServer.java)18
-rw-r--r--config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServerTest.java109
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/EndpointList.java7
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java16
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-overview.json40
-rw-r--r--docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/metrics/DimensionMetrics.java18
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_generic_join.h (renamed from eval/src/vespa/eval/tensor/dense/dense_tensor_apply.h)4
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp (renamed from eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp)14
-rw-r--r--eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp8
-rw-r--r--filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java10
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/ConfigServerInfo.java1
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/docker/DockerOperationsImpl.java13
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java132
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java1
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImpl.java17
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgent.java8
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextSupplier.java3
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java222
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentScheduler.java3
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelper.java1
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/StoredBoolean.java2
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/Templar.java4
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java2
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java8
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/util/SecretAgentCheckConfig.java101
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/util/package-info.java5
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java165
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java99
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ProcessFactoryImplTest.java10
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/util/SecretAgentCheckConfigTest.java88
-rw-r--r--node-admin/src/test/resources/docker.stats.json376
-rw-r--r--node-admin/src/test/resources/expected.container.system.metrics.0.txt78
-rw-r--r--node-admin/src/test/resources/expected.container.system.metrics.1.txt82
-rw-r--r--vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java2
-rw-r--r--vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/FeedParams.java34
-rw-r--r--vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/SessionParams.java13
-rw-r--r--vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/ClusterConnection.java77
-rw-r--r--vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/IOThread.java91
-rw-r--r--vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/operationProcessor/OperationProcessor.java83
-rw-r--r--vespa-http-client/src/test/java/com/yahoo/vespa/http/client/SyncFeedClientTest.java2
-rw-r--r--vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java2
47 files changed, 539 insertions, 1698 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java
index 971c2c00859..a117d283146 100644
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/ConfigserverSslContextFactoryProvider.java
@@ -2,7 +2,6 @@
package com.yahoo.vespa.hosted.athenz.instanceproviderservice;
import com.google.inject.Inject;
-import com.yahoo.config.provision.Zone;
import com.yahoo.jdisc.http.ssl.impl.TlsContextBasedProvider;
import com.yahoo.log.LogLevel;
import com.yahoo.security.KeyStoreBuilder;
@@ -64,8 +63,7 @@ public class ConfigserverSslContextFactoryProvider extends TlsContextBasedProvid
@Inject
public ConfigserverSslContextFactoryProvider(ServiceIdentityProvider bootstrapIdentity,
KeyProvider keyProvider,
- AthenzProviderServiceConfig config,
- Zone zone) {
+ AthenzProviderServiceConfig config) {
this.athenzProviderServiceConfig = config;
this.ztsClient = new DefaultZtsClient(URI.create(athenzProviderServiceConfig.ztsUrl()), bootstrapIdentity);
this.keyProvider = keyProvider;
@@ -113,7 +111,7 @@ public class ConfigserverSslContextFactoryProvider extends TlsContextBasedProvid
.orElseGet(() -> updateKeystore(configserverIdentity, generateKeystorePassword(), keyProvider, ztsClient, zoneConfig));
keyManager.updateKeystore(keyStore, new char[0]);
SSLContext sslContext = new SslContextBuilder()
- .withTrustStore(trustStoreFile)
+ .withTrustStore(trustStoreFile, KeyStoreType.JKS)
.withKeyManager(keyManager)
.build();
return new DefaultTlsContext(sslContext, PeerAuthentication.WANT);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
index e9db64f8e4b..73a401e6a2a 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ApplicationContainerCluster.java
@@ -11,6 +11,7 @@ import com.yahoo.container.BundlesConfig;
import com.yahoo.jdisc.http.ServletPathsConfig;
import com.yahoo.vespa.config.search.RankProfilesConfig;
import com.yahoo.vespa.config.search.core.RankingConstantsConfig;
+import com.yahoo.vespa.defaults.Defaults;
import com.yahoo.vespa.model.container.component.Component;
import com.yahoo.vespa.model.container.component.ConfigProducerGroup;
import com.yahoo.vespa.model.container.component.Servlet;
@@ -19,6 +20,7 @@ import com.yahoo.vespa.model.container.jersey.RestApi;
import com.yahoo.vespa.model.utils.FileSender;
import edu.umd.cs.findbugs.annotations.NonNull;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
@@ -60,6 +62,7 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
addSimpleComponent("com.yahoo.container.jdisc.SecretStoreProvider");
addSimpleComponent("com.yahoo.container.jdisc.DeprecatedSecretStoreProvider");
addSimpleComponent("com.yahoo.container.jdisc.CertificateStoreProvider");
+ addTestrunnerComponentsIfTester(deployState);
}
@Override
@@ -86,6 +89,11 @@ public final class ApplicationContainerCluster extends ContainerCluster<Applicat
}
}
+ private void addTestrunnerComponentsIfTester(DeployState deployState) {
+ if (deployState.isHosted() && deployState.getProperties().applicationId().instance().isTester())
+ addPlatformBundle(Paths.get(Defaults.getDefaults().underVespaHome("lib/jars/vespa-testrunner-components-jar-with-dependencies.jar")));
+ }
+
public void setModelEvaluation(ContainerModelEvaluation modelEvaluation) {
this.modelEvaluation = modelEvaluation;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index 7a6b1064b24..47adac637ee 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -37,7 +37,6 @@ import com.yahoo.search.config.QrStartConfig;
import com.yahoo.search.pagetemplates.PageTemplatesConfig;
import com.yahoo.search.query.profile.config.QueryProfilesConfig;
import com.yahoo.vespa.configdefinition.IlscriptsConfig;
-import com.yahoo.vespa.defaults.Defaults;
import com.yahoo.vespa.model.PortsMeta;
import com.yahoo.vespa.model.Service;
import com.yahoo.vespa.model.admin.monitoring.Monitoring;
@@ -64,7 +63,6 @@ import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -192,7 +190,6 @@ public abstract class ContainerCluster<CONTAINER extends Container>
addSimpleComponent("com.yahoo.container.handler.VipStatus");
addSimpleComponent(com.yahoo.container.handler.ClustersStatus.class.getName());
addJaxProviders();
- addTestrunnerComponentsIfTester(deployState);
}
public void setZone(Zone zone) {
@@ -207,11 +204,6 @@ public abstract class ContainerCluster<CONTAINER extends Container>
addVipHandler();
}
- private void addTestrunnerComponentsIfTester(DeployState deployState) {
- if (deployState.isHosted() && deployState.getProperties().applicationId().instance().isTester())
- addPlatformBundle(Paths.get(Defaults.getDefaults().underVespaHome("lib/jars/vespa-testrunner-components-jar-with-dependencies.jar")));
- }
-
public final void addDefaultHandlersExceptStatus() {
addDefaultRootHandler();
addMetricStateHandler();
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java
index db3b787f9f9..5ffc7293742 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java
@@ -1,10 +1,21 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.proxy;
-import com.yahoo.jrt.*;
+import com.yahoo.jrt.Acceptor;
+import com.yahoo.jrt.Int32Value;
+import com.yahoo.jrt.ListenFailedException;
+import com.yahoo.jrt.Method;
+import com.yahoo.jrt.Request;
+import com.yahoo.jrt.Spec;
+import com.yahoo.jrt.StringArray;
+import com.yahoo.jrt.StringValue;
+import com.yahoo.jrt.Supervisor;
+import com.yahoo.jrt.Target;
+import com.yahoo.jrt.TargetWatcher;
import com.yahoo.log.LogLevel;
-import com.yahoo.vespa.config.*;
import com.yahoo.vespa.config.ErrorCode;
+import com.yahoo.vespa.config.JRTMethods;
+import com.yahoo.vespa.config.RawConfig;
import com.yahoo.vespa.config.protocol.JRTConfigRequestFactory;
import com.yahoo.vespa.config.protocol.JRTServerConfigRequest;
import com.yahoo.vespa.config.protocol.JRTServerConfigRequestV3;
@@ -12,6 +23,9 @@ import com.yahoo.vespa.config.protocol.JRTServerConfigRequestV3;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
@@ -28,6 +42,7 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer
private final Spec spec;
private final Supervisor supervisor;
private final ProxyServer proxyServer;
+ private final ExecutorService rpcExecutor = Executors.newFixedThreadPool(8);
ConfigProxyRpcServer(ProxyServer proxyServer, Supervisor supervisor, Spec spec) {
this.proxyServer = proxyServer;
@@ -50,6 +65,12 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer
void shutdown() {
supervisor.transport().shutdown();
+ try {
+ rpcExecutor.shutdownNow();
+ rpcExecutor.awaitTermination(10, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
}
Spec getSpec() {
@@ -109,12 +130,16 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer
* @param req a Request
*/
private void getConfigV3(Request req) {
- log.log(LogLevel.SPAM, () -> "getConfigV3");
- JRTServerConfigRequest request = JRTServerConfigRequestV3.createFromRequest(req);
- if (isProtocolVersionSupported(request)) {
- preHandle(req);
- getConfigImpl(request);
- }
+ dispatchRpcRequest(req, () -> {
+ JRTServerConfigRequest request = JRTServerConfigRequestV3.createFromRequest(req);
+ if (isProtocolVersionSupported(request)) {
+ proxyServer.getStatistics().incRpcRequests();
+ req.target().addWatcher(this);
+ getConfigImpl(request);
+ return;
+ }
+ req.returnRequest();
+ });
}
/**
@@ -122,8 +147,11 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer
*
* @param req a Request
*/
- void ping(Request req) {
- req.returnValues().add(new Int32Value(0));
+ private void ping(Request req) {
+ dispatchRpcRequest(req, () -> {
+ req.returnValues().add(new Int32Value(0));
+ req.returnRequest();
+ });
}
/**
@@ -131,81 +159,120 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer
*
* @param req a Request
*/
- void printStatistics(Request req) {
- StringBuilder sb = new StringBuilder();
- sb.append("\nDelayed responses queue size: ");
- sb.append(proxyServer.delayedResponses.size());
- sb.append("\nContents: ");
- for (DelayedResponse delayed : proxyServer.delayedResponses.responses()) {
- sb.append(delayed.getRequest().toString()).append("\n");
- }
-
- req.returnValues().add(new StringValue(sb.toString()));
- }
+ private void printStatistics(Request req) {
+ dispatchRpcRequest(req, () -> {
+ StringBuilder sb = new StringBuilder();
+ sb.append("\nDelayed responses queue size: ");
+ sb.append(proxyServer.delayedResponses.size());
+ sb.append("\nContents: ");
+ for (DelayedResponse delayed : proxyServer.delayedResponses.responses()) {
+ sb.append(delayed.getRequest().toString()).append("\n");
+ }
- void listCachedConfig(Request req) {
- listCachedConfig(req, false);
+ req.returnValues().add(new StringValue(sb.toString()));
+ req.returnRequest();
+ });
}
- void listCachedConfigFull(Request req) {
- listCachedConfig(req, true);
+ private void listCachedConfig(Request req) {
+ dispatchRpcRequest(req, () -> listCachedConfig(req, false));
}
- void listSourceConnections(Request req) {
- String[] ret = new String[2];
- ret[0] = "Current source: " + proxyServer.getActiveSourceConnection();
- ret[1] = "All sources:\n" + printSourceConnections();
- req.returnValues().add(new StringArray(ret));
+ private void listCachedConfigFull(Request req) {
+ dispatchRpcRequest(req, () -> listCachedConfig(req, true));
}
- void updateSources(Request req) {
- String sources = req.parameters().get(0).asString();
- String ret;
- System.out.println(proxyServer.getMode());
- if (proxyServer.getMode().requiresConfigSource()) {
- proxyServer.updateSourceConnections(Arrays.asList(sources.split(",")));
- ret = "Updated config sources to: " + sources;
- } else {
- ret = "Cannot update sources when in '" + proxyServer.getMode().name() + "' mode";
- }
- req.returnValues().add(new StringValue(ret));
+ private void listSourceConnections(Request req) {
+ dispatchRpcRequest(req, () -> {
+ String[] ret = new String[2];
+ ret[0] = "Current source: " + proxyServer.getActiveSourceConnection();
+ ret[1] = "All sources:\n" + printSourceConnections();
+ req.returnValues().add(new StringArray(ret));
+ req.returnRequest();
+ });
}
- void invalidateCache(Request req) {
- proxyServer.getMemoryCache().clear();
- String[] s = new String[2];
- s[0] = "0";
- s[1] = "success";
- req.returnValues().add(new StringArray(s));
+ private void updateSources(Request req) {
+ dispatchRpcRequest(req, () -> {
+ String sources = req.parameters().get(0).asString();
+ String ret;
+ System.out.println(proxyServer.getMode());
+ if (proxyServer.getMode().requiresConfigSource()) {
+ proxyServer.updateSourceConnections(Arrays.asList(sources.split(",")));
+ ret = "Updated config sources to: " + sources;
+ } else {
+ ret = "Cannot update sources when in '" + proxyServer.getMode().name() + "' mode";
+ }
+ req.returnValues().add(new StringValue(ret));
+ req.returnRequest();
+ });
}
- void setMode(Request req) {
- String suppliedMode = req.parameters().get(0).asString();
- log.log(LogLevel.DEBUG, () -> "Supplied mode=" + suppliedMode);
- String[] s = new String[2];
- if (Mode.validModeName(suppliedMode.toLowerCase())) {
- proxyServer.setMode(suppliedMode);
+ private void invalidateCache(Request req) {
+ dispatchRpcRequest(req, () -> {
+ proxyServer.getMemoryCache().clear();
+ String[] s = new String[2];
s[0] = "0";
s[1] = "success";
- } else {
- s[0] = "1";
- s[1] = "Could not set mode to '" + suppliedMode + "'. Legal modes are '" + Mode.modes() + "'";
- }
+ req.returnValues().add(new StringArray(s));
+ req.returnRequest();
+ });
+ }
+
+ private void setMode(Request req) {
+ dispatchRpcRequest(req, () -> {
+ String suppliedMode = req.parameters().get(0).asString();
+ log.log(LogLevel.DEBUG, () -> "Supplied mode=" + suppliedMode);
+ String[] s = new String[2];
+ if (Mode.validModeName(suppliedMode.toLowerCase())) {
+ proxyServer.setMode(suppliedMode);
+ s[0] = "0";
+ s[1] = "success";
+ } else {
+ s[0] = "1";
+ s[1] = "Could not set mode to '" + suppliedMode + "'. Legal modes are '" + Mode.modes() + "'";
+ }
- req.returnValues().add(new StringArray(s));
+ req.returnValues().add(new StringArray(s));
+ req.returnRequest();
+ });
}
- void getMode(Request req) {
- req.returnValues().add(new StringValue(proxyServer.getMode().name()));
+ private void getMode(Request req) {
+ dispatchRpcRequest(req, () -> {
+ req.returnValues().add(new StringValue(proxyServer.getMode().name()));
+ req.returnRequest();
+ });
}
- void dumpCache(Request req) {
- final MemoryCache memoryCache = proxyServer.getMemoryCache();
- req.returnValues().add(new StringValue(memoryCache.dumpCacheToDisk(req.parameters().get(0).asString(), memoryCache)));
+ private void dumpCache(Request req) {
+ dispatchRpcRequest(req, () -> {
+ final MemoryCache memoryCache = proxyServer.getMemoryCache();
+ req.returnValues().add(new StringValue(memoryCache.dumpCacheToDisk(req.parameters().get(0).asString(), memoryCache)));
+ req.returnRequest();
+ });
}
//----------------------------------------------------
+ private void dispatchRpcRequest(Request request, Runnable handler) {
+ request.detach();
+ log.log(LogLevel.SPAM, () -> String.format("Dispatching RPC request %s", requestLogId(request)));
+ rpcExecutor.execute(() -> {
+ try {
+ log.log(LogLevel.SPAM, () -> String.format("Executing RPC request %s.", requestLogId(request)));
+ handler.run();
+ } catch (Exception e) {
+ log.log(LogLevel.WARNING,
+ String.format("Exception thrown during execution of RPC request %s: %s", requestLogId(request), e.getMessage()), e);
+ }
+ });
+ }
+
+ private String requestLogId(Request request) {
+ return String.format("%s/%08X", request.methodName(), request.hashCode());
+ }
+
private boolean isProtocolVersionSupported(JRTServerConfigRequest request) {
Set<Long> supportedProtocolVersions = JRTConfigRequestFactory.supportedProtocolVersions();
if (supportedProtocolVersions.contains(request.getProtocolVersion())) {
@@ -219,12 +286,6 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer
return false;
}
- private void preHandle(Request req) {
- proxyServer.getStatistics().incRpcRequests();
- req.detach();
- req.target().addWatcher(this);
- }
-
/**
* Handles all versions of "getConfig" requests.
*
@@ -262,7 +323,7 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer
return sb.toString();
}
- final void listCachedConfig(Request req, boolean full) {
+ private void listCachedConfig(Request req, boolean full) {
String[] ret;
MemoryCache cache = proxyServer.getMemoryCache();
ret = new String[cache.size()];
@@ -287,6 +348,7 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer
}
Arrays.sort(ret);
req.returnValues().add(new StringArray(ret));
+ req.returnRequest();
}
/**
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java
index 40526641855..55e546072fc 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ProxyServer.java
@@ -9,12 +9,10 @@ import com.yahoo.jrt.Transport;
import com.yahoo.log.LogLevel;
import com.yahoo.log.LogSetup;
import com.yahoo.log.event.Event;
-import com.yahoo.vespa.config.JRTConnectionPool;
import com.yahoo.vespa.config.RawConfig;
import com.yahoo.vespa.config.TimingValues;
import com.yahoo.vespa.config.protocol.JRTServerConfigRequest;
-import com.yahoo.vespa.filedistribution.FileDistributionRpcServer;
-import com.yahoo.vespa.filedistribution.FileDownloader;
+import com.yahoo.vespa.config.proxy.filedistribution.FileDistributionAndUrlDownload;
import com.yahoo.yolean.system.CatchSignals;
import java.util.List;
@@ -37,6 +35,7 @@ import static java.util.concurrent.TimeUnit.SECONDS;
public class ProxyServer implements Runnable {
private static final int DEFAULT_RPC_PORT = 19090;
+ private static final int JRT_TRANSPORT_THREADS = 4;
static final String DEFAULT_PROXY_CONFIG_SOURCES = "tcp/localhost:19070";
final static Logger log = Logger.getLogger(ProxyServer.class.getName());
@@ -44,7 +43,7 @@ public class ProxyServer implements Runnable {
// Scheduled executor that periodically checks for requests that have timed out and response should be returned to clients
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, new DaemonThreadFactory());
- private final Supervisor supervisor = new Supervisor(new Transport());
+ private final Supervisor supervisor = new Supervisor(new Transport(JRT_TRANSPORT_THREADS));
private final ClientUpdater clientUpdater;
private ScheduledFuture<?> delayedResponseScheduler;
@@ -60,6 +59,7 @@ public class ProxyServer implements Runnable {
private static final double timingValuesRatio = 0.8;
private final static TimingValues defaultTimingValues;
private final boolean delayedResponseHandling;
+ private final FileDistributionAndUrlDownload fileDistributionAndUrlDownload;
private volatile Mode mode = new Mode(DEFAULT);
@@ -87,8 +87,7 @@ public class ProxyServer implements Runnable {
this.rpcServer = createRpcServer(spec);
clientUpdater = new ClientUpdater(rpcServer, statistics, delayedResponses);
this.configClient = createClient(clientUpdater, delayedResponses, source, timingValues, memoryCache, configClient);
- new FileDistributionRpcServer(supervisor, new FileDownloader(new JRTConnectionPool(source)));
- new UrlDownloadRpcServer(supervisor);
+ this.fileDistributionAndUrlDownload = new FileDistributionAndUrlDownload(supervisor, source);
}
static ProxyServer createTestServer(ConfigSourceSet source) {
@@ -266,6 +265,7 @@ public class ProxyServer implements Runnable {
if (statistics != null) {
statistics.stop();
}
+ fileDistributionAndUrlDownload.close();
}
MemoryCache getMemoryCache() {
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/filedistribution/FileDistributionAndUrlDownload.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/filedistribution/FileDistributionAndUrlDownload.java
new file mode 100644
index 00000000000..4eef3c40df4
--- /dev/null
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/filedistribution/FileDistributionAndUrlDownload.java
@@ -0,0 +1,32 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.proxy.filedistribution;
+
+import com.yahoo.config.subscription.ConfigSourceSet;
+import com.yahoo.jrt.Supervisor;
+import com.yahoo.vespa.config.JRTConnectionPool;
+import com.yahoo.vespa.filedistribution.FileDistributionRpcServer;
+import com.yahoo.vespa.filedistribution.FileDownloader;
+
+import java.util.stream.Stream;
+
+/**
+ * Keeps track of file distribution and url download rpc servers.
+ *
+ * @author hmusum
+ */
+public class FileDistributionAndUrlDownload {
+
+ private final FileDistributionRpcServer fileDistributionRpcServer;
+ private final UrlDownloadRpcServer urlDownloadRpcServer;
+
+ public FileDistributionAndUrlDownload(Supervisor supervisor, ConfigSourceSet source) {
+ fileDistributionRpcServer = new FileDistributionRpcServer(supervisor, new FileDownloader(new JRTConnectionPool(source)));
+ urlDownloadRpcServer = new UrlDownloadRpcServer(supervisor);
+ }
+
+ public void close() {
+ fileDistributionRpcServer.close();
+ urlDownloadRpcServer.close();
+ }
+
+}
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/UrlDownloadRpcServer.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/filedistribution/UrlDownloadRpcServer.java
index 711c43340cb..9d89f1d10b2 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/UrlDownloadRpcServer.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/filedistribution/UrlDownloadRpcServer.java
@@ -1,5 +1,5 @@
-// Copyright 2019 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.config.proxy;
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.proxy.filedistribution;
import com.yahoo.concurrent.DaemonThreadFactory;
import com.yahoo.jrt.Method;
@@ -26,6 +26,7 @@ import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import static com.yahoo.vespa.config.UrlDownloader.DOES_NOT_EXIST;
@@ -37,7 +38,7 @@ import static com.yahoo.vespa.config.UrlDownloader.INTERNAL_ERROR;
*
* @author lesters
*/
-public class UrlDownloadRpcServer {
+class UrlDownloadRpcServer {
private final static Logger log = Logger.getLogger(UrlDownloadRpcServer.class.getName());
private static final String CONTENTS_FILE_NAME = "contents";
@@ -45,7 +46,7 @@ public class UrlDownloadRpcServer {
private final File downloadBaseDir;
private final ExecutorService rpcDownloadExecutor = Executors.newFixedThreadPool(Math.max(8, Runtime.getRuntime().availableProcessors()),
- new DaemonThreadFactory("Rpc download executor"));
+ new DaemonThreadFactory("Rpc URL download executor"));
UrlDownloadRpcServer(Supervisor supervisor) {
supervisor.addMethod(new Method("url.waitFor", "s", "s", this::download)
@@ -55,6 +56,15 @@ public class UrlDownloadRpcServer {
downloadBaseDir = new File(Defaults.getDefaults().underVespaHome("var/db/vespa/download"));
}
+ void close() {
+ rpcDownloadExecutor.shutdownNow();
+ try {
+ rpcDownloadExecutor.awaitTermination(10, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private void download(Request req) {
req.detach();
rpcDownloadExecutor.execute(() -> downloadFile(req));
diff --git a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServerTest.java b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServerTest.java
index f32bb2ac024..48456d8ac23 100644
--- a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServerTest.java
+++ b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServerTest.java
@@ -2,40 +2,46 @@
package com.yahoo.vespa.config.proxy;
import com.yahoo.config.subscription.ConfigSourceSet;
+import com.yahoo.jrt.Acceptor;
+import com.yahoo.jrt.ListenFailedException;
import com.yahoo.jrt.Request;
import com.yahoo.jrt.Spec;
import com.yahoo.jrt.StringValue;
import com.yahoo.jrt.Supervisor;
+import com.yahoo.jrt.Target;
import com.yahoo.jrt.Transport;
import com.yahoo.vespa.config.RawConfig;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import java.time.Duration;
+
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
/**
* @author hmusum
- * @since 5.1.9
+ * @author bjorncs
*/
public class ConfigProxyRpcServerTest {
private static final String hostname = "localhost";
private static final int port = 12345;
private static final String address = "tcp/" + hostname + ":" + port;
- private ProxyServer proxyServer;
- private ConfigProxyRpcServer rpcServer;
+ private TestServer server;
+ private TestClient client;
@Before
- public void setup() {
- proxyServer = ProxyServer.createTestServer(new ConfigSourceSet(address));
- rpcServer = new ConfigProxyRpcServer(proxyServer, new Supervisor(new Transport()), null);
+ public void setup() throws ListenFailedException {
+ server = new TestServer();
+ client = new TestClient(server.listenPort());
}
@After
public void teardown() {
- rpcServer.shutdown();
+ client.close();
+ server.close();
}
@Test
@@ -52,7 +58,7 @@ public class ConfigProxyRpcServerTest {
@Test
public void testRpcMethodPing() {
Request req = new Request("ping");
- rpcServer.ping(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
@@ -65,7 +71,7 @@ public class ConfigProxyRpcServerTest {
@Test
public void testRpcMethodListCachedConfig() {
Request req = new Request("listCachedConfig");
- rpcServer.listCachedConfig(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
String[] ret = req.returnValues().get(0).asStringArray();
@@ -73,9 +79,9 @@ public class ConfigProxyRpcServerTest {
assertThat(ret.length, is(0));
final RawConfig config = ProxyServerTest.fooConfig;
- proxyServer.getMemoryCache().update(config);
+ server.proxyServer().getMemoryCache().update(config);
req = new Request("listCachedConfig");
- rpcServer.listCachedConfig(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
ret = req.returnValues().get(0).asStringArray();
@@ -92,7 +98,7 @@ public class ConfigProxyRpcServerTest {
@Test
public void testRpcMethodListCachedConfigFull() {
Request req = new Request("listCachedConfigFull");
- rpcServer.listCachedConfigFull(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
@@ -100,9 +106,9 @@ public class ConfigProxyRpcServerTest {
assertThat(ret.length, is(0));
final RawConfig config = ProxyServerTest.fooConfig;
- proxyServer.getMemoryCache().update(config);
+ server.proxyServer().getMemoryCache().update(config);
req = new Request("listCachedConfigFull");
- rpcServer.listCachedConfigFull(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
ret = req.returnValues().get(0).asStringArray();
assertThat(ret.length, is(1));
@@ -119,7 +125,7 @@ public class ConfigProxyRpcServerTest {
@Test
public void testRpcMethodListSourceConnections() {
Request req = new Request("listSourceConnections");
- rpcServer.listSourceConnections(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
@@ -135,7 +141,7 @@ public class ConfigProxyRpcServerTest {
@Test
public void testRpcMethodPrintStatistics() {
Request req = new Request("printStatistics");
- rpcServer.printStatistics(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
assertThat(req.returnValues().get(0).asString(), is("\n" +
@@ -149,7 +155,7 @@ public class ConfigProxyRpcServerTest {
@Test
public void testRpcMethodInvalidateCache() {
Request req = new Request("invalidateCache");
- rpcServer.invalidateCache(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
@@ -165,7 +171,7 @@ public class ConfigProxyRpcServerTest {
@Test
public void testRpcMethodGetModeAndSetMode() {
Request req = new Request("getMode");
- rpcServer.getMode(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
assertThat(req.returnValues().get(0).asString(), is("default"));
@@ -173,17 +179,17 @@ public class ConfigProxyRpcServerTest {
req = new Request("setMode");
String mode = "memorycache";
req.parameters().add(new StringValue(mode));
- rpcServer.setMode(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
String[] ret = req.returnValues().get(0).asStringArray();
assertThat(ret.length, is(2));
assertThat(ret[0], is("0"));
assertThat(ret[1], is("success"));
- assertThat(proxyServer.getMode().name(), is(mode));
+ assertThat(server.proxyServer().getMode().name(), is(mode));
req = new Request("getMode");
- rpcServer.getMode(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
assertThat(req.returnValues().get(0).asString(), is(mode));
@@ -192,14 +198,14 @@ public class ConfigProxyRpcServerTest {
String oldMode = mode;
mode = "invalid";
req.parameters().add(new StringValue(mode));
- rpcServer.setMode(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
ret = req.returnValues().get(0).asStringArray();
assertThat(ret.length, is(2));
assertThat(ret[0], is("1"));
assertThat(ret[1], is("Could not set mode to '" + mode + "'. Legal modes are '" + Mode.modes() + "'"));
- assertThat(proxyServer.getMode().name(), is(oldMode));
+ assertThat(server.proxyServer().getMode().name(), is(oldMode));
}
/**
@@ -211,17 +217,17 @@ public class ConfigProxyRpcServerTest {
String spec1 = "tcp/a:19070";
String spec2 = "tcp/b:19070";
req.parameters().add(new StringValue(spec1 + "," + spec2));
- rpcServer.updateSources(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
assertThat(req.returnValues().get(0).asString(), is("Updated config sources to: " + spec1 + "," + spec2));
- proxyServer.setMode(Mode.ModeName.MEMORYCACHE.name());
+ server.proxyServer().setMode(Mode.ModeName.MEMORYCACHE.name());
req = new Request("updateSources");
req.parameters().add(new StringValue(spec1 + "," + spec2));
- rpcServer.updateSources(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
assertThat(req.returnValues().get(0).asString(), is("Cannot update sources when in '" + Mode.ModeName.MEMORYCACHE.name().toLowerCase() + "' mode"));
@@ -245,10 +251,59 @@ public class ConfigProxyRpcServerTest {
Request req = new Request("dumpCache");
String path = "/tmp";
req.parameters().add(new StringValue(path));
- rpcServer.dumpCache(req);
+ client.invoke(req);
assertFalse(req.errorMessage(), req.isError());
assertThat(req.returnValues().size(), is(1));
assertThat(req.returnValues().get(0).asString(), is("success"));
}
+ private static class TestServer implements AutoCloseable {
+
+ private static final Spec SPEC = new Spec(0);
+
+ private final ProxyServer proxyServer = ProxyServer.createTestServer(new ConfigSourceSet(address));
+ private final Supervisor supervisor = new Supervisor(new Transport());
+ private final ConfigProxyRpcServer rpcServer = new ConfigProxyRpcServer(proxyServer, supervisor, SPEC);
+ private final Acceptor acceptor;
+
+ TestServer() throws ListenFailedException {
+ acceptor = supervisor.listen(SPEC);
+ }
+
+ ProxyServer proxyServer() {
+ return proxyServer;
+ }
+
+ int listenPort() {
+ return acceptor.port();
+ }
+
+ @Override
+ public void close() {
+ acceptor.shutdown().join();
+ supervisor.transport().shutdown().join();
+ rpcServer.shutdown();
+ }
+ }
+
+ private static class TestClient implements AutoCloseable {
+
+ private final Supervisor supervisor;
+ private final Target target;
+
+ TestClient(int rpcPort) {
+ this.supervisor = new Supervisor(new Transport());
+ this.target = supervisor.connect(new Spec(rpcPort));
+ }
+
+ void invoke(Request request) {
+ target.invokeSync(request, Duration.ofMinutes(10).getSeconds());
+ }
+
+ @Override
+ public void close() {
+ target.close();
+ supervisor.transport().shutdown().join();
+ }
+ }
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/EndpointList.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/EndpointList.java
index feedc1c8f9d..d9aea783880 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/EndpointList.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/EndpointList.java
@@ -25,13 +25,6 @@ public class EndpointList {
private final List<Endpoint> endpoints;
private EndpointList(List<Endpoint> endpoints) {
- long mainEndpoints = endpoints.stream()
- .filter(endpoint -> endpoint.scope() == Endpoint.Scope.global)
- .filter(Predicate.not(Endpoint::directRouting))
- .filter(Predicate.not(Endpoint::legacy)).count();
- if (mainEndpoints > 1) {
- throw new IllegalArgumentException("Can have only 1 non-legacy global endpoint, got " + endpoints);
- }
if (endpoints.stream().distinct().count() != endpoints.size()) {
throw new IllegalArgumentException("Expected all endpoints to be distinct, got " + endpoints);
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java
index cd7c0d6236d..b34ea79c670 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java
@@ -6,26 +6,26 @@ import com.yahoo.component.Version;
import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.zone.ZoneId;
import com.yahoo.container.jdisc.HttpResponse;
import com.yahoo.slime.Cursor;
import com.yahoo.slime.Slime;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.Controller;
import com.yahoo.vespa.hosted.controller.NotExistsException;
+import com.yahoo.vespa.hosted.controller.api.integration.LogEntry;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.JobType;
import com.yahoo.vespa.hosted.controller.api.integration.deployment.RunId;
-import com.yahoo.config.provision.zone.ZoneId;
-import com.yahoo.vespa.hosted.controller.api.integration.deployment.ApplicationVersion;
+import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
import com.yahoo.vespa.hosted.controller.application.Change;
import com.yahoo.vespa.hosted.controller.application.Deployment;
import com.yahoo.vespa.hosted.controller.application.JobStatus;
-import com.yahoo.vespa.hosted.controller.api.integration.deployment.SourceRevision;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentSteps;
import com.yahoo.vespa.hosted.controller.deployment.JobController;
-import com.yahoo.vespa.hosted.controller.api.integration.LogEntry;
-import com.yahoo.vespa.hosted.controller.deployment.RunLog;
import com.yahoo.vespa.hosted.controller.deployment.Run;
+import com.yahoo.vespa.hosted.controller.deployment.RunLog;
import com.yahoo.vespa.hosted.controller.deployment.Step;
import com.yahoo.vespa.hosted.controller.deployment.Versions;
import com.yahoo.vespa.hosted.controller.restapi.MessageResponse;
@@ -94,14 +94,14 @@ class JobControllerApiHandlerHelper {
Slime slime = new Slime();
Cursor responseObject = slime.setObject();
+ Cursor lastVersionsObject = responseObject.setObject("lastVersions");
if (application.deploymentJobs().statusOf(component).flatMap(JobStatus::lastSuccess).isPresent()) {
- Cursor lastVersionsObject = responseObject.setObject("lastVersions");
lastPlatformToSlime(lastVersionsObject.setObject("platform"), controller, application, change, steps);
lastApplicationToSlime(lastVersionsObject.setObject("application"), application, change, steps, controller);
}
+ Cursor deployingObject = responseObject.setObject("deploying");
if ( ! change.isEmpty()) {
- Cursor deployingObject = responseObject.setObject("deploying");
change.platform().ifPresent(version -> deployingObject.setString("platform", version.toString()));
change.application().ifPresent(version -> applicationVersionToSlime(deployingObject.setObject("application"), version));
}
@@ -141,7 +141,7 @@ class JobControllerApiHandlerHelper {
&& type.environment().isManuallyDeployed()
&& application.deployments().containsKey(type.zone(controller.system())))
controller.jobController().last(application.id(), type)
- .ifPresent(last -> runToSlime(devJobsObject.setObject(type.jobName()),
+ .ifPresent(last -> runToSlime(devJobsObject.setObject(type.jobName()).setArray("runs").addObject(),
last,
baseUriForJobs.resolve(baseUriForJobs.getPath() + "/" + type.jobName()).normalize()));
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-overview.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-overview.json
index c845d31a5fc..93b6138d987 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-overview.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/dev-overview.json
@@ -1,25 +1,31 @@
{
+ "lastVersions": {},
+ "deploying": {},
"deployments": [],
"jobs": {},
"devJobs": {
"dev-us-east-1": {
- "id": 1,
- "status": "success",
- "start": 0,
- "end": 0,
- "wantedPlatform": "6.1",
- "wantedApplication": {
- "hash": "unknown"
- },
- "steps": {
- "deployReal": "succeeded",
- "installReal": "succeeded"
- },
- "tasks": {
- "deploy": "succeeded",
- "install": "succeeded"
- },
- "log": "https://some.url:43/root/dev-us-east-1/run/1"
+ "runs": [
+ {
+ "id": 1,
+ "status": "success",
+ "start": 0,
+ "end": 0,
+ "wantedPlatform": "6.1",
+ "wantedApplication": {
+ "hash": "unknown"
+ },
+ "steps": {
+ "deployReal": "succeeded",
+ "installReal": "succeeded"
+ },
+ "tasks": {
+ "deploy": "succeeded",
+ "install": "succeeded"
+ },
+ "log": "https://some.url:43/root/dev-us-east-1/run/1"
+ }
+ ]
}
}
}
diff --git a/docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/metrics/DimensionMetrics.java b/docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/metrics/DimensionMetrics.java
index 46a0f9b9b10..590ef207e3f 100644
--- a/docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/metrics/DimensionMetrics.java
+++ b/docker-api/src/main/java/com/yahoo/vespa/hosted/dockerapi/metrics/DimensionMetrics.java
@@ -1,22 +1,15 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.dockerapi.metrics;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.TreeMap;
import java.util.stream.Collectors;
/**
* @author freva
*/
public class DimensionMetrics {
- private static final ObjectMapper objectMapper = new ObjectMapper();
- private static final Map<String, Object> routing = Map.of("yamas", Map.of("namespaces", List.of("Vespa")));
private final String application;
private final Dimensions dimensions;
@@ -30,17 +23,6 @@ public class DimensionMetrics {
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
- public String toSecretAgentReport() throws JsonProcessingException {
- Map<String, Object> report = new TreeMap<>();
- report.put("application", application);
- report.put("dimensions", new TreeMap<>(dimensions.asMap()));
- report.put("metrics", new TreeMap<>(metrics));
- report.put("routing", routing);
- report.put("timestamp", System.currentTimeMillis() / 1000);
-
- return objectMapper.writeValueAsString(report);
- }
-
public String getApplication() {
return application;
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.h b/eval/src/vespa/eval/tensor/dense/dense_generic_join.h
index cd524b27171..daf678d4916 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.h
+++ b/eval/src/vespa/eval/tensor/dense/dense_generic_join.h
@@ -15,10 +15,10 @@ namespace vespalib::tensor::dense {
*/
template <typename Function>
std::unique_ptr<Tensor>
-apply(const DenseTensorView &lhs, const Tensor &rhs, Function &&func);
+generic_join(const DenseTensorView &lhs, const Tensor &rhs, Function &&func);
template <typename Function>
std::unique_ptr<Tensor>
-apply(const DenseTensorView &lhs, const DenseTensorView &rhs, Function &&func);
+generic_join(const DenseTensorView &lhs, const DenseTensorView &rhs, Function &&func);
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp b/eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp
index 409e1ad087f..aa08e6982bb 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_apply.hpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_generic_join.hpp
@@ -2,7 +2,7 @@
#pragma once
-#include "dense_tensor_apply.h"
+#include "dense_generic_join.h"
#include "dense_dimension_combiner.h"
#include "typed_dense_tensor_builder.h"
@@ -10,14 +10,14 @@ namespace vespalib::tensor::dense {
template <typename LCT, typename RCT, typename OCT, typename Function>
std::unique_ptr<Tensor>
-apply(DenseDimensionCombiner & combiner,
+generic_join(DenseDimensionCombiner & combiner,
TypedDenseTensorBuilder<OCT> & builder,
const ConstArrayRef<LCT> & lhsCells,
const ConstArrayRef<RCT> & rhsCells, Function &&func) __attribute__((noinline));
template <typename LCT, typename RCT, typename OCT, typename Function>
std::unique_ptr<Tensor>
-apply(DenseDimensionCombiner & combiner,
+generic_join(DenseDimensionCombiner & combiner,
TypedDenseTensorBuilder<OCT> & builder,
const ConstArrayRef<LCT> & lhsCells,
const ConstArrayRef<RCT> & rhsCells, Function &&func)
@@ -35,7 +35,7 @@ apply(DenseDimensionCombiner & combiner,
return builder.build();
}
-struct CallApply {
+struct CallGenericJoin {
template <typename LCT, typename RCT, typename Function>
static std::unique_ptr<Tensor>
call(const ConstArrayRef<LCT> & lhsArr,
@@ -45,20 +45,20 @@ struct CallApply {
{
using OCT = typename OutputCellType<LCT, RCT>::output_type;
TypedDenseTensorBuilder<OCT> builder(combiner.result_type);
- return apply(combiner, builder, lhsArr, rhsArr, std::move(func));
+ return generic_join(combiner, builder, lhsArr, rhsArr, std::move(func));
}
};
template <typename Function>
std::unique_ptr<Tensor>
-apply(const DenseTensorView &lhs, const Tensor &rhs, Function &&func)
+generic_join(const DenseTensorView &lhs, const Tensor &rhs, Function &&func)
{
const DenseTensorView *view = dynamic_cast<const DenseTensorView *>(&rhs);
if (view) {
DenseDimensionCombiner combiner(lhs.fast_type(), view->fast_type());
TypedCells lhsCells = lhs.cellsRef();
TypedCells rhsCells = view->cellsRef();
- return dispatch_2<CallApply>(lhsCells, rhsCells, combiner, std::move(func));
+ return dispatch_2<CallGenericJoin>(lhsCells, rhsCells, combiner, std::move(func));
}
return Tensor::UP();
}
diff --git a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp
index 1ae198d1171..d98cf52d279 100644
--- a/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp
+++ b/eval/src/vespa/eval/tensor/dense/dense_tensor_view.cpp
@@ -1,7 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "dense_tensor_view.h"
-#include "dense_tensor_apply.hpp"
+#include "dense_generic_join.hpp"
#include "dense_tensor_reduce.hpp"
#include "dense_tensor_modify.h"
#include <vespa/vespalib/util/stringfmt.h>
@@ -302,12 +302,12 @@ DenseTensorView::join(join_fun_t function, const Tensor &arg) const
return joinDenseTensors(*this, arg, "join", function);
}
if (function == eval::operation::Mul::f) {
- return dense::apply(*this, arg, [](double a, double b) { return (a * b); });
+ return dense::generic_join(*this, arg, [](double a, double b) { return (a * b); });
}
if (function == eval::operation::Add::f) {
- return dense::apply(*this, arg, [](double a, double b) { return (a + b); });
+ return dense::generic_join(*this, arg, [](double a, double b) { return (a + b); });
}
- return dense::apply(*this, arg, function);
+ return dense::generic_join(*this, arg, function);
}
Tensor::UP
diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java
index d27d7422beb..cc76eef014f 100644
--- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java
+++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java
@@ -18,6 +18,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -41,6 +42,15 @@ public class FileDistributionRpcServer {
declareFileDistributionMethods();
}
+ public void close() {
+ rpcDownloadExecutor.shutdownNow();
+ try {
+ rpcDownloadExecutor.awaitTermination(10, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private void declareFileDistributionMethods() {
// Legacy method, needs to be the same name as used in filedistributor
supervisor.addMethod(new Method("waitFor", "s", "s", this::getFile)
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/ConfigServerInfo.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/ConfigServerInfo.java
index 1811fc0c8f0..d515f0d0353 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/ConfigServerInfo.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/ConfigServerInfo.java
@@ -2,7 +2,6 @@
package com.yahoo.vespa.hosted.node.admin.component;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
-import com.yahoo.vespa.athenz.api.AthenzService;
import java.net.URI;
import java.util.Collections;
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/docker/DockerOperationsImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/docker/DockerOperationsImpl.java
index d8d6b4781c8..91fcdc89da3 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/docker/DockerOperationsImpl.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/docker/DockerOperationsImpl.java
@@ -42,8 +42,8 @@ public class DockerOperationsImpl implements DockerOperations {
private static final String MANAGER_NAME = "node-admin";
- private static final String IPV6_NPT_PREFIX = "fd00::";
- private static final String IPV4_NPT_PREFIX = "172.17.0.0";
+ private static final InetAddress IPV6_NPT_PREFIX = InetAddresses.forString("fd00::");
+ private static final InetAddress IPV4_NPT_PREFIX = InetAddresses.forString("172.17.0.0");
private final Docker docker;
private final ProcessExecuter processExecuter;
@@ -96,16 +96,12 @@ public class DockerOperationsImpl implements DockerOperations {
command.withNetworkMode(networking.getDockerNetworkMode());
if (networking == DockerNetworking.NPT) {
- InetAddress ipV6Prefix = InetAddresses.forString(IPV6_NPT_PREFIX);
- InetAddress ipV6Local = IPAddresses.prefixTranslate(ipV6Address, ipV6Prefix, 8);
+ InetAddress ipV6Local = IPAddresses.prefixTranslate(ipV6Address, IPV6_NPT_PREFIX, 8);
command.withIpAddress(ipV6Local);
// IPv4 - Only present for some containers
Optional<InetAddress> ipV4Local = ipAddresses.getIPv4Address(context.node().hostname())
- .map(ipV4Address -> {
- InetAddress ipV4Prefix = InetAddresses.forString(IPV4_NPT_PREFIX);
- return IPAddresses.prefixTranslate(ipV4Address, ipV4Prefix, 2);
- });
+ .map(ipV4Address -> IPAddresses.prefixTranslate(ipV4Address, IPV4_NPT_PREFIX, 2));
ipV4Local.ifPresent(command::withIpAddress);
addEtcHosts(containerData, context.node().hostname(), ipV4Local, ipV6Local);
@@ -303,7 +299,6 @@ public class DockerOperationsImpl implements DockerOperations {
context.pathInNodeUnderVespaHome("var/maven"),
context.pathInNodeUnderVespaHome("var/mediasearch"), // TODO: Remove when vespa-routing is no more
context.pathInNodeUnderVespaHome("var/run"),
- context.pathInNodeUnderVespaHome("var/scoreboards"),
context.pathInNodeUnderVespaHome("var/service"),
context.pathInNodeUnderVespaHome("var/share"),
context.pathInNodeUnderVespaHome("var/spool"),
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java
index 26e4dcda88e..167ca15bdbf 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainer.java
@@ -3,17 +3,14 @@ package com.yahoo.vespa.hosted.node.admin.maintenance;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
-import com.yahoo.config.provision.NodeType;
import com.yahoo.log.LogLevel;
import com.yahoo.vespa.hosted.dockerapi.Container;
import com.yahoo.vespa.hosted.node.admin.component.TaskContext;
-import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations;
import com.yahoo.vespa.hosted.node.admin.maintenance.coredump.CoredumpHandler;
import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContext;
import com.yahoo.vespa.hosted.node.admin.task.util.file.FileFinder;
import com.yahoo.vespa.hosted.node.admin.task.util.file.UnixPath;
import com.yahoo.vespa.hosted.node.admin.task.util.process.Terminal;
-import com.yahoo.vespa.hosted.node.admin.util.SecretAgentCheckConfig;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -22,11 +19,8 @@ import java.time.Duration;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@@ -35,7 +29,6 @@ import java.util.regex.Pattern;
import static com.yahoo.vespa.hosted.node.admin.task.util.file.FileFinder.nameMatches;
import static com.yahoo.vespa.hosted.node.admin.task.util.file.FileFinder.olderThan;
-import static com.yahoo.vespa.hosted.node.admin.util.SecretAgentCheckConfig.nodeTypeToRole;
import static com.yahoo.yolean.Exceptions.uncheck;
/**
@@ -47,7 +40,6 @@ public class StorageMaintainer {
.ofPattern("yyyyMMddHHmmss").withZone(ZoneOffset.UTC);
private final Terminal terminal;
- private final DockerOperations dockerOperations;
private final CoredumpHandler coredumpHandler;
private final Path archiveContainerStoragePath;
@@ -57,134 +49,12 @@ public class StorageMaintainer {
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
- public StorageMaintainer(Terminal terminal, DockerOperations dockerOperations, CoredumpHandler coredumpHandler, Path archiveContainerStoragePath) {
+ public StorageMaintainer(Terminal terminal, CoredumpHandler coredumpHandler, Path archiveContainerStoragePath) {
this.terminal = terminal;
- this.dockerOperations = dockerOperations;
this.coredumpHandler = coredumpHandler;
this.archiveContainerStoragePath = archiveContainerStoragePath;
}
- public void writeMetricsConfig(NodeAgentContext context) {
- List<SecretAgentCheckConfig> configs = new ArrayList<>();
- Map<String, Object> tags = generateTags(context);
-
- // host-life
- Path hostLifeCheckPath = context.pathInNodeUnderVespaHome("libexec/yms/yms_check_host_life");
- configs.add(new SecretAgentCheckConfig("host-life", 60, hostLifeCheckPath).withTags(tags));
-
- // coredumps (except for the done coredumps which is handled by the host)
- Path coredumpCheckPath = context.pathInNodeUnderVespaHome("libexec/yms/yms_check_coredumps");
- configs.add(new SecretAgentCheckConfig("system-coredumps-processing", 300, coredumpCheckPath,
- "--application", "system-coredumps-processing",
- "--lastmin", "129600",
- "--crit", "1",
- "--coredir", context.pathInNodeUnderVespaHome("var/crash/processing").toString())
- .withTags(tags));
-
- // athenz certificate check
- Path athenzCertExpiryCheckPath = context.pathInNodeUnderVespaHome("libexec64/yms/yms_check_athenz_certs");
- configs.add(new SecretAgentCheckConfig("athenz-certificate-expiry", 60, athenzCertExpiryCheckPath,
- "--threshold", "20")
- .withRunAsUser("root")
- .withTags(tags));
-
- if (context.nodeType() != NodeType.config) {
- // vespa-health
- Path vespaHealthCheckPath = context.pathInNodeUnderVespaHome("libexec/yms/yms_check_vespa_health");
- configs.add(new SecretAgentCheckConfig("vespa-health", 60, vespaHealthCheckPath, "all")
- .withRunAsUser(context.vespaUser())
- .withTags(tags));
-
- // vespa
- Path vespaCheckPath = context.pathInNodeUnderVespaHome("libexec/yms/yms_check_vespa");
- SecretAgentCheckConfig vespaSchedule = new SecretAgentCheckConfig("vespa", 60, vespaCheckPath, "all");
- vespaSchedule.withRunAsUser(context.vespaUser());
- if (isConfigserverLike(context.nodeType())) {
- Map<String, Object> tagsWithoutNameSpace = new LinkedHashMap<>(tags);
- tagsWithoutNameSpace.remove("namespace");
- vespaSchedule.withTags(tagsWithoutNameSpace);
- }
- configs.add(vespaSchedule);
- }
-
- if (context.nodeType() == NodeType.config || context.nodeType() == NodeType.controller) {
-
- // configserver/controller
- Path configServerNewCheckPath = Paths.get("/usr/bin/curl");
- configs.add(new SecretAgentCheckConfig(nodeTypeToRole(context.nodeType()), 60, configServerNewCheckPath,
- "-s", "localhost:19071/yamas-metrics")
- .withTags(tags));
-
- //zkbackupage
- Path zkbackupCheckPath = context.pathInNodeUnderVespaHome("libexec/yamas2/yms_check_file_age.py");
- configs.add(new SecretAgentCheckConfig("zkbackupage", 300, zkbackupCheckPath,
- "-f", context.pathInNodeUnderVespaHome("var/vespa-hosted/zkbackup.stat").toString(),
- "-m", "150",
- "-a", "config-zkbackupage")
- .withTags(tags));
-
- String appName = nodeTypeToRole(context.nodeType()) + "-logd";
- Path logdCheckPath = context.pathInNodeUnderVespaHome("libexec/yms/convert-state-metrics-2-yamas.py");
- configs.add(new SecretAgentCheckConfig(appName, 60, logdCheckPath,
- appName, "http://localhost:19089/state/v1/metrics")
- .withTags(tags));
- }
-
- if (context.nodeType() == NodeType.proxy) {
- //routing-configage
- Path routingAgeCheckPath = context.pathInNodeUnderVespaHome("libexec/yamas2/yms_check_file_age.py");
- configs.add(new SecretAgentCheckConfig("routing-configage", 60, routingAgeCheckPath,
- "-f", context.pathInNodeUnderVespaHome("var/vespa-hosted/routing/nginx.conf.tmp").toString(),
- "-m", "1",
- "-a", "routing-configage",
- "--ignore_file_not_found")
- .withTags(tags));
-
- //ssl-check
- Path sslCheckPath = context.pathInNodeUnderVespaHome("libexec/yms/yms_check_ssl_status");
- configs.add(new SecretAgentCheckConfig("ssl-status", 300, sslCheckPath,
- "-e", "localhost",
- "-p", "4443",
- "-t", "30")
- .withTags(tags));
- }
-
- // Write config and restart yamas-agent
- Path yamasAgentFolder = context.pathOnHostFromPathInNode("/etc/yamas-agent");
- configs.forEach(s -> uncheck(() -> s.writeTo(yamasAgentFolder)));
- dockerOperations.executeCommandInContainerAsRoot(context, "service", "yamas-agent", "restart");
- }
-
- private Map<String, Object> generateTags(NodeAgentContext context) {
- Map<String, String> tags = new LinkedHashMap<>();
- tags.put("namespace", "Vespa");
- tags.put("role", nodeTypeToRole(context.node().type()));
- tags.put("zone", context.zone().getId().value());
- context.node().currentVespaVersion().ifPresent(version -> tags.put("vespaVersion", version.toFullString()));
-
- if (! isConfigserverLike(context.nodeType())) {
- tags.put("state", context.node().state().toString());
- context.node().parentHostname().ifPresent(parent -> tags.put("parentHostname", parent));
- context.node().owner().ifPresent(owner -> {
- tags.put("tenantName", owner.tenant());
- tags.put("app", owner.application() + "." + owner.instance());
- tags.put("applicationName", owner.application());
- tags.put("instanceName", owner.instance());
- tags.put("applicationId", owner.tenant() + "." + owner.application() + "." + owner.instance());
- });
- context.node().membership().ifPresent(membership -> {
- tags.put("clustertype", membership.clusterType());
- tags.put("clusterid", membership.clusterId());
- });
- }
-
- return Collections.unmodifiableMap(tags);
- }
-
- private boolean isConfigserverLike(NodeType nodeType) {
- return nodeType == NodeType.config || nodeType == NodeType.controller;
- }
-
public Optional<Long> getDiskUsageFor(NodeAgentContext context) {
try {
Path path = context.pathOnHostFromPathInNode("/");
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java
index 550d6e7021e..ce7a99fd841 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/maintenance/identity/AthenzCredentialsMaintainer.java
@@ -9,7 +9,6 @@ import com.yahoo.security.Pkcs10Csr;
import com.yahoo.security.SslContextBuilder;
import com.yahoo.security.X509CertificateUtils;
import com.yahoo.vespa.athenz.api.AthenzIdentity;
-import com.yahoo.vespa.athenz.api.AthenzService;
import com.yahoo.vespa.athenz.client.zts.DefaultZtsClient;
import com.yahoo.vespa.athenz.client.zts.InstanceIdentity;
import com.yahoo.vespa.athenz.client.zts.ZtsClient;
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImpl.java
index cb10eac9e6c..5d2639d0a77 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImpl.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminImpl.java
@@ -149,7 +149,7 @@ public class NodeAdminImpl implements NodeAdmin {
@Override
public Duration subsystemFreezeDuration() {
if (startOfFreezeConvergence == null) {
- return Duration.ofSeconds(0);
+ return Duration.ZERO;
} else {
return Duration.between(startOfFreezeConvergence, clock.instant());
}
@@ -172,7 +172,7 @@ public class NodeAdminImpl implements NodeAdmin {
@Override
public void stop() {
// Stop all node-agents in parallel, will block until the last NodeAgent is stopped
- nodeAgentWithSchedulerByHostname.values().parallelStream().forEach(NodeAgent::stopForRemoval);
+ nodeAgentWithSchedulerByHostname.values().parallelStream().forEach(NodeAgentWithScheduler::stopForRemoval);
}
// Set-difference. Returns minuend minus subtrahend.
@@ -182,7 +182,7 @@ public class NodeAdminImpl implements NodeAdmin {
return result;
}
- static class NodeAgentWithScheduler implements NodeAgent, NodeAgentScheduler {
+ static class NodeAgentWithScheduler implements NodeAgentScheduler {
private final NodeAgent nodeAgent;
private final NodeAgentScheduler nodeAgentScheduler;
@@ -191,14 +191,15 @@ public class NodeAdminImpl implements NodeAdmin {
this.nodeAgentScheduler = nodeAgentScheduler;
}
- @Override public void start() { nodeAgent.start(); }
- @Override public void stopForHostSuspension() { nodeAgent.stopForHostSuspension(); }
- @Override public void stopForRemoval() { nodeAgent.stopForRemoval(); }
- @Override public void updateContainerNodeMetrics() { nodeAgent.updateContainerNodeMetrics(); }
- @Override public int getAndResetNumberOfUnhandledExceptions() { return nodeAgent.getAndResetNumberOfUnhandledExceptions(); }
+ void start() { nodeAgent.start(currentContext()); }
+ void stopForHostSuspension() { nodeAgent.stopForHostSuspension(currentContext()); }
+ void stopForRemoval() { nodeAgent.stopForRemoval(currentContext()); }
+ void updateContainerNodeMetrics() { nodeAgent.updateContainerNodeMetrics(currentContext()); }
+ int getAndResetNumberOfUnhandledExceptions() { return nodeAgent.getAndResetNumberOfUnhandledExceptions(); }
@Override public void scheduleTickWith(NodeAgentContext context, Instant at) { nodeAgentScheduler.scheduleTickWith(context, at); }
@Override public boolean setFrozen(boolean frozen, Duration timeout) { return nodeAgentScheduler.setFrozen(frozen, timeout); }
+ @Override public NodeAgentContext currentContext() { return nodeAgentScheduler.currentContext(); }
}
@FunctionalInterface
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgent.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgent.java
index de5ee1b69a4..f537884e708 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgent.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgent.java
@@ -13,24 +13,24 @@ public interface NodeAgent {
* Starts the agent. After this method is called, the agent will asynchronously maintain the node, continuously
* striving to make the current state equal to the wanted state.
*/
- void start();
+ void start(NodeAgentContext context);
/**
* Stop the node in anticipation of host suspension, e.g. reboot or docker upgrade.
*/
- void stopForHostSuspension();
+ void stopForHostSuspension(NodeAgentContext context);
/**
* Signals to the agent that the node is at the end of its lifecycle and no longer needs a managing agent.
* Cleans up any resources the agent owns, such as threads, connections etc. Cleanup is synchronous; when this
* method returns, no more actions will be taken by the agent.
*/
- void stopForRemoval();
+ void stopForRemoval(NodeAgentContext context);
/**
* Updates metric receiver with the latest node-agent stats
*/
- void updateContainerNodeMetrics();
+ default void updateContainerNodeMetrics(NodeAgentContext context) {}
/**
* Returns and resets number of unhandled exceptions
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextSupplier.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextSupplier.java
index 1fc730a3cb0..65611886f9c 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextSupplier.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextSupplier.java
@@ -13,9 +13,6 @@ public interface NodeAgentContextSupplier {
*/
NodeAgentContext nextContext() throws InterruptedException;
- /** @return the last context returned by {@link #nextContext()} or a default value */
- NodeAgentContext currentContext();
-
/** Interrupts the thread(s) currently waiting in {@link #nextContext()} */
void interrupt();
}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java
index 90eda96d445..77c08133e82 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.node.admin.nodeagent;
-import com.fasterxml.jackson.core.JsonProcessingException;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.zone.ZoneApi;
@@ -12,13 +11,8 @@ import com.yahoo.vespa.flags.FlagSource;
import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.hosted.dockerapi.Container;
import com.yahoo.vespa.hosted.dockerapi.ContainerResources;
-import com.yahoo.vespa.hosted.dockerapi.ContainerStats;
import com.yahoo.vespa.hosted.dockerapi.exception.ContainerNotFoundException;
import com.yahoo.vespa.hosted.dockerapi.exception.DockerException;
-import com.yahoo.vespa.hosted.dockerapi.exception.DockerExecTimeoutException;
-import com.yahoo.vespa.hosted.dockerapi.metrics.DimensionMetrics;
-import com.yahoo.vespa.hosted.dockerapi.metrics.Dimensions;
-import com.yahoo.vespa.hosted.dockerapi.metrics.Metrics;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeAttributes;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeOwner;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository;
@@ -31,11 +25,8 @@ import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer;
import com.yahoo.vespa.hosted.node.admin.maintenance.acl.AclMaintainer;
import com.yahoo.vespa.hosted.node.admin.maintenance.identity.CredentialsMaintainer;
import com.yahoo.vespa.hosted.node.admin.nodeadmin.ConvergenceException;
-import com.yahoo.vespa.hosted.node.admin.util.SecretAgentCheckConfig;
import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -68,16 +59,16 @@ public class NodeAgentImpl implements NodeAgent {
private final Optional<CredentialsMaintainer> credentialsMaintainer;
private final Optional<AclMaintainer> aclMaintainer;
private final Optional<HealthChecker> healthChecker;
-
private final DoubleFlag containerCpuCap;
+ private Thread loopThread;
+ private ContainerState containerState = UNKNOWN;
+ private NodeSpec lastNode;
+
private int numberOfUnhandledException = 0;
private long currentRebootGeneration = 0;
private Optional<Long> currentRestartGeneration = Optional.empty();
- private final Thread loopThread;
-
-
/**
* ABSENT means container is definitely absent - A container that was absent will not suddenly appear without
* NodeAgent explicitly starting it.
@@ -92,10 +83,6 @@ public class NodeAgentImpl implements NodeAgent {
UNKNOWN
}
- private ContainerState containerState = UNKNOWN;
-
- private NodeSpec lastNode = null;
- private CpuUsageReporter lastCpuMetric = new CpuUsageReporter();
// Created in NodeAdminImpl
public NodeAgentImpl(
@@ -116,11 +103,15 @@ public class NodeAgentImpl implements NodeAgent {
this.credentialsMaintainer = credentialsMaintainer;
this.aclMaintainer = aclMaintainer;
this.healthChecker = healthChecker;
+ this.containerCpuCap = Flags.CONTAINER_CPU_CAP.bindTo(flagSource);
+ }
- this.containerCpuCap = Flags.CONTAINER_CPU_CAP.bindTo(flagSource)
- .with(FetchVector.Dimension.HOSTNAME, contextSupplier.currentContext().node().hostname());
+ @Override
+ public void start(NodeAgentContext initialContext) {
+ if (loopThread != null)
+ throw new IllegalStateException("Can not re-start a node agent.");
- this.loopThread = new Thread(() -> {
+ loopThread = new Thread(() -> {
while (!terminated.get()) {
try {
NodeAgentContext context = contextSupplier.nextContext();
@@ -128,19 +119,15 @@ public class NodeAgentImpl implements NodeAgent {
} catch (InterruptedException ignored) { }
}
});
- this.loopThread.setName("tick-" + contextSupplier.currentContext().hostname());
- }
-
- @Override
- public void start() {
+ loopThread.setName("tick-" + initialContext.hostname());
loopThread.start();
}
@Override
- public void stopForRemoval() {
- if (!terminated.compareAndSet(false, true)) {
- throw new RuntimeException("Can not re-stop a node agent.");
- }
+ public void stopForRemoval(NodeAgentContext context) {
+ if (!terminated.compareAndSet(false, true))
+ throw new IllegalStateException("Can not re-stop a node agent.");
+
contextSupplier.interrupt();
do {
@@ -149,7 +136,7 @@ public class NodeAgentImpl implements NodeAgent {
} catch (InterruptedException ignored) { }
} while (loopThread.isAlive());
- contextSupplier.currentContext().log(logger, "Stopped");
+ context.log(logger, "Stopped");
}
void startServicesIfNeeded(NodeAgentContext context) {
@@ -209,7 +196,6 @@ public class NodeAgentImpl implements NodeAgent {
ContainerData containerData = createContainerData(context);
dockerOperations.createContainer(context, containerData, getContainerResources(context));
dockerOperations.startContainer(context);
- lastCpuMetric = new CpuUsageReporter();
hasStartedServices = true; // Automatically started with the container
hasResumedNode = false;
@@ -255,8 +241,7 @@ public class NodeAgentImpl implements NodeAgent {
}
}
- private void stopServices() {
- NodeAgentContext context = contextSupplier.currentContext();
+ private void stopServices(NodeAgentContext context) {
context.log(logger, "Stopping services");
if (containerState == ABSENT) return;
try {
@@ -268,13 +253,11 @@ public class NodeAgentImpl implements NodeAgent {
}
@Override
- public void stopForHostSuspension() {
- NodeAgentContext context = contextSupplier.currentContext();
+ public void stopForHostSuspension(NodeAgentContext context) {
getContainer(context).ifPresent(container -> removeContainer(context, container, "suspending host", true));
}
- public void suspend() {
- NodeAgentContext context = contextSupplier.currentContext();
+ public void suspend(NodeAgentContext context) {
context.log(logger, "Suspending services on node");
if (containerState == ABSENT) return;
try {
@@ -331,9 +314,9 @@ public class NodeAgentImpl implements NodeAgent {
try {
if (context.node().state() != NodeState.dirty) {
- suspend();
+ suspend(context);
}
- stopServices();
+ stopServices(context);
} catch (Exception e) {
context.log(logger, LogLevel.WARNING, "Failed stopping services, ignoring", e);
}
@@ -365,6 +348,7 @@ public class NodeAgentImpl implements NodeAgent {
.map(NodeOwner::asApplicationId)
.map(appId -> containerCpuCap.with(FetchVector.Dimension.APPLICATION_ID, appId.serializedForm()))
.orElse(containerCpuCap)
+ .with(FetchVector.Dimension.HOSTNAME, context.node().hostname())
.value() * context.node().vcpus();
return ContainerResources.from(cpuCap, context.node().vcpus(), context.node().memoryGb());
@@ -415,12 +399,6 @@ public class NodeAgentImpl implements NodeAgent {
currentRestartGeneration.map(current -> current < node.currentRestartGeneration().get()).orElse(false))
currentRestartGeneration = node.currentRestartGeneration();
- // Every time the node spec changes, we should clear the metrics for this container as the dimensions
- // will change and we will be reporting duplicate metrics.
- if (container.map(c -> c.state.isRunning()).orElse(false)) {
- storageMaintainer.writeMetricsConfig(context);
- }
-
lastNode = node;
}
@@ -513,100 +491,6 @@ public class NodeAgentImpl implements NodeAgent {
}
}
- @SuppressWarnings("unchecked")
- public void updateContainerNodeMetrics() {
- if (containerState != UNKNOWN) return;
- final NodeAgentContext context = contextSupplier.currentContext();
- final NodeSpec node = context.node();
-
- Optional<ContainerStats> containerStats = dockerOperations.getContainerStats(context);
- if (!containerStats.isPresent()) return;
-
- Dimensions.Builder dimensionsBuilder = new Dimensions.Builder()
- .add("host", context.hostname().value())
- .add("role", SecretAgentCheckConfig.nodeTypeToRole(context.nodeType()))
- .add("state", node.state().toString());
- node.parentHostname().ifPresent(parent -> dimensionsBuilder.add("parentHostname", parent));
- node.allowedToBeDown().ifPresent(allowed ->
- dimensionsBuilder.add("orchestratorState", allowed ? "ALLOWED_TO_BE_DOWN" : "NO_REMARKS"));
- Dimensions dimensions = dimensionsBuilder.build();
-
- ContainerStats stats = containerStats.get();
- final String APP = Metrics.APPLICATION_NODE;
- final int totalNumCpuCores = stats.getCpuStats().getOnlineCpus();
- final long memoryTotalBytes = stats.getMemoryStats().getLimit();
- final long memoryTotalBytesUsage = stats.getMemoryStats().getUsage();
- final long memoryTotalBytesCache = stats.getMemoryStats().getCache();
- final long diskTotalBytes = (long) (node.diskGb() * BYTES_IN_GB);
- final Optional<Long> diskTotalBytesUsed = storageMaintainer.getDiskUsageFor(context);
-
- lastCpuMetric.updateCpuDeltas(stats.getCpuStats());
-
- // Ratio of CPU cores allocated to this container to total number of CPU cores on this host
- final double allocatedCpuRatio = node.vcpus() / totalNumCpuCores;
- double cpuUsageRatioOfAllocated = lastCpuMetric.getCpuUsageRatio() / allocatedCpuRatio;
- double cpuKernelUsageRatioOfAllocated = lastCpuMetric.getCpuKernelUsageRatio() / allocatedCpuRatio;
- double cpuThrottledTimeRate = lastCpuMetric.getThrottledTimeRate();
- double cpuThrottledCpuTimeRate = lastCpuMetric.getThrottledCpuTimeRate();
-
- long memoryTotalBytesUsed = memoryTotalBytesUsage - memoryTotalBytesCache;
- double memoryUsageRatio = (double) memoryTotalBytesUsed / memoryTotalBytes;
- double memoryTotalUsageRatio = (double) memoryTotalBytesUsage / memoryTotalBytes;
- Optional<Double> diskUsageRatio = diskTotalBytesUsed.map(used -> (double) used / diskTotalBytes);
-
- List<DimensionMetrics> metrics = new ArrayList<>();
- DimensionMetrics.Builder systemMetricsBuilder = new DimensionMetrics.Builder(APP, dimensions)
- .withMetric("mem.limit", memoryTotalBytes)
- .withMetric("mem.used", memoryTotalBytesUsed)
- .withMetric("mem.util", 100 * memoryUsageRatio)
- .withMetric("mem_total.used", memoryTotalBytesUsage)
- .withMetric("mem_total.util", 100 * memoryTotalUsageRatio)
- .withMetric("cpu.util", 100 * cpuUsageRatioOfAllocated)
- .withMetric("cpu.sys.util", 100 * cpuKernelUsageRatioOfAllocated)
- .withMetric("cpu.throttled_time.rate", cpuThrottledTimeRate)
- .withMetric("cpu.throttled_cpu_time.rate", cpuThrottledCpuTimeRate)
- .withMetric("cpu.vcpus", node.vcpus())
- .withMetric("disk.limit", diskTotalBytes);
-
- diskTotalBytesUsed.ifPresent(diskUsed -> systemMetricsBuilder.withMetric("disk.used", diskUsed));
- diskUsageRatio.ifPresent(diskRatio -> systemMetricsBuilder.withMetric("disk.util", 100 * diskRatio));
- metrics.add(systemMetricsBuilder.build());
-
- stats.getNetworks().forEach((interfaceName, interfaceStats) -> {
- Dimensions netDims = dimensionsBuilder.add("interface", interfaceName).build();
- DimensionMetrics networkMetrics = new DimensionMetrics.Builder(APP, netDims)
- .withMetric("net.in.bytes", interfaceStats.getRxBytes())
- .withMetric("net.in.errors", interfaceStats.getRxErrors())
- .withMetric("net.in.dropped", interfaceStats.getRxDropped())
- .withMetric("net.out.bytes", interfaceStats.getTxBytes())
- .withMetric("net.out.errors", interfaceStats.getTxErrors())
- .withMetric("net.out.dropped", interfaceStats.getTxDropped())
- .build();
- metrics.add(networkMetrics);
- });
-
- pushMetricsToContainer(context, metrics);
- }
-
- private void pushMetricsToContainer(NodeAgentContext context, List<DimensionMetrics> metrics) {
- StringBuilder params = new StringBuilder();
- try {
- for (DimensionMetrics dimensionMetrics : metrics) {
- params.append(dimensionMetrics.toSecretAgentReport());
- }
- String wrappedMetrics = "s:" + params.toString();
-
- // Push metrics to the metrics proxy in each container.
- // TODO Remove port selection logic when all hosted apps have upgraded to Vespa 7.
- int port = context.node().currentVespaVersion().map(version -> version.getMajor() == 6).orElse(false) ? 19091 : 19095;
- String[] command = {"vespa-rpc-invoke", "-t", "2", "tcp/localhost:" + port, "setExtraMetrics", wrappedMetrics};
- dockerOperations.executeCommandInContainerAsRoot(context, 5L, command);
- } catch (JsonProcessingException | DockerExecTimeoutException e) {
- context.log(logger, LogLevel.WARNING, "Failed to push metrics to container", e);
- }
-
- }
-
private Optional<Container> getContainer(NodeAgentContext context) {
if (containerState == ABSENT) return Optional.empty();
Optional<Container> container = dockerOperations.getContainer(context);
@@ -621,66 +505,6 @@ public class NodeAgentImpl implements NodeAgent {
return temp;
}
- class CpuUsageReporter {
- private static final double PERIOD_IN_NANOSECONDS = 1_000d * ContainerResources.CPU_PERIOD_US;
- private long containerKernelUsage = 0;
- private long totalContainerUsage = 0;
- private long totalSystemUsage = 0;
- private long throttledTime = 0;
- private long throttlingActivePeriods = 0;
- private long throttledPeriods = 0;
-
- private long deltaContainerKernelUsage;
- private long deltaContainerUsage;
- private long deltaSystemUsage;
- private long deltaThrottledTime;
- private long deltaThrottlingActivePeriods;
- private long deltaThrottledPeriods;
-
- private void updateCpuDeltas(ContainerStats.CpuStats cpuStats) {
- // Do not calculate delta during the first tick - that will result in a metric value that is
- // average since container start
- if (totalSystemUsage != 0) {
- deltaSystemUsage = cpuStats.getSystemCpuUsage() - totalSystemUsage;
- deltaContainerUsage = cpuStats.getTotalUsage() - totalContainerUsage;
- deltaContainerKernelUsage = cpuStats.getUsageInKernelMode() - containerKernelUsage;
- deltaThrottledTime = cpuStats.getThrottledTime() - throttledTime;
- deltaThrottlingActivePeriods = cpuStats.getThrottlingActivePeriods() - throttlingActivePeriods;
- deltaThrottledPeriods = cpuStats.getThrottledPeriods() - throttledPeriods;
- }
-
- totalSystemUsage = cpuStats.getSystemCpuUsage();
- totalContainerUsage = cpuStats.getTotalUsage();
- containerKernelUsage = cpuStats.getUsageInKernelMode();
- throttledTime = cpuStats.getThrottledTime();
- throttlingActivePeriods = cpuStats.getThrottlingActivePeriods();
- throttledPeriods = cpuStats.getThrottledPeriods();
- }
-
- /**
- * Returns the CPU usage ratio for the docker container that this NodeAgent is managing
- * in the time between the last two times updateCpuDeltas() was called. This is calculated
- * by dividing the CPU time used by the container with the CPU time used by the entire system.
- */
- double getCpuUsageRatio() {
- return deltaSystemUsage == 0 ? Double.NaN : (double) deltaContainerUsage / deltaSystemUsage;
- }
-
- double getCpuKernelUsageRatio() {
- return deltaSystemUsage == 0 ? Double.NaN : (double) deltaContainerKernelUsage / deltaSystemUsage;
- }
-
- double getThrottledTimeRate() {
- return deltaThrottlingActivePeriods == 0 ? Double.NaN :
- (double) deltaThrottledPeriods / deltaThrottlingActivePeriods;
- }
-
- double getThrottledCpuTimeRate() {
- return deltaThrottlingActivePeriods == 0 ? Double.NaN :
- deltaThrottledTime / (PERIOD_IN_NANOSECONDS * deltaThrottlingActivePeriods);
- }
- }
-
// TODO: Also skip orchestration if we're downgrading in test/staging
// How to implement:
// - test/staging: We need to figure out whether we're in test/staging, zone is available in Environment
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentScheduler.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentScheduler.java
index a5daab8dcfd..956302dcdcc 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentScheduler.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentScheduler.java
@@ -19,4 +19,7 @@ public interface NodeAgentScheduler {
* @return True if node agent has converged to the desired state
*/
boolean setFrozen(boolean frozen, Duration timeout);
+
+ /** @return the last scheduled context or a default value */
+ NodeAgentContext currentContext();
}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelper.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelper.java
index cc31374669c..5bd3d7800e6 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelper.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/DebugHandlerHelper.java
@@ -19,7 +19,6 @@ import java.util.stream.Collectors;
*/
@ThreadSafe
public class DebugHandlerHelper implements NodeAdminDebugHandler {
- private Object monitor = new Object();
private final ConcurrentMap<String, Supplier<Object>> suppliers = new ConcurrentHashMap<>();
public void addThreadSafeSupplier(String name, Supplier<Object> threadSafeSupplier) {
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/StoredBoolean.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/StoredBoolean.java
index 5400c19d63e..3bcd806bc85 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/StoredBoolean.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/StoredBoolean.java
@@ -14,7 +14,7 @@ import java.util.logging.Logger;
* @author hakonhall
*/
public class StoredBoolean {
- private static Logger logger = Logger.getLogger(StoredBoolean.class.getName());
+ private static final Logger logger = Logger.getLogger(StoredBoolean.class.getName());
private final UnixPath path;
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/Templar.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/Templar.java
index 113af76972b..e8c22184406 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/Templar.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/Templar.java
@@ -14,8 +14,8 @@ import java.util.Map;
public class Templar {
private final String template;
- private String prefix = "<%=";
- private String suffix = "%>";
+ private static final String prefix = "<%=";
+ private static final String suffix = "%>";
private final Map<String, String> settings = new HashMap<>();
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java
index 376fda1d2dc..cf6c6c432f4 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/UnixPath.java
@@ -60,7 +60,7 @@ public class UnixPath {
public Optional<String> readUtf8FileIfExists() {
try {
- return Optional.of(new String(Files.readAllBytes(path), StandardCharsets.UTF_8));
+ return Optional.of(Files.readString(path));
} catch (NoSuchFileException ignored) {
return Optional.empty();
} catch (IOException e) {
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java
index ba1952545a0..85a7c065a86 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/yum/Yum.java
@@ -7,7 +7,6 @@ import com.yahoo.vespa.hosted.node.admin.task.util.process.CommandResult;
import com.yahoo.vespa.hosted.node.admin.task.util.process.Terminal;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
@@ -37,7 +36,7 @@ public class Yum {
.map(formatter -> "%{" + formatter + "}")
.collect(Collectors.joining("\\n"));
private static final Function<YumPackageName.Builder, List<Function<String, YumPackageName.Builder>>>
- PACKAGE_NAME_BUILDERS_GENERATOR = builder -> Arrays.asList(
+ PACKAGE_NAME_BUILDERS_GENERATOR = builder -> List.of(
builder::setName, builder::setEpoch, builder::setVersion, builder::setRelease, builder::setArchitecture);
@@ -183,7 +182,7 @@ public class Yum {
return new GenericYumCommand(
terminal,
yumCommand,
- Arrays.asList(packages),
+ List.of(packages),
noopPattern);
}
@@ -209,9 +208,8 @@ public class Yum {
}
}
- @SuppressWarnings("unchecked")
public GenericYumCommand enableRepos(String... repos) {
- enabledRepo.addAll(Arrays.asList(repos));
+ enabledRepo.addAll(List.of(repos));
return this;
}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/util/SecretAgentCheckConfig.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/util/SecretAgentCheckConfig.java
deleted file mode 100644
index cdf67871a1a..00000000000
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/util/SecretAgentCheckConfig.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.node.admin.util;
-
-import com.yahoo.config.provision.NodeType;
-import com.yahoo.vespa.hosted.node.admin.task.util.file.FileWriter;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Helper class to generate and write the secret-agent check config files.
- *
- * @author freva
- */
-public class SecretAgentCheckConfig {
- private final String id;
- private final int interval;
- private final Path checkExecutable;
- private final String[] arguments;
- private String user = "nobody";
- private final Map<String, Object> tags = new LinkedHashMap<>();
-
- public SecretAgentCheckConfig(String id, int interval, Path checkExecutable, String... arguments) {
- this.id = id;
- this.interval = interval;
- this.checkExecutable = checkExecutable;
- this.arguments = arguments;
- }
-
- public SecretAgentCheckConfig withRunAsUser(String user) {
- this.user = user;
- return this;
- }
-
- public SecretAgentCheckConfig withTag(String tagKey, Object tagValue) {
- tags.put(tagKey, tagValue);
- return this;
- }
-
- public SecretAgentCheckConfig withTags(Map<String, Object> tags) {
- this.tags.clear();
- this.tags.putAll(tags);
- return this;
- }
-
- public void setTags(Map<String, Object> tags) {
- this.tags.clear();
- this.tags.putAll(tags);
- }
-
- public void writeTo(Path yamasAgentDirectory) throws IOException {
- Files.createDirectories(yamasAgentDirectory);
- Path scheduleFilePath = yamasAgentDirectory.resolve(id + ".yaml");
- Files.write(scheduleFilePath, render().getBytes());
- }
-
- public FileWriter getFileWriterTo(Path destinationPath) {
- return new FileWriter(destinationPath, this::render);
- }
-
- public String render() {
- StringBuilder stringBuilder = new StringBuilder()
- .append("- id: ").append(id).append("\n")
- .append(" interval: ").append(interval).append("\n")
- .append(" user: ").append(user).append("\n")
- .append(" check: ").append(checkExecutable.toFile()).append("\n");
-
- if (arguments.length > 0) {
- stringBuilder.append(" args:\n");
- for (String arg : arguments) {
- stringBuilder.append(" - ").append(arg).append("\n");
- }
- }
-
- if (!tags.isEmpty()) {
- stringBuilder.append(" tags:\n");
- tags.forEach((key, value) ->
- stringBuilder.append(" ").append(key).append(": ").append(value).append("\n"));
- }
-
- return stringBuilder.toString();
- }
-
- // TODO: Change role dimension to nodeType?
- public static String nodeTypeToRole(NodeType nodeType) {
- switch (nodeType) {
- case tenant: return "tenants";
- case host: return "docker";
- case proxy: return "routing";
- case proxyhost: return "routinghost";
- case config: return "configserver";
- case confighost: return "configserverhost";
- case controller: return "controller";
- case controllerhost: return "controllerhost";
- default: throw new IllegalArgumentException("Unknown node type " + nodeType);
- }
- }
-}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/util/package-info.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/util/package-info.java
deleted file mode 100644
index 56cb135e723..00000000000
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/util/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-@ExportPackage
-package com.yahoo.vespa.hosted.node.admin.util;
-
-import com.yahoo.osgi.annotation.ExportPackage;
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java
index 57b18606def..d034d3c1cd0 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/maintenance/StorageMaintainerTest.java
@@ -2,21 +2,9 @@
package com.yahoo.vespa.hosted.node.admin.maintenance;
import com.google.common.collect.ImmutableSet;
-import com.yahoo.component.Version;
-import com.yahoo.config.provision.Environment;
-import com.yahoo.config.provision.NodeType;
-import com.yahoo.config.provision.RegionName;
-import com.yahoo.config.provision.zone.ZoneApi;
-import com.yahoo.config.provision.zone.ZoneId;
-import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeMembership;
-import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeOwner;
-import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeSpec;
-import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeState;
-import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations;
import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContext;
import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentContextImpl;
import com.yahoo.vespa.hosted.node.admin.task.util.file.FileFinder;
-import com.yahoo.vespa.hosted.node.admin.task.util.file.UnixPath;
import com.yahoo.vespa.hosted.node.admin.task.util.process.TestTerminal;
import com.yahoo.vespa.test.file.TestFileSystem;
import org.junit.After;
@@ -35,162 +23,15 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import static com.yahoo.yolean.Exceptions.uncheck;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
/**
* @author dybis
*/
@RunWith(Enclosed.class)
public class StorageMaintainerTest {
- private static final DockerOperations docker = mock(DockerOperations.class);
-
- public static class SecretAgentCheckTests {
- private final StorageMaintainer storageMaintainer = new StorageMaintainer(null, docker, null, null);
-
- @Test
- public void tenant() {
- Path path = executeAs(NodeType.tenant);
-
- assertChecks(path, "athenz-certificate-expiry", "host-life",
- "system-coredumps-processing", "vespa", "vespa-health");
-
- // All dimensions for vespa metrics should be set by metricsproxy
- assertCheckEnds(path.resolve("vespa.yaml"),
- " args:\n" +
- " - all\n");
-
- // For non vespa metrics, we need to set all the dimensions ourselves
- assertCheckEnds(path.resolve("host-life.yaml"),
- "tags:\n" +
- " namespace: Vespa\n" +
- " role: tenants\n" +
- " zone: prod.us-north-1\n" +
- " vespaVersion: 6.305.12\n" +
- " state: active\n" +
- " parentHostname: host123.test.domain.tld\n" +
- " tenantName: tenant\n" +
- " app: application.instance\n" +
- " applicationName: application\n" +
- " instanceName: instance\n" +
- " applicationId: tenant.application.instance\n" +
- " clustertype: clusterType\n" +
- " clusterid: clusterId\n");
- }
-
- @Test
- public void proxy() {
- Path path = executeAs(NodeType.proxy);
-
- assertChecks(path, "athenz-certificate-expiry", "host-life", "routing-configage",
- "ssl-status", "system-coredumps-processing", "vespa", "vespa-health");
-
- // All dimensions for vespa metrics should be set by the source
- assertCheckEnds(path.resolve("vespa.yaml"),
- " args:\n" +
- " - all\n");
-
- // For non vespa metrics, we need to set all the dimensions ourselves
- assertCheckEnds(path.resolve("host-life.yaml"),
- "tags:\n" +
- " namespace: Vespa\n" +
- " role: routing\n" +
- " zone: prod.us-north-1\n" +
- " vespaVersion: 6.305.12\n" +
- " state: active\n" +
- " parentHostname: host123.test.domain.tld\n" +
- " tenantName: tenant\n" +
- " app: application.instance\n" +
- " applicationName: application\n" +
- " instanceName: instance\n" +
- " applicationId: tenant.application.instance\n" +
- " clustertype: clusterType\n" +
- " clusterid: clusterId\n");
- }
-
- @Test
- public void configserver() {
- Path path = executeAs(NodeType.config);
-
- assertChecks(path, "athenz-certificate-expiry", "configserver", "configserver-logd", "host-life",
- "system-coredumps-processing", "zkbackupage");
-
- assertCheckEnds(path.resolve("configserver.yaml"),
- " tags:\n" +
- " namespace: Vespa\n" +
- " role: configserver\n" +
- " zone: prod.us-north-1\n" +
- " vespaVersion: 6.305.12\n");
- }
-
- @Test
- public void controller() {
- Path path = executeAs(NodeType.controller);
-
- assertChecks(path, "athenz-certificate-expiry", "controller", "controller-logd", "host-life",
- "system-coredumps-processing", "vespa", "vespa-health", "zkbackupage");
-
-
- // Do not set namespace for vespa metrics. WHY?
- assertCheckEnds(path.resolve("vespa.yaml"),
- " tags:\n" +
- " role: controller\n" +
- " zone: prod.us-north-1\n" +
- " vespaVersion: 6.305.12\n");
-
- assertCheckEnds(path.resolve("controller.yaml"),
- " tags:\n" +
- " namespace: Vespa\n" +
- " role: controller\n" +
- " zone: prod.us-north-1\n" +
- " vespaVersion: 6.305.12\n");
- }
-
- private Path executeAs(NodeType nodeType) {
- ZoneApi zone = mock(ZoneApi.class);
- when(zone.getId()).thenReturn(ZoneId.from(Environment.prod, RegionName.from("us-north-1")));
-
- NodeSpec nodeSpec = new NodeSpec.Builder()
- .hostname("host123-5.test.domain.tld")
- .type(nodeType)
- .state(NodeState.active)
- .parentHostname("host123.test.domain.tld")
- .owner(new NodeOwner("tenant", "application", "instance"))
- .membership(new NodeMembership("clusterType", "clusterId", null, 0, false))
- .currentVespaVersion(Version.fromString("6.305.12"))
- .flavor("d-2-8-50")
- .canonicalFlavor("d-2-8-50")
- .build();
- NodeAgentContext context = new NodeAgentContextImpl.Builder(nodeSpec)
- .fileSystem(TestFileSystem.create())
- .zone(zone)
- .build();
- Path path = context.pathOnHostFromPathInNode("/etc/yamas-agent");
- uncheck(() -> Files.createDirectories(path));
- storageMaintainer.writeMetricsConfig(context);
- return path;
- }
-
- private void assertCheckEnds(Path checkPath, String contentsEnd) {
- String contents = new UnixPath(checkPath).readUtf8File();
- assertTrue(contents, contents.endsWith(contentsEnd));
- }
-
- private void assertChecks(Path checksPath, String... checkNames) {
- List<String> expectedChecks = Stream.of(checkNames).sorted().collect(Collectors.toList());
- List<String> actualChecks = FileFinder.files(checksPath).stream()
- .map(FileFinder.FileAttributes::filename)
- .map(filename -> filename.replaceAll("\\.yaml$", ""))
- .sorted()
- .collect(Collectors.toList());
- assertEquals(expectedChecks, actualChecks);
- }
- }
public static class DiskUsageTests {
@@ -198,7 +39,7 @@ public class StorageMaintainerTest {
@Test
public void testDiskUsed() throws IOException {
- StorageMaintainer storageMaintainer = new StorageMaintainer(terminal, docker, null, null);
+ StorageMaintainer storageMaintainer = new StorageMaintainer(terminal, null, null);
FileSystem fileSystem = TestFileSystem.create();
NodeAgentContext context = new NodeAgentContextImpl.Builder("host-1.domain.tld").fileSystem(fileSystem).build();
Files.createDirectories(context.pathOnHostFromPathInNode("/"));
@@ -212,7 +53,7 @@ public class StorageMaintainerTest {
@Test
public void testNonExistingDiskUsed() {
- StorageMaintainer storageMaintainer = new StorageMaintainer(terminal, docker, null, null);
+ StorageMaintainer storageMaintainer = new StorageMaintainer(terminal, null, null);
long usedBytes = storageMaintainer.getDiskUsedInBytes(null, Paths.get("/fake/path"));
assertEquals(0L, usedBytes);
}
@@ -244,7 +85,7 @@ public class StorageMaintainerTest {
// Archive container-1
- StorageMaintainer storageMaintainer = new StorageMaintainer(null, docker, null, pathToArchiveDir);
+ StorageMaintainer storageMaintainer = new StorageMaintainer(null, null, pathToArchiveDir);
storageMaintainer.archiveNodeStorage(context1);
// container-1 should be gone from container-storage
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java
index 46af7e7bafd..c0b032bc4d4 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImplTest.java
@@ -9,12 +9,8 @@ import com.yahoo.vespa.flags.InMemoryFlagSource;
import com.yahoo.vespa.hosted.dockerapi.Container;
import com.yahoo.vespa.hosted.dockerapi.ContainerName;
import com.yahoo.vespa.hosted.dockerapi.ContainerResources;
-import com.yahoo.vespa.hosted.dockerapi.ContainerStats;
import com.yahoo.vespa.hosted.dockerapi.exception.DockerException;
-import com.yahoo.vespa.hosted.dockerapi.metrics.Metrics;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeAttributes;
-import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeMembership;
-import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeOwner;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeRepository;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeSpec;
import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeState;
@@ -28,21 +24,12 @@ import com.yahoo.vespa.hosted.node.admin.nodeadmin.ConvergenceException;
import org.junit.Test;
import org.mockito.InOrder;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.List;
import java.util.Optional;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import static com.yahoo.yolean.Exceptions.uncheck;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@@ -76,7 +63,6 @@ public class NodeAgentImplTest {
private final NodeRepository nodeRepository = mock(NodeRepository.class);
private final Orchestrator orchestrator = mock(Orchestrator.class);
private final StorageMaintainer storageMaintainer = mock(StorageMaintainer.class);
- private final Metrics metrics = new Metrics();
private final AclMaintainer aclMaintainer = mock(AclMaintainer.class);
private final HealthChecker healthChecker = mock(HealthChecker.class);
private final CredentialsMaintainer credentialsMaintainer = mock(CredentialsMaintainer.class);
@@ -152,7 +138,7 @@ public class NodeAgentImplTest {
inOrder.verify(dockerOperations, never()).startServices(eq(context));
inOrder.verify(dockerOperations, times(1)).resumeNode(eq(context));
- nodeAgent.stopForHostSuspension();
+ nodeAgent.stopForHostSuspension(context);
nodeAgent.doConverge(context);
inOrder.verify(dockerOperations, never()).startServices(eq(context));
inOrder.verify(dockerOperations, times(1)).resumeNode(eq(context)); // Expect a resume, but no start services
@@ -162,7 +148,7 @@ public class NodeAgentImplTest {
inOrder.verify(dockerOperations, never()).startServices(eq(context));
inOrder.verify(dockerOperations, never()).resumeNode(eq(context));
- nodeAgent.stopForHostSuspension();
+ nodeAgent.stopForHostSuspension(context);
nodeAgent.doConverge(context);
inOrder.verify(dockerOperations, times(1)).createContainer(eq(context), any(), any());
inOrder.verify(dockerOperations, times(1)).startContainer(eq(context));
@@ -638,81 +624,6 @@ public class NodeAgentImplTest {
}
@Test
- @SuppressWarnings("unchecked")
- public void testGetRelevantMetrics() throws Exception {
- String json = Files.readString(Paths.get("src/test/resources/docker.stats.json"));
- ContainerStats stats2 = ContainerStats.fromJson(json);
- ContainerStats stats1 = ContainerStats.fromJson(json.replace("\"cpu_stats\"", "\"cpu_stats2\"").replace("\"precpu_stats\"", "\"cpu_stats\""));
-
- NodeOwner owner = new NodeOwner("tester", "testapp", "testinstance");
- NodeMembership membership = new NodeMembership("clustType", "clustId", "grp", 3, false);
- final NodeSpec node = nodeBuilder
- .wantedDockerImage(dockerImage)
- .currentDockerImage(dockerImage)
- .state(NodeState.active)
- .currentVespaVersion(vespaVersion)
- .owner(owner)
- .membership(membership)
- .memoryGb(2)
- .allowedToBeDown(true)
- .parentHostname("parent.host.name.yahoo.com")
- .build();
-
- NodeAgentContext context = createContext(node);
- NodeAgentImpl nodeAgent = makeNodeAgent(dockerImage, true);
-
- when(nodeRepository.getOptionalNode(eq(hostName))).thenReturn(Optional.of(node));
- when(storageMaintainer.getDiskUsageFor(eq(context))).thenReturn(Optional.of(39625000000L));
- when(dockerOperations.getContainerStats(eq(context)))
- .thenReturn(Optional.of(stats1))
- .thenReturn(Optional.of(stats2));
-
- List<String> expectedMetrics = Stream.of(0, 1)
- .map(i -> Paths.get("src/test/resources/expected.container.system.metrics." + i + ".txt"))
- .map(path -> uncheck(() -> Files.readString(path)))
- .map(content -> content.replaceAll("\\s", "").replaceAll("\\n", ""))
- .collect(Collectors.toList());
- int[] counter = {0};
-
- doAnswer(invocation -> {
- NodeAgentContext calledContainerName = (NodeAgentContext) invocation.getArguments()[0];
- long calledTimeout = (long) invocation.getArguments()[1];
- String[] calledCommand = new String[invocation.getArguments().length - 2];
- System.arraycopy(invocation.getArguments(), 2, calledCommand, 0, calledCommand.length);
- calledCommand[calledCommand.length - 1] = calledCommand[calledCommand.length - 1]
- .replaceAll("\"timestamp\":\\d+", "\"timestamp\":0")
- .replaceAll("([0-9]+\\.[0-9]{1,3})([0-9]*)", "$1"); // Only keep the first 3 decimals
-
- assertEquals(context, calledContainerName);
- assertEquals(5L, calledTimeout);
- String[] expectedCommand = {"vespa-rpc-invoke", "-t", "2", "tcp/localhost:19095",
- "setExtraMetrics", expectedMetrics.get(counter[0])};
- assertArrayEquals("Ivocation #" + counter[0], expectedCommand, calledCommand);
- counter[0]++;
- return null;
- }).when(dockerOperations).executeCommandInContainerAsRoot(any(), any(), any());
-
- nodeAgent.updateContainerNodeMetrics();
- nodeAgent.updateContainerNodeMetrics();
- }
-
- @Test
- public void testGetRelevantMetricsForReadyNode() {
- final NodeSpec node = nodeBuilder
- .state(NodeState.ready)
- .build();
-
- NodeAgentContext context = createContext(node);
- NodeAgentImpl nodeAgent = makeNodeAgent(null, false);
-
- when(dockerOperations.getContainerStats(eq(context))).thenReturn(Optional.empty());
-
- nodeAgent.updateContainerNodeMetrics();
-
- assertEquals(List.of(), metrics.getDefaultMetrics());
- }
-
- @Test
public void testRunningConfigServer() {
final NodeSpec node = nodeBuilder
.type(NodeType.config)
@@ -747,8 +658,6 @@ public class NodeAgentImplTest {
private NodeAgentImpl makeNodeAgent(DockerImage dockerImage, boolean isRunning) {
mockGetContainer(dockerImage, isRunning);
- doNothing().when(storageMaintainer).writeMetricsConfig(any());
-
return new NodeAgentImpl(contextSupplier, nodeRepository, orchestrator, dockerOperations,
storageMaintainer, flagSource, Optional.of(credentialsMaintainer), Optional.of(aclMaintainer),
Optional.of(healthChecker));
@@ -776,8 +685,6 @@ public class NodeAgentImplTest {
}
private NodeAgentContext createContext(NodeSpec nodeSpec) {
- NodeAgentContext context = new NodeAgentContextImpl.Builder(nodeSpec).build();
- when(contextSupplier.currentContext()).thenReturn(context);
- return context;
+ return new NodeAgentContextImpl.Builder(nodeSpec).build();
}
}
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ProcessFactoryImplTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ProcessFactoryImplTest.java
index 333cb81f9d4..e66b3a7aed2 100644
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ProcessFactoryImplTest.java
+++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/task/util/process/ProcessFactoryImplTest.java
@@ -11,7 +11,7 @@ import java.nio.file.Path;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
-import java.util.Arrays;
+import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -31,7 +31,7 @@ public class ProcessFactoryImplTest {
@Test
public void testSpawn() {
CommandLine commandLine = mock(CommandLine.class);
- when(commandLine.getArguments()).thenReturn(Arrays.asList("program"));
+ when(commandLine.getArguments()).thenReturn(List.of("program"));
when(commandLine.getRedirectStderrToStdoutInsteadOfDiscard()).thenReturn(true);
when(commandLine.programName()).thenReturn("program");
Path outputPath;
@@ -56,8 +56,8 @@ public class ProcessFactoryImplTest {
public void testSpawnWithPersistentOutputFile() {
class TemporaryFile implements AutoCloseable {
- Path path;
- TemporaryFile() {
+ private final Path path;
+ private TemporaryFile() {
String outputFileName = ProcessFactoryImplTest.class.getSimpleName() + "-temporary-test-file.out";
FileAttribute<Set<PosixFilePermission>> fileAttribute = PosixFilePermissions.asFileAttribute(
PosixFilePermissions.fromString("rw-------"));
@@ -68,7 +68,7 @@ public class ProcessFactoryImplTest {
try (TemporaryFile outputPath = new TemporaryFile()) {
CommandLine commandLine = mock(CommandLine.class);
- when(commandLine.getArguments()).thenReturn(Arrays.asList("program"));
+ when(commandLine.getArguments()).thenReturn(List.of("program"));
when(commandLine.programName()).thenReturn("program");
when(commandLine.getOutputFile()).thenReturn(Optional.of(outputPath.path));
try (ChildProcess2Impl child = processFactory.spawn(commandLine)) {
diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/util/SecretAgentCheckConfigTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/util/SecretAgentCheckConfigTest.java
deleted file mode 100644
index 30263403757..00000000000
--- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/util/SecretAgentCheckConfigTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.node.admin.util;
-
-import com.yahoo.config.provision.NodeType;
-import org.junit.Test;
-
-import java.nio.file.Paths;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * @author freva
- */
-public class SecretAgentCheckConfigTest {
-
- @Test
- public void generateFullSecretAgentScheduleTest() {
- SecretAgentCheckConfig scheduleMaker = new SecretAgentCheckConfig("system-checks", 60,
- Paths.get("/some/test"), "arg1", "arg2 with space")
- .withTag("tenantName", "vespa")
- .withTag("applicationName", "canary-docker")
- .withTag("instanceName", "default")
- .withTag("applicationId", "vespa.canary-docker.default")
- .withTag("app", "canary-docker.default")
- .withTag("clustertype", "container")
- .withTag("clusterid", "canary")
- .withTag("vespaVersion", "6.13.37")
- .withTag("role", "tenants")
- .withTag("flavor", "docker")
- .withTag("state", "active")
- .withTag("zone", "test.us-west-5");
-
- assertEquals(
- "- id: system-checks\n" +
- " interval: 60\n" +
- " user: nobody\n" +
- " check: /some/test\n" +
- " args:\n" +
- " - arg1\n" +
- " - arg2 with space\n" +
- " tags:\n" +
- " tenantName: vespa\n" +
- " applicationName: canary-docker\n" +
- " instanceName: default\n" +
- " applicationId: vespa.canary-docker.default\n" +
- " app: canary-docker.default\n" +
- " clustertype: container\n" +
- " clusterid: canary\n" +
- " vespaVersion: 6.13.37\n" +
- " role: tenants\n" +
- " flavor: docker\n" +
- " state: active\n" +
- " zone: test.us-west-5\n", scheduleMaker.render());
- }
-
- @Test
- public void generateMinimalSecretAgentScheduleTest() {
- SecretAgentCheckConfig scheduleMaker = new SecretAgentCheckConfig("system-checks", 60,
- Paths.get("/some/test"));
-
- assertEquals(
- "- id: system-checks\n" +
- " interval: 60\n" +
- " user: nobody\n" +
- " check: /some/test\n", scheduleMaker.render());
- }
-
- @Test
- public void generateSecretAgentScheduleWithDifferentUserTest() {
- SecretAgentCheckConfig scheduleMaker = new SecretAgentCheckConfig("system-checks", 60,
- Paths.get("/some/test")).withRunAsUser("barfoo");
-
- assertEquals(
- "- id: system-checks\n" +
- " interval: 60\n" +
- " user: barfoo\n" +
- " check: /some/test\n", scheduleMaker.render());
- }
-
- @Test
- public void supportsAllNodeTypes() {
- for (NodeType nodeType : NodeType.values()) {
- assertNotNull(SecretAgentCheckConfig.nodeTypeToRole(nodeType));
- }
- }
-
-}
diff --git a/node-admin/src/test/resources/docker.stats.json b/node-admin/src/test/resources/docker.stats.json
deleted file mode 100644
index 5b42d9a2428..00000000000
--- a/node-admin/src/test/resources/docker.stats.json
+++ /dev/null
@@ -1,376 +0,0 @@
-{
- "read":"2016-10-05T07:28:17.228361751Z",
- "precpu_stats":{
- "cpu_usage":{
- "total_usage":332026268600,
- "percpu_usage":[
- 46767331190,
- 46637593621,
- 36196010351,
- 38846420953,
- 44237804850,
- 35751912062,
- 44546685143,
- 39042510430
- ],
- "usage_in_kernelmode":44040000000,
- "usage_in_usermode":158940000000
- },
- "system_cpu_usage":5876874910000000,
- "throttling_data":{
- "periods":820694,
- "throttled_periods":177731,
- "throttled_time":81891944744550
- }
- },
- "cpu_stats":{
- "cpu_usage":{
- "total_usage":332131163600,
- "percpu_usage":[
- 46774042376,
- 46639549207,
- 36204341756,
- 38879138416,
- 44256253747,
- 35760081676,
- 44567860460,
- 39049895962
- ],
- "usage_in_kernelmode":44106083850,
- "usage_in_usermode":158950000000
- },
- "system_cpu_usage":5876882680000000,
- "throttling_data":{
- "periods":821264,
- "throttled_periods":178201,
- "throttled_time":82181944744550
- }
- },
- "memory_stats":{
- "usage":1752707072,
- "max_usage":1818116096,
- "stats":{
- "active_anon":1326051328,
- "active_file":188919808,
- "cache":678965248,
- "hierarchical_memory_limit":4294967296,
- "hierarchical_memsw_limit":8589934592,
- "inactive_anon":0,
- "inactive_file":237735936,
- "mapped_file":62976000,
- "pgfault":3102812,
- "pgmajfault":1403,
- "pgpgin":1691151,
- "pgpgout":1263244,
- "rss":1326026752,
- "rss_huge":0,
- "swap":0,
- "total_active_anon":1326051328,
- "total_active_file":188919808,
- "total_cache":426680320,
- "total_inactive_anon":0,
- "total_inactive_file":237735936,
- "total_mapped_file":62976000,
- "total_pgfault":3102812,
- "total_pgmajfault":1403,
- "total_pgpgin":1691151,
- "total_pgpgout":1263244,
- "total_rss":1326026752,
- "total_rss_huge":0,
- "total_swap":0,
- "total_unevictable":0,
- "unevictable":0
- },
- "failcnt":0,
- "limit":4294967296
- },
- "blkio_stats":{
- "io_service_bytes_recursive":[
- {
- "major":252,
- "minor":0,
- "op":"Read",
- "value":53248
- },
- {
- "major":252,
- "minor":0,
- "op":"Write",
- "value":602112
- },
- {
- "major":252,
- "minor":0,
- "op":"Sync",
- "value":0
- },
- {
- "major":252,
- "minor":0,
- "op":"Async",
- "value":655360
- },
- {
- "major":252,
- "minor":0,
- "op":"Total",
- "value":655360
- },
- {
- "major":7,
- "minor":0,
- "op":"Read",
- "value":308224
- },
- {
- "major":7,
- "minor":0,
- "op":"Write",
- "value":573440
- },
- {
- "major":7,
- "minor":0,
- "op":"Sync",
- "value":0
- },
- {
- "major":7,
- "minor":0,
- "op":"Async",
- "value":881664
- },
- {
- "major":7,
- "minor":0,
- "op":"Total",
- "value":881664
- },
- {
- "major":253,
- "minor":0,
- "op":"Read",
- "value":308224
- },
- {
- "major":253,
- "minor":0,
- "op":"Write",
- "value":573440
- },
- {
- "major":253,
- "minor":0,
- "op":"Sync",
- "value":0
- },
- {
- "major":253,
- "minor":0,
- "op":"Async",
- "value":881664
- },
- {
- "major":253,
- "minor":0,
- "op":"Total",
- "value":881664
- },
- {
- "major":253,
- "minor":3,
- "op":"Read",
- "value":343847936
- },
- {
- "major":253,
- "minor":3,
- "op":"Write",
- "value":786432
- },
- {
- "major":253,
- "minor":3,
- "op":"Sync",
- "value":131072
- },
- {
- "major":253,
- "minor":3,
- "op":"Async",
- "value":344503296
- },
- {
- "major":253,
- "minor":3,
- "op":"Total",
- "value":344634368
- }
- ],
- "io_serviced_recursive":[
- {
- "major":252,
- "minor":0,
- "op":"Read",
- "value":13
- },
- {
- "major":252,
- "minor":0,
- "op":"Write",
- "value":147
- },
- {
- "major":252,
- "minor":0,
- "op":"Sync",
- "value":0
- },
- {
- "major":252,
- "minor":0,
- "op":"Async",
- "value":160
- },
- {
- "major":252,
- "minor":0,
- "op":"Total",
- "value":160
- },
- {
- "major":7,
- "minor":0,
- "op":"Read",
- "value":37
- },
- {
- "major":7,
- "minor":0,
- "op":"Write",
- "value":124
- },
- {
- "major":7,
- "minor":0,
- "op":"Sync",
- "value":0
- },
- {
- "major":7,
- "minor":0,
- "op":"Async",
- "value":161
- },
- {
- "major":7,
- "minor":0,
- "op":"Total",
- "value":161
- },
- {
- "major":253,
- "minor":0,
- "op":"Read",
- "value":37
- },
- {
- "major":253,
- "minor":0,
- "op":"Write",
- "value":124
- },
- {
- "major":253,
- "minor":0,
- "op":"Sync",
- "value":0
- },
- {
- "major":253,
- "minor":0,
- "op":"Async",
- "value":161
- },
- {
- "major":253,
- "minor":0,
- "op":"Total",
- "value":161
- },
- {
- "major":253,
- "minor":3,
- "op":"Read",
- "value":11812
- },
- {
- "major":253,
- "minor":3,
- "op":"Write",
- "value":142
- },
- {
- "major":253,
- "minor":3,
- "op":"Sync",
- "value":2
- },
- {
- "major":253,
- "minor":3,
- "op":"Async",
- "value":11952
- },
- {
- "major":253,
- "minor":3,
- "op":"Total",
- "value":11954
- }
- ],
- "io_queue_recursive":[
-
- ],
- "io_service_time_recursive":[
-
- ],
- "io_wait_time_recursive":[
-
- ],
- "io_merged_recursive":[
-
- ],
- "io_time_recursive":[
-
- ],
- "sectors_recursive":[
-
- ]
- },
- "pids_stats":{
-
- },
- "networks":{
- "eth0":{
- "rx_bytes":19499270,
- "rx_packets":58913,
- "rx_errors":55,
- "rx_dropped":4,
- "tx_bytes":20303455,
- "tx_packets":62319,
- "tx_errors":3,
- "tx_dropped":13
- },
- "eth1":{
- "rx_bytes":3245766,
- "rx_packets":23462,
- "rx_errors":0,
- "rx_dropped":0,
- "tx_bytes":54246745,
- "tx_packets":34562,
- "tx_errors":0,
- "tx_dropped":0
- }
- }
-} \ No newline at end of file
diff --git a/node-admin/src/test/resources/expected.container.system.metrics.0.txt b/node-admin/src/test/resources/expected.container.system.metrics.0.txt
deleted file mode 100644
index ea6036ce2ea..00000000000
--- a/node-admin/src/test/resources/expected.container.system.metrics.0.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-s:
-{
- "application": "vespa.node",
- "dimensions": {
- "host": "host1.test.yahoo.com",
- "orchestratorState":"ALLOWED_TO_BE_DOWN",
- "parentHostname": "parent.host.name.yahoo.com",
- "role": "tenants",
- "state": "active"
- },
- "metrics": {
- "cpu.vcpus": 2.0,
- "disk.limit": 250000000000,
- "disk.used": 39625000000,
- "disk.util": 15.85,
- "mem.limit": 4294967296,
- "mem.used": 1073741824,
- "mem.util": 25.0,
- "mem_total.used": 1752707072,
- "mem_total.util": 40.808
- },
- "routing": {
- "yamas": {
- "namespaces": ["Vespa"]
- }
- },
- "timestamp": 0
-}
-{
- "application": "vespa.node",
- "dimensions": {
- "host": "host1.test.yahoo.com",
- "interface": "eth0",
- "orchestratorState":"ALLOWED_TO_BE_DOWN",
- "parentHostname": "parent.host.name.yahoo.com",
- "role": "tenants",
- "state": "active"
- },
- "metrics": {
- "net.in.bytes": 19499270,
- "net.in.dropped": 4,
- "net.in.errors": 55,
- "net.out.bytes": 20303455,
- "net.out.dropped": 13,
- "net.out.errors": 3
- },
- "routing": {
- "yamas": {
- "namespaces": ["Vespa"]
- }
- },
- "timestamp": 0
-}
-{
- "application": "vespa.node",
- "dimensions": {
- "host": "host1.test.yahoo.com",
- "interface": "eth1",
- "orchestratorState":"ALLOWED_TO_BE_DOWN",
- "parentHostname": "parent.host.name.yahoo.com",
- "role": "tenants",
- "state": "active"
- },
- "metrics": {
- "net.in.bytes": 3245766,
- "net.in.dropped": 0,
- "net.in.errors": 0,
- "net.out.bytes": 54246745,
- "net.out.dropped": 0,
- "net.out.errors": 0
- },
- "routing": {
- "yamas": {
- "namespaces": ["Vespa"]
- }
- },
- "timestamp": 0
-} \ No newline at end of file
diff --git a/node-admin/src/test/resources/expected.container.system.metrics.1.txt b/node-admin/src/test/resources/expected.container.system.metrics.1.txt
deleted file mode 100644
index 54d4d36c7d0..00000000000
--- a/node-admin/src/test/resources/expected.container.system.metrics.1.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-s:
-{
- "application": "vespa.node",
- "dimensions": {
- "host": "host1.test.yahoo.com",
- "orchestratorState":"ALLOWED_TO_BE_DOWN",
- "parentHostname": "parent.host.name.yahoo.com",
- "role": "tenants",
- "state": "active"
- },
- "metrics": {
- "cpu.sys.util": 3.402,
- "cpu.throttled_cpu_time.rate": 5.087,
- "cpu.throttled_time.rate": 0.824,
- "cpu.util": 5.4,
- "cpu.vcpus": 2.0,
- "disk.limit": 250000000000,
- "disk.used": 39625000000,
- "disk.util": 15.85,
- "mem.limit": 4294967296,
- "mem.used": 1073741824,
- "mem.util": 25.0,
- "mem_total.used": 1752707072,
- "mem_total.util": 40.808
- },
- "routing": {
- "yamas": {
- "namespaces": ["Vespa"]
- }
- },
- "timestamp": 0
-}
-{
- "application": "vespa.node",
- "dimensions": {
- "host": "host1.test.yahoo.com",
- "interface": "eth0",
- "orchestratorState":"ALLOWED_TO_BE_DOWN",
- "parentHostname": "parent.host.name.yahoo.com",
- "role": "tenants",
- "state": "active"
- },
- "metrics": {
- "net.in.bytes": 19499270,
- "net.in.dropped": 4,
- "net.in.errors": 55,
- "net.out.bytes": 20303455,
- "net.out.dropped": 13,
- "net.out.errors": 3
- },
- "routing": {
- "yamas": {
- "namespaces": ["Vespa"]
- }
- },
- "timestamp": 0
-}
-{
- "application": "vespa.node",
- "dimensions": {
- "host": "host1.test.yahoo.com",
- "interface": "eth1",
- "orchestratorState":"ALLOWED_TO_BE_DOWN",
- "parentHostname": "parent.host.name.yahoo.com",
- "role": "tenants",
- "state": "active"
- },
- "metrics": {
- "net.in.bytes": 3245766,
- "net.in.dropped": 0,
- "net.in.errors": 0,
- "net.out.bytes": 54246745,
- "net.out.dropped": 0,
- "net.out.errors": 0
- },
- "routing": {
- "yamas": {
- "namespaces": ["Vespa"]
- }
- },
- "timestamp": 0
-} \ No newline at end of file
diff --git a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java
index e4633fb708b..bff40d67fa6 100644
--- a/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java
+++ b/vespa-athenz/src/main/java/com/yahoo/vespa/athenz/identityprovider/client/AthenzIdentityProviderImpl.java
@@ -67,7 +67,7 @@ public final class AthenzIdentityProviderImpl extends AbstractComponent implemen
private final static Duration ROLE_TOKEN_EXPIRY = Duration.ofMinutes(30);
// TODO Make path to trust store config
- private static final Path DEFAULT_TRUST_STORE = Paths.get(Defaults.getDefaults().underVespaHome("share/ssl/certs/yahoo_certificate_bundle.pem"));
+ private static final Path DEFAULT_TRUST_STORE = Paths.get(Defaults.getDefaults().underVespaHome("share/ssl/certs/yahoo_certificate_bundle.jks"));
public static final String CERTIFICATE_EXPIRY_METRIC_NAME = "athenz-tenant-cert.expiry.seconds";
diff --git a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/FeedParams.java b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/FeedParams.java
index 008f3b63a89..fff0aa910d5 100644
--- a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/FeedParams.java
+++ b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/FeedParams.java
@@ -13,13 +13,9 @@ import java.util.concurrent.TimeUnit;
*/
public final class FeedParams {
- public boolean getDenyIfBusyV3() {
- return denyIfBusyV3;
- }
+ public boolean getDenyIfBusyV3() { return denyIfBusyV3; }
- public long getMaxSleepTimeMs() {
- return maxSleepTimeMs;
- }
+ public long getMaxSleepTimeMs() { return maxSleepTimeMs; }
public boolean getSilentUpgrade() { return silentUpgrade; }
@@ -36,6 +32,7 @@ public final class FeedParams {
* Mutable class used to instantiate a {@link FeedParams}.
*/
public static final class Builder {
+
private DataFormat dataFormat = DataFormat.JSON_UTF8;
private long serverTimeout = TimeUnit.SECONDS.toMillis(180);
private long clientTimeout = TimeUnit.SECONDS.toMillis(20);
@@ -57,7 +54,7 @@ public final class FeedParams {
* @return this, for chaining
*/
@Beta
- public Builder withSilentUpgrade(boolean silentUpgrade) {
+ public Builder setSilentUpgrade(boolean silentUpgrade) {
this.silentUpgrade = silentUpgrade;
return this;
}
@@ -165,6 +162,7 @@ public final class FeedParams {
/**
* Sets the maximum number of operations to be in-flight.
+ *
* @param maxInFlightRequests max number of operations.
* @return this, for chaining
*/
@@ -246,11 +244,14 @@ public final class FeedParams {
return maxChunkSizeBytes;
}
- public int getmaxInFlightRequests() {
+ public int getMaxInFlightRequests() {
return maxInFlightRequests;
}
+
}
+ // NOTE! See toBuilder at the end of this class if you add fields here
+
private final DataFormat dataFormat;
private final long serverTimeoutMillis;
private final long clientTimeoutMillis;
@@ -263,7 +264,6 @@ public final class FeedParams {
private final long maxSleepTimeMs;
private final boolean silentUpgrade;
-
private FeedParams(DataFormat dataFormat, long serverTimeout, long clientTimeout, String route,
int maxChunkSizeBytes, final int maxInFlightRequests,
long localQueueTimeOut, String priority, boolean denyIfBusyV3, long maxSleepTimeMs,
@@ -319,4 +319,20 @@ public final class FeedParams {
return localQueueTimeOut;
}
+ /** Returns a builder initialized to the values of this */
+ public FeedParams.Builder toBuilder() {
+ Builder b = new Builder();
+ b.setDataFormat(dataFormat);
+ b.setServerTimeout(serverTimeoutMillis, TimeUnit.MILLISECONDS);
+ b.setClientTimeout(clientTimeoutMillis, TimeUnit.MILLISECONDS);
+ b.setRoute(route);
+ b.setMaxChunkSizeBytes(maxChunkSizeBytes);
+ b.setMaxInFlightRequests(maxInFlightRequests);
+ b.setPriority(priority);
+ b.setDenyIfBusyV3(denyIfBusyV3);
+ b.setMaxSleepTimeMs(maxSleepTimeMs);
+ b.setSilentUpgrade(silentUpgrade);
+ return b;
+ }
+
}
diff --git a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/SessionParams.java b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/SessionParams.java
index 48fd21e2b1f..4e1406ab966 100644
--- a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/SessionParams.java
+++ b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/config/SessionParams.java
@@ -133,6 +133,8 @@ public final class SessionParams {
}
}
+ // NOTE! See toBuilder at the end of this class if you add fields here
+
private final List<Cluster> clusters;
private final FeedParams feedParams;
private final ConnectionParams connectionParams;
@@ -179,4 +181,15 @@ public final class SessionParams {
return errorReport;
}
+ public Builder toBuilder() {
+ Builder b = new Builder();
+ clusters.forEach(c -> b.addCluster(c));
+ b.setFeedParams(feedParams);
+ b.setConnectionParams(connectionParams);
+ b.setClientQueueSize(clientQueueSize);
+ b.setErrorReporter(errorReport);
+ b.setThrottlerMinSize(throttlerMinSize);
+ return b;
+ }
+
}
diff --git a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/ClusterConnection.java b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/ClusterConnection.java
index da45acc5687..6e1f3419e8e 100644
--- a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/ClusterConnection.java
+++ b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/ClusterConnection.java
@@ -8,7 +8,6 @@ import com.yahoo.vespa.http.client.config.Cluster;
import com.yahoo.vespa.http.client.config.ConnectionParams;
import com.yahoo.vespa.http.client.config.Endpoint;
import com.yahoo.vespa.http.client.config.FeedParams;
-import com.yahoo.vespa.http.client.config.SessionParams;
import com.yahoo.vespa.http.client.core.Document;
import com.yahoo.vespa.http.client.core.Exceptions;
import com.yahoo.vespa.http.client.core.operationProcessor.OperationProcessor;
@@ -25,45 +24,35 @@ import java.util.concurrent.TimeUnit;
*/
public class ClusterConnection implements AutoCloseable {
- private final OperationProcessor operationProcessor;
private final List<IOThread> ioThreads = new ArrayList<>();
private final int clusterId;
- private final SessionParams.ErrorReporter errorReporter;
private static JsonFactory jsonFactory = new JsonFactory();
private static ObjectMapper objectMapper = new ObjectMapper();
- public ClusterConnection(
- OperationProcessor operationProcessor,
- FeedParams feedParams,
- ConnectionParams connectionParams,
- SessionParams.ErrorReporter errorReporter,
- Cluster cluster,
- int clusterId,
- int clientQueueSizePerCluster,
- ScheduledThreadPoolExecutor timeoutExecutor) {
- this.errorReporter = errorReporter;
- if (cluster.getEndpoints().isEmpty()) {
+ public ClusterConnection(OperationProcessor operationProcessor,
+ FeedParams feedParams,
+ ConnectionParams connectionParams,
+ Cluster cluster,
+ int clusterId,
+ int clientQueueSizePerCluster,
+ ScheduledThreadPoolExecutor timeoutExecutor) {
+ if (cluster.getEndpoints().isEmpty())
throw new IllegalArgumentException("Cannot feed to empty cluster.");
- }
- this.operationProcessor = operationProcessor;
+
this.clusterId = clusterId;
- final int totalNumberOfEndpointsInThisCluster = cluster.getEndpoints().size()
- * connectionParams.getNumPersistentConnectionsPerEndpoint();
- if (totalNumberOfEndpointsInThisCluster == 0) {
- return;
- }
+ int totalNumberOfEndpointsInThisCluster = cluster.getEndpoints().size() * connectionParams.getNumPersistentConnectionsPerEndpoint();
+ if (totalNumberOfEndpointsInThisCluster == 0) return;
+
// Lower than 1 does not make any sense.
- final int maxInFlightPerSession = Math.max(
- 1, feedParams.getMaxInFlightRequests() / totalNumberOfEndpointsInThisCluster);
+ int maxInFlightPerSession = Math.max(1, feedParams.getMaxInFlightRequests() / totalNumberOfEndpointsInThisCluster);
+
DocumentQueue documentQueue = null;
for (Endpoint endpoint : cluster.getEndpoints()) {
- final EndpointResultQueue endpointResultQueue = new EndpointResultQueue(
- operationProcessor,
- endpoint,
- clusterId,
- timeoutExecutor,
- feedParams.getServerTimeout(TimeUnit.MILLISECONDS)
- + feedParams.getClientTimeout(TimeUnit.MILLISECONDS));
+ EndpointResultQueue endpointResultQueue = new EndpointResultQueue(operationProcessor,
+ endpoint,
+ clusterId,
+ timeoutExecutor,
+ feedParams.getServerTimeout(TimeUnit.MILLISECONDS) + feedParams.getClientTimeout(TimeUnit.MILLISECONDS));
for (int i = 0; i < connectionParams.getNumPersistentConnectionsPerEndpoint(); i++) {
GatewayConnection gatewayConnection;
if (connectionParams.isDryRun()) {
@@ -74,24 +63,22 @@ public class ClusterConnection implements AutoCloseable {
feedParams,
cluster.getRoute(),
connectionParams,
- new ApacheGatewayConnection.HttpClientFactory(
- connectionParams, endpoint.isUseSsl()),
+ new ApacheGatewayConnection.HttpClientFactory(connectionParams, endpoint.isUseSsl()),
operationProcessor.getClientId()
);
}
if (documentQueue == null) {
documentQueue = new DocumentQueue(clientQueueSizePerCluster);
}
- final IOThread ioThread = new IOThread(
- operationProcessor.getIoThreadGroup(),
- endpointResultQueue,
- gatewayConnection,
- clusterId,
- feedParams.getMaxChunkSizeBytes(),
- maxInFlightPerSession,
- feedParams.getLocalQueueTimeOut(),
- documentQueue,
- feedParams.getMaxSleepTimeMs());
+ IOThread ioThread = new IOThread(operationProcessor.getIoThreadGroup(),
+ endpointResultQueue,
+ gatewayConnection,
+ clusterId,
+ feedParams.getMaxChunkSizeBytes(),
+ maxInFlightPerSession,
+ feedParams.getLocalQueueTimeOut(),
+ documentQueue,
+ feedParams.getMaxSleepTimeMs());
ioThreads.add(ioThread);
}
}
@@ -103,9 +90,9 @@ public class ClusterConnection implements AutoCloseable {
public void post(Document document) throws EndpointIOException {
String documentIdStr = document.getDocumentId();
- //the same document ID must always go to the same destination
+ // The same document ID must always go to the same destination
// In noHandshakeMode this has no effect as the documentQueue is shared between the IOThreads.
- int hash = documentIdStr.hashCode() & 0x7FFFFFFF; //strip sign bit
+ int hash = documentIdStr.hashCode() & 0x7FFFFFFF; // Strip sign bit
IOThread ioThread = ioThreads.get(hash % ioThreads.size());
try {
ioThread.post(document);
@@ -148,7 +135,7 @@ public class ClusterConnection implements AutoCloseable {
}
public String getStatsAsJSon() throws IOException {
- final StringWriter stringWriter = new StringWriter();
+ StringWriter stringWriter = new StringWriter();
JsonGenerator jsonGenerator = jsonFactory.createGenerator(stringWriter);
jsonGenerator.writeStartObject();
jsonGenerator.writeArrayFieldStart("session");
diff --git a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/IOThread.java b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/IOThread.java
index 8c4ff3ae108..8ec4f6cb7f4 100644
--- a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/IOThread.java
+++ b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/communication/IOThread.java
@@ -24,7 +24,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
- * Class for handling asynchronous feeding of new documents and processing of results.
+ * Thread which feeds document operations asynchronously and processes the results.
*
* @author Einar M R Rosenvinge
*/
@@ -53,19 +53,18 @@ class IOThread implements Runnable, AutoCloseable {
private final AtomicInteger docsReceivedCounter = new AtomicInteger(0);
private final AtomicInteger statusReceivedCounter = new AtomicInteger(0);
private final AtomicInteger pendingDocumentStatusCount = new AtomicInteger(0);
- private final AtomicInteger successfullHandshakes = new AtomicInteger(0);
+ private final AtomicInteger successfulHandshakes = new AtomicInteger(0);
private final AtomicInteger lastGatewayProcessTimeMillis = new AtomicInteger(0);
- IOThread(
- ThreadGroup ioThreadGroup,
- EndpointResultQueue endpointResultQueue,
- GatewayConnection client,
- int clusterId,
- int maxChunkSizeBytes,
- int maxInFlightRequests,
- long localQueueTimeOut,
- DocumentQueue documentQueue,
- long maxSleepTimeMs) {
+ IOThread(ThreadGroup ioThreadGroup,
+ EndpointResultQueue endpointResultQueue,
+ GatewayConnection client,
+ int clusterId,
+ int maxChunkSizeBytes,
+ int maxInFlightRequests,
+ long localQueueTimeOut,
+ DocumentQueue documentQueue,
+ long maxSleepTimeMs) {
this.documentQueue = documentQueue;
this.endpoint = client.getEndpoint();
this.client = client;
@@ -86,6 +85,9 @@ class IOThread implements Runnable, AutoCloseable {
}
public static class ConnectionStats {
+
+ // NOTE: These fields are accessed by reflection in JSON serialization
+
public final int wrongSessionDetectedCounter;
public final int wrongVersionDetectedCounter;
public final int problemStatusCodeFromServerCounter;
@@ -96,16 +98,15 @@ class IOThread implements Runnable, AutoCloseable {
public final int successfullHandshakes;
public final int lastGatewayProcessTimeMillis;
- protected ConnectionStats(
- final int wrongSessionDetectedCounter,
- final int wrongVersionDetectedCounter,
- final int problemStatusCodeFromServerCounter,
- final int executeProblemsCounter,
- final int docsReceivedCounter,
- final int statusReceivedCounter,
- final int pendingDocumentStatusCount,
- final int successfullHandshakes,
- final int lastGatewayProcessTimeMillis) {
+ ConnectionStats(int wrongSessionDetectedCounter,
+ int wrongVersionDetectedCounter,
+ int problemStatusCodeFromServerCounter,
+ int executeProblemsCounter,
+ int docsReceivedCounter,
+ int statusReceivedCounter,
+ int pendingDocumentStatusCount,
+ int successfullHandshakes,
+ int lastGatewayProcessTimeMillis) {
this.wrongSessionDetectedCounter = wrongSessionDetectedCounter;
this.wrongVersionDetectedCounter = wrongVersionDetectedCounter;
this.problemStatusCodeFromServerCounter = problemStatusCodeFromServerCounter;
@@ -130,16 +131,14 @@ class IOThread implements Runnable, AutoCloseable {
docsReceivedCounter.get(),
statusReceivedCounter.get(),
pendingDocumentStatusCount.get(),
- successfullHandshakes.get(),
+ successfulHandshakes.get(),
lastGatewayProcessTimeMillis.get());
}
@Override
public void close() {
documentQueue.close();
- if (stopSignal.getCount() == 0) {
- return;
- }
+ if (stopSignal.getCount() == 0) return;
stopSignal.countDown();
log.finer("Closed called.");
@@ -166,8 +165,7 @@ class IOThread implements Runnable, AutoCloseable {
log.fine("Session to " + endpoint + " closed.");
}
-
- public void post(final Document document) throws InterruptedException {
+ public void post(Document document) throws InterruptedException {
documentQueue.put(document, Thread.currentThread().getThreadGroup() == ioThreadGroup);
}
@@ -177,8 +175,8 @@ class IOThread implements Runnable, AutoCloseable {
}
- List<Document> getNextDocsForFeeding(int maxWaitUnits, TimeUnit timeUnit) {
- final List<Document> docsForSendChunk = new ArrayList<>();
+ List<Document> getNextDocsForFeeding(long maxWaitUnits, TimeUnit timeUnit) {
+ List<Document> docsForSendChunk = new ArrayList<>();
int chunkSizeBytes = 0;
try {
drainFirstDocumentsInQueueIfOld();
@@ -214,8 +212,7 @@ class IOThread implements Runnable, AutoCloseable {
}
}
- private void markDocumentAsFailed(
- List<Document> docs, ServerResponseException servletException) {
+ private void markDocumentAsFailed(List<Document> docs, ServerResponseException servletException) {
for (Document doc : docs) {
resultQueue.failOperation(
EndPointResultFactory.createTransientError(
@@ -223,8 +220,7 @@ class IOThread implements Runnable, AutoCloseable {
}
}
- private InputStream sendAndReceive(List<Document> docs)
- throws IOException, ServerResponseException {
+ private InputStream sendAndReceive(List<Document> docs) throws IOException, ServerResponseException {
try {
// Post the new docs and get async responses for other posts.
return client.writeOperations(docs);
@@ -238,17 +234,19 @@ class IOThread implements Runnable, AutoCloseable {
}
private static class ProcessResponse {
+
private final int transitiveErrorCount;
private final int processResultsCount;
+
ProcessResponse(int transitiveErrorCount, int processResultsCount) {
this.transitiveErrorCount = transitiveErrorCount;
this.processResultsCount = processResultsCount;
}
+
}
private ProcessResponse processResponse(InputStream serverResponse) throws IOException {
- final Collection<EndpointResult> endpointResults =
- EndPointResultFactory.createResult(endpoint, serverResponse);
+ Collection<EndpointResult> endpointResults = EndPointResultFactory.createResult(endpoint, serverResponse);
statusReceivedCounter.addAndGet(endpointResults.size());
int transientErrors = 0;
for (EndpointResult endpointResult : endpointResults) {
@@ -271,15 +269,14 @@ class IOThread implements Runnable, AutoCloseable {
return processResponse;
}
- private ProcessResponse pullAndProcessData(int maxWaitTimeMilliSecs)
- throws ServerResponseException, IOException {
- final int pendingResultQueueSize = resultQueue.getPendingSize();
+ private ProcessResponse pullAndProcessData(long maxWaitTimeMs) throws ServerResponseException, IOException {
+ int pendingResultQueueSize = resultQueue.getPendingSize();
pendingDocumentStatusCount.set(pendingResultQueueSize);
- List<Document> nextDocsForFeeding = (pendingResultQueueSize > maxInFlightRequests)
+ List<Document> nextDocsForFeeding =
+ (pendingResultQueueSize > maxInFlightRequests)
? new ArrayList<>() // The queue is full, will not send more documents.
- : getNextDocsForFeeding(maxWaitTimeMilliSecs, TimeUnit.MILLISECONDS);
-
+ : getNextDocsForFeeding(maxWaitTimeMs, TimeUnit.MILLISECONDS);
if (nextDocsForFeeding.isEmpty() && pendingResultQueueSize == 0) {
//we have no unfinished business with the server now.
@@ -288,6 +285,7 @@ class IOThread implements Runnable, AutoCloseable {
}
log.finest("Awaiting " + pendingResultQueueSize + " results.");
ProcessResponse processResponse = feedDocumentAndProcessResults(nextDocsForFeeding);
+
if (pendingResultQueueSize > maxInFlightRequests && processResponse.processResultsCount == 0) {
try {
// Max outstanding document operations, no more results on server side, wait a bit
@@ -319,7 +317,7 @@ class IOThread implements Runnable, AutoCloseable {
case CONNECTED:
try {
client.handshake();
- successfullHandshakes.getAndIncrement();
+ successfulHandshakes.getAndIncrement();
} catch (ServerResponseException ser) {
executeProblemsCounter.incrementAndGet();
log.info("Handshake did not work out " + endpoint + ": " + Exceptions.toMessageString(ser));
@@ -337,7 +335,7 @@ class IOThread implements Runnable, AutoCloseable {
return ThreadState.SESSION_SYNCED;
case SESSION_SYNCED:
try {
- ProcessResponse processResponse = pullAndProcessData(100);
+ ProcessResponse processResponse = pullAndProcessData(1);
gatewayThrottler.handleCall(processResponse.transitiveErrorCount);
}
catch (ServerResponseException ser) {
@@ -387,9 +385,8 @@ class IOThread implements Runnable, AutoCloseable {
private void drainFirstDocumentsInQueueIfOld() {
while (true) {
Optional<Document> document = documentQueue.pollDocumentIfTimedoutInQueue(localQueueTimeOut);
- if (! document.isPresent()) {
- return;
- }
+ if ( ! document.isPresent()) return;
+
EndpointResult endpointResult = EndPointResultFactory.createTransientError(
endpoint, document.get().getOperationId(),
new Exception("Not sending document operation, timed out in queue after "
diff --git a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/operationProcessor/OperationProcessor.java b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/operationProcessor/OperationProcessor.java
index 45133901567..692d90abe50 100644
--- a/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/operationProcessor/OperationProcessor.java
+++ b/vespa-http-client/src/main/java/com/yahoo/vespa/http/client/core/operationProcessor/OperationProcessor.java
@@ -56,41 +56,34 @@ public class OperationProcessor {
private final ThreadGroup ioThreadGroup;
private final String clientId = new BigInteger(130, random).toString(32);
- public OperationProcessor(
- IncompleteResultsThrottler incompleteResultsThrottler,
- FeedClient.ResultCallback resultCallback,
- SessionParams sessionParams,
- ScheduledThreadPoolExecutor timeoutExecutor) {
+ public OperationProcessor(IncompleteResultsThrottler incompleteResultsThrottler,
+ FeedClient.ResultCallback resultCallback,
+ SessionParams sessionParams,
+ ScheduledThreadPoolExecutor timeoutExecutor) {
this.numDestinations = sessionParams.getClusters().size();
this.resultCallback = resultCallback;
this.incompleteResultsThrottler = incompleteResultsThrottler;
this.timeoutExecutor = timeoutExecutor;
this.ioThreadGroup = new ThreadGroup("operationprocessor");
- if (sessionParams.getClusters().isEmpty()) {
+ if (sessionParams.getClusters().isEmpty())
throw new IllegalArgumentException("Cannot feed to 0 clusters.");
- }
for (Cluster cluster : sessionParams.getClusters()) {
- if (cluster.getEndpoints().isEmpty()) {
+ if (cluster.getEndpoints().isEmpty())
throw new IllegalArgumentException("Cannot feed to empty cluster.");
- }
}
for (int i = 0; i < sessionParams.getClusters().size(); i++) {
Cluster cluster = sessionParams.getClusters().get(i);
-
- clusters.add(new ClusterConnection(
- this,
- sessionParams.getFeedParams(),
- sessionParams.getConnectionParams(),
- sessionParams.getErrorReport(),
- cluster,
- i,
- sessionParams.getClientQueueSize() / sessionParams.getClusters().size(),
- timeoutExecutor));
-
- }
+ clusters.add(new ClusterConnection(this,
+ sessionParams.getFeedParams(),
+ sessionParams.getConnectionParams(),
+ cluster,
+ i,
+ sessionParams.getClientQueueSize() / sessionParams.getClusters().size(),
+ timeoutExecutor));
+ }
operationStats = new OperationStats(sessionParams, clusters, incompleteResultsThrottler);
maxRetries = sessionParams.getConnectionParams().getMaxRetries();
minTimeBetweenRetriesMs = sessionParams.getConnectionParams().getMinTimeBetweenRetriesMs();
@@ -122,21 +115,16 @@ public class OperationProcessor {
}
private boolean retriedThis(EndpointResult endpointResult, DocumentSendInfo documentSendInfo, int clusterId) {
- final Result.Detail detail = endpointResult.getDetail();
- // If success, no retries to do.
- if (detail.getResultType() == Result.ResultType.OPERATION_EXECUTED) {
- return false;
- }
+ Result.Detail detail = endpointResult.getDetail();
+ if (detail.getResultType() == Result.ResultType.OPERATION_EXECUTED) return false; // Success: No retries
int retries = documentSendInfo.incRetries(clusterId, detail);
- if (retries > maxRetries) {
- return false;
- }
+ if (retries > maxRetries) return false;
String exceptionMessage = detail.getException() == null ? "" : detail.getException().getMessage();
- if (exceptionMessage == null) {
+ if (exceptionMessage == null)
exceptionMessage = "";
- }
+
// TODO: Return proper error code in structured data in next version of internal API.
// Error codes from messagebus/src/cpp/messagebus/errorcode.h
boolean retryThisOperation =
@@ -151,12 +139,10 @@ public class OperationProcessor {
if (retryThisOperation) {
int waitTime = (int) (minTimeBetweenRetriesMs * (1 + random.nextDouble() / 3));
- log.finest("Retrying due to " + detail.toString() + " attempt " + retries
- + " in " + waitTime + " ms.");
- timeoutExecutor.schedule(
- () -> postToCluster(clusters.get(clusterId), documentSendInfo.getDocument()),
- waitTime,
- TimeUnit.MILLISECONDS);
+ log.finest("Retrying due to " + detail.toString() + " attempt " + retries + " in " + waitTime + " ms.");
+ timeoutExecutor.schedule(() -> postToCluster(clusters.get(clusterId), documentSendInfo.getDocument()),
+ waitTime,
+ TimeUnit.MILLISECONDS);
return true;
}
@@ -173,28 +159,20 @@ public class OperationProcessor {
}
DocumentSendInfo documentSendInfo = docSendInfoByOperationId.get(endpointResult.getOperationId());
- if (retriedThis(endpointResult, documentSendInfo, clusterId)) {
- return null;
- }
+ if (retriedThis(endpointResult, documentSendInfo, clusterId)) return null;
- if (!documentSendInfo.addIfNotAlreadyThere(endpointResult.getDetail(), clusterId)) {
- // Duplicate message, we have seen this operation before.
- return null;
- }
+ // Duplicate message
+ if ( ! documentSendInfo.addIfNotAlreadyThere(endpointResult.getDetail(), clusterId)) return null;
// Is this the last operation we are waiting for?
- if (documentSendInfo.detailCount() != numDestinations) {
- return null;
- }
+ if (documentSendInfo.detailCount() != numDestinations) return null;
result = documentSendInfo.createResult();
docSendInfoByOperationId.remove(endpointResult.getOperationId());
String documentId = documentSendInfo.getDocument().getDocumentId();
- /**
- * If we got a pending operation against this document
- * dont't remove it from inflightDocuments and send blocked document operation
- */
+ // If we got a pending operation against this document
+ // dont't remove it from inflightDocuments and send blocked document operation
List<Document> blockedDocuments = blockedDocumentsByDocumentId.get(documentId);
if (blockedDocuments.isEmpty()) {
inflightDocumentIds.remove(documentId);
@@ -210,7 +188,6 @@ public class OperationProcessor {
public void resultReceived(EndpointResult endpointResult, int clusterId) {
Result result = process(endpointResult, clusterId);
-
if (result != null) {
incompleteResultsThrottler.resultReady(result.isSuccess());
resultCallback.onCompletion(result.getDocumentId(), result);
@@ -252,7 +229,6 @@ public class OperationProcessor {
}
private void sendToClusters(Document document) {
-
synchronized (monitor) {
boolean traceThisDoc = traceEveryXOperation > 0 && traceCounter++ % traceEveryXOperation == 0;
docSendInfoByOperationId.put(document.getOperationId(), new DocumentSendInfo(document, traceThisDoc));
@@ -319,4 +295,5 @@ public class OperationProcessor {
throw new RuntimeException("Did not manage to shut down retry threads. Please report problem.");
}
}
+
}
diff --git a/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/SyncFeedClientTest.java b/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/SyncFeedClientTest.java
index a2d5b18999e..388c71087ec 100644
--- a/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/SyncFeedClientTest.java
+++ b/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/SyncFeedClientTest.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.http.client;
import com.yahoo.vespa.http.client.config.Cluster;
import com.yahoo.vespa.http.client.config.ConnectionParams;
import com.yahoo.vespa.http.client.config.Endpoint;
+import com.yahoo.vespa.http.client.config.FeedParams;
import com.yahoo.vespa.http.client.config.SessionParams;
import org.junit.Test;
@@ -36,7 +37,6 @@ public class SyncFeedClientTest {
.build();
SyncFeedClient feedClient = new SyncFeedClient(sessionParams);
-
assertFeedSuccessful(feedClient);
assertFeedSuccessful(feedClient); // ensure the client can be reused
feedClient.close();
diff --git a/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java b/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java
index 3143282081b..5a4c6d05185 100644
--- a/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java
+++ b/vespa-http-client/src/test/java/com/yahoo/vespa/http/client/core/communication/IOThreadTest.java
@@ -162,7 +162,7 @@ public class IOThreadTest {
@Test
public void requireThatEndpointConnectExceptionsArePropagated()
- throws IOException, ServerResponseException, InterruptedException, TimeoutException, ExecutionException {
+ throws IOException, ServerResponseException, InterruptedException, TimeoutException, ExecutionException {
when(apacheGatewayConnection.connect()).thenReturn(true);
String errorMessage = "generic error message";
IOException cause = new IOException(errorMessage);