diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2022-06-30 11:35:01 +0200 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2022-06-30 11:35:01 +0200 |
commit | 1171ecf2630f31e22f8f837095abc6f14ce669c8 (patch) | |
tree | e7d7b33866b1dd105da75e8ed77d7b813326130d /container-search-and-docproc | |
parent | dc1b5d78ca36f10d959cc19469e96c3f719030cf (diff) |
Reapply "Bjorncs/application status handler""
Diffstat (limited to 'container-search-and-docproc')
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; - } - } -} |