diff options
Diffstat (limited to 'clustercontroller-core/src')
6 files changed, 102 insertions, 65 deletions
diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java index 8027cec4e3c..a5fa0d08bb8 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java @@ -2,7 +2,6 @@ package com.yahoo.vespa.clustercontroller.core; import com.yahoo.document.FixedBucketSpaces; -import com.yahoo.exception.ExceptionUtils; import com.yahoo.vdslib.distribution.ConfiguredNode; import com.yahoo.vdslib.state.ClusterState; import com.yahoo.vdslib.state.Node; @@ -22,10 +21,9 @@ import com.yahoo.vespa.clustercontroller.core.status.LegacyIndexPageRequestHandl import com.yahoo.vespa.clustercontroller.core.status.LegacyNodePageRequestHandler; import com.yahoo.vespa.clustercontroller.core.status.NodeHealthRequestHandler; import com.yahoo.vespa.clustercontroller.core.status.StatusHandler; -import com.yahoo.vespa.clustercontroller.core.status.statuspage.StatusPageResponse; import com.yahoo.vespa.clustercontroller.core.status.statuspage.StatusPageServer; import com.yahoo.vespa.clustercontroller.utils.util.MetricReporter; -import java.io.FileNotFoundException; + import java.time.Duration; import java.time.Instant; import java.util.ArrayDeque; @@ -37,7 +35,6 @@ import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Set; -import java.util.TimeZone; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; @@ -508,43 +505,6 @@ public class FleetController implements NodeListener, SlobrokListener, SystemSta } } - public StatusPageResponse fetchStatusPage(StatusPageServer.HttpRequest httpRequest) { - verifyInControllerThread(); - StatusPageResponse.ResponseCode responseCode; - String message; - final String hiddenMessage; - try { - StatusPageServer.RequestHandler handler = statusRequestRouter.resolveHandler(httpRequest); - if (handler == null) { - throw new FileNotFoundException("No handler found for request: " + httpRequest.getPath()); - } - return handler.handle(httpRequest); - } catch (FileNotFoundException e) { - responseCode = StatusPageResponse.ResponseCode.NOT_FOUND; - message = e.getMessage(); - hiddenMessage = ""; - } catch (Exception e) { - responseCode = StatusPageResponse.ResponseCode.INTERNAL_SERVER_ERROR; - message = "Internal Server Error"; - hiddenMessage = ExceptionUtils.getStackTraceAsString(e); - context.log(logger, Level.FINE, () -> "Unknown exception thrown for request " + httpRequest.getRequest() + ": " + hiddenMessage); - } - - TimeZone tz = TimeZone.getTimeZone("UTC"); - long currentTime = timer.getCurrentTimeInMillis(); - StatusPageResponse response = new StatusPageResponse(); - StringBuilder content = new StringBuilder(); - response.setContentType("text/html"); - response.setResponseCode(responseCode); - content.append("<!-- Answer to request ").append(httpRequest.getRequest()).append(" -->\n"); - content.append("<p>UTC time when creating this page: ").append(RealTimer.printDateNoMilliSeconds(currentTime, tz)).append("</p>"); - response.writeHtmlHeader(content, message); - response.writeHtmlFooter(content, hiddenMessage); - response.writeContent(content.toString()); - - return response; - } - public void tick() throws Exception { synchronized (monitor) { boolean didWork; @@ -635,7 +595,8 @@ public class FleetController implements NodeListener, SlobrokListener, SystemSta private boolean processAnyPendingStatusPageRequest() { StatusPageServer.HttpRequest statusRequest = statusPageServer.getCurrentHttpRequest(); if (statusRequest != null) { - statusPageServer.answerCurrentStatusRequest(fetchStatusPage(statusRequest)); + verifyInControllerThread(); + statusPageServer.fetchStatusPage(statusRequest, statusRequestRouter, timer); return true; } return false; diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/MissingIdException.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/MissingIdException.java index 21229b4b358..18a3b923908 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/MissingIdException.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/MissingIdException.java @@ -4,14 +4,12 @@ package com.yahoo.vespa.clustercontroller.core.restapiv2; import com.yahoo.vdslib.state.Node; import com.yahoo.vespa.clustercontroller.utils.staterestapi.errors.MissingUnitException; +import java.util.List; + public class MissingIdException extends MissingUnitException { - private static String[] createPath(String cluster, Node n) { - String[] path = new String[3]; - path[0] = cluster; - path[1] = n.getType().toString(); - path[2] = String.valueOf(n.getIndex()); - return path; + private static List<String> createPath(String cluster, Node n) { + return List.of(cluster, n.getType().toString(), String.valueOf(n.getIndex())); } public MissingIdException(String cluster, Node n) { diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/UnitPathResolver.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/UnitPathResolver.java index 11fd5f39fad..0db11cad955 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/UnitPathResolver.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/restapiv2/UnitPathResolver.java @@ -7,6 +7,7 @@ import com.yahoo.vespa.clustercontroller.utils.staterestapi.errors.MissingUnitEx import com.yahoo.vespa.clustercontroller.utils.staterestapi.errors.OperationNotSupportedForUnitException; import com.yahoo.vespa.clustercontroller.utils.staterestapi.errors.StateRestApiException; import java.util.HashMap; +import java.util.List; import java.util.Map; public class UnitPathResolver<T> { @@ -22,10 +23,10 @@ public class UnitPathResolver<T> { public static abstract class AbstractVisitor<T> implements Visitor<T> { - private final String[] path; + private final List<String> path; private final String failureMessage; - public AbstractVisitor(String[] path, String failureMessage) { + public AbstractVisitor(List<String> path, String failureMessage) { this.path = path; this.failureMessage = failureMessage; } @@ -46,41 +47,41 @@ public class UnitPathResolver<T> { this.fleetControllers = new HashMap<>(fleetControllers); } - public RemoteClusterControllerTaskScheduler resolveFleetController(String[] path) throws StateRestApiException { - if (path.length == 0) return null; - RemoteClusterControllerTaskScheduler fc = fleetControllers.get(path[0]); + public RemoteClusterControllerTaskScheduler resolveFleetController(List<String> path) throws StateRestApiException { + if (path.size() == 0) return null; + RemoteClusterControllerTaskScheduler fc = fleetControllers.get(path.get(0)); if (fc == null) { throw new MissingUnitException(path, 0); } return fc; } - public Request<? extends T> visit(String[] path, Visitor<T> visitor) throws StateRestApiException { - if (path.length == 0) { + public Request<? extends T> visit(List<String> path, Visitor<T> visitor) throws StateRestApiException { + if (path.size() == 0) { return visitor.visitGlobal(); } - RemoteClusterControllerTaskScheduler fc = fleetControllers.get(path[0]); + RemoteClusterControllerTaskScheduler fc = fleetControllers.get(path.get(0)); if (fc == null) throw new MissingUnitException(path, 0); - Id.Cluster cluster = new Id.Cluster(path[0]); - if (path.length == 1) { + Id.Cluster cluster = new Id.Cluster(path.get(0)); + if (path.size() == 1) { return visitor.visitCluster(cluster); } Id.Service service; try{ - service = new Id.Service(cluster, NodeType.get(path[1])); + service = new Id.Service(cluster, NodeType.get(path.get(1))); } catch (IllegalArgumentException e) { throw new MissingUnitException(path, 1); } - if (path.length == 2) { + if (path.size() == 2) { return visitor.visitService(service); } Id.Node node; try{ - node = new Id.Node(service, Integer.valueOf(path[2])); + node = new Id.Node(service, Integer.parseInt(path.get(2))); } catch (NumberFormatException e) { throw new MissingUnitException(path, 2); } - if (path.length == 3) { + if (path.size() == 3) { return visitor.visitNode(node); } throw new MissingUnitException(path, 4); diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/status/StatusHandler.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/status/StatusHandler.java index 65b06afb0c5..6ed121284b6 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/status/StatusHandler.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/status/StatusHandler.java @@ -1,14 +1,20 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.clustercontroller.core.status; +import com.yahoo.exception.ExceptionUtils; +import com.yahoo.vespa.clustercontroller.core.RealTimer; +import com.yahoo.vespa.clustercontroller.core.Timer; import com.yahoo.vespa.clustercontroller.core.status.statuspage.StatusPageResponse; import com.yahoo.vespa.clustercontroller.core.status.statuspage.StatusPageServer; import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest; import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequestHandler; import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpResult; + +import java.io.FileNotFoundException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.util.Map; +import java.util.TimeZone; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -42,6 +48,46 @@ public class StatusHandler implements HttpRequestHandler { return r; } } + + public void fetchStatusPage(StatusPageServer.HttpRequest httpRequest, + StatusPageServer.PatternRequestRouter statusRequestRouter, + Timer timer) { + StatusPageResponse.ResponseCode responseCode; + String message; + final String hiddenMessage; + try { + StatusPageServer.RequestHandler handler = statusRequestRouter.resolveHandler(httpRequest); + if (handler == null) { + throw new FileNotFoundException("No handler found for request: " + httpRequest.getPath()); + } + answerCurrentStatusRequest(handler.handle(httpRequest)); + return; + } catch (FileNotFoundException e) { + responseCode = StatusPageResponse.ResponseCode.NOT_FOUND; + message = e.getMessage(); + hiddenMessage = ""; + } catch (Exception e) { + responseCode = StatusPageResponse.ResponseCode.INTERNAL_SERVER_ERROR; + message = "Internal Server Error"; + hiddenMessage = ExceptionUtils.getStackTraceAsString(e); + } + + TimeZone tz = TimeZone.getTimeZone("UTC"); + long currentTime = timer.getCurrentTimeInMillis(); + StatusPageResponse response = new StatusPageResponse(); + StringBuilder content = new StringBuilder(); + response.setContentType("text/html"); + response.setResponseCode(responseCode); + content.append("<!-- Answer to request ").append(httpRequest.getRequest()).append(" -->\n"); + content.append("<p>UTC time when creating this page: ").append(RealTimer.printDateNoMilliSeconds(currentTime, tz)).append("</p>"); + response.writeHtmlHeader(content, message); + response.writeHtmlFooter(content, hiddenMessage); + response.writeContent(content.toString()); + + + answerCurrentStatusRequest(response); + } + public void answerCurrentStatusRequest(StatusPageResponse r) { synchronized (answerMonitor) { response = r; diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateRequests.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateRequests.java new file mode 100644 index 00000000000..f0f98120d72 --- /dev/null +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateRequests.java @@ -0,0 +1,30 @@ +package com.yahoo.vespa.clustercontroller.core; + +import com.yahoo.vespa.clustercontroller.utils.staterestapi.requests.UnitStateRequest; + +import java.util.List; + +public class StateRequests { + + public static class Get extends StateRequests implements UnitStateRequest { + private final List<String> path; + private final int recursive; + + public Get(String req, int recursive) { + path = req.isEmpty() ? List.of() : List.of(req.split("/")); + this.recursive = recursive; + } + + @Override + public int getRecursiveLevels() { + return recursive; + } + + @Override + public List<String> getUnitPath() { + return path; + } + + } + +} diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/StateRestApiTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/StateRestApiTest.java index 205d5b05b29..bec12ccb195 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/StateRestApiTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/restapiv2/StateRestApiTest.java @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; @@ -36,18 +37,18 @@ public abstract class StateRestApiTest { Map<Integer, ClusterControllerStateRestAPI.Socket> ccSockets; public static class StateRequest implements UnitStateRequest { - private final String[] path; + private final List<String> path; private final int recursive; StateRequest(String req, int recursive) { - path = req.isEmpty() ? new String[0] : req.split("/"); + path = req.isEmpty() ? List.of() : List.of(req.split("/")); this.recursive = recursive; } @Override public int getRecursiveLevels() { return recursive; } @Override - public String[] getUnitPath() { return path; } + public List<String> getUnitPath() { return path; } } protected void setUp(boolean dontInitializeNode2) { |