diff options
4 files changed, 63 insertions, 90 deletions
diff --git a/container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java b/container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java index fffb33fa796..67862533259 100644 --- a/container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java +++ b/container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java @@ -6,7 +6,7 @@ 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.AbstractComponent; +import com.yahoo.component.Component; import com.yahoo.component.ComponentId; import com.yahoo.component.Vtag; import com.yahoo.component.annotation.Inject; @@ -52,7 +52,7 @@ public class ApplicationStatusHandler extends AbstractRequestHandler { Map<String, ? extends JsonNode> produceExtraFields(ApplicationStatusHandler handler); } - public static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final ObjectMapper jsonMapper = new ObjectMapper(); private final JsonNode applicationJson; private final JsonNode clientsJson; @@ -83,10 +83,6 @@ public class ApplicationStatusHandler extends AbstractRequestHandler { @Override public ContentChannel handleRequest(com.yahoo.jdisc.Request request, ResponseHandler handler) { - JsonNode json = new StatusResponse(applicationJson, clientsJson, serversJson, - requestFiltersJson, responseFiltersJson, bindingsConfig, this, extensions) - .render(); - FastContentWriter writer = new FastContentWriter(new ResponseDispatch() { @Override protected com.yahoo.jdisc.Response newResponse() { @@ -97,7 +93,7 @@ public class ApplicationStatusHandler extends AbstractRequestHandler { }.connect(handler)); try { - writer.write(jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(json)); + writer.write(jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(render())); } catch (JsonProcessingException e) { throw new RuntimeException("Invalid JSON: " + e.getMessage(), e); } @@ -106,8 +102,18 @@ public class ApplicationStatusHandler extends AbstractRequestHandler { return new IgnoredContent(); } + public ObjectMapper jsonMapper() { return jsonMapper; } + + public Collection<RequestHandler> requestHandlers() { return container().getRequestHandlerRegistry().allComponents(); } + + private Map<ComponentId, RequestHandler> requestHandlersById() { return container().getRequestHandlerRegistry().allComponentsById(); } + + private List<? extends Component> components() { return container().getComponentRegistry().allComponents(); } + + private static Container container() { return Container.get(); } + static JsonNode renderApplicationConfigs(ApplicationMetadataConfig metaConfig, - ApplicationUserdataConfig userConfig) { + ApplicationUserdataConfig userConfig) { ObjectNode vespa = jsonMapper.createObjectNode(); vespa.put("version", Vtag.currentVersion.toString()); @@ -177,10 +183,10 @@ public class ApplicationStatusHandler extends AbstractRequestHandler { return ret; } - private static JsonNode renderAbstractComponents(List<? extends AbstractComponent> components) { + private static JsonNode renderAbstractComponents(List<? extends Component> components) { ArrayNode ret = jsonMapper.createArrayNode(); - for (AbstractComponent c : components) { + for (Component c : components) { JsonNode jc = renderComponent(c, c.getId()); ret.add(jc); } @@ -223,79 +229,48 @@ public class ApplicationStatusHandler extends AbstractRequestHandler { } } - public 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; - private final ApplicationStatusHandler handler; - private final Collection<Extension> extensions; - - StatusResponse(JsonNode applicationJson, - JsonNode clientsJson, - JsonNode serversJson, - JsonNode requestFiltersJson, - JsonNode responseFiltersJson, - JdiscBindingsConfig bindingsConfig, - ApplicationStatusHandler handler, - Collection<Extension> extensions) { - this.applicationJson = applicationJson; - this.clientsJson = clientsJson; - this.serversJson = serversJson; - this.requestFiltersJson = requestFiltersJson; - this.responseFiltersJson = responseFiltersJson; - this.bindingsConfig = bindingsConfig; - this.handler = handler; - this.extensions = extensions; - } - - public JsonNode render() { - ObjectNode root = jsonMapper.createObjectNode(); + JsonNode render() { + ObjectNode root = jsonMapper.createObjectNode(); - root.set("application", applicationJson); - root.set("abstractComponents", - renderAbstractComponents(Container.get().getComponentRegistry().allComponents())); + root.set("application", applicationJson); + root.set("abstractComponents", + renderAbstractComponents(components())); - 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("handlers", renderRequestHandlers(bindingsConfig, requestHandlersById())); + root.set("clients", clientsJson); + root.set("servers", serversJson); + root.set("httpRequestFilters", requestFiltersJson); + root.set("httpResponseFilters", responseFiltersJson); - root.set("processingChains", renderProcessingChains(Container.get())); - for (Extension extension : extensions) { - extension.produceExtraFields(handler).forEach((field, json) -> { - if (root.has(field)) throw new IllegalArgumentException("Field '" + field + "' already defined"); - root.set(field, json); - }); + root.set("processingChains", renderProcessingChains()); + for (Extension extension : extensions) { + extension.produceExtraFields(this).forEach((field, json) -> { + if (root.has(field)) throw new IllegalArgumentException("Field '" + field + "' already defined"); + root.set(field, json); + }); - } - return root; } + return root; + } - 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); - } + private JsonNode renderProcessingChains() { + JsonNode ret = jsonMapper.createObjectNode(); + for (RequestHandler h : requestHandlers()) { + if (h instanceof ProcessingHandler) { + ChainRegistry<Processor> registry = ((ProcessingHandler) h).getChainRegistry(); + return renderChains(registry); } - return ret; } + return ret; + } - // Note the generic param here! The key to make this work is '? extends Chain', but why? - public 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; + // Note the generic param here! The key to make this work is '? extends Chain', but why? + public 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 class IgnoredContent implements ContentChannel { diff --git a/container-disc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java b/container-disc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java index 2f1cbf997c1..4c58a943199 100644 --- a/container-disc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java +++ b/container-disc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java @@ -113,7 +113,7 @@ public class ApplicationStatusHandlerTest { Chain<Processor> chain = new Chain<>("myChain", new VoidProcessor(new ComponentId("voidProcessor"))); chains.register(new ComponentId("myChain"), chain); - String json = ApplicationStatusHandler.StatusResponse.renderChains(chains).toString(); + String json = ApplicationStatusHandler.renderChains(chains).toString(); assertTrue(json.contains("myChain")); assertTrue(json.contains("voidProcessor")); } diff --git a/container-search/src/main/java/com/yahoo/search/handler/observability/SearchStatusExtension.java b/container-search/src/main/java/com/yahoo/search/handler/observability/SearchStatusExtension.java index aba2f9cd689..836bb1b8354 100644 --- a/container-search/src/main/java/com/yahoo/search/handler/observability/SearchStatusExtension.java +++ b/container-search/src/main/java/com/yahoo/search/handler/observability/SearchStatusExtension.java @@ -2,7 +2,6 @@ package com.yahoo.search.handler.observability; import com.fasterxml.jackson.databind.JsonNode; -import com.yahoo.container.Container; import com.yahoo.container.handler.observability.ApplicationStatusHandler; import com.yahoo.jdisc.handler.RequestHandler; import com.yahoo.search.handler.SearchHandler; @@ -16,18 +15,18 @@ import java.util.Map; public class SearchStatusExtension implements ApplicationStatusHandler.Extension { @Override - public Map<String, ? extends JsonNode> produceExtraFields(ApplicationStatusHandler handler) { - return Map.of("searchChains", renderSearchChains(Container.get())); + public Map<String, ? extends JsonNode> produceExtraFields(ApplicationStatusHandler statusHandler) { + return Map.of("searchChains", renderSearchChains(statusHandler)); } - private static JsonNode renderSearchChains(Container container) { - for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) { + private static JsonNode renderSearchChains(ApplicationStatusHandler statusHandler) { + for (RequestHandler h : statusHandler.requestHandlers()) { if (h instanceof SearchHandler) { SearchChainRegistry scReg = ((SearchHandler) h).getSearchChainRegistry(); - return ApplicationStatusHandler.StatusResponse.renderChains(scReg); + return ApplicationStatusHandler.renderChains(scReg); } } - return ApplicationStatusHandler.jsonMapper.createObjectNode(); + return statusHandler.jsonMapper().createObjectNode(); } } diff --git a/docproc/src/main/java/com/yahoo/docproc/jdisc/observability/DocprocsStatusExtension.java b/docproc/src/main/java/com/yahoo/docproc/jdisc/observability/DocprocsStatusExtension.java index 91d1fa8457b..15f6c3a5cd9 100644 --- a/docproc/src/main/java/com/yahoo/docproc/jdisc/observability/DocprocsStatusExtension.java +++ b/docproc/src/main/java/com/yahoo/docproc/jdisc/observability/DocprocsStatusExtension.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.component.provider.ComponentRegistry; -import com.yahoo.container.Container; import com.yahoo.container.handler.observability.ApplicationStatusHandler; import com.yahoo.docproc.Call; import com.yahoo.docproc.impl.DocprocService; @@ -22,25 +21,25 @@ import java.util.Map; public class DocprocsStatusExtension implements ApplicationStatusHandler.Extension { @Override - public Map<String, ? extends JsonNode> produceExtraFields(ApplicationStatusHandler handler) { - return Map.of("docprocChains", renderDocprocChains(Container.get())); + public Map<String, ? extends JsonNode> produceExtraFields(ApplicationStatusHandler statusHandler) { + return Map.of("docprocChains", renderDocprocChains(statusHandler)); } - private static JsonNode renderDocprocChains(Container container) { - ObjectNode ret = ApplicationStatusHandler.jsonMapper.createObjectNode(); - for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) { + private static JsonNode renderDocprocChains(ApplicationStatusHandler statusHandler) { + ObjectNode ret = statusHandler.jsonMapper().createObjectNode(); + for (RequestHandler h : statusHandler.requestHandlers()) { if (h instanceof DocumentProcessingHandler) { ComponentRegistry<DocprocService> registry = ((DocumentProcessingHandler) h).getDocprocServiceRegistry(); for (DocprocService service : registry.allComponents()) { - ret.set(service.getId().stringValue(), renderCalls(service.getCallStack().iterator())); + ret.set(service.getId().stringValue(), renderCalls(statusHandler, service.getCallStack().iterator())); } } } return ret; } - private static JsonNode renderCalls(Iterator<Call> components) { - ArrayNode ret = ApplicationStatusHandler.jsonMapper.createArrayNode(); + private static JsonNode renderCalls(ApplicationStatusHandler statusHandler, Iterator<Call> components) { + ArrayNode ret = statusHandler.jsonMapper().createArrayNode(); while (components.hasNext()) { Call c = components.next(); JsonNode jc = ApplicationStatusHandler.renderComponent(c.getDocumentProcessor(), c.getDocumentProcessor().getId()); |