summaryrefslogtreecommitdiffstats
path: root/container-disc/src
diff options
context:
space:
mode:
Diffstat (limited to 'container-disc/src')
-rw-r--r--container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java288
-rw-r--r--container-disc/src/main/java/com/yahoo/container/handler/observability/package-info.java8
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/SystemInfoProvider.java2
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java4
-rw-r--r--container-disc/src/main/resources/configdefinitions/container.handler.observability.application-userdata.def8
-rwxr-xr-xcontainer-disc/src/main/sh/vespa-start-container-daemon.sh7
-rw-r--r--container-disc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java131
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/ContainerThreadFactoryTest.java18
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/DisableOsgiFrameworkTest.java60
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/FilterBindingsProviderTest.java18
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/component/DeconstructorTest.java18
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/metric/ForwardingMetricConsumerTest.java8
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/metric/GarbageCollectionMetricsTest.java6
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricConsumerProviderTest.java11
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricProviderTest.java12
-rw-r--r--container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricUpdaterTest.java8
16 files changed, 529 insertions, 78 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
new file mode 100644
index 00000000000..67862533259
--- /dev/null
+++ b/container-disc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
@@ -0,0 +1,288 @@
+// 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.Component;
+import com.yahoo.component.ComponentId;
+import com.yahoo.component.Vtag;
+import com.yahoo.component.annotation.Inject;
+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.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 org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+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
+ * @author bjorncs
+ */
+public class ApplicationStatusHandler extends AbstractRequestHandler {
+
+ public interface Extension {
+ Map<String, ? extends JsonNode> produceExtraFields(ApplicationStatusHandler handler);
+ }
+
+ 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;
+ private final Collection<Extension> extensions;
+
+ @Inject
+ public ApplicationStatusHandler(ApplicationMetadataConfig metaConfig,
+ ApplicationUserdataConfig userConfig,
+ JdiscBindingsConfig bindingsConfig,
+ ComponentRegistry<ClientProvider> clientProviderRegistry,
+ ComponentRegistry<ServerProvider> serverProviderRegistry,
+ ComponentRegistry<RequestFilterBase> requestFilterRegistry,
+ ComponentRegistry<ResponseFilterBase> responseFilterRegistry,
+ ComponentRegistry<Extension> extensions) {
+ applicationJson = renderApplicationConfigs(metaConfig, userConfig);
+ clientsJson = renderRequestHandlers(bindingsConfig, clientProviderRegistry.allComponentsById());
+ serversJson = renderObjectComponents(serverProviderRegistry.allComponentsById());
+ requestFiltersJson = renderObjectComponents(requestFilterRegistry.allComponentsById());
+ responseFiltersJson = renderObjectComponents(responseFilterRegistry.allComponentsById());
+
+ this.bindingsConfig = bindingsConfig;
+ this.extensions = extensions.allComponents();
+ }
+
+ @Override
+ public ContentChannel handleRequest(com.yahoo.jdisc.Request request, ResponseHandler handler) {
+ 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(render()));
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException("Invalid JSON: " + e.getMessage(), e);
+ }
+ writer.close();
+
+ 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) {
+ 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 Component> components) {
+ ArrayNode ret = jsonMapper.createArrayNode();
+
+ for (Component c : components) {
+ JsonNode jc = renderComponent(c, c.getId());
+ ret.add(jc);
+ }
+ return ret;
+ }
+
+ public 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;
+ }
+ }
+
+ JsonNode render() {
+ ObjectNode root = jsonMapper.createObjectNode();
+
+ root.set("application", applicationJson);
+ root.set("abstractComponents",
+ renderAbstractComponents(components()));
+
+ 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());
+ 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;
+ }
+
+ 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;
+ }
+
+ // 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 {
+ @Override
+ public void write(ByteBuffer buf, CompletionHandler handler) {
+ handler.completed();
+ }
+
+ @Override
+ public void close(CompletionHandler handler) {
+ handler.completed();
+ }
+ }
+
+}
diff --git a/container-disc/src/main/java/com/yahoo/container/handler/observability/package-info.java b/container-disc/src/main/java/com/yahoo/container/handler/observability/package-info.java
new file mode 100644
index 00000000000..1a669b176d0
--- /dev/null
+++ b/container-disc/src/main/java/com/yahoo/container/handler/observability/package-info.java
@@ -0,0 +1,8 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+/**
+ * @author bjorncs
+ */
+@ExportPackage
+package com.yahoo.container.handler.observability;
+
+import com.yahoo.osgi.annotation.ExportPackage; \ No newline at end of file
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/SystemInfoProvider.java b/container-disc/src/main/java/com/yahoo/container/jdisc/SystemInfoProvider.java
index 280e10f7022..d98ea0ffc25 100644
--- a/container-disc/src/main/java/com/yahoo/container/jdisc/SystemInfoProvider.java
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/SystemInfoProvider.java
@@ -2,6 +2,7 @@
package com.yahoo.container.jdisc;
import ai.vespa.cloud.ApplicationId;
+import ai.vespa.cloud.Cloud;
import ai.vespa.cloud.Cluster;
import ai.vespa.cloud.Environment;
import ai.vespa.cloud.Node;
@@ -34,6 +35,7 @@ public class SystemInfoProvider extends AbstractComponent implements Provider<Sy
applicationIdConfig.application(),
applicationIdConfig.instance()),
new Zone(Environment.valueOf(csConfig.environment()), csConfig.region()),
+ new Cloud(csConfig.cloud()),
new Cluster(ciConfig.nodeCount(), ciConfig.nodeIndices()),
new Node(qrConfig.nodeIndex()));
}
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java b/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java
index 4b75bc233d6..3f7990288f5 100644
--- a/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricUpdater.java
@@ -9,6 +9,7 @@ import com.yahoo.nativec.NativeHeap;
import java.lang.management.BufferPoolMXBean;
import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadMXBean;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -39,6 +40,7 @@ public class MetricUpdater extends AbstractComponent {
private static final String DIRECT_COUNT = "mem.direct.count";
private static final String MEMORY_MAPPINGS_COUNT = "jdisc.memory_mappings";
private static final String OPEN_FILE_DESCRIPTORS = "jdisc.open_file_descriptors";
+ private static final String TOTAL_THREADS = "jdisc.threads.total";
private final Scheduler scheduler;
@@ -99,6 +101,7 @@ public class MetricUpdater extends AbstractComponent {
private final ContainerWatchdogMetrics containerWatchdogMetrics;
private final GarbageCollectionMetrics garbageCollectionMetrics;
private final JrtMetrics jrtMetrics;
+ private final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
public UpdaterTask(Metric metric, ContainerWatchdogMetrics containerWatchdogMetrics) {
this.metric = metric;
@@ -148,6 +151,7 @@ public class MetricUpdater extends AbstractComponent {
metric.set(HEAP_TOTAL_MEMORY_BYTES, totalMemory, null);
metric.set(MEMORY_MAPPINGS_COUNT, count_mappings(), null);
metric.set(OPEN_FILE_DESCRIPTORS, count_open_files(), null);
+ metric.set(TOTAL_THREADS, threadMXBean.getThreadCount(), null);
directMemoryUsed();
nativeHeapUsed();
diff --git a/container-disc/src/main/resources/configdefinitions/container.handler.observability.application-userdata.def b/container-disc/src/main/resources/configdefinitions/container.handler.observability.application-userdata.def
new file mode 100644
index 00000000000..cde92df9ef4
--- /dev/null
+++ b/container-disc/src/main/resources/configdefinitions/container.handler.observability.application-userdata.def
@@ -0,0 +1,8 @@
+# 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-disc/src/main/sh/vespa-start-container-daemon.sh b/container-disc/src/main/sh/vespa-start-container-daemon.sh
index b27e02b6c23..b4ce6a03ba8 100755
--- a/container-disc/src/main/sh/vespa-start-container-daemon.sh
+++ b/container-disc/src/main/sh/vespa-start-container-daemon.sh
@@ -27,14 +27,10 @@ else
fi
CONTAINER_HOME="${VESPA_HOME}/var/jdisc_container/${DISCRIMINATOR}/"
-if [[ "$VESPA_SERVICE_NAME" = "container" || "$VESPA_SERVICE_NAME" = "container-clustercontroller" || "$VESPA_SERVICE_NAME" = "qrserver" ]]; then
+if [[ "$VESPA_SERVICE_NAME" = "container" || "$VESPA_SERVICE_NAME" = "container-clustercontroller" ]]; then
ZOOKEEPER_LOG_FILE_PREFIX="${VESPA_HOME}/logs/vespa/zookeeper.${VESPA_SERVICE_NAME}"
rm -f $ZOOKEEPER_LOG_FILE_PREFIX*lck
zookeeper_log_file_property="-Dzookeeper_log_file_prefix=${ZOOKEEPER_LOG_FILE_PREFIX}"
-# TODO: Temporary, remove else clause after 2022-05-20
-else
- ZOOKEEPER_LOG_FILE_PREFIX="${VESPA_HOME}/logs/vespa/zookeeper.${VESPA_SERVICE_NAME}"
- rm -f $ZOOKEEPER_LOG_FILE_PREFIX*
fi
# common setup
@@ -192,7 +188,6 @@ configure_cpu() {
configure_numactl() {
numactlcmd=$(get_numa_ctl_cmd)
- log_message debug "starting ${VESPA_SERVICE_NAME} for ${VESPA_CONFIG_ID} with numactl command : $numactlcmd"
}
configure_gcopts() {
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
new file mode 100644
index 00000000000..30c31a64a29
--- /dev/null
+++ b/container-disc/src/test/java/com/yahoo/container/handler/observability/ApplicationStatusHandlerTest.java
@@ -0,0 +1,131 @@
+// 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.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.util.HashMap;
+
+import static com.yahoo.container.jdisc.JdiscBindingsConfig.Handlers;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * @author gjoranv
+ */
+public class ApplicationStatusHandlerTest {
+
+ @Test
+ 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
+ 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
+ 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
+ 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
+ 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.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;
+ }
+ }
+}
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/ContainerThreadFactoryTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/ContainerThreadFactoryTest.java
index ec727c506b5..d55bf18c823 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/ContainerThreadFactoryTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/ContainerThreadFactoryTest.java
@@ -3,13 +3,13 @@ package com.yahoo.container.jdisc;
import com.yahoo.container.jdisc.metric.MetricConsumerProvider;
import com.yahoo.jdisc.application.ContainerThread;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.concurrent.ThreadFactory;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Simon Thoresen Hult
@@ -17,7 +17,7 @@ import static org.junit.Assert.fail;
public class ContainerThreadFactoryTest {
@Test
- public void requireThatMetricConsumerProviderCanNotBeNull() {
+ void requireThatMetricConsumerProviderCanNotBeNull() {
try {
new ContainerThreadFactory(null);
fail();
@@ -27,15 +27,15 @@ public class ContainerThreadFactoryTest {
}
@Test
- public void requireThatThreadsCreatedAreJDiscContainerThreads() {
+ void requireThatThreadsCreatedAreJDiscContainerThreads() {
assertEquals(ContainerThread.class,
- new ContainerThreadFactory(Mockito.mock(MetricConsumerProvider.class))
- .newThread(Mockito.mock(Runnable.class))
- .getClass());
+ new ContainerThreadFactory(Mockito.mock(MetricConsumerProvider.class))
+ .newThread(Mockito.mock(Runnable.class))
+ .getClass());
}
@Test
- public void requireThatThreadFactoryCallsProvider() {
+ void requireThatThreadFactoryCallsProvider() {
MetricConsumerProvider provider = Mockito.mock(MetricConsumerProvider.class);
ThreadFactory factory = new ContainerThreadFactory(provider);
factory.newThread(Mockito.mock(Runnable.class));
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/DisableOsgiFrameworkTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/DisableOsgiFrameworkTest.java
index 46acd5ce2b8..f6b2424e0e1 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/DisableOsgiFrameworkTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/DisableOsgiFrameworkTest.java
@@ -1,47 +1,63 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.jdisc;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.osgi.framework.BundleException;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
/**
* @author Ulf Lilleengen
*/
public class DisableOsgiFrameworkTest {
- @Test(expected = RuntimeException.class)
- public void require_that_installBundle_throws_exception() throws BundleException {
- new DisableOsgiFramework().installBundle("foo");
+ @Test
+ void require_that_installBundle_throws_exception() throws BundleException {
+ assertThrows(RuntimeException.class, () -> {
+ new DisableOsgiFramework().installBundle("foo");
+ });
}
- @Test(expected = RuntimeException.class)
- public void require_that_startBundles_throws_exception() throws BundleException {
- new DisableOsgiFramework().startBundles(null, true);
+ @Test
+ void require_that_startBundles_throws_exception() throws BundleException {
+ assertThrows(RuntimeException.class, () -> {
+ new DisableOsgiFramework().startBundles(null, true);
+ });
}
- @Test(expected = RuntimeException.class)
- public void require_that_bundleContext_throws_exception() throws BundleException {
- new DisableOsgiFramework().bundleContext();
+ @Test
+ void require_that_bundleContext_throws_exception() throws BundleException {
+ assertThrows(RuntimeException.class, () -> {
+ new DisableOsgiFramework().bundleContext();
+ });
}
- @Test(expected = RuntimeException.class)
- public void require_that_refreshPackages_throws_exception() {
- new DisableOsgiFramework().refreshPackages();
+ @Test
+ void require_that_refreshPackages_throws_exception() {
+ assertThrows(RuntimeException.class, () -> {
+ new DisableOsgiFramework().refreshPackages();
+ });
}
- @Test(expected = RuntimeException.class)
- public void require_that_bundles_throws_exception() {
- new DisableOsgiFramework().bundles();
+ @Test
+ void require_that_bundles_throws_exception() {
+ assertThrows(RuntimeException.class, () -> {
+ new DisableOsgiFramework().bundles();
+ });
}
- @Test(expected = RuntimeException.class)
- public void require_that_start_throws_exception() throws BundleException {
- new DisableOsgiFramework().start();
+ @Test
+ void require_that_start_throws_exception() throws BundleException {
+ assertThrows(RuntimeException.class, () -> {
+ new DisableOsgiFramework().start();
+ });
}
- @Test(expected = RuntimeException.class)
- public void require_that_stop_throws_exception() throws BundleException {
- new DisableOsgiFramework().stop();
+ @Test
+ void require_that_stop_throws_exception() throws BundleException {
+ assertThrows(RuntimeException.class, () -> {
+ new DisableOsgiFramework().stop();
+ });
}
}
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/FilterBindingsProviderTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/FilterBindingsProviderTest.java
index 70e956480ed..fe18206b5af 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/FilterBindingsProviderTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/FilterBindingsProviderTest.java
@@ -9,15 +9,15 @@ import com.yahoo.jdisc.http.ServerConfig;
import com.yahoo.jdisc.http.filter.RequestFilter;
import com.yahoo.jdisc.http.filter.ResponseFilter;
import com.yahoo.jdisc.http.server.jetty.FilterBindings;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.util.Set;
import java.util.stream.Collectors;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock;
/**
@@ -28,7 +28,7 @@ public class FilterBindingsProviderTest {
final ServerConfig.Builder configBuilder = new ServerConfig.Builder();
@Test
- public void requireThatEmptyInputGivesEmptyOutput() {
+ void requireThatEmptyInputGivesEmptyOutput() {
final FilterChainRepository filterChainRepository = new FilterChainRepository(
new ChainsConfig(new ChainsConfig.Builder()),
new ComponentRegistry<>(),
@@ -50,7 +50,7 @@ public class FilterBindingsProviderTest {
}
@Test
- public void requireThatCorrectlyConfiguredFiltersAreIncluded() {
+ void requireThatCorrectlyConfiguredFiltersAreIncluded() {
final String requestFilter1Id = "requestFilter1";
final String requestFilter2Id = "requestFilter2";
final String requestFilter3Id = "requestFilter3";
@@ -107,7 +107,7 @@ public class FilterBindingsProviderTest {
private interface DualRoleFilter extends RequestFilter, ResponseFilter {}
@Test
- public void requireThatInstanceCanNotBeBothRequestAndResponseFilter() {
+ void requireThatInstanceCanNotBeBothRequestAndResponseFilter() {
final String filterId = "filter";
// Set up config.
@@ -137,7 +137,7 @@ public class FilterBindingsProviderTest {
}
@Test
- public void requireThatConfigWithUnknownReferenceFails() {
+ void requireThatConfigWithUnknownReferenceFails() {
// Set up config.
configBuilder.filter(new ServerConfig.Filter.Builder().id("someFilter").binding("http://*/*"));
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/component/DeconstructorTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/component/DeconstructorTest.java
index 715c2759aa6..76b4d7701ea 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/component/DeconstructorTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/component/DeconstructorTest.java
@@ -6,8 +6,8 @@ import com.yahoo.container.bundle.MockBundle;
import com.yahoo.container.di.componentgraph.Provider;
import com.yahoo.jdisc.ResourceReference;
import com.yahoo.jdisc.SharedResource;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import java.time.Instant;
import java.util.List;
@@ -15,7 +15,7 @@ import java.util.function.Supplier;
import static java.util.Collections.emptyList;
import static java.util.Collections.singleton;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author gjoranv
@@ -23,13 +23,13 @@ import static org.junit.Assert.assertTrue;
public class DeconstructorTest {
public static Deconstructor deconstructor;
- @Before
+ @BeforeEach
public void init() {
deconstructor = new Deconstructor();
}
@Test
- public void deconstructor_waits_for_completion_on_shutdown() {
+ void deconstructor_waits_for_completion_on_shutdown() {
deconstructor = new Deconstructor();
var slowDeconstructComponent = new SlowDeconstructComponent();
@@ -39,7 +39,7 @@ public class DeconstructorTest {
}
@Test
- public void require_abstract_component_destructed() throws InterruptedException {
+ void require_abstract_component_destructed() throws InterruptedException {
TestAbstractComponent abstractComponent = new TestAbstractComponent();
deconstructor.deconstruct(0, List.of(abstractComponent), emptyList());
@@ -48,7 +48,7 @@ public class DeconstructorTest {
}
@Test
- public void require_provider_destructed() throws InterruptedException {
+ void require_provider_destructed() throws InterruptedException {
TestProvider provider = new TestProvider();
deconstructor.deconstruct(0, List.of(provider), emptyList());
@@ -57,7 +57,7 @@ public class DeconstructorTest {
}
@Test
- public void require_shared_resource_released() throws InterruptedException {
+ void require_shared_resource_released() throws InterruptedException {
TestSharedResource sharedResource = new TestSharedResource();
deconstructor.deconstruct(0, List.of(sharedResource), emptyList());
waitForDeconstructToComplete(() -> sharedResource.released);
@@ -65,7 +65,7 @@ public class DeconstructorTest {
}
@Test
- public void bundles_are_uninstalled() throws InterruptedException {
+ void bundles_are_uninstalled() throws InterruptedException {
var bundle = new UninstallableMockBundle();
// Done by executor, so it takes some time even with a 0 delay.
deconstructor.deconstruct(0, emptyList(), singleton(bundle));
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/ForwardingMetricConsumerTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/ForwardingMetricConsumerTest.java
index 95b179c207f..982ad4389c2 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/ForwardingMetricConsumerTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/ForwardingMetricConsumerTest.java
@@ -3,13 +3,13 @@ package com.yahoo.container.jdisc.metric;
import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.application.MetricConsumer;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.HashMap;
import java.util.Map;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* @author Simon Thoresen Hult
@@ -17,7 +17,7 @@ import static org.junit.Assert.assertNotNull;
public class ForwardingMetricConsumerTest {
@Test
- public void requireThatAllMethodsAreForwarded() {
+ void requireThatAllMethodsAreForwarded() {
MetricConsumer fooConsumer = Mockito.mock(MetricConsumer.class);
Metric.Context fooCtx = Mockito.mock(Metric.Context.class);
Mockito.when(fooConsumer.createContext(Mockito.<Map<String, ?>>any())).thenReturn(fooCtx);
@@ -26,7 +26,7 @@ public class ForwardingMetricConsumerTest {
Metric.Context barCtx = Mockito.mock(Metric.Context.class);
Mockito.when(barConsumer.createContext(Mockito.<Map<String, ?>>any())).thenReturn(barCtx);
- MetricConsumer fwdConsumer = new ForwardingMetricConsumer(new MetricConsumer[] { fooConsumer, barConsumer });
+ MetricConsumer fwdConsumer = new ForwardingMetricConsumer(new MetricConsumer[]{fooConsumer, barConsumer});
Map<String, ?> properties = new HashMap<>();
Metric.Context ctx = fwdConsumer.createContext(properties);
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/GarbageCollectionMetricsTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/GarbageCollectionMetricsTest.java
index e4f8c6d76ed..8e38420b872 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/GarbageCollectionMetricsTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/GarbageCollectionMetricsTest.java
@@ -3,13 +3,13 @@ package com.yahoo.container.jdisc.metric;
import com.yahoo.jdisc.Metric;
import com.yahoo.test.ManualClock;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.lang.management.ManagementFactory;
import java.time.Duration;
import java.util.LinkedList;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
@@ -21,7 +21,7 @@ import static org.mockito.Mockito.verify;
*/
public class GarbageCollectionMetricsTest {
@Test
- public void gc_metrics_are_collected_in_a_sliding_window() {
+ void gc_metrics_are_collected_in_a_sliding_window() {
ManualClock clock = new ManualClock();
Metric metric = mock(Metric.class);
int garbageCollectors = ManagementFactory.getGarbageCollectorMXBeans().size();
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricConsumerProviderTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricConsumerProviderTest.java
index e0650ad3d0c..5a67b7189c4 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricConsumerProviderTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricConsumerProviderTest.java
@@ -2,12 +2,11 @@
package com.yahoo.container.jdisc.metric;
import com.yahoo.jdisc.application.MetricConsumer;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertSame;
/**
* @author Simon Thoresen Hult
@@ -15,14 +14,14 @@ import static org.junit.Assert.assertSame;
public class MetricConsumerProviderTest {
@Test
- public void requireThatSingleConsumerIsNotDelegated() {
+ void requireThatSingleConsumerIsNotDelegated() {
MetricConsumer consumer = Mockito.mock(MetricConsumer.class);
MetricConsumerProvider provider = MetricConsumerProviders.newSingletonFactories(consumer);
assertSame(consumer, provider.newInstance());
}
@Test
- public void requireThatMultipleConsumersAreDelegated() {
+ void requireThatMultipleConsumersAreDelegated() {
MetricConsumer foo = Mockito.mock(MetricConsumer.class);
MetricConsumer bar = Mockito.mock(MetricConsumer.class);
MetricConsumerProvider provider = MetricConsumerProviders.newSingletonFactories(foo, bar);
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricProviderTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricProviderTest.java
index eac3ad2f060..5ad7d5767a6 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricProviderTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricProviderTest.java
@@ -4,7 +4,7 @@ package com.yahoo.container.jdisc.metric;
import com.yahoo.container.di.componentgraph.Provider;
import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.application.MetricConsumer;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import java.util.concurrent.Callable;
@@ -13,9 +13,9 @@ import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Simon Thoresen Hult
@@ -23,7 +23,7 @@ import static org.junit.Assert.assertTrue;
public class MetricProviderTest {
@Test
- public void requireThatMetricProviderDelegatesToConsumerFactory() {
+ void requireThatMetricProviderDelegatesToConsumerFactory() {
MetricConsumer consumer = Mockito.mock(MetricConsumer.class);
MetricProvider provider = MetricProviders.newInstance(consumer);
@@ -38,7 +38,7 @@ public class MetricProviderTest {
}
@Test
- public void requireThatThreadLocalConsumersAreProvided() throws Exception {
+ void requireThatThreadLocalConsumersAreProvided() throws Exception {
AtomicInteger cnt = new AtomicInteger(0);
final MetricProvider metricProvider = MetricProviders.newInstance(MetricConsumerFactories.newCounter(cnt));
assertEquals(0, cnt.get());
diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricUpdaterTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricUpdaterTest.java
index 0652f35a5d1..bc196b08ab9 100644
--- a/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricUpdaterTest.java
+++ b/container-disc/src/test/java/com/yahoo/container/jdisc/metric/MetricUpdaterTest.java
@@ -3,7 +3,7 @@ package com.yahoo.container.jdisc.metric;
import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.statistics.ContainerWatchdogMetrics;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import java.lang.management.ManagementFactory;
import java.time.Duration;
@@ -18,16 +18,16 @@ import static org.mockito.Mockito.verify;
* @author bjorncs
*/
public class MetricUpdaterTest {
-
+
@Test
- public void metrics_are_updated_in_scheduler_cycle() {
+ void metrics_are_updated_in_scheduler_cycle() {
int gcCount = ManagementFactory.getGarbageCollectorMXBeans().size();
Metric metric = mock(Metric.class);
ContainerWatchdogMetrics containerWatchdogMetrics = mock(ContainerWatchdogMetrics.class);
new MetricUpdater(new MockScheduler(), metric, containerWatchdogMetrics);
verify(containerWatchdogMetrics, times(1)).emitMetrics(any());
- verify(metric, times(13 + 2 * gcCount)).set(anyString(), any(), any());
+ verify(metric, times(14 + 2 * gcCount)).set(anyString(), any(), any());
}
private static class MockScheduler implements MetricUpdater.Scheduler {