summaryrefslogtreecommitdiffstats
path: root/container-search-and-docproc
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /container-search-and-docproc
Publish
Diffstat (limited to 'container-search-and-docproc')
-rw-r--r--container-search-and-docproc/.gitignore2
-rw-r--r--container-search-and-docproc/OWNERS1
-rw-r--r--container-search-and-docproc/pom.xml244
-rw-r--r--container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java335
-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/java/org/apache/commons/codec/binary/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/commons/codec/digest/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/commons/codec/language/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/commons/codec/net/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/commons/codec/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/auth/package-info.java9
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/client/entity/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/client/methods/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/client/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/conn/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/conn/params/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/conn/scheme/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/conn/ssl/package-info.java6
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/entity/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/impl/client/package-info.java9
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/impl/conn/package-info.java9
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/message/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/package-info.java9
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/params/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/protocol/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/java/org/apache/http/util/package-info.java7
-rw-r--r--container-search-and-docproc/src/main/resources/configdefinitions/application-userdata.def9
-rw-r--r--container-search-and-docproc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java135
28 files changed, 885 insertions, 0 deletions
diff --git a/container-search-and-docproc/.gitignore b/container-search-and-docproc/.gitignore
new file mode 100644
index 00000000000..12251442258
--- /dev/null
+++ b/container-search-and-docproc/.gitignore
@@ -0,0 +1,2 @@
+/target
+/pom.xml.build
diff --git a/container-search-and-docproc/OWNERS b/container-search-and-docproc/OWNERS
new file mode 100644
index 00000000000..3b2ba1ede81
--- /dev/null
+++ b/container-search-and-docproc/OWNERS
@@ -0,0 +1 @@
+gjoranv
diff --git a/container-search-and-docproc/pom.xml b/container-search-and-docproc/pom.xml
new file mode 100644
index 00000000000..8c567c189ac
--- /dev/null
+++ b/container-search-and-docproc/pom.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0"?>
+<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+ http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>parent</artifactId>
+ <version>6-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+ <artifactId>container-search-and-docproc</artifactId>
+ <version>6-SNAPSHOT</version>
+ <packaging>container-plugin</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-library</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>simplemetrics</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>provided-dependencies</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>component</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>container-search</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>container-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>component</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>processing</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>config</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>vespajlib</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>vespalog</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>jrt</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>searchlib</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>docproc</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>container-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>component</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>processing</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>config</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>vespajlib</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>vespalog</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>jrt</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>searchlib</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>configdefinitions</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>config-bundle</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>vespajlib</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>vespalog</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>documentapi</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>messagebus</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>document</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>container-core</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>jrt</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>messagebus-disc</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>container-messagebus</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>container-disc</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>searchlib</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.yahoo.vespa</groupId>
+ <artifactId>bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+ <Vespa-Version>${project.version}</Vespa-Version>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
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
new file mode 100644
index 00000000000..b633c34e642
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
@@ -0,0 +1,335 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.handler.observability;
+
+import com.google.inject.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.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.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+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 <a href="mailto:einarmr@yahoo-inc.com">Einar M R Rosenvinge</a>
+ */
+public class ApplicationStatusHandler extends AbstractRequestHandler {
+
+ private final JSONObject applicationJson;
+ private final JSONArray clientsJson;
+ private final JSONArray serversJson;
+ private final JSONArray requestFiltersJson;
+ private final JSONArray 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) {
+ JSONObject 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", Arrays.asList(new String[]{"application/json"}));
+ return response;
+ }
+ }.connect(handler));
+
+ writer.write(json.toString());
+ writer.close();
+
+ return new IgnoredContent();
+ }
+
+ static JSONObject renderApplicationConfigs(ApplicationMetadataConfig metaConfig,
+ ApplicationUserdataConfig userConfig) {
+ JSONObject vespa = new JSONObject();
+ putJson(vespa, "version", Vtag.currentVersion);
+
+ JSONObject meta = new JSONObject();
+ putJson(meta, "name", metaConfig.name());
+ putJson(meta, "user", metaConfig.user());
+ putJson(meta, "path", metaConfig.path());
+ putJson(meta, "generation", metaConfig.generation());
+ putJson(meta, "timestamp", metaConfig.timestamp());
+ putJson(meta, "date", new Date(metaConfig.timestamp()).toString());
+ putJson(meta, "checksum", metaConfig.checksum());
+
+ JSONObject user = new JSONObject();
+ putJson(user, "version", userConfig.version());
+
+ JSONObject application = new JSONObject();
+ putJson(application, "vespa", vespa);
+ putJson(application, "meta", meta);
+ putJson(application, "user", user);
+ return application;
+ }
+
+ static JSONArray renderObjectComponents(Map<ComponentId, ?> componentsById) {
+ JSONArray ret = new JSONArray();
+
+ for (Map.Entry<ComponentId, ?> componentEntry : componentsById.entrySet()) {
+ JSONObject jc = renderComponent(componentEntry.getValue(), componentEntry.getKey());
+ ret.put(jc);
+ }
+ return ret;
+ }
+
+ static JSONArray renderRequestHandlers(JdiscBindingsConfig bindingsConfig,
+ Map<ComponentId, ? extends RequestHandler> handlersById) {
+ JSONArray ret = new JSONArray();
+
+ for (Map.Entry<ComponentId, ? extends RequestHandler> handlerEntry : handlersById.entrySet()) {
+ String id = handlerEntry.getKey().stringValue();
+ RequestHandler handler = handlerEntry.getValue();
+
+ JSONObject handlerJson = renderComponent(handler, handlerEntry.getKey());
+ addBindings(bindingsConfig, id, handlerJson);
+ ret.put(handlerJson);
+ }
+ return ret;
+ }
+
+ private static void addBindings(JdiscBindingsConfig bindingsConfig, String id, JSONObject 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();
+ }
+ putJson(handlerJson, "serverBindings", renderBindings(serverBindings));
+ putJson(handlerJson, "clientBindings", renderBindings(clientBindings));
+ }
+
+ private static JSONArray renderBindings(List<String> bindings) {
+ JSONArray ret = new JSONArray();
+
+ for (String binding : bindings)
+ ret.put(binding);
+
+ return ret;
+ }
+
+ private static JSONArray renderAbstractComponents(List<? extends AbstractComponent> components) {
+ JSONArray ret = new JSONArray();
+
+ for (AbstractComponent c : components) {
+ JSONObject jc = renderComponent(c, c.getId());
+ ret.put(jc);
+ }
+ return ret;
+ }
+
+ private static JSONObject renderComponent(Object component, ComponentId id) {
+ JSONObject jc = new JSONObject();
+ putJson(jc, "id", id.stringValue());
+ addBundleInfo(jc, component);
+ return jc;
+ }
+
+ private static void addBundleInfo(JSONObject jsonObject, Object component) {
+ BundleInfo bundleInfo = bundleInfo(component);
+ putJson(jsonObject, "class", bundleInfo.className);
+ putJson(jsonObject, "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.", "");
+ }
+ }
+
+ private static void putJson(JSONObject json, String key, Object value) {
+ try {
+ json.put(key, value);
+ } catch (JSONException e) {
+ // The original JSONException lacks key-value info.
+ throw new RuntimeException("Trying to add invalid JSON object with key '" + key + "' and value '" + value + "' - " + e.getMessage(), e);
+ }
+ }
+
+ 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 JSONObject applicationJson;
+ private final JSONArray clientsJson;
+ private final JSONArray serversJson;
+ private final JSONArray requestFiltersJson;
+ private final JSONArray responseFiltersJson;
+ private final JdiscBindingsConfig bindingsConfig;
+
+ StatusResponse(JSONObject applicationJson,
+ JSONArray clientsJson,
+ JSONArray serversJson,
+ JSONArray requestFiltersJson,
+ JSONArray responseFiltersJson,
+ JdiscBindingsConfig bindingsConfig) {
+ this.applicationJson = applicationJson;
+ this.clientsJson = clientsJson;
+ this.serversJson = serversJson;
+ this.requestFiltersJson = requestFiltersJson;
+ this.responseFiltersJson = responseFiltersJson;
+ this.bindingsConfig = bindingsConfig;
+ }
+
+ public JSONObject render() {
+ JSONObject root = new JSONObject();
+
+ putJson(root, "application", applicationJson);
+ putJson(root, "abstractComponents",
+ renderAbstractComponents(Container.get().getComponentRegistry().allComponents()));
+
+ putJson(root, "handlers",
+ renderRequestHandlers(bindingsConfig, Container.get().getRequestHandlerRegistry().allComponentsById()));
+ putJson(root, "clients", clientsJson);
+ putJson(root, "servers", serversJson);
+ putJson(root, "httpRequestFilters", requestFiltersJson);
+ putJson(root, "httpResponseFilters", responseFiltersJson);
+
+ putJson(root, "searchChains", renderSearchChains(Container.get()));
+ putJson(root, "docprocChains", renderDocprocChains(Container.get()));
+ putJson(root, "processingChains", renderProcessingChains(Container.get()));
+
+ return root;
+ }
+
+ private static JSONObject renderSearchChains(Container container) {
+ for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) {
+ if (h instanceof SearchHandler) {
+ SearchChainRegistry scReg = ((SearchHandler) h).getSearchChainRegistry();
+ return renderChains(scReg);
+ }
+ }
+ return new JSONObject();
+ }
+
+ private static JSONObject renderDocprocChains(Container container) {
+ JSONObject ret = new JSONObject();
+ for (RequestHandler h : container.getRequestHandlerRegistry().allComponents()) {
+ if (h instanceof DocumentProcessingHandler) {
+ ComponentRegistry<DocprocService> registry = ((DocumentProcessingHandler) h).getDocprocServiceRegistry();
+ for (DocprocService service : registry.allComponents()) {
+ putJson(ret, service.getId().stringValue(), renderCalls(service.getCallStack().iterator()));
+ }
+ }
+ }
+ return ret;
+ }
+
+ private static JSONObject renderProcessingChains(Container container) {
+ JSONObject ret = new JSONObject();
+ 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 JSONObject renderChains(ComponentRegistry<? extends Chain<?>> chains) {
+ JSONObject ret = new JSONObject();
+ for (Chain<?> chain : chains.allComponents()) {
+ putJson(ret, chain.getId().stringValue(), renderAbstractComponents(chain.components()));
+ }
+ return ret;
+ }
+
+ private static JSONArray renderCalls(Iterator<Call> components) {
+ JSONArray ret = new JSONArray();
+ while (components.hasNext()) {
+ Call c = components.next();
+ JSONObject jc = renderComponent(c.getDocumentProcessor(), c.getDocumentProcessor().getId());
+ ret.put(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
new file mode 100644
index 00000000000..0f903c42562
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/package-info.java
@@ -0,0 +1,5 @@
+// Copyright 2016 Yahoo Inc. 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/java/org/apache/commons/codec/binary/package-info.java b/container-search-and-docproc/src/main/java/org/apache/commons/codec/binary/package-info.java
new file mode 100644
index 00000000000..f9309677f2f
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/commons/codec/binary/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 1, minor = 4, micro = 0))
+package org.apache.commons.codec.binary;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/commons/codec/digest/package-info.java b/container-search-and-docproc/src/main/java/org/apache/commons/codec/digest/package-info.java
new file mode 100644
index 00000000000..60a67fb11e4
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/commons/codec/digest/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 1, minor = 4, micro = 0))
+package org.apache.commons.codec.digest;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/commons/codec/language/package-info.java b/container-search-and-docproc/src/main/java/org/apache/commons/codec/language/package-info.java
new file mode 100644
index 00000000000..225284f9c78
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/commons/codec/language/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 1, minor = 4, micro = 0))
+package org.apache.commons.codec.language;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/commons/codec/net/package-info.java b/container-search-and-docproc/src/main/java/org/apache/commons/codec/net/package-info.java
new file mode 100644
index 00000000000..43b384bb605
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/commons/codec/net/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 1, minor = 4, micro = 0))
+package org.apache.commons.codec.net;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/commons/codec/package-info.java b/container-search-and-docproc/src/main/java/org/apache/commons/codec/package-info.java
new file mode 100644
index 00000000000..6f4bbeff143
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/commons/codec/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 1, minor = 4, micro = 0))
+package org.apache.commons.codec;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/auth/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/auth/package-info.java
new file mode 100644
index 00000000000..424833a69a8
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/auth/package-info.java
@@ -0,0 +1,9 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+/*
+ * Exported due to usage in HTTPSearcher API
+ */
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.auth;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/client/entity/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/client/entity/package-info.java
new file mode 100644
index 00000000000..b81f5bb0372
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/client/entity/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.client.entity;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/client/methods/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/client/methods/package-info.java
new file mode 100644
index 00000000000..86a30dc68aa
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/client/methods/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.client.methods;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/client/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/client/package-info.java
new file mode 100644
index 00000000000..7a989ea74e6
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/client/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.client;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/conn/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/conn/package-info.java
new file mode 100644
index 00000000000..ae002eb33bb
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/conn/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.conn;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/conn/params/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/conn/params/package-info.java
new file mode 100644
index 00000000000..6b8e00ea45f
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/conn/params/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.conn.params;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/conn/scheme/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/conn/scheme/package-info.java
new file mode 100644
index 00000000000..28999dd4bb6
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/conn/scheme/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.conn.scheme;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/conn/ssl/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/conn/ssl/package-info.java
new file mode 100644
index 00000000000..deebc48ceef
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/conn/ssl/package-info.java
@@ -0,0 +1,6 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.conn.ssl;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/entity/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/entity/package-info.java
new file mode 100644
index 00000000000..177c77da9dc
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/entity/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 3))
+package org.apache.http.entity;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/impl/client/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/impl/client/package-info.java
new file mode 100644
index 00000000000..fa0116f7eb0
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/impl/client/package-info.java
@@ -0,0 +1,9 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+/*
+ * Exported due to usage in HTTPSearcher API
+ */
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.impl.client;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/impl/conn/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/impl/conn/package-info.java
new file mode 100644
index 00000000000..b9f14170a3f
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/impl/conn/package-info.java
@@ -0,0 +1,9 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+/*
+ * Exported due to usage in HTTPSearcher API
+ */
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 6))
+package org.apache.http.impl.conn;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/message/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/message/package-info.java
new file mode 100644
index 00000000000..b12addfebcb
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/message/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 3))
+package org.apache.http.message;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/package-info.java
new file mode 100644
index 00000000000..9548eaafc8c
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/package-info.java
@@ -0,0 +1,9 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+/*
+ * Exported due to usage in HTTPSearcher API
+ */
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 3))
+package org.apache.http;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/params/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/params/package-info.java
new file mode 100644
index 00000000000..25db8447659
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/params/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 3))
+package org.apache.http.params;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/protocol/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/protocol/package-info.java
new file mode 100644
index 00000000000..5ee75d2dc0d
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/protocol/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 3))
+package org.apache.http.protocol;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/java/org/apache/http/util/package-info.java b/container-search-and-docproc/src/main/java/org/apache/http/util/package-info.java
new file mode 100644
index 00000000000..17395c45ac0
--- /dev/null
+++ b/container-search-and-docproc/src/main/java/org/apache/http/util/package-info.java
@@ -0,0 +1,7 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage(version = @Version(major = 4, minor = 3, micro = 3))
+package org.apache.http.util;
+
+import com.yahoo.osgi.annotation.ExportPackage;
+import com.yahoo.osgi.annotation.Version;
+
diff --git a/container-search-and-docproc/src/main/resources/configdefinitions/application-userdata.def b/container-search-and-docproc/src/main/resources/configdefinitions/application-userdata.def
new file mode 100644
index 00000000000..78d4522706f
--- /dev/null
+++ b/container-search-and-docproc/src/main/resources/configdefinitions/application-userdata.def
@@ -0,0 +1,9 @@
+# Copyright 2016 Yahoo Inc. 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
+
+version=1
+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
new file mode 100644
index 00000000000..8e88f174adc
--- /dev/null
+++ b/container-search-and-docproc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java
@@ -0,0 +1,135 @@
+// Copyright 2016 Yahoo Inc. 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.Metric;
+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 java.util.concurrent.Executors;
+
+import static com.yahoo.container.jdisc.JdiscBindingsConfig.Handlers;
+import static org.junit.Assert.assertThat;
+import static org.hamcrest.CoreMatchers.containsString;
+
+/**
+ * @author gjoranv
+ * @since 5.1.10
+ */
+public class ApplicationStatusHandlerTest {
+
+ @Test
+ public void application_configs_are_rendered() throws Exception {
+ 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();
+ assertThat(json, containsString("version"));
+ assertThat(json, containsString("meta"));
+ assertThat(json, containsString("abc"));
+ assertThat(json, containsString("app"));
+ assertThat(json, containsString("/a/b/c"));
+ assertThat(json, containsString("3000"));
+ assertThat(json, containsString("donald"));
+
+ assertThat(json, containsString("v1"));
+ }
+
+ @Test
+ public void object_components_are_rendered() throws Exception {
+ HashMap<ComponentId, Object> id2object = new HashMap<>();
+ id2object.put(new ComponentId("myComponent"), new Object());
+
+ String json = ApplicationStatusHandler.renderObjectComponents(id2object).toString();
+ assertThat(json, containsString("myComponent"));
+ }
+
+ @Test
+ public void request_handlers_are_rendered() throws Exception {
+ 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();
+ assertThat(json, containsString("\"" + id + "\""));
+ assertThat(json, containsString(serverBinding1));
+ assertThat(json, containsString(serverBinding2));
+ assertThat(json, containsString(clientBinding));
+ }
+
+ @Test
+ public void client_providers_are_rendered() throws Exception {
+ 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);
+ assertThat(json, containsString("\"" + id + "\""));
+ assertThat(json, containsString(clientBinding));
+ assertThat(json, containsString(clientBinding2));
+ assertThat(json, containsString(serverBinding));
+ }
+
+ @Test
+ public void chains_are_rendered() throws Exception {
+ ChainRegistry<Processor> chains = new ChainRegistry<>();
+ Chain<Processor> chain = new Chain<Processor>("myChain", new VoidProcessor(new ComponentId("voidProcessor")));
+ chains.register(new ComponentId("myChain"), chain);
+
+ String json = ApplicationStatusHandler.StatusResponse.renderChains(chains).toString();
+ assertThat(json, containsString("myChain"));
+ assertThat(json, containsString("voidProcessor"));
+ }
+
+ private static class VoidProcessor extends Processor {
+ private VoidProcessor(ComponentId id) {
+ super();
+ initId(id);
+ }
+ @Override
+ public Response process(Request request, Execution processorExecution) {
+ return null;
+ }
+ }
+}