aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHÃ¥kon Hallingstad <hakon@oath.com>2018-12-01 00:47:29 +0100
committerGitHub <noreply@github.com>2018-12-01 00:47:29 +0100
commit8e4eeb40e46f7b2fde27ac82bf14f27be4de6ecb (patch)
treeb7237df951072a75d3d527b757f11e6b08214c3d
parentc0513ac34d2c438e9f97e699659855029e1f06e8 (diff)
Revert "Remove zombie code"
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java1
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java7
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java1
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java1
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java5
-rw-r--r--container-core/src/main/java/com/yahoo/container/ConfigHack.java31
-rwxr-xr-xcontainer-core/src/main/java/com/yahoo/container/Container.java30
-rw-r--r--container-core/src/main/java/com/yahoo/container/Server.java50
-rw-r--r--container-core/src/main/java/com/yahoo/container/config/StatisticsEmitter.java20
-rw-r--r--container-core/src/main/java/com/yahoo/container/config/StatisticsRequestHandler.java55
-rw-r--r--container-core/src/main/java/com/yahoo/container/config/package-info.java5
-rw-r--r--container-core/src/main/java/com/yahoo/container/config/testutil/TestUtil.java85
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/slobrok/SlobrokConfigurator.java26
-rw-r--r--container-core/src/main/java/com/yahoo/container/osgi/AbstractRpcAdaptor.java15
-rw-r--r--container-core/src/main/java/com/yahoo/container/osgi/ContainerRpcAdaptor.java129
-rw-r--r--container-core/src/main/java/com/yahoo/container/osgi/package-info.java5
-rw-r--r--container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java2
-rw-r--r--container-di/src/main/java/com/yahoo/container/di/Container.java2
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java6
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java3
-rw-r--r--container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java66
21 files changed, 471 insertions, 74 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java
index c07d6f66237..5698485b004 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java
@@ -116,6 +116,7 @@ public class DomAdminV4Builder extends DomAdminBuilderBase {
// Add base handlers and the log handler
logServerCluster.addMetricStateHandler();
logServerCluster.addApplicationStatusHandler();
+ logServerCluster.addStatisticsHandler();
logServerCluster.addDefaultRootHandler();
logServerCluster.addVipHandler();
addLogHandler(logServerCluster);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index d43defaeeb1..12613018ca7 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -232,6 +232,7 @@ public final class ContainerCluster
addSimpleComponent("com.yahoo.container.jdisc.state.StateMonitor");
addSimpleComponent("com.yahoo.container.jdisc.ContainerThreadFactory");
addSimpleComponent("com.yahoo.container.protect.FreezeDetector");
+ addSimpleComponent("com.yahoo.container.core.slobrok.SlobrokConfigurator");
addSimpleComponent("com.yahoo.container.handler.VipStatus");
addSimpleComponent(com.yahoo.container.handler.ClustersStatus.class.getName());
addJaxProviders();
@@ -288,6 +289,12 @@ public final class ContainerCluster
addComponent(vipHandler);
}
+ public void addStatisticsHandler() {
+ Handler<?> statsHandler = Handler.fromClassName(STATISTICS_HANDLER_CLASS);
+ statsHandler.addServerBindings("http://*/statistics/*", "https://*/statistics/*");
+ addComponent(statsHandler);
+ }
+
@SuppressWarnings("deprecation")
private void addJaxProviders() {
addSimpleComponent(com.yahoo.container.xml.providers.DatatypeFactoryProvider.class);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
index b5c1b1e1496..0be25808541 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java
@@ -289,6 +289,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
cluster.addDefaultRootHandler();
cluster.addMetricStateHandler();
cluster.addApplicationStatusHandler();
+ cluster.addStatisticsHandler();
}
private void addClientProviders(DeployState deployState, Element spec, ContainerCluster cluster) {
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java
index 49a989a9474..8158db51271 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerDocumentApiBuilderTest.java
@@ -104,6 +104,7 @@ public class ContainerDocumentApiBuilderTest extends ContainerModelBuilderTestBa
Map<String, Handler<?>> handlerMap = getHandlers("cluster1");
+ assertThat(handlerMap.get("com.yahoo.container.config.StatisticsRequestHandler"), not(nullValue()));
assertThat(handlerMap.get("com.yahoo.container.handler.VipStatusHandler"), not(nullValue()));
assertThat(handlerMap.get("com.yahoo.container.handler.observability.ApplicationStatusHandler"), not(nullValue()));
assertThat(handlerMap.get("com.yahoo.container.jdisc.state.StateHandler"), not(nullValue()));
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java
index 0030392f318..aa1ac401014 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java
@@ -18,6 +18,7 @@ import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.ComponentsConfig;
import com.yahoo.container.QrConfig;
+import com.yahoo.container.config.StatisticsRequestHandler;
import com.yahoo.container.core.ChainsConfig;
import com.yahoo.container.core.VipStatusConfig;
import com.yahoo.container.handler.VipStatusHandler;
@@ -274,6 +275,10 @@ public class ContainerModelBuilderTest extends ContainerModelBuilderTestBase {
assertThat(applicationStatusHandler.serverBindings(),
contains("http://*/ApplicationStatus", "https://*/ApplicationStatus"));
+ JdiscBindingsConfig.Handlers statisticsRequestHandler = config.handlers(StatisticsRequestHandler.class.getName());
+ assertTrue(statisticsRequestHandler.serverBindings(0).startsWith("http://*/statistics"));
+ assertTrue(statisticsRequestHandler.serverBindings(1).startsWith("https://*/statistics"));
+
JdiscBindingsConfig.Handlers fileRequestHandler = config.handlers(VipStatusHandler.class.getName());
assertThat(fileRequestHandler.serverBindings(),
contains("http://*/status.html", "https://*/status.html"));
diff --git a/container-core/src/main/java/com/yahoo/container/ConfigHack.java b/container-core/src/main/java/com/yahoo/container/ConfigHack.java
new file mode 100644
index 00000000000..55cf208e163
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/ConfigHack.java
@@ -0,0 +1,31 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container;
+
+import com.yahoo.container.config.StatisticsEmitter;
+
+/**
+ * Distribution point for QRS specific stuff in a more or less
+ * container agnostic way. This is only a stepping stone to moving these things
+ * to Container and other pertinent classes, or simply removing the problems.
+ *
+ * <p>
+ * This class should not reach a final release.
+ *
+ * @author Steinar Knutsen
+ */
+public final class ConfigHack {
+
+ private volatile StatisticsEmitter statisticsEmitter = new StatisticsEmitter();
+ public static final String TILED_TEMPLATE = "tiled";
+
+ public static final ConfigHack instance = new ConfigHack();
+
+ public StatisticsEmitter getStatisticsHandler() {
+ return statisticsEmitter;
+ }
+
+ public void setStatisticsEmitter(StatisticsEmitter statisticsEmitter) {
+ this.statisticsEmitter = statisticsEmitter;
+ }
+
+}
diff --git a/container-core/src/main/java/com/yahoo/container/Container.java b/container-core/src/main/java/com/yahoo/container/Container.java
index c83dd2199ea..f378e7d51bd 100755
--- a/container-core/src/main/java/com/yahoo/container/Container.java
+++ b/container-core/src/main/java/com/yahoo/container/Container.java
@@ -4,6 +4,8 @@ package com.yahoo.container;
import com.yahoo.component.AbstractComponent;
import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.container.core.config.BundleLoader;
+import com.yahoo.container.osgi.AbstractRpcAdaptor;
+import com.yahoo.container.osgi.ContainerRpcAdaptor;
import com.yahoo.filedistribution.fileacquirer.FileAcquirer;
import com.yahoo.filedistribution.fileacquirer.FileAcquirerFactory;
import com.yahoo.jdisc.handler.RequestHandler;
@@ -31,23 +33,35 @@ public class Container {
private volatile ComponentRegistry<ServerProvider> serverProviderRegistry;
private volatile ComponentRegistry<AbstractComponent> componentRegistry;
private volatile FileAcquirer fileAcquirer;
+ private Osgi osgi;
+
+ private final ContainerRpcAdaptor rpcAdaptor = new ContainerRpcAdaptor(osgi);
private volatile BundleLoader bundleLoader;
private static Logger logger = Logger.getLogger(Container.class.getName());
- // TODO: Make this final again.
+ //TODO: Make this final again.
private static Container instance = new Container();
public static Container get() { return instance; }
public void setOsgi(Osgi osgi) {
+ this.osgi = osgi;
bundleLoader = new BundleLoader(osgi);
}
public void shutdown() {
+ com.yahoo.container.Server.get().shutdown();
if (fileAcquirer != null)
fileAcquirer.shutdown();
+
+ rpcAdaptor.shutdown();
+ }
+
+ /** Returns the rpc adaptor owned by this */
+ public ContainerRpcAdaptor getRpcAdaptor() {
+ return rpcAdaptor;
}
//Used to acquire files originating from the application package.
@@ -61,13 +75,22 @@ public class Container {
return bundleLoader;
}
- /**
- * Hack. For internal use only, will be removed later
+ /** Hack. For internal use only, will be removed later
*
* Used by Application to be able to repeatedly set up containers.
**/
public static void resetInstance() {
instance = new Container();
+ com.yahoo.container.Server.resetInstance();
+ }
+
+ /**
+ * Add an application specific RPC adaptor.
+ *
+ * @param adaptor the RPC adaptor to add to the Container
+ */
+ public void addOptionalRpcAdaptor(AbstractRpcAdaptor adaptor) {
+ rpcAdaptor.bindRpcAdaptor(adaptor);
}
public ComponentRegistry<RequestHandler> getRequestHandlerRegistry() {
@@ -142,5 +165,4 @@ public class Container {
}
});
}
-
}
diff --git a/container-core/src/main/java/com/yahoo/container/Server.java b/container-core/src/main/java/com/yahoo/container/Server.java
index a4dec6de5a2..293e8b4674e 100644
--- a/container-core/src/main/java/com/yahoo/container/Server.java
+++ b/container-core/src/main/java/com/yahoo/container/Server.java
@@ -3,43 +3,83 @@ package com.yahoo.container;
import com.yahoo.config.subscription.ConfigSubscriber;
import com.yahoo.container.QrConfig.Rpc;
+import com.yahoo.container.osgi.ContainerRpcAdaptor;
/**
* The http server singleton managing listeners for various ports,
* and the threads used to respond to requests on the ports
*
* @author bratseth
- * @deprecated
*/
@SuppressWarnings("deprecation")
-@Deprecated // TODO: Remove this when the last usage og getServerDiscriminator is removed
public class Server {
//TODO: Make this final again.
- private static final Server instance = new Server();
+ private static Server instance = new Server();
+ private ConfigSubscriber subscriber = new ConfigSubscriber();
+
+ /** The OSGi container instance of this server */
+ private Container container = Container.get();
/** A short string which is different for all the qrserver instances on a given node. */
private String localServerDiscriminator = "qrserver.0";
+ /** Creates a new server instance. Not usually useful, use get() to get the current server */
private Server() { }
+ /** @deprecated returns 0 */
+ @Deprecated
+ public int searchQueriesInFlight() {
+ return 0;
+ }
+
+ /**
+ * An estimate of current number of connections. It is better to be
+ * inaccurate than to acquire a lock per query fsync.
+ *
+ * @return The current number of open search connections
+ */
+ /** @deprecated returns 0 */
+ @Deprecated
+ public int getCurrentConnections() {
+ return 0;
+ }
+
public static Server get() {
return instance;
}
+ private void initRpcServer(Rpc rpcConfig) {
+ if (rpcConfig.enabled()) {
+ ContainerRpcAdaptor rpcAdaptor = container.getRpcAdaptor();
+ rpcAdaptor.listen(rpcConfig.port());
+ rpcAdaptor.setSlobrokId(rpcConfig.slobrokId());
+ }
+ }
+
+ /** Ugly hack, see Container.resetInstance */
+ static void resetInstance() {
+ instance = new Server();
+ }
+
+ // TODO: Make independent of config
public void initialize(QrConfig config) {
localServerDiscriminator = config.discriminator();
+ container.setupFileAcquirer(config.filedistributor());
+ initRpcServer(config.rpc());
}
/**
* A string unique for this QRS on this server.
*
* @return a server specific string
- * @deprecated do not use
*/
- @Deprecated
public String getServerDiscriminator() {
return localServerDiscriminator;
}
+ public void shutdown() {
+ if (subscriber!=null) subscriber.close();
+ }
+
}
diff --git a/container-core/src/main/java/com/yahoo/container/config/StatisticsEmitter.java b/container-core/src/main/java/com/yahoo/container/config/StatisticsEmitter.java
new file mode 100644
index 00000000000..0e9d7ec9ce8
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/config/StatisticsEmitter.java
@@ -0,0 +1,20 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.config;
+
+
+import com.yahoo.container.jdisc.HttpRequest;
+
+/**
+ * An insulating layer between HTTP and whatever kind of HTTP statistics
+ * interface is made available. This is an intermediary step towards a
+ * generalized network layer.
+ *
+ * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ */
+public class StatisticsEmitter {
+
+ public StringBuilder respond(HttpRequest request) {
+ return new StringBuilder("No statistics available yet.");
+ }
+
+}
diff --git a/container-core/src/main/java/com/yahoo/container/config/StatisticsRequestHandler.java b/container-core/src/main/java/com/yahoo/container/config/StatisticsRequestHandler.java
new file mode 100644
index 00000000000..e0b6392b64a
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/config/StatisticsRequestHandler.java
@@ -0,0 +1,55 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.config;
+
+import com.google.inject.Inject;
+import com.yahoo.jdisc.Metric;
+import com.yahoo.container.ConfigHack;
+import com.yahoo.container.jdisc.HttpRequest;
+import com.yahoo.container.jdisc.HttpResponse;
+import com.yahoo.container.jdisc.ThreadedHttpRequestHandler;
+import com.yahoo.container.logging.AccessLog;
+import com.yahoo.text.Utf8;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.concurrent.Executor;
+
+/**
+ * Handler of statistics http requests. Temporary hack as a step towards a more
+ * general network interface.
+ *
+ * @author Steinar Knutsen
+ * @author Einar M R Rosenvinge
+ */
+public class StatisticsRequestHandler extends ThreadedHttpRequestHandler {
+
+ @Inject
+ public StatisticsRequestHandler(Executor executor, Metric metric) {
+ super(executor, metric);
+ }
+
+ @Override
+ public HttpResponse handle(HttpRequest request) {
+ return new StatisticsResponse(ConfigHack.instance.getStatisticsHandler().respond(request));
+ }
+
+ protected static class StatisticsResponse extends HttpResponse {
+
+ private final StringBuilder string;
+
+ private StatisticsResponse(StringBuilder stringBuilder) {
+ super(com.yahoo.jdisc.http.HttpResponse.Status.OK);
+ this.string = stringBuilder;
+ }
+
+ @Override
+ public void render(OutputStream stream) throws IOException {
+ Writer osWriter = new OutputStreamWriter(stream, Utf8.getCharset());
+ osWriter.write(string.toString());
+ osWriter.flush();
+ osWriter.close();
+ }
+ }
+}
diff --git a/container-core/src/main/java/com/yahoo/container/config/package-info.java b/container-core/src/main/java/com/yahoo/container/config/package-info.java
new file mode 100644
index 00000000000..b8e45b636dc
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/config/package-info.java
@@ -0,0 +1,5 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage
+package com.yahoo.container.config;
+
+import com.yahoo.osgi.annotation.ExportPackage;
diff --git a/container-core/src/main/java/com/yahoo/container/config/testutil/TestUtil.java b/container-core/src/main/java/com/yahoo/container/config/testutil/TestUtil.java
new file mode 100644
index 00000000000..dbf8be8e1dc
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/config/testutil/TestUtil.java
@@ -0,0 +1,85 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.config.testutil;
+
+import com.yahoo.container.core.config.HandlersConfigurerDi;
+
+import java.io.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author gjoranv
+ */
+public class TestUtil {
+
+ public static void createComponentsConfig(String configFile,
+ String componentsFile,
+ String componentType) throws IOException {
+ createComponentsConfig(configFile, componentsFile, componentType, false);
+ }
+
+ /**
+ * Copies the component ids from another config, e.g. 'handlers' to a 'components' array in a new components file,
+ * to avoid a manually written 'components' file for tests where the bundle spec is given by the component id.
+ * @param configFile Full path to the original config file, e.g. 'handlers'
+ * @param componentsFile Full path to the new 'components' file
+ * @param componentType The type of component, e.g. 'handler'
+ * @param append 'true' will append to an already existing 'componentsFile'
+ */
+ public static void createComponentsConfig(String configFile,
+ String componentsFile,
+ String componentType,
+ boolean append) throws IOException {
+ StringBuilder buf = new StringBuilder();
+ String line;
+ int i = 0;
+ if (append) {
+ final Pattern p = Pattern.compile("^[a-z]+" + "\\[\\d+\\]\\.id (.+)");
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ new FileInputStream(new File(componentsFile)), "UTF-8"));
+ while ((line = reader.readLine()) != null) {
+ Matcher m = p.matcher(line);
+ if (m.matches() && !m.group(1).equals(HandlersConfigurerDi.RegistriesHack.class.getName())) {
+ buf.append("components[").append(i).append("].id ").append(m.group(1)).append("\n");
+ i++;
+ }
+ }
+ reader.close();
+ }
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ new FileInputStream(new File(configFile)), "UTF-8"));
+ final Pattern component = Pattern.compile("^" + componentType + "\\[\\d+\\]\\.id (.+)");
+ while ((line = reader.readLine()) != null) {
+ Matcher m = component.matcher(line);
+ if (m.matches()) {
+ buf.append("components[").append(i).append("].id ").append(m.group(1)).append("\n");
+ i++;
+ }
+ }
+ buf.append("components[").append(i).append("].id ").
+ append(HandlersConfigurerDi.RegistriesHack.class.getName()).append("\n");
+ i++;
+ reader.close();
+ buf.insert(0, "components["+i+"]\n");
+
+ Writer writer = new OutputStreamWriter(new FileOutputStream(new File(componentsFile)), "UTF-8");
+ writer.write(buf.toString());
+ writer.flush();
+ writer.close();
+ }
+
+ /**
+ * Copies src file to dst file. If the dst file does not exist, it is created.
+ */
+ public static void copyFile(String srcName, File dstFile) throws IOException {
+ InputStream src = new FileInputStream(new File(srcName));
+ OutputStream dst = new FileOutputStream(dstFile);
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = src.read(buf)) > 0) {
+ dst.write(buf, 0, len);
+ }
+ src.close();
+ dst.close();
+ }
+}
diff --git a/container-core/src/main/java/com/yahoo/container/core/slobrok/SlobrokConfigurator.java b/container-core/src/main/java/com/yahoo/container/core/slobrok/SlobrokConfigurator.java
new file mode 100644
index 00000000000..9472fa07bb5
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/core/slobrok/SlobrokConfigurator.java
@@ -0,0 +1,26 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.core.slobrok;
+
+import com.yahoo.cloud.config.SlobroksConfig;
+import com.yahoo.cloud.config.SlobroksConfig.Slobrok;
+import com.yahoo.container.Container;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Configures which slobrok nodes the container should register with.
+ * @author Tony Vaagenes
+ */
+public class SlobrokConfigurator {
+ public SlobrokConfigurator(SlobroksConfig config) {
+ Container.get().getRpcAdaptor().registerInSlobrok(
+ connectionSpecs(config.slobrok()));
+ }
+
+ private static List<String> connectionSpecs(List<Slobrok> slobroks) {
+ return slobroks.stream().
+ map(Slobrok::connectionspec).
+ collect(Collectors.toList());
+ }
+}
diff --git a/container-core/src/main/java/com/yahoo/container/osgi/AbstractRpcAdaptor.java b/container-core/src/main/java/com/yahoo/container/osgi/AbstractRpcAdaptor.java
new file mode 100644
index 00000000000..9486fe367f9
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/osgi/AbstractRpcAdaptor.java
@@ -0,0 +1,15 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.osgi;
+
+import com.yahoo.jrt.Supervisor;
+
+/**
+ * Helper class for optional RPC adaptors in the Container.
+ *
+ * @author Steinar Knutsen
+ */
+public abstract class AbstractRpcAdaptor {
+
+ public abstract void bindCommands(Supervisor supervisor);
+
+}
diff --git a/container-core/src/main/java/com/yahoo/container/osgi/ContainerRpcAdaptor.java b/container-core/src/main/java/com/yahoo/container/osgi/ContainerRpcAdaptor.java
new file mode 100644
index 00000000000..7db7d4032d5
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/osgi/ContainerRpcAdaptor.java
@@ -0,0 +1,129 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.osgi;
+
+import com.yahoo.jrt.Acceptor;
+import com.yahoo.jrt.ErrorCode;
+import com.yahoo.jrt.ListenFailedException;
+import com.yahoo.jrt.Method;
+import com.yahoo.jrt.Request;
+import com.yahoo.jrt.Spec;
+import com.yahoo.jrt.StringValue;
+import com.yahoo.jrt.Supervisor;
+import com.yahoo.jrt.Transport;
+import com.yahoo.jrt.slobrok.api.Register;
+import com.yahoo.jrt.slobrok.api.SlobrokList;
+import com.yahoo.net.HostName;
+import com.yahoo.log.LogLevel;
+import com.yahoo.osgi.Osgi;
+import com.yahoo.yolean.Exceptions;
+import org.osgi.framework.Bundle;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+/**
+ * An rpc adaptor to container Osgi commands.
+ *
+ * @author bratseth
+ */
+public class ContainerRpcAdaptor extends AbstractRpcAdaptor {
+
+ private static final Logger log = Logger.getLogger(ContainerRpcAdaptor.class.getName());
+
+ private Acceptor acceptor;
+ private final Supervisor supervisor;
+
+ private final Osgi osgi;
+ private final String hostname;
+
+ private Optional<String> slobrokId = Optional.empty();
+ private Optional<Register> slobrokRegistrator = Optional.empty();
+
+ public ContainerRpcAdaptor(Osgi osgi) {
+ this.osgi = osgi;
+ this.supervisor = new Supervisor(new Transport());
+ this.hostname = HostName.getLocalhost();
+
+ bindCommands(supervisor);
+ }
+
+ public void list(Request request) {
+ try {
+ StringBuilder buffer=new StringBuilder("Installed bundles:");
+ for (Bundle bundle : osgi.getBundles()) {
+ if (bundle.getSymbolicName().equals("system.bundle")) continue;
+ buffer.append("\n");
+ buffer.append(bundle.getSymbolicName());
+ buffer.append(" (");
+ buffer.append(bundle.getLocation());
+ buffer.append(")");
+ }
+ request.returnValues().add(new StringValue(buffer.toString()));
+ }
+ catch (Exception e) {
+ request.setError(ErrorCode.METHOD_FAILED,Exceptions.toMessageString(e));
+ }
+ }
+
+ public void bindCommands(Supervisor supervisor) {
+ supervisor.addMethod(new Method("list","","s",this,"list"));
+ }
+
+ public synchronized void listen(int port) {
+ Spec spec = new Spec(port);
+ try {
+ acceptor = supervisor.listen(spec);
+ log.log(LogLevel.DEBUG, "Added new rpc server listening at" + " port '" + port + "'.");
+ } catch (ListenFailedException e) {
+ throw new RuntimeException("Could not create rpc server listening on " + spec, e);
+ }
+ }
+
+ public synchronized void setSlobrokId(String slobrokId) {
+ this.slobrokId = Optional.of(slobrokId);
+ }
+
+ public synchronized void registerInSlobrok(List<String> slobrokConnectionSpecs) {
+ shutdownSlobrokRegistrator();
+
+ if (slobrokConnectionSpecs.isEmpty()) {
+ return;
+ }
+
+ if (!slobrokId.isPresent()) {
+ throw new AssertionError("Slobrok id must be set first");
+ }
+
+ SlobrokList slobrokList = new SlobrokList();
+ slobrokList.setup(slobrokConnectionSpecs.stream().toArray(String[]::new));
+
+ Spec mySpec = new Spec(hostname, acceptor.port());
+
+ Register register = new Register(supervisor, slobrokList, mySpec);
+ register.registerName(slobrokId.get());
+ slobrokRegistrator = Optional.of(register);
+
+ log.log(LogLevel.INFO, "Registered name '" + slobrokId.get() + "' at " + mySpec + " with: " + slobrokList);
+ }
+
+ private synchronized void shutdownSlobrokRegistrator() {
+ slobrokRegistrator.ifPresent(Register::shutdown);
+ slobrokRegistrator = Optional.empty();
+ }
+
+ public synchronized void shutdown() {
+ shutdownSlobrokRegistrator();
+
+ if (acceptor != null) {
+ acceptor.shutdown().join();
+ }
+ supervisor.transport().shutdown().join();
+ }
+
+
+ public synchronized void bindRpcAdaptor(AbstractRpcAdaptor adaptor) {
+ adaptor.bindCommands(supervisor);
+ }
+
+}
diff --git a/container-core/src/main/java/com/yahoo/container/osgi/package-info.java b/container-core/src/main/java/com/yahoo/container/osgi/package-info.java
new file mode 100644
index 00000000000..0768489a767
--- /dev/null
+++ b/container-core/src/main/java/com/yahoo/container/osgi/package-info.java
@@ -0,0 +1,5 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage
+package com.yahoo.container.osgi;
+
+import com.yahoo.osgi.annotation.ExportPackage;
diff --git a/container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java b/container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java
index 2e37a278387..d9ccd5c590f 100644
--- a/container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java
+++ b/container-core/src/main/java/com/yahoo/osgi/OsgiImpl.java
@@ -16,6 +16,8 @@ import java.util.logging.Logger;
*/
public class OsgiImpl implements Osgi {
+ private static final Logger log = Logger.getLogger(OsgiImpl.class.getName());
+
private final OsgiFramework jdiscOsgi;
public OsgiImpl(OsgiFramework jdiscOsgi) {
diff --git a/container-di/src/main/java/com/yahoo/container/di/Container.java b/container-di/src/main/java/com/yahoo/container/di/Container.java
index 1b02961082f..d3d635eb522 100644
--- a/container-di/src/main/java/com/yahoo/container/di/Container.java
+++ b/container-di/src/main/java/com/yahoo/container/di/Container.java
@@ -35,7 +35,6 @@ import static com.yahoo.log.LogLevel.DEBUG;
* @author ollivir
*/
public class Container {
-
private static final Logger log = Logger.getLogger(Container.class.getName());
private final SubscriberFactory subscriberFactory;
@@ -264,5 +263,4 @@ public class Container {
public static BundleInstantiationSpecification bundleInstatiationSpecification(ComponentsConfig.Components config) {
return BundleInstantiationSpecification.getFromStrings(config.id(), config.classId(), config.bundle());
}
-
}
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java b/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java
index 27defe08fa8..69a525a2c54 100644
--- a/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java
@@ -11,6 +11,7 @@ import com.yahoo.config.ConfigInstance;
import com.yahoo.config.subscription.ConfigInterruptedException;
import com.yahoo.container.Container;
import com.yahoo.container.QrConfig;
+import com.yahoo.container.Server;
import com.yahoo.container.core.ChainsConfig;
import com.yahoo.container.core.config.HandlersConfigurerDi;
import com.yahoo.container.di.config.Subscriber;
@@ -133,11 +134,10 @@ public final class ConfiguredApplication implements Application {
portWatcher.start();
}
- @SuppressWarnings("deprecation")
+
private static void hackToInitializeServer(QrConfig config) {
try {
- Container.get().setupFileAcquirer(config.filedistributor());
- com.yahoo.container.Server.get().initialize(config);
+ Server.get().initialize(config);
} catch (Exception e) {
log.log(LogLevel.ERROR, "Caught exception when initializing server. Exiting.", e);
Runtime.getRuntime().halt(1);
diff --git a/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java b/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java
index 2fa6e14019e..115e9cd44a1 100644
--- a/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java
+++ b/container-search/src/main/java/com/yahoo/prelude/templates/TiledTemplateSet.java
@@ -1,6 +1,7 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.templates;
+import com.yahoo.container.ConfigHack;
import com.yahoo.prelude.hitfield.HitField;
import com.yahoo.prelude.hitfield.JSONString;
import com.yahoo.prelude.hitfield.XMLString;
@@ -80,7 +81,7 @@ public class TiledTemplateSet extends DefaultTemplateSet {
private FormattingOptions hitOptions;
public TiledTemplateSet() {
- this("tiled");
+ this(ConfigHack.TILED_TEMPLATE);
}
public TiledTemplateSet(String templateName) {
diff --git a/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java b/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java
index 699e8619cd0..e9eb90378f4 100644
--- a/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/searchchain/config/test/SearchChainConfigurerTestCase.java
@@ -3,7 +3,7 @@ package com.yahoo.search.searchchain.config.test;
import com.yahoo.config.search.IntConfig;
import com.yahoo.config.search.StringConfig;
-import com.yahoo.container.core.config.HandlersConfigurerDi;
+import com.yahoo.container.config.testutil.TestUtil;
import com.yahoo.container.core.config.testutil.HandlersConfigurerTestWrapper;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
@@ -19,8 +19,6 @@ import org.junit.Test;
import java.io.*;
import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
@@ -52,7 +50,7 @@ public class SearchChainConfigurerTestCase {
}
@AfterClass
- public static void removeDefaultComponentsConfigs() {
+ public static void removeDefaultComponentsConfigs() throws IOException {
new File(testDir + "components.cfg").delete();
}
@@ -62,7 +60,7 @@ public class SearchChainConfigurerTestCase {
}
@Test
- public synchronized void testConfiguration() {
+ public synchronized void testConfiguration() throws Exception {
HandlersConfigurerTestWrapper configurer = new HandlersConfigurerTestWrapper("dir:" + testDir);
SearchChain simple=getSearchChainRegistryFrom(configurer).getComponent("simple");
@@ -184,7 +182,7 @@ public class SearchChainConfigurerTestCase {
* and that a searcher that has been removed from the configuration is not in the new registry.
*/
@Test
- public void testChainsConfigUpdate() throws IOException {
+ public void testChainsConfigUpdate() throws IOException, InterruptedException {
File cfgDir = getCfgDir();
copyFile(testDir + "handlers.cfg", cfgDir + "/handlers.cfg");
copyFile(testDir + "qr-search.cfg", cfgDir + "/qr-search.cfg");
@@ -268,7 +266,7 @@ public class SearchChainConfigurerTestCase {
//// Helper methods
- public static void printFile(File f, String content) throws IOException {
+ public static void printFile(File f, String content) throws IOException, InterruptedException {
OutputStream out = new FileOutputStream(f);
out.write(content.getBytes());
out.close();
@@ -302,58 +300,8 @@ public class SearchChainConfigurerTestCase {
* Also adds the default SearchHandler.
*/
public static void createComponentsConfig(String chainsFile, String handlersFile, String componentsFile) throws IOException {
- createComponentsConfig(handlersFile, componentsFile, "handler", false);
- createComponentsConfig(chainsFile, componentsFile, "components", true);
- }
-
- /**
- * Copies the component ids from another config, e.g. 'handlers' to a 'components' array in a new components file,
- * to avoid a manually written 'components' file for tests where the bundle spec is given by the component id.
- * @param configFile Full path to the original config file, e.g. 'handlers'
- * @param componentsFile Full path to the new 'components' file
- * @param componentType The type of component, e.g. 'handler'
- * @param append 'true' will append to an already existing 'componentsFile'
- */
- public static void createComponentsConfig(String configFile,
- String componentsFile,
- String componentType,
- boolean append) throws IOException {
- StringBuilder buf = new StringBuilder();
- String line;
- int i = 0;
- if (append) {
- Pattern p = Pattern.compile("^[a-z]+" + "\\[\\d+\\]\\.id (.+)");
- BufferedReader reader = new BufferedReader(new InputStreamReader(
- new FileInputStream(new File(componentsFile)), "UTF-8"));
- while ((line = reader.readLine()) != null) {
- Matcher m = p.matcher(line);
- if (m.matches() && !m.group(1).equals(HandlersConfigurerDi.RegistriesHack.class.getName())) {
- buf.append("components[").append(i).append("].id ").append(m.group(1)).append("\n");
- i++;
- }
- }
- reader.close();
- }
- BufferedReader reader = new BufferedReader(new InputStreamReader(
- new FileInputStream(new File(configFile)), "UTF-8"));
- Pattern component = Pattern.compile("^" + componentType + "\\[\\d+\\]\\.id (.+)");
- while ((line = reader.readLine()) != null) {
- Matcher m = component.matcher(line);
- if (m.matches()) {
- buf.append("components[").append(i).append("].id ").append(m.group(1)).append("\n");
- i++;
- }
- }
- buf.append("components[").append(i).append("].id ").
- append(HandlersConfigurerDi.RegistriesHack.class.getName()).append("\n");
- i++;
- reader.close();
- buf.insert(0, "components["+i+"]\n");
-
- Writer writer = new OutputStreamWriter(new FileOutputStream(new File(componentsFile)), "UTF-8");
- writer.write(buf.toString());
- writer.flush();
- writer.close();
+ TestUtil.createComponentsConfig(handlersFile, componentsFile, "handler");
+ TestUtil.createComponentsConfig(chainsFile, componentsFile, "components", true);
}
}