diff options
author | Harald Musum <musum@oath.com> | 2018-01-02 17:54:41 +0100 |
---|---|---|
committer | Harald Musum <musum@oath.com> | 2018-01-02 17:54:41 +0100 |
commit | 6f71863a4dfc3d7eefd561482c2ff14c7ad4eb9d (patch) | |
tree | 4efcd37dece9493e6fd8f0e6c3ee6c6eca754b57 /configserver | |
parent | 9967338b1a3514830e92924d868046ee2cfc97db (diff) |
Rewrite status handler
Rewrite and simplify to use Slime and a regular handler instead of Jersey,
so it's not necessary to manually update handler when config changes
(which had not been done in years)
Diffstat (limited to 'configserver')
8 files changed, 112 insertions, 201 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/status/StatusHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/status/StatusHandler.java new file mode 100644 index 00000000000..a6249104c7f --- /dev/null +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/status/StatusHandler.java @@ -0,0 +1,69 @@ +package com.yahoo.vespa.config.server.http.status; + +import com.google.inject.Inject; +import com.yahoo.cloud.config.ConfigserverConfig; +import com.yahoo.config.model.api.ModelFactory; +import com.yahoo.config.provision.Version; +import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.slime.Cursor; +import com.yahoo.slime.JsonFormat; +import com.yahoo.vespa.config.ConfigPayload; +import com.yahoo.vespa.config.SlimeUtils; +import com.yahoo.vespa.config.server.GlobalComponentRegistry; +import com.yahoo.vespa.config.server.http.HttpConfigResponse; +import com.yahoo.vespa.config.server.http.HttpHandler; +import com.yahoo.vespa.config.server.http.JSONResponse; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.List; +import java.util.stream.Collectors; + +import static com.yahoo.jdisc.http.HttpResponse.Status.OK; + + +public class StatusHandler extends HttpHandler { + + private final ConfigserverConfig config; + private final List<String> modelVersions; + + @Inject + public StatusHandler(Context ctx, GlobalComponentRegistry componentRegistry) { + super(ctx); + this.config = componentRegistry.getConfigserverConfig(); + this.modelVersions = componentRegistry.getModelFactoryRegistry().getFactories().stream() + .map(ModelFactory::getVersion) + .map(Version::toString) + .collect(Collectors.toList()); + } + + @Override + public HttpResponse handleGET(HttpRequest req) { + return new StatusResponse(OK, config, modelVersions); + } + + private static class StatusResponse extends JSONResponse { + + StatusResponse(int status, ConfigserverConfig config, List<String> modelVersions) { + super(status); + + Cursor configCursor = object.setObject("configserverConfig"); + SlimeUtils.copyObject(ConfigPayload.fromInstance(config).getSlime().get(), configCursor); + + Cursor modelVersionsCursor = object.setArray("modelVersions"); + modelVersions.forEach(modelVersionsCursor::addString); + } + + @Override + public void render(OutputStream outputStream) throws IOException { + new JsonFormat(true).encode(outputStream, object); + } + + @Override + public String getContentType() { + return HttpConfigResponse.JSON_CONTENT_TYPE; + } + } + +} diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/impl/StatusResource.java b/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/impl/StatusResource.java deleted file mode 100644 index 1aabbb9aeb3..00000000000 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/impl/StatusResource.java +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.config.server.restapi.impl; - -import com.google.common.annotations.Beta; -import com.yahoo.cloud.config.ConfigserverConfig; -import com.yahoo.config.model.api.ModelFactory; -import com.yahoo.config.provision.Version; -import com.yahoo.container.jaxrs.annotation.Component; -import com.yahoo.vespa.config.server.GlobalComponentRegistry; -import com.yahoo.vespa.config.server.http.v2.HttpGetConfigHandler; -import com.yahoo.vespa.config.server.http.v2.HttpListConfigsHandler; -import com.yahoo.vespa.config.server.http.v2.HttpListNamedConfigsHandler; -import com.yahoo.vespa.config.server.http.v2.SessionActiveHandler; -import com.yahoo.vespa.config.server.http.v2.SessionContentHandler; -import com.yahoo.vespa.config.server.http.v2.SessionCreateHandler; -import com.yahoo.vespa.config.server.http.v2.SessionPrepareHandler; -import com.yahoo.vespa.config.server.restapi.resources.StatusInformation; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import java.util.List; -import java.util.stream.Collectors; - -/** - * A simple status handler that can provide the status of the config server. - * - * @author lulf - * @since 5.1 - */ -@Beta -@Path("/") -@Produces(MediaType.APPLICATION_JSON) -public class StatusResource { - private final ConfigserverConfig configserverConfig; - private final List<String> modelVersions; - - @SuppressWarnings("UnusedParameters") - public StatusResource(@Component SessionCreateHandler create, - @Component SessionContentHandler content, - @Component SessionPrepareHandler prepare, - @Component SessionActiveHandler active, - @Component HttpGetConfigHandler getHandler, - @Component HttpListConfigsHandler listHandler, - @Component HttpListNamedConfigsHandler listNamedHandler, - @Component GlobalComponentRegistry componentRegistry) { - this.configserverConfig = componentRegistry.getConfigserverConfig(); - this.modelVersions = componentRegistry.getModelFactoryRegistry().getFactories().stream() - .map(ModelFactory::getVersion).map(Version::toString).collect(Collectors.toList()); - } - - @GET - public StatusInformation getStatus() { - return new StatusInformation(configserverConfig, modelVersions); - } -} diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/impl/package-info.java b/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/impl/package-info.java deleted file mode 100644 index 5b17eed4b7f..00000000000 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/impl/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -package com.yahoo.vespa.config.server.restapi.impl; - -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/resources/StatusInformation.java b/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/resources/StatusInformation.java deleted file mode 100644 index 5acd56c252e..00000000000 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/resources/StatusInformation.java +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.config.server.restapi.resources; - -import static com.yahoo.vespa.defaults.Defaults.getDefaults; - -import java.util.Collection; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Status information of config server. Currently needs to convert generated configserver config to a POJO that can - * be serialized to JSON. - * - * @author lulf - * @since 5.21 - */ -public class StatusInformation { - - public ConfigserverConfig configserverConfig; - public List<String> modelVersions; - - public StatusInformation(com.yahoo.cloud.config.ConfigserverConfig configserverConfig, List<String> modelVersions) { - this.configserverConfig = new ConfigserverConfig(configserverConfig); - this.modelVersions = modelVersions; - } - - public static class ConfigserverConfig { - public final int rpcport; - public final int numthreads; - public final String zookeepercfg; - public final Collection<ZooKeeperServer> zookeeeperserver; - public final long zookeeperBarrierTimeout; - public final Collection<String> configModelPluginDir; - public final String configServerDBDir; - public final int maxgetconfigclients; - public final long sessionLifetime; - public final String applicationDirectory; - public final long masterGeneration; - public final boolean multitenant; - public final int numDelayedResponseThreads; - public final com.yahoo.cloud.config.ConfigserverConfig.PayloadCompressionType.Enum payloadCompressionType; - public final boolean useVespaVersionInRequest; - public final String serverId; - public final String region; - public final String environment; - - - public ConfigserverConfig(com.yahoo.cloud.config.ConfigserverConfig configserverConfig) { - this.rpcport = configserverConfig.rpcport(); - this.numthreads = configserverConfig.numthreads(); - this.zookeepercfg = getDefaults().underVespaHome(configserverConfig.zookeepercfg()); - this.zookeeeperserver = configserverConfig.zookeeperserver().stream() - .map(zks -> new ZooKeeperServer(zks.hostname(), zks.port())) - .collect(Collectors.toList()); - this.zookeeperBarrierTimeout = configserverConfig.zookeeper().barrierTimeout(); - this.configModelPluginDir = configserverConfig.configModelPluginDir(); - this.configServerDBDir = getDefaults().underVespaHome(configserverConfig.configServerDBDir()); - this.maxgetconfigclients = configserverConfig.maxgetconfigclients(); - this.sessionLifetime = configserverConfig.sessionLifetime(); - this.applicationDirectory = getDefaults().underVespaHome(configserverConfig.applicationDirectory()); - this.masterGeneration = configserverConfig.masterGeneration(); - this.multitenant = configserverConfig.multitenant(); - this.numDelayedResponseThreads = configserverConfig.numDelayedResponseThreads(); - this.payloadCompressionType = configserverConfig.payloadCompressionType(); - this.useVespaVersionInRequest = configserverConfig.useVespaVersionInRequest(); - this.serverId = configserverConfig.serverId(); - this.region = configserverConfig.region(); - this.environment = configserverConfig.environment(); - } - } - - public static class ZooKeeperServer { - public final String hostname; - public final int port; - - public ZooKeeperServer(String hostname, int port) { - this.hostname = hostname; - this.port = port; - } - } -} diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/resources/package-info.java b/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/resources/package-info.java deleted file mode 100644 index 520094cd593..00000000000 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/restapi/resources/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -package com.yahoo.vespa.config.server.restapi.resources; - -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/configserver/src/main/resources/configserver-app/services.xml b/configserver/src/main/resources/configserver-app/services.xml index fd77fedd789..1a0b61fbe96 100644 --- a/configserver/src/main/resources/configserver-app/services.xml +++ b/configserver/src/main/resources/configserver-app/services.xml @@ -68,13 +68,6 @@ </components> </rest-api> - <rest-api path="status" jersey2="true"> - <components bundle="configserver"> - <package>com.yahoo.vespa.config.server.restapi.impl</package> - <package>com.yahoo.vespa.config.server.restapi.resources</package> - </components> - </rest-api> - <handler id='com.yahoo.vespa.config.server.http.HttpGetConfigHandler' bundle='configserver'> <binding>http://*/config/v1/*/*</binding> <binding>https://*/config/v1/*/*</binding> @@ -91,6 +84,9 @@ <binding>http://*/config/v1/*/*/</binding> <binding>https://*/config/v1/*/*/</binding> </handler> + <handler id='com.yahoo.vespa.config.server.http.status.StatusHandler' bundle='configserver'> + <binding>http://*/status</binding> + </handler> <handler id='com.yahoo.vespa.config.server.http.v2.TenantHandler' bundle='configserver'> <binding>http://*/application/v2/tenant/</binding> <binding>https://*/application/v2/tenant/</binding> diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java new file mode 100644 index 00000000000..ab886d102a6 --- /dev/null +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/status/StatusHandlerTest.java @@ -0,0 +1,40 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.config.server.http.status; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.yahoo.cloud.config.ConfigserverConfig; +import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.vespa.config.server.TestComponentRegistry; +import com.yahoo.vespa.config.server.http.SessionHandlerTest; +import org.junit.Test; + +import java.io.IOException; + +import static com.yahoo.jdisc.http.HttpRequest.Method.GET; +import static org.junit.Assert.assertEquals; + +/** + * @author hmusum + */ +public class StatusHandlerTest { + private final ObjectMapper mapper = new ObjectMapper(); + + + @Test + public void require_that_handler_works() throws IOException { + TestComponentRegistry componentRegistry = new TestComponentRegistry.Builder().build(); + StatusHandler handler = new StatusHandler(StatusHandler.testOnlyContext(), componentRegistry); + + HttpResponse response = handler.handle(HttpRequest.createTestRequest("/status", GET)); + JsonNode jsonNode = mapper.readTree(SessionHandlerTest.getRenderedString(response)); + + ConfigserverConfig expectedConfig = componentRegistry.getConfigserverConfig(); + assertEquals(expectedConfig.rpcport(), jsonNode.get("configserverConfig").get("rpcport").asInt()); + assertEquals(expectedConfig.applicationDirectory(), jsonNode.get("configserverConfig").get("applicationDirectory").asText()); + + assertEquals("6.10.0", jsonNode.get("modelVersions").get(0).asText()); + } + +} diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/restapi/impl/StatusResourceTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/restapi/impl/StatusResourceTest.java deleted file mode 100644 index b912b67c7db..00000000000 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/restapi/impl/StatusResourceTest.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.config.server.restapi.impl; - -import com.yahoo.cloud.config.ConfigserverConfig; -import com.yahoo.vespa.config.server.TestComponentRegistry; -import com.yahoo.vespa.config.server.restapi.resources.StatusInformation; -import static com.yahoo.vespa.defaults.Defaults.getDefaults; -import org.junit.Test; - -import java.io.IOException; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; - -/** - * @author lulf - * @since 5.1 - */ -public class StatusResourceTest { - @Test - public void require_that_status_handler_responds_to_ping() throws IOException { - StatusResource handler = new StatusResource(null, null, null, null, null, null, null, new TestComponentRegistry.Builder().build()); - assertNotNull(handler.getStatus().configserverConfig); - } - - @Test - public void require_that_generated_config_is_converted() { - ConfigserverConfig orig = new ConfigserverConfig(new ConfigserverConfig.Builder()); - StatusInformation.ConfigserverConfig conv = new StatusInformation.ConfigserverConfig(orig); - assertThat(conv.applicationDirectory, is(getDefaults().underVespaHome(orig.applicationDirectory()))); - assertThat(conv.configModelPluginDir.size(), is(orig.configModelPluginDir().size())); - assertThat(conv.zookeeeperserver.size(), is(orig.zookeeperserver().size())); - assertThat(conv.zookeeperBarrierTimeout, is(orig.zookeeper().barrierTimeout())); - assertThat(conv.configServerDBDir, is(getDefaults().underVespaHome(orig.configServerDBDir()))); - assertThat(conv.masterGeneration, is(orig.masterGeneration())); - assertThat(conv.maxgetconfigclients, is(orig.maxgetconfigclients())); - assertThat(conv.multitenant, is(orig.multitenant())); - assertThat(conv.numDelayedResponseThreads, is(orig.numDelayedResponseThreads())); - assertThat(conv.numthreads, is(orig.numthreads())); - assertThat(conv.payloadCompressionType, is(orig.payloadCompressionType())); - assertThat(conv.rpcport, is(orig.rpcport())); - assertThat(conv.sessionLifetime, is(orig.sessionLifetime())); - assertThat(conv.zookeepercfg, is(getDefaults().underVespaHome(orig.zookeepercfg()))); - } -} |