diff options
41 files changed, 275 insertions, 260 deletions
diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/rpc/RpcServer.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/rpc/RpcServer.java index 7f525c438bf..87901a9bdb4 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/rpc/RpcServer.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/rpc/RpcServer.java @@ -139,25 +139,25 @@ public class RpcServer { public void addMethods() { - Method m = new Method("getMaster", "", "is", this, "queueRpcRequest"); + Method m = new Method("getMaster", "", "is", this::queueRpcRequest); m.methodDesc("Get index of current fleetcontroller master"); m.returnDesc(0, "masterindex", "The index of the current master according to this node, or -1 if there is none."); m.returnDesc(1, "description", "A textual field, used for additional information, such as why there is no master."); supervisor.addMethod(m); - m = new Method("getNodeList", "", "SS", this, "queueRpcRequest"); + m = new Method("getNodeList", "", "SS", this::queueRpcRequest); m.methodDesc("Get list of connection-specs to all nodes in the system"); m.returnDesc(0, "distributors", "connection-spec of all distributor-nodes (empty string for unknown nodes)"); m.returnDesc(1, "storagenodes", "connection-spec of all storage-nodes, (empty string for unknown nodes)"); supervisor.addMethod(m); - m = new Method("getSystemState", "", "ss", this, "queueRpcRequest"); + m = new Method("getSystemState", "", "ss", this::queueRpcRequest); m.methodDesc("Get nodeState of all nodes and the system itself"); m.returnDesc(0, "systemstate", "nodeState string of system"); m.returnDesc(1, "nodestate", "nodeState-string for distributor and storage-nodes"); supervisor.addMethod(m); - m = new Method("getNodeState", "si", "ssss", this, "queueRpcRequest"); + m = new Method("getNodeState", "si", "ssss", this::queueRpcRequest); m.methodDesc("Get nodeState of a node"); m.paramDesc(0, "nodeType", "Type of node. Should be 'storage' or 'distributor'"); m.paramDesc(1, "nodeIndex", "The node index"); @@ -167,7 +167,7 @@ public class RpcServer { m.returnDesc(3, "rpcAddress", "This nodes RPC server address"); supervisor.addMethod(m); - m = new Method("setNodeState", "ss", "s", this, "queueRpcRequest"); + m = new Method("setNodeState", "ss", "s", this::queueRpcRequest); m.methodDesc("Set nodeState of a node"); m.paramDesc(0, "slobrokAddress", "Slobrok address of node"); m.paramDesc(1, "nodeState", "Desired nodeState of the node (complete nodeState string - [key:value ]*)"); @@ -176,7 +176,7 @@ public class RpcServer { } // Called by rpc - public void queueRpcRequest(Request req) { + private void queueRpcRequest(Request req) { synchronized(monitor) { req.detach(); rpcRequests.add(req); diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DummyVdsNode.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DummyVdsNode.java index bd68f0fa343..27415cde407 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DummyVdsNode.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DummyVdsNode.java @@ -331,13 +331,13 @@ public class DummyVdsNode { private void addMethods() { Method m; - m = new Method("vespa.storage.connect", "s", "i", this, "rpc_storageConnect"); + m = new Method("vespa.storage.connect", "s", "i", this::rpc_storageConnect); m.methodDesc("Binds connection to a storage API handle"); m.paramDesc(0, "somearg", "Argument looking like slobrok address of the ones we're asking for some reason"); m.returnDesc(0, "returnCode", "Returncode of request. Should be 0 = OK"); supervisor.addMethod(m); - m = new Method("getnodestate", "", "issi", this, "rpc_getNodeState"); + m = new Method("getnodestate", "", "issi", this::rpc_getNodeState); m.methodDesc("Get nodeState of a node"); m.returnDesc(0, "returnCode", "Returncode of request. Should be 1 = OK"); m.returnDesc(1, "returnMessage", "Textual error message if returncode is not ok."); @@ -345,7 +345,7 @@ public class DummyVdsNode { m.returnDesc(3, "progress", "Progress in percent of node initialization"); supervisor.addMethod(m); - m = new Method("setsystemstate", "s", "is", this, "rpc_setSystemState"); + m = new Method("setsystemstate", "s", "is", this::rpc_setSystemState); m.methodDesc("Set system state of entire system"); m.paramDesc(0, "systemState", "new systemstate"); m.returnDesc(0, "returnCode", "Returncode of request. Should be 1 = OK"); @@ -353,20 +353,20 @@ public class DummyVdsNode { supervisor.addMethod(m); if (stateCommunicationVersion > 0) { - m = new Method("getnodestate2", "si", "s", this, "rpc_getNodeState2"); + m = new Method("getnodestate2", "si", "s", this::rpc_getNodeState2); m.methodDesc("Get nodeState of a node, answer when state changes from given state."); m.paramDesc(0, "nodeStateIn", "The node state of the given node"); m.paramDesc(1, "timeout", "Time timeout in milliseconds set by the state requester."); m.returnDesc(0, "nodeStateOut", "The node state of the given node"); supervisor.addMethod(m); - m = new Method("setsystemstate2", "s", "", this, "rpc_setSystemState2"); + m = new Method("setsystemstate2", "s", "", this::rpc_setSystemState2); m.methodDesc("Set system state of entire system"); m.paramDesc(0, "systemState", "new systemstate"); supervisor.addMethod(m); if (stateCommunicationVersion > 1) { - m = new Method("getnodestate3", "sii", "ss", this, "rpc_getNodeState2"); + m = new Method("getnodestate3", "sii", "ss", this::rpc_getNodeState2); m.methodDesc("Get nodeState of a node, answer when state changes from given state."); m.paramDesc(0, "nodeStateIn", "The node state of the given node"); m.paramDesc(1, "timeout", "Time timeout in milliseconds set by the state requester."); @@ -376,7 +376,7 @@ public class DummyVdsNode { } } if (stateCommunicationVersion >= RPCCommunicator.SET_DISTRIBUTION_STATES_RPC_VERSION) { - m = new Method(RPCCommunicator.SET_DISTRIBUTION_STATES_RPC_METHOD_NAME, "bix", "", this, "rpc_setDistributionStates"); + m = new Method(RPCCommunicator.SET_DISTRIBUTION_STATES_RPC_METHOD_NAME, "bix", "", this::rpc_setDistributionStates); m.methodDesc("Set distribution states for cluster and bucket spaces"); m.paramDesc(0, "compressionType", "Compression type for payload"); m.paramDesc(1, "uncompressedSize", "Uncompressed size of payload"); @@ -384,7 +384,7 @@ public class DummyVdsNode { supervisor.addMethod(m); } if (stateCommunicationVersion >= RPCCommunicator.ACTIVATE_CLUSTER_STATE_VERSION_RPC_VERSION) { - m = new Method(RPCCommunicator.ACTIVATE_CLUSTER_STATE_VERSION_RPC_METHOD_NAME, "i", "i", this, "rpc_activateClusterStateVersion"); + m = new Method(RPCCommunicator.ACTIVATE_CLUSTER_STATE_VERSION_RPC_METHOD_NAME, "i", "i", this::rpc_activateClusterStateVersion); m.methodDesc("Activate a given cluster state version"); m.paramDesc(0, "stateVersion", "Cluster state version to activate"); m.returnDesc(0, "actualVersion", "Actual cluster state version on node"); @@ -392,7 +392,7 @@ public class DummyVdsNode { } } - public void rpc_storageConnect(Request req) { + private void rpc_storageConnect(Request req) { synchronized(timer) { log.log(LogLevel.SPAM, "Dummy node " + this + " got old type handle connect message."); req.returnValues().add(new Int32Value(0)); @@ -400,7 +400,7 @@ public class DummyVdsNode { } } - public void rpc_getNodeState(Request req) { + private void rpc_getNodeState(Request req) { synchronized(timer) { if (!negotiatedHandle) { req.setError(75000, "Connection not bound to a handle"); @@ -431,7 +431,7 @@ public class DummyVdsNode { return false; } - public void rpc_getNodeState2(Request req) { + private void rpc_getNodeState2(Request req) { log.log(LogLevel.DEBUG, "Dummy node " + this + ": Got " + req.methodName() + " request"); try{ String oldState = req.parameters().get(0).asString(); @@ -500,7 +500,7 @@ public class DummyVdsNode { } } - public void rpc_setSystemState(Request req) { + private void rpc_setSystemState(Request req) { try{ if (shouldFailSetSystemStateRequests()) { req.setError(ErrorCode.GENERAL_ERROR, "Dummy node configured to fail setSystemState() calls"); @@ -527,7 +527,7 @@ public class DummyVdsNode { } } - public void rpc_setSystemState2(Request req) { + private void rpc_setSystemState2(Request req) { try{ if (shouldFailSetSystemStateRequests()) { req.setError(ErrorCode.GENERAL_ERROR, "Dummy node configured to fail setSystemState2() calls"); @@ -550,7 +550,7 @@ public class DummyVdsNode { } } - public void rpc_setDistributionStates(Request req) { + private void rpc_setDistributionStates(Request req) { try { if (shouldFailSetSystemStateRequests()) { req.setError(ErrorCode.GENERAL_ERROR, "Dummy node configured to fail setDistributionStates() calls"); @@ -573,7 +573,7 @@ public class DummyVdsNode { } } - public void rpc_activateClusterStateVersion(Request req) { + private void rpc_activateClusterStateVersion(Request req) { try { if (shouldFailSetSystemStateRequests()) { // We assume that failing setDistributionStates also implies failing version activations 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 f80c2699da2..db3b787f9f9 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 @@ -57,45 +57,45 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer } private void declareConfigMethods() { - supervisor.addMethod(JRTMethods.createConfigV3GetConfigMethod(this, "getConfigV3")); + supervisor.addMethod(JRTMethods.createConfigV3GetConfigMethod(this::getConfigV3)); supervisor.addMethod(new Method("ping", "", "i", - this, "ping") + this::ping) .methodDesc("ping") .returnDesc(0, "ret code", "return code, 0 is OK")); supervisor.addMethod(new Method("printStatistics", "", "s", - this, "printStatistics") + this::printStatistics) .methodDesc("printStatistics") .returnDesc(0, "statistics", "Statistics for server")); supervisor.addMethod(new Method("listCachedConfig", "", "S", - this, "listCachedConfig") + this::listCachedConfig) .methodDesc("list cached configs)") .returnDesc(0, "data", "string array of configs")); supervisor.addMethod(new Method("listCachedConfigFull", "", "S", - this, "listCachedConfigFull") + this::listCachedConfigFull) .methodDesc("list cached configs with cache content)") .returnDesc(0, "data", "string array of configs")); supervisor.addMethod(new Method("listSourceConnections", "", "S", - this, "listSourceConnections") + this::listSourceConnections) .methodDesc("list config source connections)") .returnDesc(0, "data", "string array of source connections")); supervisor.addMethod(new Method("invalidateCache", "", "S", - this, "invalidateCache") + this::invalidateCache) .methodDesc("list config source connections)") .returnDesc(0, "data", "0 if success, 1 otherwise")); supervisor.addMethod(new Method("updateSources", "s", "s", - this, "updateSources") + this::updateSources) .methodDesc("update list of config sources") .returnDesc(0, "ret", "list of updated config sources")); supervisor.addMethod(new Method("setMode", "s", "S", - this, "setMode") + this::setMode) .methodDesc("Set config proxy mode { default | memorycache }") .returnDesc(0, "ret", "0 if success, 1 otherwise as first element, description as second element")); supervisor.addMethod(new Method("getMode", "", "s", - this, "getMode") + this::getMode) .methodDesc("What serving mode the config proxy is in (default, memorycache)") .returnDesc(0, "ret", "mode as a string")); supervisor.addMethod(new Method("dumpCache", "s", "s", - this, "dumpCache") + this::dumpCache) .methodDesc("Dump cache to disk") .paramDesc(0, "path", "path to write cache contents to") .returnDesc(0, "ret", "Empty string or error message")); @@ -108,8 +108,7 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer * * @param req a Request */ - @SuppressWarnings({"UnusedDeclaration"}) - public final void getConfigV3(Request req) { + private void getConfigV3(Request req) { log.log(LogLevel.SPAM, () -> "getConfigV3"); JRTServerConfigRequest request = JRTServerConfigRequestV3.createFromRequest(req); if (isProtocolVersionSupported(request)) { @@ -123,7 +122,7 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer * * @param req a Request */ - public final void ping(Request req) { + void ping(Request req) { req.returnValues().add(new Int32Value(0)); } @@ -132,7 +131,7 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer * * @param req a Request */ - public final void printStatistics(Request req) { + void printStatistics(Request req) { StringBuilder sb = new StringBuilder(); sb.append("\nDelayed responses queue size: "); sb.append(proxyServer.delayedResponses.size()); @@ -144,23 +143,22 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer req.returnValues().add(new StringValue(sb.toString())); } - public final void listCachedConfig(Request req) { + void listCachedConfig(Request req) { listCachedConfig(req, false); } - public final void listCachedConfigFull(Request req) { + void listCachedConfigFull(Request req) { listCachedConfig(req, true); } - public final void listSourceConnections(Request req) { + 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)); } - @SuppressWarnings({"UnusedDeclaration"}) - public final void updateSources(Request req) { + void updateSources(Request req) { String sources = req.parameters().get(0).asString(); String ret; System.out.println(proxyServer.getMode()); @@ -173,7 +171,7 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer req.returnValues().add(new StringValue(ret)); } - public final void invalidateCache(Request req) { + void invalidateCache(Request req) { proxyServer.getMemoryCache().clear(); String[] s = new String[2]; s[0] = "0"; @@ -181,7 +179,7 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer req.returnValues().add(new StringArray(s)); } - public final void setMode(Request req) { + void setMode(Request req) { String suppliedMode = req.parameters().get(0).asString(); log.log(LogLevel.DEBUG, () -> "Supplied mode=" + suppliedMode); String[] s = new String[2]; @@ -197,12 +195,11 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer req.returnValues().add(new StringArray(s)); } - public final void getMode(Request req) { + void getMode(Request req) { req.returnValues().add(new StringValue(proxyServer.getMode().name())); } - @SuppressWarnings({"UnusedDeclaration"}) - public final void dumpCache(Request req) { + void dumpCache(Request req) { final MemoryCache memoryCache = proxyServer.getMemoryCache(); req.returnValues().add(new StringValue(memoryCache.dumpCacheToDisk(req.parameters().get(0).asString(), memoryCache))); } 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/UrlDownloadRpcServer.java index 8c25593dde0..711c43340cb 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/UrlDownloadRpcServer.java @@ -48,15 +48,14 @@ public class UrlDownloadRpcServer { new DaemonThreadFactory("Rpc download executor")); UrlDownloadRpcServer(Supervisor supervisor) { - supervisor.addMethod(new Method("url.waitFor", "s", "s", this, "download") + supervisor.addMethod(new Method("url.waitFor", "s", "s", this::download) .methodDesc("get path to url download") .paramDesc(0, "url", "url") .returnDesc(0, "path", "path to file")); downloadBaseDir = new File(Defaults.getDefaults().underVespaHome("var/db/vespa/download")); } - @SuppressWarnings({"UnusedDeclaration"}) - public final void download(Request req) { + private void download(Request req) { req.detach(); rpcDownloadExecutor.execute(() -> downloadFile(req)); } diff --git a/config/src/main/java/com/yahoo/vespa/config/JRTMethods.java b/config/src/main/java/com/yahoo/vespa/config/JRTMethods.java index 1f9bd66972f..bc0c9cdec51 100644 --- a/config/src/main/java/com/yahoo/vespa/config/JRTMethods.java +++ b/config/src/main/java/com/yahoo/vespa/config/JRTMethods.java @@ -14,11 +14,6 @@ public class JRTMethods { private static final String configV3GetConfigRequestTypes = "s"; private static final String configV3GetConfigResponseTypes = "sx"; - public static Method createConfigV3GetConfigMethod(Object handler, String handlerMethod) { - return addDescriptions( - new Method(configV3getConfigMethodName, configV3GetConfigRequestTypes, configV3GetConfigResponseTypes, handler, handlerMethod)); - } - public static Method createConfigV3GetConfigMethod(MethodHandler methodHandler) { return addDescriptions( new Method(configV3getConfigMethodName, configV3GetConfigRequestTypes, configV3GetConfigResponseTypes, methodHandler)); diff --git a/config/src/main/java/com/yahoo/vespa/config/benchmark/StressTester.java b/config/src/main/java/com/yahoo/vespa/config/benchmark/StressTester.java index a7076d0e32a..4234a6deff1 100644 --- a/config/src/main/java/com/yahoo/vespa/config/benchmark/StressTester.java +++ b/config/src/main/java/com/yahoo/vespa/config/benchmark/StressTester.java @@ -176,7 +176,7 @@ public class StressTester { RpcServer(String host, int port, StressTester tester) { this.tester = tester; - setUp(this); + setUp(); spec = new Spec(host, port); } @@ -194,7 +194,7 @@ public class StressTester { supervisor.transport().shutdown().join(); } - public final void start(Request request) { + private void start(Request request) { debug("start: Got " + request); int ret = 1; int clients = request.parameters().get(0).asInt32(); @@ -210,7 +210,7 @@ public class StressTester { request.returnValues().add(new Int32Value(ret)); } - public final void verify(Request request) { + private void verify(Request request) { debug("verify: Got " + request); long generation = request.parameters().get(0).asInt64(); String verificationFile = request.parameters().get(1).asString(); @@ -235,7 +235,7 @@ public class StressTester { request.returnValues().add(new StringValue(errorMessage)); } - public final void stop(Request request) { + private void stop(Request request) { debug("stop: Got " + request); int ret = 1; try { @@ -250,26 +250,20 @@ public class StressTester { /** * Set up RPC method handlers. - * - * @param handler a MethodHandler that will handle the RPC methods */ - - protected void setUp(Object handler) { - supervisor.addMethod(new Method("start", "i", "i", - handler, "start") + protected void setUp() { + supervisor.addMethod(new Method("start", "i", "i", this::start) .methodDesc("start") .paramDesc(0, "clients", "number of clients") .returnDesc(0, "ret code", "return code, 0 is OK")); - supervisor.addMethod(new Method("verify", "lsl", "is", - handler, "verify") + supervisor.addMethod(new Method("verify", "lsl", "is", this::verify) .methodDesc("verify") .paramDesc(0, "generation", "config generation") .paramDesc(1, "verification file", "name of verification file") .paramDesc(2, "timeout", "timeout when verifying") .returnDesc(0, "ret code", "return code, 0 is OK") .returnDesc(1, "error message", "error message, if non zero return code")); - supervisor.addMethod(new Method("stop", "", "i", - handler, "stop") + supervisor.addMethod(new Method("stop", "", "i", this::stop) .methodDesc("stop") .returnDesc(0, "ret code", "return code, 0 is OK")); } diff --git a/container-search/abi-spec.json b/container-search/abi-spec.json index fb50da7bff1..e96d208679d 100644 --- a/container-search/abi-spec.json +++ b/container-search/abi-spec.json @@ -6425,10 +6425,12 @@ ], "methods": [ "public void <init>()", - "public void put(java.lang.String, java.lang.String)", + "public void put(java.lang.String, double)", "public void put(java.lang.String, com.yahoo.tensor.Tensor)", + "public void put(java.lang.String, java.lang.String)", "public java.lang.String get(java.lang.String)", "public java.lang.Object getObject(java.lang.String)", + "public java.util.OptionalDouble getDouble(java.lang.String)", "public java.util.Optional getTensor(java.lang.String)", "public java.util.Map asMap()", "public boolean isEmpty()", diff --git a/container-search/src/main/java/com/yahoo/fs4/MapEncoder.java b/container-search/src/main/java/com/yahoo/fs4/MapEncoder.java index 565a4c483c3..3e45d7e5f53 100644 --- a/container-search/src/main/java/com/yahoo/fs4/MapEncoder.java +++ b/container-search/src/main/java/com/yahoo/fs4/MapEncoder.java @@ -64,12 +64,12 @@ public class MapEncoder { buffer.putInt(utf8.length); buffer.put(utf8); buffer.putInt(map.size()); - for (Map.Entry<String, ?> property : map.entrySet()) { - String key = property.getKey(); + for (Map.Entry<String, ?> entry : map.entrySet()) { + String key = entry.getKey(); utf8 = Utf8.toBytes(key); buffer.putInt(utf8.length); buffer.put(utf8); - Object value = property.getValue(); + Object value = entry.getValue(); if (value == null) { utf8 = Utf8.toBytes(""); } else { diff --git a/container-search/src/main/java/com/yahoo/search/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/search/cluster/ClusterSearcher.java index ff099d4d490..e99199d85f7 100644 --- a/container-search/src/main/java/com/yahoo/search/cluster/ClusterSearcher.java +++ b/container-search/src/main/java/com/yahoo/search/cluster/ClusterSearcher.java @@ -160,7 +160,7 @@ public abstract class ClusterSearcher<T> extends PingableSearcher implements Nod result = robustSearch(query, execution, connection); - if (!shouldRetry(query, result)) + if ( ! shouldRetry(query, result)) return result; if (query.getTraceLevel() >= 6) diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/MapConverter.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/MapConverter.java index 74828dd6740..7c97da6a77d 100644 --- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/MapConverter.java +++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/MapConverter.java @@ -16,6 +16,7 @@ import java.util.function.Consumer; * @author ollivir */ public class MapConverter { + public static void convertMapTensors(Map<String, Object> map, Consumer<TensorProperty.Builder> inserter) { for (var entry : map.entrySet()) { var value = entry.getValue(); @@ -26,7 +27,7 @@ public class MapConverter { } } - public static void convertMapStrings(Map<String, Object> map, Consumer<StringProperty.Builder> inserter) { + public static void convertMapPrimitives(Map<String, Object> map, Consumer<StringProperty.Builder> inserter) { for (var entry : map.entrySet()) { var value = entry.getValue(); if (!(value instanceof Tensor)) { @@ -66,4 +67,5 @@ public class MapConverter { } } } + } diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java index 5ef4562f040..39a1587afea 100644 --- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java +++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.function.Consumer; public class ProtobufSerialization { + private static final int INITIAL_SERIALIZATION_BUFFER_SIZE = 10 * 1024; public static byte[] serializeSearchRequest(Query query, String serverId) { @@ -87,7 +88,7 @@ public class ProtobufSerialization { } var featureMap = ranking.getFeatures().asMap(); - MapConverter.convertMapStrings(featureMap, builder::addFeatureOverrides); + MapConverter.convertMapPrimitives(featureMap, builder::addFeatureOverrides); MapConverter.convertMapTensors(featureMap, builder::addTensorFeatureOverrides); mergeRankProperties(ranking, builder::addRankProperties, builder::addTensorRankProperties); } @@ -101,8 +102,10 @@ public class ProtobufSerialization { } } - public static SearchProtocol.DocsumRequest.Builder createDocsumRequestBuilder(Query query, String serverId, String summaryClass, - boolean includeQueryData) { + public static SearchProtocol.DocsumRequest.Builder createDocsumRequestBuilder(Query query, + String serverId, + String summaryClass, + boolean includeQueryData) { var builder = SearchProtocol.DocsumRequest.newBuilder() .setTimeout((int) query.getTimeLeft()) .setDumpFeatures(query.properties().getBoolean(Ranking.RANKFEATURES, false)); @@ -146,7 +149,7 @@ public class ProtobufSerialization { if (ranking.getLocation() != null) { builder.setGeoLocation(ranking.getLocation().toString()); } - MapConverter.convertMapStrings(featureMap, builder::addFeatureOverrides); + MapConverter.convertMapPrimitives(featureMap, builder::addFeatureOverrides); MapConverter.convertMapTensors(featureMap, builder::addTensorFeatureOverrides); if (query.getPresentation().getHighlight() != null) { MapConverter.convertStringMultiMap(query.getPresentation().getHighlight().getHighlightTerms(), builder::addHighlightTerms); @@ -165,8 +168,12 @@ public class ProtobufSerialization { return result; } - private static Result convertToResult(Query query, SearchProtocol.SearchReply protobuf, DocumentDatabase documentDatabase, int partId, - int distKey, String source) { + private static Result convertToResult(Query query, + SearchProtocol.SearchReply protobuf, + DocumentDatabase documentDatabase, + int partId, + int distKey, + String source) { var result = new Result(query); result.setTotalHitCount(protobuf.getTotalHitCount()); @@ -269,12 +276,14 @@ public class ProtobufSerialization { } } - private static void mergeRankProperties(Ranking ranking, Consumer<StringProperty.Builder> stringProperties, - Consumer<TensorProperty.Builder> tensorProperties) { + private static void mergeRankProperties(Ranking ranking, + Consumer<StringProperty.Builder> stringProperties, + Consumer<TensorProperty.Builder> tensorProperties) { MapConverter.convertMultiMap(ranking.getProperties().asMap(), propB -> { if (!GetDocSumsPacket.sessionIdKey.equals(propB.getName())) { stringProperties.accept(propB); } }, tensorProperties); } + } diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java b/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java index 9786eba163a..3bc3a629c5d 100644 --- a/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java +++ b/container-search/src/main/java/com/yahoo/search/query/ranking/RankFeatures.java @@ -11,6 +11,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.OptionalDouble; /** * Contains the rank features of a query. @@ -29,8 +30,8 @@ public class RankFeatures implements Cloneable { this.features = features; } - /** Sets a rank feature by full name to a value */ - public void put(String name, String value) { + /** Sets a double rank feature */ + public void put(String name, double value) { features.put(name, value); } @@ -39,6 +40,11 @@ public class RankFeatures implements Cloneable { features.put(name, value); } + /** Sets a rank feature to a value represented as a string */ + public void put(String name, String value) { + features.put(name, value); + } + /** Returns a rank feature as a string by full name or null if not set */ public String get(String name) { Object value = features.get(name); @@ -52,6 +58,18 @@ public class RankFeatures implements Cloneable { } /** + * Returns a double rank feature, or empty if there is no value with this name. + * + * @throws IllegalArgumentException if the value is set but is not a double + */ + public OptionalDouble getDouble(String name) { + Object feature = features.get(name); + if (feature == null) return OptionalDouble.empty(); + if (feature instanceof Double) return OptionalDouble.of((Double)feature); + throw new IllegalArgumentException("Expected a double value of '" + name + "' but has " + feature); + } + + /** * Returns a tensor rank feature, or empty if there is no value with this name. * * @throws IllegalArgumentException if the value is set but is not a tensor diff --git a/container-search/src/test/java/com/yahoo/fs4/test/RankFeaturesTestCase.java b/container-search/src/test/java/com/yahoo/fs4/test/RankFeaturesTestCase.java index e8c16e572ae..b52c708ce4b 100644 --- a/container-search/src/test/java/com/yahoo/fs4/test/RankFeaturesTestCase.java +++ b/container-search/src/test/java/com/yahoo/fs4/test/RankFeaturesTestCase.java @@ -24,12 +24,31 @@ public class RankFeaturesTestCase { public void requireThatRankPropertiesTakesBothStringAndObject() { RankProperties p = new RankProperties(); p.put("string", "b"); - p.put("object", Integer.valueOf(7)); + p.put("object", 7); assertEquals("7", p.get("object").get(0)); assertEquals("b", p.get("string").get(0)); } @Test + public void requireThatRankFeaturesUsingDoubleAndDoubleToStringEncodeTheSameWay() { + RankFeatures withDouble = new RankFeatures(); + withDouble.put("query(myDouble)", 3.8); + assertEquals(3.8, withDouble.getDouble("query(myDouble)").getAsDouble(), 0.000001); + + RankFeatures withString = new RankFeatures(); + withString.put("query(myDouble)", String.valueOf(3.8)); + + RankProperties withDoubleP = new RankProperties(); + withDouble.prepare(withDoubleP); + RankProperties withStringP = new RankProperties(); + withString.prepare(withStringP); + + byte[] withDoubleEncoded = encode(withDoubleP); + byte[] withStringEncoded = encode(withStringP); + assertEquals(Arrays.toString(withStringEncoded), Arrays.toString(withDoubleEncoded)); + } + + @Test public void requireThatSingleTensorIsBinaryEncoded() { TensorType type = new TensorType.Builder().mapped("x").mapped("y").mapped("z").build(); Tensor tensor = Tensor.from(type, "{ {x:a, y:b, z:c}:2.0, {x:a, y:b, z:c2}:3.0 }"); @@ -113,4 +132,5 @@ public class RankFeaturesTestCase { } return result; } + } diff --git a/container-search/src/test/java/com/yahoo/search/cluster/test/ClusteredConnectionTestCase.java b/container-search/src/test/java/com/yahoo/search/cluster/test/ClusteredConnectionTestCase.java index a565c171b98..a35cbdf289e 100644 --- a/container-search/src/test/java/com/yahoo/search/cluster/test/ClusteredConnectionTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/cluster/test/ClusteredConnectionTestCase.java @@ -34,7 +34,7 @@ public class ClusteredConnectionTestCase { connections.add(connection0); connections.add(connection1); connections.add(connection2); - MyBackend myBackend=new MyBackend(new ComponentId("test"),connections); + MyBackend myBackend = new MyBackend(new ComponentId("test"), connections); Result r; r=new Execution(myBackend, Execution.Context.createContextStub()).search(new SimpleQuery(0)); @@ -67,7 +67,7 @@ public class ClusteredConnectionTestCase { assertEquals("from:0",r.hits().get(0).getId().stringValue()); connection0.setInService(false); - r=new Execution(myBackend, Execution.Context.createContextStub()).search(new SimpleQuery(0)); + r = new Execution(myBackend, Execution.Context.createContextStub()).search(new SimpleQuery(0)); assertEquals("Failed calling connection '2' in searcher 'test' for query 'NULL': Connection failed", r.hits().getError().getDetailedMessage()); @@ -134,7 +134,7 @@ public class ClusteredConnectionTestCase { private String id; - private boolean inService=true; + private boolean inService = true; public Connection(String id) { this.id=id; @@ -142,12 +142,12 @@ public class ClusteredConnectionTestCase { /** This is used for both fill, pings and queries */ public String getResponse() { - if (!inService) throw new RuntimeException("Connection failed"); + if ( ! inService) throw new RuntimeException("Connection failed"); return id; } public void setInService(boolean inservice) { - this.inService=inservice; + this.inService = inservice; } public String toString() { @@ -164,25 +164,25 @@ public class ClusteredConnectionTestCase { private static class MyBackend extends ClusterSearcher<Connection> { public MyBackend(ComponentId componentId, List<Connection> connections) { - super(componentId,connections,false); + super(componentId,connections, false); } @Override - public Result search(Query query,Execution execution,Connection connection) { - Result result=new Result(query); + public Result search(Query query,Execution execution, Connection connection) { + Result result = new Result(query); result.hits().add(new Hit("from:" + connection.getResponse())); return result; } @Override - public void fill(Result result,String summary,Execution execution,Connection connection) { + public void fill(Result result,String summary, Execution execution, Connection connection) { result.hits().get(0).fields().put("filled",connection.getResponse()); } @Override public Pong ping(Ping ping,Connection connection) { - Pong pong=new Pong(); - if (connection.getResponse()==null) + Pong pong = new Pong(); + if (connection.getResponse() == null) pong.addError(ErrorMessage.createBackendCommunicationError("No ping response from '" + connection + "'")); return pong; } @@ -203,6 +203,11 @@ public class ClusteredConnectionTestCase { return hashValue; } + @Override + public long getTimeout() { + return 5000; + } + } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/TenantType.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/TenantType.java index 9f89da717be..0f04a31a9ed 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/TenantType.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/application/v4/model/TenantType.java @@ -6,5 +6,6 @@ package com.yahoo.vespa.hosted.controller.api.application.v4.model; */ public enum TenantType { USER, - ATHENS + ATHENS, + CLOUD } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index f5b6f284d6b..d231b034e8a 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -1144,7 +1144,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler { private void toSlime(Cursor object, Tenant tenant, HttpRequest request) { object.setString("tenant", tenant.name().value()); - object.setString("type", tentantType(tenant)); + object.setString("type", tenantType(tenant)); switch (tenant.type()) { case athenz: AthenzTenant athenzTenant = (AthenzTenant) tenant; @@ -1181,7 +1181,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler { private void tenantInTenantsListToSlime(Tenant tenant, URI requestURI, Cursor object) { object.setString("tenant", tenant.name().value()); Cursor metaData = object.setObject("metaData"); - metaData.setString("type", tentantType(tenant)); + metaData.setString("type", tenantType(tenant)); switch (tenant.type()) { case athenz: AthenzTenant athenzTenant = (AthenzTenant) tenant; @@ -1389,7 +1389,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler { return ImmutableSet.of("all", "true", "deployment").contains(request.getProperty("recursive")); } - private static String tentantType(Tenant tenant) { + private static String tenantType(Tenant tenant) { switch (tenant.type()) { case user: return "USER"; case athenz: return "ATHENS"; 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 bf9201e6cda..d27d7422beb 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileDistributionRpcServer.java @@ -43,23 +43,19 @@ public class FileDistributionRpcServer { private void declareFileDistributionMethods() { // Legacy method, needs to be the same name as used in filedistributor - supervisor.addMethod(new Method("waitFor", "s", "s", - this, "getFile") + supervisor.addMethod(new Method("waitFor", "s", "s", this::getFile) .methodDesc("get path to file reference") .paramDesc(0, "file reference", "file reference") .returnDesc(0, "path", "path to file")); - supervisor.addMethod(new Method("filedistribution.getFile", "s", "s", - this, "getFile") + supervisor.addMethod(new Method("filedistribution.getFile", "s", "s", this::getFile) .methodDesc("get path to file reference") .paramDesc(0, "file reference", "file reference") .returnDesc(0, "path", "path to file")); - supervisor.addMethod(new Method("filedistribution.getActiveFileReferencesStatus", "", "SD", - this, "getActiveFileReferencesStatus") + supervisor.addMethod(new Method("filedistribution.getActiveFileReferencesStatus", "", "SD", this::getActiveFileReferencesStatus) .methodDesc("download status for file references") .returnDesc(0, "file references", "array of file references") .returnDesc(1, "download status", "percentage downloaded of each file reference in above array")); - supervisor.addMethod(new Method("filedistribution.setFileReferencesToDownload", "S", "i", - this, "setFileReferencesToDownload") + supervisor.addMethod(new Method("filedistribution.setFileReferencesToDownload", "S", "i", this::setFileReferencesToDownload) .methodDesc("set which file references to download") .paramDesc(0, "file references", "file reference to download") .returnDesc(0, "ret", "0 if success, 1 otherwise")); @@ -75,14 +71,12 @@ public class FileDistributionRpcServer { private static final int fileReferenceRemoved = fileReferenceDoesNotExists + 1; private static final int fileReferenceInternalError = fileReferenceRemoved + 1; - @SuppressWarnings({"UnusedDeclaration"}) - public final void getFile(Request req) { + private void getFile(Request req) { req.detach(); rpcDownloadExecutor.execute(() -> downloadFile(req)); } - @SuppressWarnings({"UnusedDeclaration"}) - public final void getActiveFileReferencesStatus(Request req) { + private void getActiveFileReferencesStatus(Request req) { Map<FileReference, Double> downloadStatus = downloader.downloadStatus(); String[] fileRefArray = new String[downloadStatus.keySet().size()]; @@ -101,8 +95,7 @@ public class FileDistributionRpcServer { req.returnValues().add(new DoubleArray(downloadStatusArray)); } - @SuppressWarnings({"UnusedDeclaration"}) - public final void setFileReferencesToDownload(Request req) { + private void setFileReferencesToDownload(Request req) { log.log(LogLevel.DEBUG, () -> "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); Arrays.stream(req.parameters().get(0).asStringArray()) .map(FileReference::new) diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReceiver.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReceiver.java index b9714cf8126..60a5e25b3e0 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReceiver.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReceiver.java @@ -156,27 +156,27 @@ public class FileReceiver { } private void registerMethods() { - receiveFileMethod(this).forEach(supervisor::addMethod); + receiveFileMethod().forEach(supervisor::addMethod); } // Defined here so that it can be added to supervisor used by client (server will use same connection when calling // receiveFile after getting a serveFile method call). handler needs to implement receiveFile* methods - private List<Method> receiveFileMethod(Object handler) { + private List<Method> receiveFileMethod() { List<Method> methods = new ArrayList<>(); - methods.add(new Method(RECEIVE_META_METHOD, "sssl", "ii", handler,"receiveFileMeta") + methods.add(new Method(RECEIVE_META_METHOD, "sssl", "ii", this::receiveFileMeta) .paramDesc(0, "filereference", "file reference to download") .paramDesc(1, "filename", "filename") .paramDesc(2, "type", "'file' or 'compressed'") .paramDesc(3, "filelength", "length in bytes of file") .returnDesc(0, "ret", "0 if success, 1 otherwise") .returnDesc(1, "session-id", "Session id to be used for this transfer")); - methods.add(new Method(RECEIVE_PART_METHOD, "siix", "i", handler,"receiveFilePart") + methods.add(new Method(RECEIVE_PART_METHOD, "siix", "i", this::receiveFilePart) .paramDesc(0, "filereference", "file reference to download") .paramDesc(1, "session-id", "Session id to be used for this transfer") .paramDesc(2, "partid", "relative part number starting at zero") .paramDesc(3, "data", "bytes in this part") .returnDesc(0, "ret", "0 if success, 1 otherwise")); - methods.add(new Method(RECEIVE_EOF_METHOD, "silis", "i", handler,"receiveFileEof") + methods.add(new Method(RECEIVE_EOF_METHOD, "silis", "i", this::receiveFileEof) .paramDesc(0, "filereference", "file reference to download") .paramDesc(1, "session-id", "Session id to be used for this transfer") .paramDesc(2, "crc-code", "crc code (xxhash64)") @@ -209,8 +209,7 @@ public class FileReceiver { } } - @SuppressWarnings({"UnusedDeclaration"}) - public final void receiveFileMeta(Request req) { + private void receiveFileMeta(Request req) { log.log(LogLevel.DEBUG, () -> "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); FileReference reference = new FileReference(req.parameters().get(0).asString()); String fileName = req.parameters().get(1).asString(); @@ -235,8 +234,7 @@ public class FileReceiver { req.returnValues().add(new Int32Value(sessionId)); } - @SuppressWarnings({"UnusedDeclaration"}) - public final void receiveFilePart(Request req) { + private void receiveFilePart(Request req) { log.log(LogLevel.DEBUG, () -> "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); FileReference reference = new FileReference(req.parameters().get(0).asString()); @@ -257,8 +255,7 @@ public class FileReceiver { req.returnValues().add(new Int32Value(retval)); } - @SuppressWarnings({"UnusedDeclaration"}) - public final void receiveFileEof(Request req) { + private void receiveFileEof(Request req) { log.log(LogLevel.DEBUG, () -> "Received method call '" + req.methodName() + "' with parameters : " + req.parameters()); FileReference reference = new FileReference(req.parameters().get(0).asString()); int sessionId = req.parameters().get(1).asInt32(); diff --git a/jrt/src/com/yahoo/jrt/MandatoryMethods.java b/jrt/src/com/yahoo/jrt/MandatoryMethods.java index 1176884eed5..57dd40c324b 100644 --- a/jrt/src/com/yahoo/jrt/MandatoryMethods.java +++ b/jrt/src/com/yahoo/jrt/MandatoryMethods.java @@ -3,7 +3,6 @@ package com.yahoo.jrt; import java.util.Collection; -import java.util.Iterator; class MandatoryMethods { @@ -15,21 +14,19 @@ class MandatoryMethods { //--------------------------------------------------------------------- Method m; //--------------------------------------------------------------------- - m = new Method("frt.rpc.ping", "", "", this, "ping"); + m = new Method("frt.rpc.ping", "", "", this::ping); m.methodDesc("Method that may be used to " + "check if the server is online"); parent.addMethod(m); //--------------------------------------------------------------------- - m = new Method("frt.rpc.getMethodList", "", "SSS", this, - "getMethodList"); + m = new Method("frt.rpc.getMethodList", "", "SSS", this::getMethodList); m.methodDesc("Obtain a list of all available methods"); m.returnDesc(0, "names", "Method names"); m.returnDesc(1, "params", "Method parameter types"); m.returnDesc(2, "return", "Method return types"); parent.addMethod(m); //--------------------------------------------------------------------- - m = new Method("frt.rpc.getMethodInfo", "s", "sssSSSS", this, - "getMethodInfo"); + m = new Method("frt.rpc.getMethodInfo", "s", "sssSSSS", this::getMethodInfo); m.methodDesc("Obtain detailed information about a single method"); m.paramDesc (0, "methodName", "The method we want information about"); m.returnDesc(0, "desc", "Description of what the method does"); @@ -43,11 +40,11 @@ class MandatoryMethods { //--------------------------------------------------------------------- } - public void ping(Request req) { + private void ping(Request req) { // no code needed :) } - public void getMethodList(Request req) { + private void getMethodList(Request req) { Collection<Method> methods = parent.methodMap().values(); int cnt = methods.size(); String[] ret0_names = new String[cnt]; @@ -66,7 +63,7 @@ class MandatoryMethods { req.returnValues().add(new StringArray(ret2_return)); } - public void getMethodInfo(Request req) { + private void getMethodInfo(Request req) { Method method = parent.methodMap().get(req.parameters().get(0).asString()); if (method == null) { req.setError(ErrorCode.METHOD_FAILED, "No Such Method"); diff --git a/jrt/src/com/yahoo/jrt/Method.java b/jrt/src/com/yahoo/jrt/Method.java index b3c5b037f27..59006202e8f 100644 --- a/jrt/src/com/yahoo/jrt/Method.java +++ b/jrt/src/com/yahoo/jrt/Method.java @@ -83,7 +83,10 @@ public class Method { * * @throws MethodCreateException if the handler method cannot be * resolved. + * + * @deprecated Use {@link Method#Method(String, String, String, MethodHandler)} instead. **/ + @Deprecated(forRemoval = true) public Method(String name, String paramTypes, String returnTypes, Object handler, String handlerMethod) { diff --git a/jrt/src/com/yahoo/jrt/MethodHandler.java b/jrt/src/com/yahoo/jrt/MethodHandler.java index 84fa100bf2d..f72e196e46a 100644 --- a/jrt/src/com/yahoo/jrt/MethodHandler.java +++ b/jrt/src/com/yahoo/jrt/MethodHandler.java @@ -10,6 +10,7 @@ package com.yahoo.jrt; * or with reflection. This choice is reflected by the two different * constructors in the {@link Method} class.</p> **/ +@FunctionalInterface public interface MethodHandler { /** diff --git a/jrt/tests/com/yahoo/jrt/AbortTest.java b/jrt/tests/com/yahoo/jrt/AbortTest.java index 9093158162d..edd74152a1c 100644 --- a/jrt/tests/com/yahoo/jrt/AbortTest.java +++ b/jrt/tests/com/yahoo/jrt/AbortTest.java @@ -21,7 +21,7 @@ public class AbortTest { client = new Supervisor(new Transport()); acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("test", "i", "i", this, "rpc_test")); + server.addMethod(new Method("test", "i", "i", this::rpc_test)); barrier = new Test.Barrier(); } diff --git a/jrt/tests/com/yahoo/jrt/BackTargetTest.java b/jrt/tests/com/yahoo/jrt/BackTargetTest.java index ade24f40c55..2a0066d68a0 100644 --- a/jrt/tests/com/yahoo/jrt/BackTargetTest.java +++ b/jrt/tests/com/yahoo/jrt/BackTargetTest.java @@ -25,15 +25,13 @@ public class BackTargetTest { acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("inc", "", "", this, "server_inc")); - server.addMethod(new Method("sample_target", "", "", this, - "server_sample_target")); - server.addMethod(new Method("back_inc", "", "", this, "back_inc")); + server.addMethod(new Method("inc", "", "", this::server_inc)); + server.addMethod(new Method("sample_target", "", "", this::server_sample_target)); + server.addMethod(new Method("back_inc", "", "", this::back_inc)); - client.addMethod(new Method("inc", "", "", this, "client_inc")); - client.addMethod(new Method("sample_target", "", "", this, - "client_sample_target")); - client.addMethod(new Method("back_inc", "", "", this, "back_inc")); + client.addMethod(new Method("inc", "", "", this::client_inc)); + client.addMethod(new Method("sample_target", "", "", this::client_sample_target)); + client.addMethod(new Method("back_inc", "", "", this::back_inc)); serverValue = 0; clientValue = 0; @@ -49,23 +47,23 @@ public class BackTargetTest { server.transport().shutdown().join(); } - public void server_inc(Request req) { + private void server_inc(Request req) { serverValue++; } - public void server_sample_target(Request req) { + private void server_sample_target(Request req) { serverBackTarget = req.target(); } - public void client_inc(Request req) { + private void client_inc(Request req) { clientValue++; } - public void client_sample_target(Request req) { + private void client_sample_target(Request req) { clientBackTarget = req.target(); } - public void back_inc(Request req) { + private void back_inc(Request req) { Target t = req.target(); t.invokeVoid(new Request("inc")); } diff --git a/jrt/tests/com/yahoo/jrt/DetachTest.java b/jrt/tests/com/yahoo/jrt/DetachTest.java index 808d029b5a5..8b107c8b61b 100644 --- a/jrt/tests/com/yahoo/jrt/DetachTest.java +++ b/jrt/tests/com/yahoo/jrt/DetachTest.java @@ -23,12 +23,9 @@ public class DetachTest { acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("d_inc", "i", "i", this, - "rpc_detach_inc")); - server.addMethod(new Method("d_inc_r", "i", "i", this, - "rpc_detach_inc_return")); - server.addMethod(new Method("inc_b", "i", "i", this, - "rpc_inc_barrier")); + server.addMethod(new Method("d_inc", "i", "i", this::rpc_detach_inc)); + server.addMethod(new Method("d_inc_r", "i", "i", this::rpc_detach_inc_return)); + server.addMethod(new Method("inc_b", "i", "i", this::rpc_inc_barrier)); receptor = new Test.Receptor(); barrier = new Test.Barrier(); } @@ -43,21 +40,21 @@ public class DetachTest { Request detached = null; - public void rpc_detach_inc(Request req) { + private void rpc_detach_inc(Request req) { req.detach(); int value = req.parameters().get(0).asInt32(); req.returnValues().add(new Int32Value(value + 1)); detached = req; } - public void rpc_detach_inc_return(Request req) { + private void rpc_detach_inc_return(Request req) { req.detach(); int value = req.parameters().get(0).asInt32(); req.returnValues().add(new Int32Value(value + 1)); req.returnRequest(); } - public void rpc_inc_barrier(Request req) { + private void rpc_inc_barrier(Request req) { int value = req.parameters().get(0).asInt32(); req.returnValues().add(new Int32Value(value + 1)); receptor.put(req); diff --git a/jrt/tests/com/yahoo/jrt/EchoTest.java b/jrt/tests/com/yahoo/jrt/EchoTest.java index 67544d3f1d4..97139fd60ab 100644 --- a/jrt/tests/com/yahoo/jrt/EchoTest.java +++ b/jrt/tests/com/yahoo/jrt/EchoTest.java @@ -95,7 +95,7 @@ public class EchoTest { client = new Supervisor(new Transport(crypto, 1)); acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("echo", "*", "*", this, "rpc_echo")); + server.addMethod(new Method("echo", "*", "*", this::rpc_echo)); refValues = new Values(); byte[] dataValue = { 1, 2, 3, 4 }; byte[] int8Array = { 1, 2, 3, 4 }; @@ -135,7 +135,7 @@ public class EchoTest { server.transport().shutdown().join(); } - public void rpc_echo(Request req) { + private void rpc_echo(Request req) { if (!Test.equals(req.parameters(), refValues)) { System.err.println("Parameters does not match reference values"); req.setError(ErrorCode.METHOD_FAILED, "parameter mismatch"); diff --git a/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java b/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java index cdc52e9441a..92925fc1a12 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java @@ -23,7 +23,7 @@ public class InvokeAsyncTest { client = new Supervisor(new Transport()); acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("concat", "ss", "s", this, "rpc_concat") + server.addMethod(new Method("concat", "ss", "s", this::rpc_concat) .methodDesc("Concatenate 2 strings") .paramDesc(0, "str1", "a string") .paramDesc(1, "str2", "another string") @@ -39,7 +39,7 @@ public class InvokeAsyncTest { server.transport().shutdown().join(); } - public void rpc_concat(Request req) { + private void rpc_concat(Request req) { barrier.waitFor(); req.returnValues().add(new StringValue(req.parameters() .get(0).asString() + diff --git a/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java b/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java index 4e810b71fb6..becc87a78c1 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java @@ -23,9 +23,8 @@ public class InvokeErrorTest { client = new Supervisor(new Transport()); acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("test", "iib", "i", this, "rpc_test")); - server.addMethod(new Method("test_barrier", "iib", "i", this, - "rpc_test_barrier")); + server.addMethod(new Method("test", "iib", "i", this::rpc_test)); + server.addMethod(new Method("test_barrier", "iib", "i", this::rpc_test_barrier)); barrier = new Test.Barrier(); } @@ -37,7 +36,7 @@ public class InvokeErrorTest { server.transport().shutdown().join(); } - public void rpc_test(Request req) { + private void rpc_test(Request req) { int value = req.parameters().get(0).asInt32(); int error = req.parameters().get(1).asInt32(); int extra = req.parameters().get(2).asInt8(); @@ -51,7 +50,7 @@ public class InvokeErrorTest { } } - public void rpc_test_barrier(Request req) { + private void rpc_test_barrier(Request req) { rpc_test(req); barrier.waitFor(); } diff --git a/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java b/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java index 931001804aa..6a227575ed9 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java @@ -1,16 +1,16 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jrt; +import com.yahoo.jrt.tool.RpcInvoker; +import org.junit.After; +import org.junit.Before; + import java.io.ByteArrayOutputStream; import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; -import com.yahoo.jrt.tool.RpcInvoker; -import org.junit.After; -import org.junit.Before; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -28,12 +28,12 @@ public class InvokeSyncTest { client = new Supervisor(new Transport()); acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("concat", "ss", "s", this, "rpc_concat") + server.addMethod(new Method("concat", "ss", "s", this::rpc_concat) .methodDesc("Concatenate 2 strings") .paramDesc(0, "str1", "a string") .paramDesc(1, "str2", "another string") .returnDesc(0, "ret", "str1 followed by str2")); - server.addMethod(new Method("alltypes", "bhilfds", "s", this, "rpc_alltypes") + server.addMethod(new Method("alltypes", "bhilfds", "s", this::rpc_alltypes) .methodDesc("Method taking all types of params")); } @@ -46,14 +46,14 @@ public class InvokeSyncTest { server.transport().shutdown().join(); } - public void rpc_concat(Request req) { + private void rpc_concat(Request req) { req.returnValues().add(new StringValue(req.parameters() .get(0).asString() + req.parameters() .get(1).asString())); } - public void rpc_alltypes(Request req) { + private void rpc_alltypes(Request req) { req.returnValues().add(new StringValue("This was alltypes. The string param was: "+req.parameters().get(6).asString())); } diff --git a/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java b/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java index 25e86a16445..09a8de53066 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java @@ -22,12 +22,12 @@ public class InvokeVoidTest { acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("set", "i", "", this, "rpc_set") + server.addMethod(new Method("set", "i", "", this::rpc_set) .methodDesc("Set the stored value") .paramDesc(0, "value", "the new value")); - server.addMethod(new Method("inc", "", "", this, "rpc_inc") + server.addMethod(new Method("inc", "", "", this::rpc_inc) .methodDesc("Increase the stored value")); - server.addMethod(new Method("get", "", "i", this, "rpc_get") + server.addMethod(new Method("get", "", "i", this::rpc_get) .methodDesc("Get the stored value") .returnDesc(0, "value", "the stored value")); } @@ -42,13 +42,13 @@ public class InvokeVoidTest { private int value = 0; - public void rpc_set(Request req) { + private void rpc_set(Request req) { value = req.parameters().get(0).asInt32(); } - public void rpc_inc(Request req) { + private void rpc_inc(Request req) { value++; } - public void rpc_get(Request req) { + private void rpc_get(Request req) { req.returnValues().add(new Int32Value(value)); } diff --git a/jrt/tests/com/yahoo/jrt/LatencyTest.java b/jrt/tests/com/yahoo/jrt/LatencyTest.java index 578ed6b14bc..97d7affd6ea 100644 --- a/jrt/tests/com/yahoo/jrt/LatencyTest.java +++ b/jrt/tests/com/yahoo/jrt/LatencyTest.java @@ -2,9 +2,6 @@ package com.yahoo.jrt; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.logging.Logger; @@ -23,13 +20,13 @@ public class LatencyTest { public Network(CryptoEngine crypto, int threads) throws ListenFailedException { server = new Supervisor(new Transport(crypto, threads)); client = new Supervisor(new Transport(crypto, threads)); - server.addMethod(new Method("inc", "i", "i", this, "rpc_inc")); + server.addMethod(new Method("inc", "i", "i", this::rpc_inc)); acceptor = server.listen(new Spec(0)); } public Target connect() { return client.connect(new Spec("localhost", acceptor.port())); } - public void rpc_inc(Request req) { + private void rpc_inc(Request req) { req.returnValues().add(new Int32Value(req.parameters().get(0).asInt32() + 1)); } public void close() { diff --git a/jrt/tests/com/yahoo/jrt/SessionTest.java b/jrt/tests/com/yahoo/jrt/SessionTest.java index dc33af96e44..29d6bb21d5f 100644 --- a/jrt/tests/com/yahoo/jrt/SessionTest.java +++ b/jrt/tests/com/yahoo/jrt/SessionTest.java @@ -130,14 +130,10 @@ public class SessionTest implements SessionHandler { target = client.connect(new Spec("localhost", acceptor.port()), new Session()); - server.addMethod(new Method("set", "i", "", this, - "rpc_set")); - server.addMethod(new Method("get", "", "i", this, - "rpc_get")); - server.addMethod(new Method("call_detach", "", "", this, - "rpc_call_detach")); - client.addMethod(new Method("detach", "", "", this, - "rpc_detach")); + server.addMethod(new Method("set", "i", "", this::rpc_set)); + server.addMethod(new Method("get", "", "i", this::rpc_get)); + server.addMethod(new Method("call_detach", "", "", this::rpc_call_detach)); + client.addMethod(new Method("detach", "", "", this::rpc_detach)); receptor = new Test.Receptor(); } @@ -197,23 +193,23 @@ public class SessionTest implements SessionHandler { } } - public void rpc_set(Request req) { + private void rpc_set(Request req) { Session s = (Session) req.target().getContext(); s.value(req.parameters().get(0).asInt32()); } - public void rpc_get(Request req) { + private void rpc_get(Request req) { Session s = (Session) req.target().getContext(); req.returnValues().add(new Int32Value(s.value())); } - public void rpc_call_detach(Request req) { + private void rpc_call_detach(Request req) { Session s = (Session) req.target().getContext(); s.touch(); req.target().invokeVoid(new Request("detach")); } - public void rpc_detach(Request req) { + private void rpc_detach(Request req) { Session s = (Session) req.target().getContext(); if (s == null) { Session.setError(); diff --git a/jrt/tests/com/yahoo/jrt/TimeoutTest.java b/jrt/tests/com/yahoo/jrt/TimeoutTest.java index 61822554a65..4bcc99c8519 100644 --- a/jrt/tests/com/yahoo/jrt/TimeoutTest.java +++ b/jrt/tests/com/yahoo/jrt/TimeoutTest.java @@ -22,7 +22,7 @@ public class TimeoutTest { client = new Supervisor(new Transport()); acceptor = server.listen(new Spec(0)); target = client.connect(new Spec("localhost", acceptor.port())); - server.addMethod(new Method("concat", "ss", "s", this, "rpc_concat") + server.addMethod(new Method("concat", "ss", "s", this::rpc_concat) .methodDesc("Concatenate 2 strings") .paramDesc(0, "str1", "a string") .paramDesc(1, "str2", "another string") @@ -38,7 +38,7 @@ public class TimeoutTest { server.transport().shutdown().join(); } - public void rpc_concat(Request req) { + private void rpc_concat(Request req) { barrier.waitFor(); req.returnValues().add(new StringValue(req.parameters() .get(0).asString() + diff --git a/jrt_test/src/java/SimpleServer.java b/jrt_test/src/java/SimpleServer.java index 8e88cee2c49..06ade36bc8e 100644 --- a/jrt_test/src/java/SimpleServer.java +++ b/jrt_test/src/java/SimpleServer.java @@ -36,9 +36,9 @@ public class SimpleServer { } Supervisor orb = new Supervisor(new Transport()); SimpleServer handler = new SimpleServer(); - orb.addMethod(new Method("inc", "i", "i", handler, "rpc_inc")); - orb.addMethod(new Method("echo", "*", "*", handler, "rpc_echo")); - orb.addMethod(new Method("test", "iib", "i", handler, "rpc_test")); + orb.addMethod(new Method("inc", "i", "i", handler::rpc_inc)); + orb.addMethod(new Method("echo", "*", "*", handler::rpc_echo)); + orb.addMethod(new Method("test", "iib", "i", handler::rpc_test)); try { orb.listen(new Spec(args[0])); } catch (ListenFailedException e) { diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/ZoneId.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/ZoneId.java deleted file mode 100644 index 02f6da2e0e3..00000000000 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/component/ZoneId.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2018 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.component; - -import com.yahoo.config.provision.Environment; -import com.yahoo.config.provision.RegionName; -import com.yahoo.config.provision.SystemName; - -import java.util.Objects; - -/** - * @author freva - */ -public class ZoneId { - private final SystemName systemName; - private final Environment environment; - private final RegionName regionName; - - public ZoneId(SystemName systemName, Environment environment, RegionName regionName) { - this.systemName = systemName; - this.environment = environment; - this.regionName = regionName; - } - - public SystemName systemName() { - return systemName; - } - - public Environment environment() { - return environment; - } - - public RegionName regionName() { - return regionName; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ZoneId zoneId = (ZoneId) o; - return systemName == zoneId.systemName && - environment == zoneId.environment && - Objects.equals(regionName, zoneId.regionName); - } - - @Override - public int hashCode() { - return Objects.hash(systemName, environment, regionName); - } -} 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 738babb4bf0..0ff36cd4560 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 @@ -159,7 +159,7 @@ public class StorageMaintainer { Map<String, String> tags = new LinkedHashMap<>(); tags.put("namespace", "Vespa"); tags.put("role", nodeTypeToRole(context.node().getNodeType())); - tags.put("zone", String.format("%s.%s", context.zoneId().environment().value(), context.zoneId().regionName().value())); + tags.put("zone", String.format("%s.%s", context.zoneId().environment().value(), context.zoneId().region().value())); context.node().getVespaVersion().ifPresent(version -> tags.put("vespaVersion", version.toFullString())); if (! isConfigserverLike(context.nodeType())) { @@ -261,7 +261,7 @@ public class StorageMaintainer { private Map<String, Object> getCoredumpNodeAttributes(NodeAgentContext context, Optional<Container> container) { Map<String, String> attributes = new HashMap<>(); attributes.put("hostname", context.node().getHostname()); - attributes.put("region", context.zoneId().regionName().value()); + attributes.put("region", context.zoneId().region().value()); attributes.put("environment", context.zoneId().environment().value()); attributes.put("flavor", context.node().getFlavor()); attributes.put("kernel_version", System.getProperty("os.version")); diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContext.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContext.java index 205e7b1e258..48016d251ef 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContext.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContext.java @@ -2,11 +2,10 @@ package com.yahoo.vespa.hosted.node.admin.nodeagent; import com.yahoo.config.provision.HostName; import com.yahoo.config.provision.NodeType; +import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.vespa.athenz.api.AthenzIdentity; -import com.yahoo.vespa.athenz.api.AthenzService; import com.yahoo.vespa.hosted.dockerapi.ContainerName; import com.yahoo.vespa.hosted.node.admin.component.TaskContext; -import com.yahoo.vespa.hosted.node.admin.component.ZoneId; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.Acl; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeSpec; import com.yahoo.vespa.hosted.node.admin.docker.DockerNetworking; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextImpl.java index 1370b70b37e..95b72725154 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentContextImpl.java @@ -1,13 +1,14 @@ package com.yahoo.vespa.hosted.node.admin.nodeagent; +import com.yahoo.config.provision.CloudName; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.SystemName; +import com.yahoo.config.provision.zone.ZoneId; import com.yahoo.vespa.athenz.api.AthenzIdentity; import com.yahoo.vespa.athenz.api.AthenzService; import com.yahoo.vespa.hosted.dockerapi.ContainerName; -import com.yahoo.vespa.hosted.node.admin.component.ZoneId; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.Acl; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeSpec; import com.yahoo.vespa.hosted.node.admin.configserver.noderepository.NodeState; @@ -238,7 +239,10 @@ public class NodeAgentContextImpl implements NodeAgentContext { Optional.ofNullable(acl).orElse(Acl.EMPTY), Optional.ofNullable(identity).orElseGet(() -> new AthenzService("domain", "service")), Optional.ofNullable(dockerNetworking).orElse(DockerNetworking.HOST_NETWORK), - Optional.ofNullable(zoneId).orElseGet(() -> new ZoneId(SystemName.main, Environment.prod, RegionName.defaultName())), + Optional.ofNullable(zoneId).orElseGet(() -> ZoneId.from(Environment.defaultEnvironment(), + RegionName.defaultName(), + CloudName.defaultName(), + SystemName.defaultSystem())), Optional.ofNullable(pathToContainerStorage).orElseGet(() -> Paths.get("/home/docker")), Optional.ofNullable(pathToVespaHome).orElseGet(() -> Paths.get("/opt/vespa")), Optional.ofNullable(vespaUser).orElse("vespa"), 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 1ec957a4dbb..b5640ddb996 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 @@ -3,11 +3,12 @@ package com.yahoo.vespa.hosted.node.admin.maintenance; import com.google.common.collect.ImmutableSet; import com.yahoo.component.Version; +import com.yahoo.config.provision.CloudName; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.SystemName; -import com.yahoo.vespa.hosted.node.admin.component.ZoneId; +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; @@ -164,7 +165,7 @@ public class StorageMaintainerTest { .build(); NodeAgentContext context = new NodeAgentContextImpl.Builder(nodeSpec) .fileSystem(TestFileSystem.create()) - .zoneId(new ZoneId(SystemName.dev, Environment.prod, RegionName.from("us-north-1"))).build(); + .zoneId(ZoneId.from(Environment.prod, RegionName.from("us-north-1"), CloudName.defaultName(), SystemName.defaultSystem())).build(); Path path = context.pathOnHostFromPathInNode("/etc/yamas-agent"); uncheck(() -> Files.createDirectories(path)); storageMaintainer.writeMetricsConfig(context); diff --git a/storage/src/tests/distributor/putoperationtest.cpp b/storage/src/tests/distributor/putoperationtest.cpp index 66ef13310a4..881ccb560b4 100644 --- a/storage/src/tests/distributor/putoperationtest.cpp +++ b/storage/src/tests/distributor/putoperationtest.cpp @@ -569,6 +569,26 @@ TEST_F(PutOperationTest, replica_not_resurrected_in_db_when_node_down_in_pending dumpBucket(bucket)); } +// TODO probably also do this for updates and removes +// TODO consider if we should use the pending state verbatim for computing targets if it exists +TEST_F(PutOperationTest, put_is_failed_with_busy_if_target_down_in_pending_state) { + setupDistributor(Redundancy(3), NodeCount(4), "version:1 distributor:1 storage:3"); + auto doc = createDummyDocument("test", "test"); + auto bucket = getExternalOperationHandler().getBucketId(doc->getId()); + addNodesToBucketDB(bucket, "0=1/2/3/t,1=1/2/3/t,2=1/2/3/t"); + getBucketDBUpdater().onSetSystemState( + std::make_shared<api::SetSystemStateCommand>( + lib::ClusterState("version:2 distributor:1 storage:4 .0.s:d .2.s:m"))); + _sender.clear(); + + sendPut(createPut(doc)); + EXPECT_EQ("", _sender.getCommands(true)); + EXPECT_EQ("PutReply(doc:test:test, BucketId(0x0000000000000000), " + "timestamp 100) ReturnCode(BUSY, " + "One or more target content nodes are unavailable in the pending cluster state)", + _sender.getLastReply(true)); +} + TEST_F(PutOperationTest, send_to_retired_nodes_if_no_up_nodes_available) { setupDistributor(Redundancy(2), NodeCount(2), "distributor:1 storage:2 .0.s:r .1.s:r"); diff --git a/storage/src/vespa/storage/distributor/operations/external/putoperation.cpp b/storage/src/vespa/storage/distributor/operations/external/putoperation.cpp index 2b1baa1e0d6..e9348e8e8e1 100644 --- a/storage/src/vespa/storage/distributor/operations/external/putoperation.cpp +++ b/storage/src/vespa/storage/distributor/operations/external/putoperation.cpp @@ -9,6 +9,7 @@ #include <vespa/storageapi/message/persistence.h> #include <vespa/vdslib/distribution/idealnodecalculatorimpl.h> #include <vespa/storage/distributor/distributor_bucket_space.h> +#include <algorithm> #include <vespa/log/log.h> LOG_SETUP(".distributor.callback.doc.put"); @@ -145,6 +146,17 @@ PutOperation::sendPutToBucketOnNode(document::BucketSpace bucketSpace, const doc } +bool PutOperation::has_unavailable_targets_in_pending_state(const OperationTargetList& targets) const { + auto* pending_state = _manager.getDistributor().pendingClusterStateOrNull(_msg->getBucket().getBucketSpace()); + if (!pending_state) { + return false; + } + const char* up_states = _manager.getDistributor().getStorageNodeUpStates(); + return std::any_of(targets.begin(), targets.end(), [pending_state, up_states](const auto& target){ + return !pending_state->getNodeState(target.getNode()).getState().oneOf(up_states); + }); +} + void PutOperation::onStart(DistributorMessageSender& sender) { @@ -188,6 +200,13 @@ PutOperation::onStart(DistributorMessageSender& sender) } } + if (has_unavailable_targets_in_pending_state(targets)) { + _tracker.fail(sender, api::ReturnCode( + api::ReturnCode::BUSY, "One or more target content nodes are unavailable in " + "the pending cluster state")); + return; + } + // Mark any entries we're not feeding to as not trusted. std::vector<BucketDatabase::Entry> entries; _bucketSpace.getBucketDatabase().getParents(bid, entries); diff --git a/storage/src/vespa/storage/distributor/operations/external/putoperation.h b/storage/src/vespa/storage/distributor/operations/external/putoperation.h index 745a4f57a35..79b3dd74b82 100644 --- a/storage/src/vespa/storage/distributor/operations/external/putoperation.h +++ b/storage/src/vespa/storage/distributor/operations/external/putoperation.h @@ -49,6 +49,8 @@ private: bool shouldImplicitlyActivateReplica(const OperationTargetList& targets) const; + bool has_unavailable_targets_in_pending_state(const OperationTargetList& targets) const; + std::shared_ptr<api::PutCommand> _msg; DistributorComponent& _manager; DistributorBucketSpace &_bucketSpace; |