summaryrefslogtreecommitdiffstats
path: root/container-search-and-docproc
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2022-06-30 11:35:01 +0200
committerBjørn Christian Seime <bjorncs@verizonmedia.com>2022-06-30 11:35:01 +0200
commit1171ecf2630f31e22f8f837095abc6f14ce669c8 (patch)
treee7d7b33866b1dd105da75e8ed77d7b813326130d /container-search-and-docproc
parentdc1b5d78ca36f10d959cc19469e96c3f719030cf (diff)
Reapply "Bjorncs/application status handler""
Diffstat (limited to 'container-search-and-docproc')
-rw-r--r--container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java334
-rw-r--r--container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/package-info.java5
-rw-r--r--container-search-and-docproc/src/main/resources/configdefinitions/container.handler.observability.application-userdata.def8
-rw-r--r--container-search-and-docproc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java132
4 files changed, 0 insertions, 479 deletions
diff --git a/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java b/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
deleted file mode 100644
index 09b5a6ff85e..00000000000
--- a/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.container.handler.observability;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.yahoo.component.annotation.Inject;
-import com.yahoo.component.AbstractComponent;
-import com.yahoo.component.ComponentId;
-import com.yahoo.component.Vtag;
-import com.yahoo.component.chain.Chain;
-import com.yahoo.component.provider.ComponentRegistry;
-import com.yahoo.container.Container;
-import com.yahoo.container.core.ApplicationMetadataConfig;
-import com.yahoo.container.jdisc.JdiscBindingsConfig;
-import com.yahoo.docproc.Call;
-import com.yahoo.docproc.impl.DocprocService;
-import com.yahoo.docproc.jdisc.DocumentProcessingHandler;
-import com.yahoo.jdisc.handler.AbstractRequestHandler;
-import com.yahoo.jdisc.handler.CompletionHandler;
-import com.yahoo.jdisc.handler.ContentChannel;
-import com.yahoo.jdisc.handler.FastContentWriter;
-import com.yahoo.jdisc.handler.RequestHandler;
-import com.yahoo.jdisc.handler.ResponseDispatch;
-import com.yahoo.jdisc.handler.ResponseHandler;
-import com.yahoo.jdisc.http.filter.RequestFilterBase;
-import com.yahoo.jdisc.http.filter.ResponseFilterBase;
-import com.yahoo.jdisc.service.ClientProvider;
-import com.yahoo.jdisc.service.ServerProvider;
-import com.yahoo.processing.Processor;
-import com.yahoo.processing.execution.chain.ChainRegistry;
-import com.yahoo.processing.handler.ProcessingHandler;
-import com.yahoo.search.handler.SearchHandler;
-import com.yahoo.search.searchchain.SearchChainRegistry;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.FrameworkUtil;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Handler that outputs meta-info about the deployed Vespa application, and status of components and chains.
- *
- * @author gjoranv
- * @author Einar M R Rosenvinge
- */
-public class ApplicationStatusHandler extends AbstractRequestHandler {
-
- private static final ObjectMapper jsonMapper = new ObjectMapper();
-
- private final JsonNode applicationJson;
- private final JsonNode clientsJson;
- private final JsonNode serversJson;
- private final JsonNode requestFiltersJson;
- private final JsonNode responseFiltersJson;
- private final JdiscBindingsConfig bindingsConfig;
-
- @Inject
- public ApplicationStatusHandler(ApplicationMetadataConfig metaConfig,
- ApplicationUserdataConfig userConfig,
- JdiscBindingsConfig bindingsConfig,
- ComponentRegistry<ClientProvider> clientProviderRegistry,
- ComponentRegistry<ServerProvider> serverProviderRegistry,
- ComponentRegistry<RequestFilterBase> requestFilterRegistry,
- ComponentRegistry<ResponseFilterBase> responseFilterRegistry) {
-
- applicationJson = renderApplicationConfigs(metaConfig, userConfig);
- clientsJson = renderRequestHandlers(bindingsConfig, clientProviderRegistry.allComponentsById());
- serversJson = renderObjectComponents(serverProviderRegistry.allComponentsById());
- requestFiltersJson = renderObjectComponents(requestFilterRegistry.allComponentsById());
- responseFiltersJson = renderObjectComponents(responseFilterRegistry.allComponentsById());
-
- this.bindingsConfig = bindingsConfig;
- }
-
- @Override
- public ContentChannel handleRequest(com.yahoo.jdisc.Request request, ResponseHandler handler) {
- JsonNode json = new StatusResponse(applicationJson, clientsJson, serversJson,
- requestFiltersJson, responseFiltersJson, bindingsConfig)
- .render();
-
- FastContentWriter writer = new FastContentWriter(new ResponseDispatch() {
- @Override
- protected com.yahoo.jdisc.Response newResponse() {
- com.yahoo.jdisc.Response response = new com.yahoo.jdisc.Response(com.yahoo.jdisc.Response.Status.OK);
- response.headers().add("Content-Type", List.of("application/json"));
- return response;
- }
- }.connect(handler));
-
- try {
- writer.write(jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(json));
- } catch (JsonProcessingException e) {
- throw new RuntimeException("Invalid JSON: " + e.getMessage(), e);
- }
- writer.close();
-
- return new IgnoredContent();
- }
-
- static JsonNode renderApplicationConfigs(ApplicationMetadataConfig metaConfig,
- ApplicationUserdataConfig userConfig) {
- ObjectNode vespa = jsonMapper.createObjectNode();
- vespa.put("version", Vtag.currentVersion.toString());
-
- ObjectNode meta = jsonMapper.createObjectNode();
- meta.put("name", metaConfig.name());
- meta.put("user", metaConfig.user());
- meta.put("path", metaConfig.path());
- meta.put("generation", metaConfig.generation());
- meta.put("timestamp", metaConfig.timestamp());
- meta.put("date", new Date(metaConfig.timestamp()).toString());
- meta.put("checksum", metaConfig.checksum());
-
- ObjectNode user = jsonMapper.createObjectNode();
- user.put("version", userConfig.version());
-
- ObjectNode application = jsonMapper.createObjectNode();
- application.set("vespa", vespa);
- application.set("meta", meta);
- application.set("user", user);
- return application;
- }
-
- static JsonNode renderObjectComponents(Map<ComponentId, ?> componentsById) {
- ArrayNode ret = jsonMapper.createArrayNode();
-
- for (Map.Entry<ComponentId, ?> componentEntry : componentsById.entrySet()) {
- JsonNode jc = renderComponent(componentEntry.getValue(), componentEntry.getKey());
- ret.add(jc);
- }
- return ret;
- }
-
- static JsonNode renderRequestHandlers(JdiscBindingsConfig bindingsConfig,
- Map<ComponentId, ? extends RequestHandler> handlersById) {
- ArrayNode ret = jsonMapper.createArrayNode();
-
- for (Map.Entry<ComponentId, ? extends RequestHandler> handlerEntry : handlersById.entrySet()) {
- String id = handlerEntry.getKey().stringValue();
- RequestHandler handler = handlerEntry.getValue();
-
- ObjectNode handlerJson = renderComponent(handler, handlerEntry.getKey());
- addBindings(bindingsConfig, id, handlerJson);
- ret.add(handlerJson);
- }
- return ret;
- }
-
- private static void addBindings(JdiscBindingsConfig bindingsConfig, String id, ObjectNode handlerJson) {
- List<String> serverBindings = new ArrayList<>();
- List<String> clientBindings = new ArrayList<>();
-
- JdiscBindingsConfig.Handlers handlerConfig = bindingsConfig.handlers(id);
- if (handlerConfig != null) {
- serverBindings = handlerConfig.serverBindings();
- clientBindings = handlerConfig.clientBindings();
- }
- handlerJson.set("serverBindings", renderBindings(serverBindings));
- handlerJson.set("clientBindings", renderBindings(clientBindings));
- }
-
- private static JsonNode renderBindings(List<String> bindings) {
- ArrayNode ret = jsonMapper.createArrayNode();
-
- for (String binding : bindings)
- ret.add(binding);
-
- return ret;
- }
-
- private static JsonNode renderAbstractComponents(List<? extends AbstractComponent> components) {
- ArrayNode ret = jsonMapper.createArrayNode();
-
- for (AbstractComponent c : components) {
- JsonNode jc = renderComponent(c, c.getId());
- ret.add(jc);
- }
- return ret;
- }
-
- private static ObjectNode renderComponent(Object component, ComponentId id) {
- ObjectNode jc = jsonMapper.createObjectNode();
- jc.put("id", id.stringValue());
- addBundleInfo(jc, component);
- return jc;
- }
-
- private static void addBundleInfo(ObjectNode jsonObject, Object component) {
- BundleInfo bundleInfo = bundleInfo(component);
- jsonObject.put("class", bundleInfo.className);
- jsonObject.put("bundle", bundleInfo.bundleName);
-
- }
-
- private static BundleInfo bundleInfo(Object component) {
- try {
- Bundle bundle = FrameworkUtil.getBundle(component.getClass());
-
- String bundleName = bundle != null ?
- bundle.getSymbolicName() + ":" + bundle.getVersion() :
- "From classpath";
- return new BundleInfo(component.getClass().getName(), bundleName);
- } catch (Exception | NoClassDefFoundError e) {
- return new BundleInfo("Unavailable, reconfiguration in progress.", "");
- }
- }
-
- static final class BundleInfo {
- public final String className;
- public final String bundleName;
- BundleInfo(String className, String bundleName) {
- this.className = className;
- this.bundleName = bundleName;
- }
- }
-
- static final class StatusResponse {
- private final JsonNode applicationJson;
- private final JsonNode clientsJson;
- private final JsonNode serversJson;
- private final JsonNode requestFiltersJson;
- private final JsonNode responseFiltersJson;
- private final JdiscBindingsConfig bindingsConfig;
-
- StatusResponse(JsonNode applicationJson,
- JsonNode clientsJson,
- JsonNode serversJson,
- JsonNode requestFiltersJson,
- JsonNode responseFiltersJson,
- JdiscBindingsConfig bindingsConfig) {
- this.applicationJson = applicationJson;
- this.clientsJson = clientsJson;
- this.serversJson = serversJson;
- this.requestFiltersJson = requestFiltersJson;
- this.responseFiltersJson = responseFiltersJson;
- this.bindingsConfig = bindingsConfig;
- }
-
- public JsonNode render() {
- ObjectNode root = jsonMapper.createObjectNode();
-
- root.set("application", applicationJson);
- root.set("abstractComponents",
- renderAbstractComponents(Container.get().getComponentRegistry().allComponents()));
-
- root.set("handlers",
- renderRequestHandlers(bindingsConfig, Container.get().getRequestHandlerRegistry().allComponentsById()));
- root.set("clients", clientsJson);
- root.set("servers", serversJson);
- root.set("httpRequestFilters", requestFiltersJson);
- root.set("httpResponseFilters", responseFiltersJson);
-
- root.set("searchChains", renderSearchChains(Container.get()));
- root.set("docprocChains", renderDocprocChains(Container.get()));
- root.set("processingChains", renderProcessingChains(Container.get()));
-
- return root;
- }
-
- private static JsonNode renderSearchChains(Container container) {
- for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) {
- if (h instanceof SearchHandler) {
- SearchChainRegistry scReg = ((SearchHandler) h).getSearchChainRegistry();
- return renderChains(scReg);
- }
- }
- return jsonMapper.createObjectNode();
- }
-
- private static JsonNode renderDocprocChains(Container container) {
- ObjectNode ret = jsonMapper.createObjectNode();
- for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) {
- if (h instanceof DocumentProcessingHandler) {
- ComponentRegistry<DocprocService> registry = ((DocumentProcessingHandler) h).getDocprocServiceRegistry();
- for (DocprocService service : registry.allComponents()) {
- ret.set(service.getId().stringValue(), renderCalls(service.getCallStack().iterator()));
- }
- }
- }
- return ret;
- }
-
- private static JsonNode renderProcessingChains(Container container) {
- JsonNode ret = jsonMapper.createObjectNode();
- for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) {
- if (h instanceof ProcessingHandler) {
- ChainRegistry<Processor> registry = ((ProcessingHandler) h).getChainRegistry();
- return renderChains(registry);
- }
- }
- return ret;
- }
-
- // Note the generic param here! The key to make this work is '? extends Chain', but why?
- static JsonNode renderChains(ComponentRegistry<? extends Chain<?>> chains) {
- ObjectNode ret = jsonMapper.createObjectNode();
- for (Chain<?> chain : chains.allComponents()) {
- ret.set(chain.getId().stringValue(), renderAbstractComponents(chain.components()));
- }
- return ret;
- }
-
- private static JsonNode renderCalls(Iterator<Call> components) {
- ArrayNode ret = jsonMapper.createArrayNode();
- while (components.hasNext()) {
- Call c = components.next();
- JsonNode jc = renderComponent(c.getDocumentProcessor(), c.getDocumentProcessor().getId());
- ret.add(jc);
- }
- return ret;
- }
-
- }
-
- private class IgnoredContent implements ContentChannel {
- @Override
- public void write(ByteBuffer buf, CompletionHandler handler) {
- handler.completed();
- }
-
- @Override
- public void close(CompletionHandler handler) {
- handler.completed();
- }
- }
-
-}
diff --git a/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/package-info.java b/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/package-info.java
deleted file mode 100644
index 7f9dc3d1cd9..00000000000
--- a/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-@ExportPackage
-package com.yahoo.container.handler.observability;
-
-import com.yahoo.osgi.annotation.ExportPackage;
diff --git a/container-search-and-docproc/src/main/resources/configdefinitions/container.handler.observability.application-userdata.def b/container-search-and-docproc/src/main/resources/configdefinitions/container.handler.observability.application-userdata.def
deleted file mode 100644
index cde92df9ef4..00000000000
--- a/container-search-and-docproc/src/main/resources/configdefinitions/container.handler.observability.application-userdata.def
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-# Contains user generated info about one deployed application
-# The values in this config are set by config overrides in vespa-services
-
-namespace=container.handler.observability
-
-# The user-defined version of this application.
-version string default=""
diff --git a/container-search-and-docproc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java b/container-search-and-docproc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java
deleted file mode 100644
index 317f5fc1329..00000000000
--- a/container-search-and-docproc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.container.handler.observability;
-
-import com.yahoo.component.ComponentId;
-import com.yahoo.component.chain.Chain;
-import com.yahoo.container.core.ApplicationMetadataConfig;
-import com.yahoo.container.jdisc.JdiscBindingsConfig;
-import com.yahoo.jdisc.handler.RequestHandler;
-import com.yahoo.jdisc.service.ClientProvider;
-import com.yahoo.processing.Processor;
-import com.yahoo.processing.Request;
-import com.yahoo.processing.Response;
-import com.yahoo.processing.execution.Execution;
-import com.yahoo.processing.execution.chain.ChainRegistry;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import java.util.HashMap;
-
-import static com.yahoo.container.jdisc.JdiscBindingsConfig.Handlers;
-import static org.junit.Assert.assertTrue;
-
-/**
- * @author gjoranv
- * @since 5.1.10
- */
-public class ApplicationStatusHandlerTest {
-
- @Test
- public void application_configs_are_rendered() {
- ApplicationMetadataConfig metaConfig = new ApplicationMetadataConfig(
- new ApplicationMetadataConfig.Builder()
- .checksum("abc")
- .name("app")
- .path("/a/b/c")
- .timestamp(3000)
- .user("donald"));
-
- ApplicationUserdataConfig userConfig = new ApplicationUserdataConfig(
- new ApplicationUserdataConfig.Builder()
- .version("v1"));
-
- String json = ApplicationStatusHandler.renderApplicationConfigs(metaConfig, userConfig).toString();
- assertTrue(json.contains("version"));
- assertTrue(json.contains("meta"));
- assertTrue(json.contains("abc"));
- assertTrue(json.contains("app"));
- assertTrue(json.contains("/a/b/c"));
- assertTrue(json.contains("3000"));
- assertTrue(json.contains("donald"));
-
- assertTrue(json.contains("v1"));
- }
-
- @Test
- public void object_components_are_rendered() {
- HashMap<ComponentId, Object> id2object = new HashMap<>();
- id2object.put(new ComponentId("myComponent"), new Object());
-
- String json = ApplicationStatusHandler.renderObjectComponents(id2object).toString();
- assertTrue(json.contains("myComponent"));
- }
-
- @Test
- public void request_handlers_are_rendered() {
- final String id = "myHandler";
- final String serverBinding1 = "http://*/serverBinding";
- final String serverBinding2 = "http://*/anotherServerBinding";
- final String clientBinding = "http://*/clientBinding";
-
- HashMap<ComponentId, RequestHandler> handlersById = new HashMap<>();
- handlersById.put(new ComponentId(id), Mockito.mock(RequestHandler.class));
-
- JdiscBindingsConfig bindingsConfig = new JdiscBindingsConfig(new JdiscBindingsConfig.Builder()
- .handlers(id, new Handlers.Builder()
- .serverBindings(serverBinding1)
- .serverBindings(serverBinding2)
- .clientBindings(clientBinding))
- );
- String json = ApplicationStatusHandler.renderRequestHandlers(bindingsConfig, handlersById).toString();
- assertTrue(json.contains("\"" + id + "\""));
- assertTrue(json.contains(serverBinding1));
- assertTrue(json.contains(serverBinding2));
- assertTrue(json.contains(clientBinding));
- }
-
- @Test
- public void client_providers_are_rendered() {
- final String id = "myClient";
- final String clientBinding = "http://*/clientBinding";
- final String clientBinding2 = "http://*/anotherClientBinding";
- final String serverBinding = "http://*/serverBinding";
-
- HashMap<ComponentId, ClientProvider> clientsById = new HashMap<>();
- clientsById.put(new ComponentId(id), Mockito.mock(ClientProvider.class));
-
- JdiscBindingsConfig bindingsConfig = new JdiscBindingsConfig(new JdiscBindingsConfig.Builder()
- .handlers(id, new Handlers.Builder()
- .clientBindings(clientBinding)
- .clientBindings(clientBinding2)
- .serverBindings(serverBinding))
- );
- String json = ApplicationStatusHandler.renderRequestHandlers(bindingsConfig, clientsById).toString();
- System.out.println(json);
- assertTrue(json.contains("\"" + id + "\""));
- assertTrue(json.contains(clientBinding));
- assertTrue(json.contains(clientBinding2));
- assertTrue(json.contains(serverBinding));
- }
-
- @Test
- public void chains_are_rendered() {
- ChainRegistry<Processor> chains = new ChainRegistry<>();
- Chain<Processor> chain = new Chain<>("myChain", new VoidProcessor(new ComponentId("voidProcessor")));
- chains.register(new ComponentId("myChain"), chain);
-
- String json = ApplicationStatusHandler.StatusResponse.renderChains(chains).toString();
- assertTrue(json.contains("myChain"));
- assertTrue(json.contains("voidProcessor"));
- }
-
- private static class VoidProcessor extends Processor {
- private VoidProcessor(ComponentId id) {
- super();
- initId(id);
- }
- @Override
- public Response process(Request request, Execution processorExecution) {
- return null;
- }
- }
-}