diff options
author | Harald Musum <musum@verizonmedia.com> | 2020-06-23 12:31:27 +0200 |
---|---|---|
committer | Harald Musum <musum@verizonmedia.com> | 2020-06-23 12:31:27 +0200 |
commit | b73948ca8cb459aa9a61269a4a9def671e569214 (patch) | |
tree | 832b13d8256890193b912d5aa82901d499dac4fc | |
parent | 7d30c840fd6c5758382d048c8c2164acc83df904 (diff) |
Add model versions that exists for an app to response
GET for an application shows only config generation, include the
set of config model versions that exist for the app
8 files changed, 68 insertions, 32 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java index becf01c191c..c0eba789761 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java @@ -481,6 +481,10 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye return getLocalSession(tenant, sessionId).getApplicationFile(Path.fromString(path), mode); } + public Tenant getTenant(ApplicationId applicationId) { + return tenantRepository.getTenant(applicationId.tenant()); + } + private Application getApplication(ApplicationId applicationId) { return getApplication(applicationId, Optional.empty()); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationSet.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationSet.java index 41119077b28..12353c0e7e3 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationSet.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationSet.java @@ -96,4 +96,12 @@ public final class ApplicationSet { return new ArrayList<>(applications.values()); } + public List<Version> getAllVersions(ApplicationId applicationId) { + return applications.values().stream() + .filter(application -> application.getId().equals(applicationId)) + .map(Application::getVespaVersion) + .sorted() + .collect(Collectors.toList()); + } + } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java index 3c909730902..d1861184c24 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java @@ -15,13 +15,16 @@ import com.yahoo.io.IOUtils; import com.yahoo.jdisc.Response; import com.yahoo.jdisc.application.BindingMatch; import com.yahoo.jdisc.application.UriPattern; +import com.yahoo.slime.Cursor; import com.yahoo.vespa.config.server.ApplicationRepository; +import com.yahoo.vespa.config.server.application.ApplicationSet; import com.yahoo.vespa.config.server.http.ContentHandler; import com.yahoo.vespa.config.server.http.ContentRequest; import com.yahoo.vespa.config.server.http.HttpErrorResponse; import com.yahoo.vespa.config.server.http.HttpHandler; import com.yahoo.vespa.config.server.http.JSONResponse; import com.yahoo.vespa.config.server.http.NotFoundException; +import com.yahoo.vespa.config.server.tenant.Tenant; import java.io.IOException; import java.time.Duration; @@ -151,7 +154,11 @@ public class ApplicationHandler extends HttpHandler { } } - return new GetApplicationResponse(Response.Status.OK, applicationRepository.getApplicationGeneration(applicationId)); + Tenant tenant = applicationRepository.getTenant(applicationId); + Optional<ApplicationSet> applicationSet = applicationRepository.getCurrentActiveApplicationSet(tenant, applicationId); + return new GetApplicationResponse(Response.Status.OK, + applicationRepository.getApplicationGeneration(applicationId), + applicationSet.get().getAllVersions(applicationId)); } @Override @@ -309,9 +316,11 @@ public class ApplicationHandler extends HttpHandler { } private static class GetApplicationResponse extends JSONResponse { - GetApplicationResponse(int status, long generation) { + GetApplicationResponse(int status, long generation, List<Version> modelVersions) { super(status); object.setLong("generation", generation); + Cursor modelVersionArray = object.setArray("modelVersions"); + modelVersions.forEach(version -> modelVersionArray.addString(version.toFullString())); } } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionStateWatcher.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionStateWatcher.java index f182a28ab70..e3f4854105a 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionStateWatcher.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionStateWatcher.java @@ -1,4 +1,4 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config.server.session; import java.util.Optional; @@ -17,6 +17,7 @@ import java.util.logging.Logger; * The session must be in the session repo. * * @author Vegard Havdal + * @author hmusum */ public class SessionStateWatcher { @@ -42,8 +43,8 @@ public class SessionStateWatcher { this.remoteSession = remoteSession; this.localSession = localSession; this.metrics = metrics; - this.fileCache.start(); this.fileCache.addListener(this::nodeChanged); + this.fileCache.start(); this.zkWatcherExecutor = zkWatcherExecutor; this.sessionRepository = sessionRepository; } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenant.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenant.java index bf0601bf2f1..08b5c59203a 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenant.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenant.java @@ -104,13 +104,13 @@ public class Tenant implements TenantHandlerProvider { * Called by watchers as a reaction to {@link #delete()}. */ void close() { - applicationRepo.close(); // Closes watchers. - sessionRepository.close(); // Closes watchers, clears memory, and deletes local files and ZK session state. + applicationRepo.close(); // Closes watchers. + sessionRepository.close(); // Closes watchers, clears memory, and deletes local files and ZK session state. } /** Deletes the tenant tree from ZooKeeper (application and session status for the tenant) and triggers {@link #close()}. */ void delete() { - curator.delete(path); // Deletes tenant ZK tree: applications and sessions. + curator.delete(path); // Deletes tenant ZK tree: applications and sessions. } } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java index c7ec2657996..685856d5cf8 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java @@ -42,7 +42,7 @@ import java.util.Optional; */ public class ZKApplicationPackage implements ApplicationPackage { - private ZKApplication zkApplication; + private final ZKApplication zkApplication; private final Map<Version, PreGeneratedFileRegistry> fileRegistryMap = new HashMap<>(); private final Optional<AllocatedHosts> allocatedHosts; diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationSetTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationSetTest.java index cf1e00674cb..f5d661e265a 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationSetTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationSetTest.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.Set; import com.yahoo.config.provision.ApplicationId; import com.yahoo.component.Version; @@ -21,8 +22,8 @@ import static org.junit.Assert.assertEquals; public class ApplicationSetTest { private ApplicationSet applicationSet; - private List<Version> vespaVersions = new ArrayList<>(); - private List<Application> applications = new ArrayList<>(); + private final List<Version> vespaVersions = new ArrayList<>(); + private final List<Application> applications = new ArrayList<>(); @Before public void setUp() { @@ -50,6 +51,13 @@ public class ApplicationSetTest { applicationSet.getForVersionOrLatest(Optional.of(vespaVersions.get(1)), Instant.now()); } + @Test + public void testGetAllVersions() { + applicationSet = ApplicationSet.fromList(applications); + assertEquals(List.of(Version.fromString("1.2.3"), Version.fromString("1.2.4"), Version.fromString("1.2.5")), + applicationSet.getAllVersions(ApplicationId.defaultId())); + } + private Application createApplication(Version version) { return new Application(new ModelStub(), null, 0, false, version, MetricUpdater.createTestUpdater(), ApplicationId.defaultId()); } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java index 06e404bee32..77c76b6dde9 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java @@ -42,6 +42,7 @@ import java.nio.charset.StandardCharsets; import java.time.Clock; import static com.yahoo.config.model.api.container.ContainerServiceType.CLUSTERCONTROLLER_CONTAINER; +import static com.yahoo.jdisc.http.HttpRequest.Method.GET; import static com.yahoo.vespa.config.server.http.SessionHandlerTest.getRenderedString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -150,8 +151,8 @@ public class ApplicationHandlerTest { @Test public void testGet() throws Exception { long sessionId = applicationRepository.deploy(testApp, prepareParams(applicationId)).sessionId(); - assertApplicationGeneration(applicationId, Zone.defaultZone(), sessionId, true); - assertApplicationGeneration(applicationId, Zone.defaultZone(), sessionId, false); + assertApplicationResponse(applicationId, Zone.defaultZone(), sessionId, true, "7.164.0"); + assertApplicationResponse(applicationId, Zone.defaultZone(), sessionId, false, "7.164.0"); } @Test @@ -196,7 +197,7 @@ public class ApplicationHandlerTest { when(mockHttpProxy.get(any(), eq(host), eq(CLUSTERCONTROLLER_CONTAINER.serviceName),eq("clustercontroller-status/v1/clusterName1"))) .thenReturn(new StaticResponse(200, "text/html", "<html>...</html>")); - HttpResponse response = mockHandler.handle(HttpRequest.createTestRequest(url, com.yahoo.jdisc.http.HttpRequest.Method.GET)); + HttpResponse response = mockHandler.handle(HttpRequest.createTestRequest(url, GET)); HandlerTest.assertHttpStatusCodeAndMessage(response, 200, "text/html", "<html>...</html>"); } @@ -229,7 +230,7 @@ public class ApplicationHandlerTest { String url = toUrlPath(applicationId, Zone.defaultZone(), true) + "/logs?from=100&to=200"; ApplicationHandler mockHandler = createApplicationHandler(); - HttpResponse response = mockHandler.handle(HttpRequest.createTestRequest(url, com.yahoo.jdisc.http.HttpRequest.Method.GET)); + HttpResponse response = mockHandler.handle(HttpRequest.createTestRequest(url, GET)); assertEquals(200, response.getStatus()); assertEquals("log line", getRenderedString(response)); @@ -240,7 +241,7 @@ public class ApplicationHandlerTest { applicationRepository.deploy(testApp, prepareParams(applicationId)); String url = toUrlPath(applicationId, Zone.defaultZone(), true) + "/tester/status"; ApplicationHandler mockHandler = createApplicationHandler(); - HttpResponse response = mockHandler.handle(HttpRequest.createTestRequest(url, com.yahoo.jdisc.http.HttpRequest.Method.GET)); + HttpResponse response = mockHandler.handle(HttpRequest.createTestRequest(url, GET)); assertEquals(200, response.getStatus()); assertEquals("OK", getRenderedString(response)); } @@ -251,7 +252,7 @@ public class ApplicationHandlerTest { String url = toUrlPath(applicationId, Zone.defaultZone(), true) + "/tester/log?after=1234"; ApplicationHandler mockHandler = createApplicationHandler(); - HttpResponse response = mockHandler.handle(HttpRequest.createTestRequest(url, com.yahoo.jdisc.http.HttpRequest.Method.GET)); + HttpResponse response = mockHandler.handle(HttpRequest.createTestRequest(url, GET)); assertEquals(200, response.getStatus()); assertEquals("log", getRenderedString(response)); } @@ -273,7 +274,7 @@ public class ApplicationHandlerTest { applicationRepository.deploy(testApp, prepareParams(applicationId)); String url = toUrlPath(applicationId, Zone.defaultZone(), true) + "/tester/ready"; ApplicationHandler mockHandler = createApplicationHandler(); - HttpRequest testRequest = HttpRequest.createTestRequest(url, com.yahoo.jdisc.http.HttpRequest.Method.GET); + HttpRequest testRequest = HttpRequest.createTestRequest(url, GET); HttpResponse response = mockHandler.handle(testRequest); assertEquals(200, response.getStatus()); } @@ -315,13 +316,14 @@ public class ApplicationHandlerTest { } } - private void assertApplicationGeneration(ApplicationId applicationId, Zone zone, long expectedGeneration, boolean fullAppIdInUrl) throws IOException { - assertApplicationGeneration(toUrlPath(applicationId, zone, fullAppIdInUrl), expectedGeneration); + private void assertApplicationResponse(ApplicationId applicationId, Zone zone, long expectedGeneration, + boolean fullAppIdInUrl, String expectedVersion) throws IOException { + assertApplicationResponse(toUrlPath(applicationId, zone, fullAppIdInUrl), expectedGeneration, expectedVersion); } private void assertSuspended(boolean expectedValue, ApplicationId application, Zone zone) throws IOException { String restartUrl = toUrlPath(application, zone, true) + "/suspended"; - HttpResponse response = createApplicationHandler().handle(HttpRequest.createTestRequest(restartUrl, com.yahoo.jdisc.http.HttpRequest.Method.GET)); + HttpResponse response = createApplicationHandler().handle(HttpRequest.createTestRequest(restartUrl, GET)); HandlerTest.assertHttpStatusCodeAndMessage(response, 200, "{\"suspended\":" + expectedValue + "}"); } @@ -332,24 +334,28 @@ public class ApplicationHandlerTest { return url; } - private void assertApplicationGeneration(String url, long expectedGeneration) throws IOException { - HttpResponse response = createApplicationHandler().handle(HttpRequest.createTestRequest(url, com.yahoo.jdisc.http.HttpRequest.Method.GET)); - HandlerTest.assertHttpStatusCodeAndMessage(response, 200, "{\"generation\":" + expectedGeneration + "}"); + private void assertApplicationResponse(String url, long expectedGeneration, String expectedVersion) throws IOException { + HttpResponse response = createApplicationHandler().handle(HttpRequest.createTestRequest(url, GET)); + assertEquals(200, response.getStatus()); + String renderedString = SessionHandlerTest.getRenderedString(response); + assertEquals("{\"generation\":" + expectedGeneration + ",\"modelVersions\":[\"" + expectedVersion + "\"]}", renderedString); } private void assertApplicationExists(ApplicationId applicationId, Zone zone) throws IOException { - String tenantName = applicationId == null ? null : applicationId.tenant().value(); - String expected = applicationId == null ? "[]" : "[\"http://myhost:14000/application/v2/tenant/" + tenantName + "/application/" + applicationId.application().value() + - "/environment/" + zone.environment().value() + - "/region/" + zone.region().value() + - "/instance/" + applicationId.instance().value() + "\"]"; + String tenantName = applicationId.tenant().value(); + String expected = "[\"http://myhost:14000/application/v2/tenant/" + + tenantName + "/application/" + applicationId.application().value() + + "/environment/" + zone.environment().value() + + "/region/" + zone.region().value() + + "/instance/" + applicationId.instance().value() + "\"]"; ListApplicationsHandler listApplicationsHandler = new ListApplicationsHandler(ListApplicationsHandler.testOnlyContext(), tenantRepository, Zone.defaultZone()); - ListApplicationsHandlerTest.assertResponse(listApplicationsHandler, "http://myhost:14000/application/v2/tenant/" + tenantName + "/application/", + ListApplicationsHandlerTest.assertResponse(listApplicationsHandler, + "http://myhost:14000/application/v2/tenant/" + tenantName + "/application/", Response.Status.OK, expected, - com.yahoo.jdisc.http.HttpRequest.Method.GET); + GET); } private void restart(ApplicationId application, Zone zone) throws IOException { @@ -360,13 +366,13 @@ public class ApplicationHandlerTest { private void converge(ApplicationId application, Zone zone) throws IOException { String convergeUrl = toUrlPath(application, zone, true) + "/serviceconverge"; - HttpResponse response = createApplicationHandler().handle(HttpRequest.createTestRequest(convergeUrl, com.yahoo.jdisc.http.HttpRequest.Method.GET)); + HttpResponse response = createApplicationHandler().handle(HttpRequest.createTestRequest(convergeUrl, GET)); HandlerTest.assertHttpStatusCodeAndMessage(response, 200, ""); } private HttpResponse fileDistributionStatus(ApplicationId application, Zone zone) { String restartUrl = toUrlPath(application, zone, true) + "/filedistributionstatus"; - return createApplicationHandler().handle(HttpRequest.createTestRequest(restartUrl, com.yahoo.jdisc.http.HttpRequest.Method.GET)); + return createApplicationHandler().handle(HttpRequest.createTestRequest(restartUrl, GET)); } private static class MockStateApiFactory implements ConfigConvergenceChecker.StateApiFactory { |