aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/serviceview/ConfigServerLocation.java38
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/serviceview/StateRequestHandler.java259
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/serviceview/StateResource.java253
-rw-r--r--configserver/src/main/resources/configserver-app/services.xml10
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/serviceview/StateResourceTest.java (renamed from configserver/src/test/java/com/yahoo/vespa/serviceview/StateRequestHandlerTest.java)43
5 files changed, 320 insertions, 283 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/serviceview/ConfigServerLocation.java b/configserver/src/main/java/com/yahoo/vespa/serviceview/ConfigServerLocation.java
new file mode 100644
index 00000000000..05d1119aa4f
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/serviceview/ConfigServerLocation.java
@@ -0,0 +1,38 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.serviceview;
+
+import ai.vespa.util.http.VespaClientBuilderFactory;
+import com.google.inject.Inject;
+import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.component.AbstractComponent;
+
+/**
+ * Wrapper for settings from the cloud.config.configserver config.
+ *
+ * @author Steinar Knutsen
+ */
+public class ConfigServerLocation extends AbstractComponent {
+
+ final int restApiPort;
+ // The client factory must be owned by a component as StateResource is instantiated per request
+ @SuppressWarnings("removal")
+ final VespaClientBuilderFactory clientBuilderFactory = new VespaClientBuilderFactory();
+
+ @Inject
+ public ConfigServerLocation(ConfigserverConfig configServer) {
+ restApiPort = configServer.httpport();
+ }
+
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("ConfigServerLocation [restApiPort=").append(restApiPort).append("]");
+ return builder.toString();
+ }
+
+ @Override
+ public void deconstruct() {
+ clientBuilderFactory.close();
+ }
+}
diff --git a/configserver/src/main/java/com/yahoo/vespa/serviceview/StateRequestHandler.java b/configserver/src/main/java/com/yahoo/vespa/serviceview/StateRequestHandler.java
deleted file mode 100644
index 38c74b16c1f..00000000000
--- a/configserver/src/main/java/com/yahoo/vespa/serviceview/StateRequestHandler.java
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.serviceview;
-
-import com.google.inject.Inject;
-import com.yahoo.cloud.config.ConfigserverConfig;
-import com.yahoo.container.jdisc.LoggingRequestHandler;
-import com.yahoo.restapi.JacksonJsonResponse;
-import com.yahoo.restapi.RestApi;
-import com.yahoo.restapi.RestApiRequestHandler;
-import com.yahoo.vespa.serviceview.bindings.ApplicationView;
-import com.yahoo.vespa.serviceview.bindings.ConfigClient;
-import com.yahoo.vespa.serviceview.bindings.HealthClient;
-import com.yahoo.vespa.serviceview.bindings.ModelResponse;
-import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.client.proxy.WebResourceFactory;
-
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientRequestFilter;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.HttpHeaders;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-/**
- * A web service to discover and proxy Vespa service state info.
- *
- * @author Steinar Knutsen
- * @author bjorncs
- */
-public class StateRequestHandler extends RestApiRequestHandler<StateRequestHandler> {
-
- private static final String USER_AGENT = "service-view-config-server-client";
- private static final String SINGLE_API_LINK = "url";
-
- @SuppressWarnings("removal")
- private final Client client = new ai.vespa.util.http.VespaClientBuilderFactory()
- .newBuilder()
- .property(ClientProperties.CONNECT_TIMEOUT, 10000)
- .property(ClientProperties.READ_TIMEOUT, 10000)
- .register((ClientRequestFilter) ctx -> ctx.getHeaders().put(HttpHeaders.USER_AGENT, List.of(USER_AGENT)))
- .build();
-
- private final int restApiPort;
-
- private static class GiveUpLinkRetargetingException extends Exception {
- public GiveUpLinkRetargetingException(Throwable reason) {
- super(reason);
- }
-
- public GiveUpLinkRetargetingException(String message) {
- super(message);
- }
- }
-
- @Inject
- public StateRequestHandler(LoggingRequestHandler.Context context,
- ConfigserverConfig configserverConfig) {
- super(context, StateRequestHandler::createRestApiDefinition);
- this.restApiPort = configserverConfig.httpport();
- }
-
- @Override
- protected void destroy() {
- client.close();
- super.destroy();
- }
-
- private static RestApi createRestApiDefinition(StateRequestHandler self) {
- return RestApi.builder()
- .addRoute(RestApi.route("/serviceview/v1/")
- .get(self::getDefaultUserInfo))
- .addRoute(RestApi.route("/serviceview/v1/tenant/{tenantName}/application/{applicationName}/environment/{environmentName}/region/{regionName}/instance/{instanceName}")
- .get(self::getUserInfo))
- .addRoute(RestApi.route("/serviceview/v1/tenant/{tenantName}/application/{applicationName}/environment/{environmentName}/region/{regionName}/instance/{instanceName}/service/{serviceIdentifier}/{*}")
- .get(self::singleService))
- .addResponseMapper(HashMap.class, (hashMap, context) -> new JacksonJsonResponse<>(200, hashMap, true))
- .addResponseMapper(ApplicationView.class, (applicationView, context) -> new JacksonJsonResponse<>(200, applicationView, true))
- .build();
- }
-
- private ApplicationView getDefaultUserInfo(RestApi.RequestContext context) {
- return getUserInfo(context.request().getUri(), "default", "default", "default", "default", "default");
- }
-
- private ApplicationView getUserInfo(RestApi.RequestContext context) {
- String tenantName = context.pathParameters().getStringOrThrow("tenantName");
- String applicationName = context.pathParameters().getStringOrThrow("applicationName");
- String environmentName = context.pathParameters().getStringOrThrow("environmentName");
- String regionName = context.pathParameters().getStringOrThrow("regionName");
- String instanceName = context.pathParameters().getStringOrThrow("instanceName");
- return getUserInfo(context.request().getUri(), tenantName, applicationName, environmentName, regionName, instanceName);
- }
-
- public HashMap<?, ?> singleService(RestApi.RequestContext context) {
- String tenantName = context.pathParameters().getStringOrThrow("tenantName");
- String applicationName = context.pathParameters().getStringOrThrow("applicationName");
- String environmentName = context.pathParameters().getStringOrThrow("environmentName");
- String regionName = context.pathParameters().getStringOrThrow("regionName");
- String instanceName = context.pathParameters().getStringOrThrow("instanceName");
- String identifier = context.pathParameters().getStringOrThrow("serviceIdentifier");
- String apiParams = context.pathParameters().getString("*").orElse("");
- return singleService(context.request().getUri(), tenantName, applicationName, environmentName, regionName, instanceName, identifier, apiParams);
- }
-
- protected ApplicationView getUserInfo(URI requestUri, String tenantName, String applicationName, String environmentName, String regionName, String instanceName) {
- ServiceModel model = new ServiceModel(
- getModelConfig(tenantName, applicationName, environmentName, regionName, instanceName));
- return model.showAllClusters(
- baseUri(requestUri).toString(),
- applicationIdentifier(tenantName, applicationName, environmentName, regionName, instanceName));
- }
-
- protected ModelResponse getModelConfig(String tenant, String application, String environment, String region, String instance) {
- try {
- WebTarget target = client.target("http://localhost:" + restApiPort + "/");
- ConfigClient resource = WebResourceFactory.newResource(ConfigClient.class, target);
- return resource.getServiceModel(tenant, application, environment, region, instance);
- } finally {
- client.close();
- }
- }
-
- protected HashMap<?, ?> singleService(
- URI requestUri, String tenantName, String applicationName, String environmentName, String regionName, String instanceName, String identifier, String apiParams) {
- ServiceModel model = new ServiceModel(getModelConfig(tenantName, applicationName, environmentName, regionName, instanceName));
- Service s = model.getService(identifier);
- int requestedPort = s.matchIdentifierWithPort(identifier);
- try {
- HealthClient resource = getHealthClient(apiParams, s, requestedPort, requestUri.getRawQuery(), client);
- HashMap<?, ?> apiResult = resource.getHealthInfo();
- rewriteResourceLinks(requestUri, apiResult, model, s, applicationIdentifier(tenantName, applicationName, environmentName, regionName, instanceName), identifier);
- return apiResult;
- } finally {
- client.close();
- }
- }
-
- protected HealthClient getHealthClient(String apiParams, Service s, int requestedPort, String uriQuery, Client client) {
- final StringBuilder uriBuffer = new StringBuilder("http://").append(s.host).append(':').append(requestedPort).append('/')
- .append(apiParams);
- addQuery(uriQuery, uriBuffer);
- WebTarget target = client.target(uriBuffer.toString());
- return WebResourceFactory.newResource(HealthClient.class, target);
- }
-
- private String applicationIdentifier(String tenant, String application, String environment, String region, String instance) {
- return "tenant/" + tenant
- + "/application/" + application
- + "/environment/" + environment
- + "/region/" + region
- + "/instance/" + instance;
- }
-
- private void rewriteResourceLinks(URI requestUri,
- Object apiResult,
- ServiceModel model,
- Service self,
- String applicationIdentifier,
- String incomingIdentifier) {
- if (apiResult instanceof List) {
- for (@SuppressWarnings("unchecked") ListIterator<Object> i = ((List<Object>) apiResult).listIterator(); i.hasNext();) {
- Object resource = i.next();
- if (resource instanceof String) {
- try {
- StringBuilder buffer = linkBuffer(requestUri, applicationIdentifier);
- // if it points to a port and host not part of the application, rewriting will not occur, so this is kind of safe
- retarget(model, self, buffer, (String) resource);
- i.set(buffer.toString());
- } catch (GiveUpLinkRetargetingException e) {
- break; // assume relatively homogenous lists when doing rewrites to avoid freezing up on scanning long lists
- }
- } else {
- rewriteResourceLinks(requestUri, resource, model, self, applicationIdentifier, incomingIdentifier);
- }
- }
- } else if (apiResult instanceof Map) {
- @SuppressWarnings("unchecked")
- Map<Object, Object> api = (Map<Object, Object>) apiResult;
- for (Map.Entry<Object, Object> entry : api.entrySet()) {
- if (SINGLE_API_LINK.equals(entry.getKey()) && entry.getValue() instanceof String) {
- try {
- rewriteSingleLink(entry, model, self, linkBuffer(requestUri, applicationIdentifier));
- } catch (GiveUpLinkRetargetingException e) {
- // NOP
- }
- } else if ("link".equals(entry.getKey()) && entry.getValue() instanceof String) {
- buildSingleLink(entry, linkBuffer(requestUri, applicationIdentifier), incomingIdentifier);
- } else {
- rewriteResourceLinks(requestUri, entry.getValue(), model, self, applicationIdentifier, incomingIdentifier);
- }
- }
- }
- }
-
- private void buildSingleLink(Map.Entry<Object, Object> entry,
- StringBuilder newUri,
- String incomingIdentifier) {
- newUri.append("/service/")
- .append(incomingIdentifier);
- newUri.append(entry.getValue());
- entry.setValue(newUri.toString());
- }
-
- private void addQuery(String query, StringBuilder newUri) {
- if (query != null && query.length() > 0) {
- newUri.append('?').append(query);
- }
- }
-
- private StringBuilder linkBuffer(URI requestUri, String applicationIdentifier) {
- return baseUri(requestUri).append(applicationIdentifier);
- }
-
- private void rewriteSingleLink(Map.Entry<Object, Object> entry,
- ServiceModel model,
- Service self,
- StringBuilder newUri) throws GiveUpLinkRetargetingException {
- String url = (String) entry.getValue();
- retarget(model, self, newUri, url);
- entry.setValue(newUri.toString());
- }
-
- private void retarget(ServiceModel model, Service self, StringBuilder newUri, String url) throws GiveUpLinkRetargetingException {
- URI link;
- try {
- link = new URI(url);
- } catch (URISyntaxException e) {
- throw new GiveUpLinkRetargetingException(e);
- }
- if (!link.isAbsolute()) {
- throw new GiveUpLinkRetargetingException("This rewriting only supports absolute URIs.");
- }
- int linkPort = link.getPort();
- if (linkPort == -1) {
- linkPort = 80;
- }
- Service s;
- try {
- s = model.resolve(link.getHost(), linkPort, self);
- } catch (IllegalArgumentException e) {
- throw new GiveUpLinkRetargetingException(e);
- }
- newUri.append("/service/").append(s.getIdentifier(linkPort));
- newUri.append(link.getRawPath());
- }
-
- private static StringBuilder baseUri(URI requestUri) {
- return new StringBuilder(requestUri.getScheme())
- .append("://")
- .append(requestUri.getHost())
- .append(':')
- .append(requestUri.getPort())
- .append("/serviceview/v1/");
- }
-}
diff --git a/configserver/src/main/java/com/yahoo/vespa/serviceview/StateResource.java b/configserver/src/main/java/com/yahoo/vespa/serviceview/StateResource.java
new file mode 100644
index 00000000000..138e6c8798c
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/serviceview/StateResource.java
@@ -0,0 +1,253 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.serviceview;
+
+import ai.vespa.util.http.VespaClientBuilderFactory;
+import com.yahoo.container.jaxrs.annotation.Component;
+import com.yahoo.vespa.serviceview.bindings.ApplicationView;
+import com.yahoo.vespa.serviceview.bindings.ConfigClient;
+import com.yahoo.vespa.serviceview.bindings.HealthClient;
+import com.yahoo.vespa.serviceview.bindings.ModelResponse;
+import com.yahoo.vespa.serviceview.bindings.StateClient;
+import org.glassfish.jersey.client.proxy.WebResourceFactory;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+
+/**
+ * A web service to discover and proxy Vespa service state info.
+ *
+ * @author Steinar Knutsen
+ */
+@Path("/")
+public class StateResource implements StateClient {
+
+ private static final String USER_AGENT = "service-view-config-server-client";
+ private static final String SINGLE_API_LINK = "url";
+
+ @SuppressWarnings("removal")
+ private final VespaClientBuilderFactory clientBuilderFactory;
+ private final int restApiPort;
+ private final String host;
+ private final UriInfo uriInfo;
+
+ @SuppressWarnings("serial")
+ private static class GiveUpLinkRetargetingException extends Exception {
+ public GiveUpLinkRetargetingException(Throwable reason) {
+ super(reason);
+ }
+
+ public GiveUpLinkRetargetingException(String message) {
+ super(message);
+ }
+ }
+
+ public StateResource(@Component ConfigServerLocation configServer, @Context UriInfo ui) {
+ this.clientBuilderFactory = configServer.clientBuilderFactory;
+ this.restApiPort = configServer.restApiPort;
+ this.host = "localhost";
+ this.uriInfo = ui;
+ }
+
+ @Override
+ @GET
+ @Path("v1/")
+ @Produces(MediaType.APPLICATION_JSON)
+ public ApplicationView getDefaultUserInfo() {
+ return getUserInfo("default", "default", "default", "default", "default");
+ }
+
+ @Override
+ @GET
+ @Path("v1/tenant/{tenantName}/application/{applicationName}/environment/{environmentName}/region/{regionName}/instance/{instanceName}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public ApplicationView getUserInfo(@PathParam("tenantName") String tenantName,
+ @PathParam("applicationName") String applicationName,
+ @PathParam("environmentName") String environmentName,
+ @PathParam("regionName") String regionName,
+ @PathParam("instanceName") String instanceName) {
+ ServiceModel model = new ServiceModel(
+ getModelConfig(tenantName, applicationName, environmentName, regionName, instanceName));
+ return model.showAllClusters(
+ getBaseUri() + "v1/",
+ applicationIdentifier(tenantName, applicationName, environmentName, regionName, instanceName));
+ }
+
+ private String getBaseUri() {
+ String baseUri = uriInfo.getBaseUri().toString();
+ if (baseUri.endsWith("/")) {
+ return baseUri;
+ } else {
+ return baseUri + "/";
+ }
+ }
+
+ protected ModelResponse getModelConfig(String tenant, String application, String environment, String region, String instance) {
+ Client client = client();
+ try {
+ WebTarget target = client.target("http://" + host + ":" + restApiPort + "/");
+ ConfigClient resource = WebResourceFactory.newResource(ConfigClient.class, target);
+ return resource.getServiceModel(tenant, application, environment, region, instance);
+ } finally {
+ client.close();
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ @GET
+ @Path("v1/tenant/{tenantName}/application/{applicationName}/environment/{environmentName}/region/{regionName}/instance/{instanceName}/service/{serviceIdentifier}/{apiParams: .*}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public HashMap singleService(@PathParam("tenantName") String tenantName,
+ @PathParam("applicationName") String applicationName,
+ @PathParam("environmentName") String environmentName,
+ @PathParam("regionName") String regionName,
+ @PathParam("instanceName") String instanceName,
+ @PathParam("serviceIdentifier") String identifier,
+ @PathParam("apiParams") String apiParams) {
+ ServiceModel model = new ServiceModel(getModelConfig(tenantName, applicationName, environmentName, regionName, instanceName));
+ Service s = model.getService(identifier);
+ int requestedPort = s.matchIdentifierWithPort(identifier);
+ Client client = client();
+ try {
+ HealthClient resource = getHealthClient(apiParams, s, requestedPort, client);
+ HashMap<?, ?> apiResult = resource.getHealthInfo();
+ rewriteResourceLinks(apiResult, model, s, applicationIdentifier(tenantName, applicationName, environmentName, regionName, instanceName), identifier);
+ return apiResult;
+ } finally {
+ client.close();
+ }
+ }
+
+ protected HealthClient getHealthClient(String apiParams, Service s, int requestedPort, Client client) {
+ final StringBuilder uriBuffer = new StringBuilder("http://").append(s.host).append(':').append(requestedPort).append('/')
+ .append(apiParams);
+ addQuery(uriBuffer);
+ WebTarget target = client.target(uriBuffer.toString());
+ return WebResourceFactory.newResource(HealthClient.class, target);
+ }
+
+ private String applicationIdentifier(String tenant, String application, String environment, String region, String instance) {
+ return "tenant/" + tenant
+ + "/application/" + application
+ + "/environment/" + environment
+ + "/region/" + region
+ + "/instance/" + instance;
+ }
+
+ private void rewriteResourceLinks(Object apiResult,
+ ServiceModel model,
+ Service self,
+ String applicationIdentifier,
+ String incomingIdentifier) {
+ if (apiResult instanceof List) {
+ for (@SuppressWarnings("unchecked") ListIterator<Object> i = ((List<Object>) apiResult).listIterator(); i.hasNext();) {
+ Object resource = i.next();
+ if (resource instanceof String) {
+ try {
+ StringBuilder buffer = linkBuffer(applicationIdentifier);
+ // if it points to a port and host not part of the application, rewriting will not occur, so this is kind of safe
+ retarget(model, self, buffer, (String) resource);
+ i.set(buffer.toString());
+ } catch (GiveUpLinkRetargetingException e) {
+ break; // assume relatively homogenous lists when doing rewrites to avoid freezing up on scanning long lists
+ }
+ } else {
+ rewriteResourceLinks(resource, model, self, applicationIdentifier, incomingIdentifier);
+ }
+ }
+ } else if (apiResult instanceof Map) {
+ @SuppressWarnings("unchecked")
+ Map<Object, Object> api = (Map<Object, Object>) apiResult;
+ for (Map.Entry<Object, Object> entry : api.entrySet()) {
+ if (SINGLE_API_LINK.equals(entry.getKey()) && entry.getValue() instanceof String) {
+ try {
+ rewriteSingleLink(entry, model, self, linkBuffer(applicationIdentifier));
+ } catch (GiveUpLinkRetargetingException e) {
+ // NOP
+ }
+ } else if ("link".equals(entry.getKey()) && entry.getValue() instanceof String) {
+ buildSingleLink(entry, linkBuffer(applicationIdentifier), incomingIdentifier);
+ } else {
+ rewriteResourceLinks(entry.getValue(), model, self, applicationIdentifier, incomingIdentifier);
+ }
+ }
+ }
+ }
+
+ private void buildSingleLink(Map.Entry<Object, Object> entry,
+ StringBuilder newUri,
+ String incomingIdentifier) {
+ newUri.append("/service/")
+ .append(incomingIdentifier);
+ newUri.append(entry.getValue());
+ entry.setValue(newUri.toString());
+ }
+
+ private void addQuery(StringBuilder newUri) {
+ String query = uriInfo.getRequestUri().getRawQuery();
+ if (query != null && query.length() > 0) {
+ newUri.append('?').append(query);
+ }
+ }
+
+ private StringBuilder linkBuffer(String applicationIdentifier) {
+ StringBuilder newUri = new StringBuilder(getBaseUri());
+ newUri.append("v1/").append(applicationIdentifier);
+ return newUri;
+ }
+
+ private void rewriteSingleLink(Map.Entry<Object, Object> entry,
+ ServiceModel model,
+ Service self,
+ StringBuilder newUri) throws GiveUpLinkRetargetingException {
+ String url = (String) entry.getValue();
+ retarget(model, self, newUri, url);
+ entry.setValue(newUri.toString());
+ }
+
+ private void retarget(ServiceModel model, Service self, StringBuilder newUri, String url) throws GiveUpLinkRetargetingException {
+ URI link;
+ try {
+ link = new URI(url);
+ } catch (URISyntaxException e) {
+ throw new GiveUpLinkRetargetingException(e);
+ }
+ if (!link.isAbsolute()) {
+ throw new GiveUpLinkRetargetingException("This rewriting only supports absolute URIs.");
+ }
+ int linkPort = link.getPort();
+ if (linkPort == -1) {
+ linkPort = 80;
+ }
+ Service s;
+ try {
+ s = model.resolve(link.getHost(), linkPort, self);
+ } catch (IllegalArgumentException e) {
+ throw new GiveUpLinkRetargetingException(e);
+ }
+ newUri.append("/service/").append(s.getIdentifier(linkPort));
+ newUri.append(link.getRawPath());
+ }
+
+ private Client client() {
+ return clientBuilderFactory.newBuilder()
+ .register((ClientRequestFilter) ctx -> ctx.getHeaders().put(HttpHeaders.USER_AGENT, List.of(USER_AGENT)))
+ .build();
+ }
+}
diff --git a/configserver/src/main/resources/configserver-app/services.xml b/configserver/src/main/resources/configserver-app/services.xml
index cfff3719d6e..a4ca7081f0b 100644
--- a/configserver/src/main/resources/configserver-app/services.xml
+++ b/configserver/src/main/resources/configserver-app/services.xml
@@ -69,10 +69,12 @@
<components bundle="orchestrator" />
</rest-api>
- <handler id="com.yahoo.vespa.serviceview.StateRequestHandler" bundle="configserver">
- <binding>http://*/serviceview/v1/</binding>
- <binding>http://*/serviceview/v1/*</binding>
- </handler>
+ <rest-api path="serviceview" jersey2="true">
+ <components bundle="configserver">
+ <package>com.yahoo.vespa.serviceview</package>
+ </components>
+ </rest-api>
+
<handler id='com.yahoo.vespa.config.server.http.HttpGetConfigHandler' bundle='configserver'>
<binding>http://*/config/v1/*/*</binding>
<binding>http://*/config/v1/*</binding>
diff --git a/configserver/src/test/java/com/yahoo/vespa/serviceview/StateRequestHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/serviceview/StateResourceTest.java
index a0bb8a5acc7..794b825db6e 100644
--- a/configserver/src/test/java/com/yahoo/vespa/serviceview/StateRequestHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/serviceview/StateResourceTest.java
@@ -2,7 +2,7 @@
package com.yahoo.vespa.serviceview;
import com.yahoo.cloud.config.ConfigserverConfig;
-import com.yahoo.jdisc.test.MockMetric;
+import com.yahoo.container.jaxrs.annotation.Component;
import com.yahoo.vespa.serviceview.bindings.ApplicationView;
import com.yahoo.vespa.serviceview.bindings.HealthClient;
import com.yahoo.vespa.serviceview.bindings.ModelResponse;
@@ -12,30 +12,30 @@ import org.junit.Test;
import org.mockito.Mockito;
import javax.ws.rs.client.Client;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.Executors;
import static org.junit.Assert.assertEquals;
/**
- * Functional test for {@link StateRequestHandler}.
+ * Functional test for {@link StateResource}.
*
* @author Steinar Knutsen
- * @author bjorncs
*/
-public class StateRequestHandlerTest {
+public class StateResourceTest {
- private static final String EXTERNAL_BASE_URI = "http://someserver:8080/serviceview/v1/";
+ private static final String EXTERNAL_BASE_URI = "http://someserver:8080/serviceview/";
- private static class TestHandler extends StateRequestHandler {
+ private static class TestResource extends StateResource {
private static final String BASE_URI = "http://vespa.yahoo.com:8080/state/v1";
- TestHandler(ConfigserverConfig config) {
- super(new Context(Executors.newSingleThreadExecutor(), new MockMetric()), config);
+ TestResource(@Component ConfigServerLocation configServer, @Context UriInfo ui) {
+ super(configServer, ui);
}
@Override
@@ -44,7 +44,7 @@ public class StateRequestHandlerTest {
}
@Override
- protected HealthClient getHealthClient(String apiParams, Service s, int requestedPort, String uriQuery, Client client) {
+ protected HealthClient getHealthClient(String apiParams, Service s, int requestedPort, Client client) {
HealthClient healthClient = Mockito.mock(HealthClient.class);
HashMap<Object, Object> dummyHealthData = new HashMap<>();
HashMap<String, String> dummyLink = new HashMap<>();
@@ -55,36 +55,39 @@ public class StateRequestHandlerTest {
}
}
- private StateRequestHandler testHandler;
+ private StateResource testResource;
private ServiceModel correspondingModel;
@Before
public void setUp() throws Exception {
- testHandler = new TestHandler(new ConfigserverConfig(new ConfigserverConfig.Builder()));
+ UriInfo base = Mockito.mock(UriInfo.class);
+ Mockito.when(base.getBaseUri()).thenReturn(new URI(EXTERNAL_BASE_URI));
+ ConfigServerLocation dummyLocation = new ConfigServerLocation(new ConfigserverConfig(new ConfigserverConfig.Builder()));
+ testResource = new TestResource(dummyLocation, base);
correspondingModel = new ServiceModel(ServiceModelTest.syntheticModelResponse());
}
@After
public void tearDown() {
- testHandler = null;
+ testResource = null;
correspondingModel = null;
}
+ @SuppressWarnings("rawtypes")
@Test
public final void test() {
Service s = correspondingModel.resolve("vespa.yahoo.com", 8080, null);
String api = "/state/v1";
- HashMap<?, ?> boom = testHandler.singleService(URI.create(EXTERNAL_BASE_URI), "default", "default", "default", "default", "default", s.getIdentifier(8080), api);
- assertEquals(EXTERNAL_BASE_URI + "tenant/default/application/default/environment/default/region/default/instance/default/service/" + s.getIdentifier(8080) + api,
- ((Map<?, ?>) ((List<?>) boom.get("resources")).get(0)).get("url"));
+ HashMap boom = testResource.singleService("default", "default", "default", "default", "default", s.getIdentifier(8080), api);
+ assertEquals(EXTERNAL_BASE_URI + "v1/tenant/default/application/default/environment/default/region/default/instance/default/service/" + s.getIdentifier(8080) + api,
+ ((Map) ((List) boom.get("resources")).get(0)).get("url"));
}
@Test
public final void testLinkEquality() {
- ApplicationView explicitParameters = testHandler.getUserInfo(URI.create(EXTERNAL_BASE_URI), "default", "default", "default", "default", "default");
- assertEquals(EXTERNAL_BASE_URI + "tenant/default/application/default/environment/default/region/default/instance" +
- "/default/service/container-clustercontroller-2ul67p8psr451t3w8kdd0qwgg/state/v1/",
- explicitParameters.clusters.get(0).services.get(0).url);
+ ApplicationView explicitParameters = testResource.getUserInfo("default", "default", "default", "default", "default");
+ ApplicationView implicitParameters = testResource.getDefaultUserInfo();
+ assertEquals(explicitParameters.clusters.get(0).services.get(0).url, implicitParameters.clusters.get(0).services.get(0).url);
}
}