summaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorJon Bratseth <jonbratseth@yahoo.com>2018-01-31 13:26:05 +0100
committerGitHub <noreply@github.com>2018-01-31 13:26:05 +0100
commitc4802f1fa7db7806ddd9b2b2d0bbb416d90720fc (patch)
treee42eb59c4779adfa2e5240cf80c5639f0b0ed2a4 /configserver
parentbf6bcd896dd47b440193053204ec9ef35237c7c0 (diff)
parent55b72a9d324cbab8492db6b5556f69214f05701a (diff)
Merge pull request #4831 from vespa-engine/hmusum/prepare-and-activate-handler
Add handler that does prepare and activate in one call
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java7
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/SessionHandler.java13
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandler.java15
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateHandler.java68
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateResponse.java42
-rw-r--r--configserver/src/main/resources/configserver-app/services.xml4
-rw-r--r--configserver/src/test/apps/app-jdisc-only/hosts.xml7
-rw-r--r--configserver/src/test/apps/app-jdisc-only/searchdefinitions/music.sd57
-rw-r--r--configserver/src/test/apps/app-jdisc-only/services.xml22
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java78
10 files changed, 298 insertions, 15 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 633207f1fcb..967cb06a13a 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
@@ -353,6 +353,13 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
return new PrepareResult(sessionId, actions, deployLog);
}
+ public PrepareResult prepareAndActivate(Tenant tenant, long sessionId, PrepareParams prepareParams,
+ boolean ignoreLockFailure, boolean ignoreSessionStaleFailure, Instant now) {
+ PrepareResult result = prepare(tenant, sessionId, prepareParams, now);
+ activate(tenant, sessionId, prepareParams.getTimeoutBudget(), ignoreLockFailure, ignoreSessionStaleFailure);
+ return result;
+ }
+
private List<ApplicationId> listApplicationIds(Tenant tenant) {
TenantApplications applicationRepo = tenant.getApplicationRepo();
return applicationRepo.listApplications();
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/SessionHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/SessionHandler.java
index 4d25ba9eeba..f6547288702 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/SessionHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/SessionHandler.java
@@ -83,4 +83,17 @@ public class SessionHandler extends HttpHandler {
return deployLog;
}
+ protected static boolean shouldIgnoreLockFailure(HttpRequest request) {
+ return request.getBooleanProperty("force");
+ }
+
+ /**
+ * True if this request should ignore activation failure because the session was made from an active session that is not active now
+ * @param request a {@link com.yahoo.container.jdisc.HttpRequest}
+ * @return true if ignore failure
+ */
+ protected static boolean shouldIgnoreSessionStaleFailure(HttpRequest request) {
+ return request.getBooleanProperty("force");
+ }
+
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandler.java
index b2330ebd97f..fc2b4c62dde 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandler.java
@@ -2,7 +2,6 @@
package com.yahoo.vespa.config.server.http.v2;
import java.time.Duration;
-import java.util.concurrent.Executor;
import com.google.inject.Inject;
import com.yahoo.config.application.api.ApplicationMetaData;
@@ -11,7 +10,6 @@ import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpResponse;
-import com.yahoo.container.logging.AccessLog;
import com.yahoo.vespa.config.server.ApplicationRepository;
import com.yahoo.vespa.config.server.tenant.Tenant;
import com.yahoo.vespa.config.server.tenant.Tenants;
@@ -56,17 +54,4 @@ public class SessionActiveHandler extends SessionHandler {
return new SessionActiveResponse(metaData.getSlime(), request, applicationId, sessionId, zone);
}
- private boolean shouldIgnoreLockFailure(HttpRequest request) {
- return request.getBooleanProperty("force");
- }
-
- /**
- * True if this request should ignore activation failure because the session was made from an active session that is not active now
- * @param request a {@link com.yahoo.container.jdisc.HttpRequest}
- * @return true if ignore failure
- */
- private boolean shouldIgnoreSessionStaleFailure(HttpRequest request) {
- return request.getBooleanProperty("force");
- }
-
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateHandler.java
new file mode 100644
index 00000000000..dc88a6ddddc
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateHandler.java
@@ -0,0 +1,68 @@
+// Copyright 2018 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.v2;
+
+import com.google.inject.Inject;
+import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.config.provision.TenantName;
+import com.yahoo.config.provision.Zone;
+import com.yahoo.container.jdisc.HttpRequest;
+import com.yahoo.container.jdisc.HttpResponse;
+import com.yahoo.vespa.config.server.ApplicationRepository;
+import com.yahoo.vespa.config.server.http.SessionHandler;
+import com.yahoo.vespa.config.server.http.Utils;
+import com.yahoo.vespa.config.server.session.PrepareParams;
+import com.yahoo.vespa.config.server.tenant.Tenant;
+import com.yahoo.vespa.config.server.tenant.Tenants;
+
+import java.time.Duration;
+import java.time.Instant;
+
+/**
+ * A handler that prepares and activates a session/application given by a session id in the request.
+ *
+ * @author hmusum
+ */
+public class SessionPrepareAndActivateHandler extends SessionHandler {
+
+ private final Tenants tenants;
+ private final Duration zookeeperBarrierTimeout;
+ private final Zone zone;
+
+ @Inject
+ public SessionPrepareAndActivateHandler(Context ctx,
+ ApplicationRepository applicationRepository,
+ Tenants tenants,
+ ConfigserverConfig configserverConfig,
+ Zone zone) {
+ super(ctx, applicationRepository);
+ this.tenants = tenants;
+ this.zookeeperBarrierTimeout = Duration.ofSeconds(configserverConfig.zookeeper().barrierTimeout());
+ this.zone = zone;
+ }
+
+ @Override
+ protected HttpResponse handlePUT(HttpRequest request) {
+ Tenant tenant = getExistingTenant(request);
+ TenantName tenantName = tenant.getName();
+ long sessionId = getSessionIdV2(request);
+ PrepareParams prepareParams = PrepareParams.fromHttpRequest(request, tenantName, zookeeperBarrierTimeout);
+
+ PrepareResult result = applicationRepository.prepareAndActivate(tenant, sessionId, prepareParams,
+ shouldIgnoreLockFailure(request),
+ shouldIgnoreSessionStaleFailure(request),
+ Instant.now());
+ return new SessionPrepareAndActivateResponse(result, tenantName, request, prepareParams.getApplicationId(), zone);
+ }
+
+ @Override
+ public Duration getTimeout() {
+ return zookeeperBarrierTimeout.plus(Duration.ofSeconds(10));
+ }
+
+ private Tenant getExistingTenant(HttpRequest request) {
+ TenantName tenantName = Utils.getTenantNameFromSessionRequest(request);
+ Utils.checkThatTenantExists(tenants, tenantName);
+ return tenants.getTenant(tenantName);
+ }
+
+}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateResponse.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateResponse.java
new file mode 100644
index 00000000000..4665a33c647
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/SessionPrepareAndActivateResponse.java
@@ -0,0 +1,42 @@
+// Copyright 2018 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.v2;
+
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.TenantName;
+import com.yahoo.config.provision.Zone;
+import com.yahoo.container.jdisc.HttpRequest;
+import com.yahoo.slime.Slime;
+import com.yahoo.vespa.config.server.configchange.ConfigChangeActions;
+import com.yahoo.vespa.config.server.configchange.ConfigChangeActionsSlimeConverter;
+import com.yahoo.vespa.config.server.http.SessionResponse;
+
+/**
+ * Creates a response for SessionPrepareHandler.
+ *
+ * @author hmusum
+ */
+class SessionPrepareAndActivateResponse extends SessionResponse {
+
+ SessionPrepareAndActivateResponse(PrepareResult result, TenantName tenantName, HttpRequest request,
+ ApplicationId applicationId, Zone zone) {
+ this(result.deployLog(), tenantName, request, result.sessionId(), result.configChangeActions(),
+ zone, applicationId);
+ }
+
+ private SessionPrepareAndActivateResponse(Slime deployLog, TenantName tenantName, HttpRequest request,
+ long sessionId, ConfigChangeActions actions, Zone zone,
+ ApplicationId applicationId) {
+ super(deployLog, deployLog.get());
+ String message = "Session " + sessionId + " for tenant '" + tenantName.value() + "' prepared and activated.";
+ this.root.setString("tenant", tenantName.value());
+ root.setString("url", "http://" + request.getHost() + ":" + request.getPort() +
+ "/application/v2/tenant/" + tenantName +
+ "/application/" + applicationId.application().value() +
+ "/environment/" + zone.environment().value() +
+ "/region/" + zone.region().value() +
+ "/instance/" + applicationId.instance().value());
+ root.setString("message", message);
+ new ConfigChangeActionsSlimeConverter(actions).toSlime(root);
+ }
+
+}
diff --git a/configserver/src/main/resources/configserver-app/services.xml b/configserver/src/main/resources/configserver-app/services.xml
index 52f63ad398c..bf38eedc97f 100644
--- a/configserver/src/main/resources/configserver-app/services.xml
+++ b/configserver/src/main/resources/configserver-app/services.xml
@@ -106,6 +106,10 @@
<binding>http://*/application/v2/tenant/*/session/*/active</binding>
<binding>https://*/application/v2/tenant/*/session/*/active</binding>
</handler>
+ <handler id='com.yahoo.vespa.config.server.http.v2.SessionPrepareAndActivateHandler' bundle='configserver'>
+ <binding>http://*/application/v2/tenant/*/session/*/prepareandactivate</binding>
+ <binding>https://*/application/v2/tenant/*/session/*/prepareandactivate</binding>
+ </handler>
<handler id='com.yahoo.vespa.config.server.http.v2.SessionContentHandler' bundle='configserver'>
<binding>http://*/application/v2/tenant/*/session/*/content/*</binding>
<binding>https://*/application/v2/tenant/*/session/*/content/*</binding>
diff --git a/configserver/src/test/apps/app-jdisc-only/hosts.xml b/configserver/src/test/apps/app-jdisc-only/hosts.xml
new file mode 100644
index 00000000000..f4256c9fc81
--- /dev/null
+++ b/configserver/src/test/apps/app-jdisc-only/hosts.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<hosts>
+ <host name="mytesthost">
+ <alias>node1</alias>
+ </host>
+</hosts>
diff --git a/configserver/src/test/apps/app-jdisc-only/searchdefinitions/music.sd b/configserver/src/test/apps/app-jdisc-only/searchdefinitions/music.sd
new file mode 100644
index 00000000000..2e40523a6d9
--- /dev/null
+++ b/configserver/src/test/apps/app-jdisc-only/searchdefinitions/music.sd
@@ -0,0 +1,57 @@
+# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+# A basic search definition - called music, should be saved to music.sd
+search music {
+
+ # It contains one document type only - called music as well
+ document music {
+
+ field title type string {
+ indexing: summary | index # How this field should be indexed
+ # index-to: title, default # Create two indexes
+ weight: 75 # Ranking importancy of this field, used by the built in nativeRank feature
+ header
+ }
+
+ field artist type string {
+ indexing: summary | attribute | index
+ # index-to: artist, default
+
+ weight: 25
+ header
+ }
+
+ field year type int {
+ indexing: summary | attribute
+ header
+ }
+
+ # Increase query
+ field popularity type int {
+ indexing: summary | attribute
+ body
+ }
+
+ field url type uri {
+ indexing: summary | index
+ header
+ }
+
+ }
+
+ rank-profile default inherits default {
+ first-phase {
+ expression: nativeRank(title,artist) + attribute(popularity)
+ }
+
+ }
+
+ rank-profile textmatch inherits default {
+ first-phase {
+ expression: nativeRank(title,artist)
+ }
+
+ }
+
+
+
+}
diff --git a/configserver/src/test/apps/app-jdisc-only/services.xml b/configserver/src/test/apps/app-jdisc-only/services.xml
new file mode 100644
index 00000000000..755ca1fd585
--- /dev/null
+++ b/configserver/src/test/apps/app-jdisc-only/services.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
+<services version="1.0">
+
+ <jdisc version="1.0">
+ <document-processing compressdocuments="true">
+ <chain id="ContainerWrapperTest">
+ <documentprocessor id="com.yahoo.vespa.config.AppleDocProc"/>
+ </chain>
+ </document-processing>
+
+ <config name="project.specific">
+ <value>someval</value>
+ </config>
+
+ <nodes>
+ <node hostalias="node1" />
+ </nodes>
+
+ </jdisc>
+
+</services>
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
new file mode 100644
index 00000000000..52c711e3157
--- /dev/null
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
@@ -0,0 +1,78 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.server;
+
+import com.yahoo.config.model.application.provider.FilesApplicationPackage;
+import com.yahoo.config.provision.Provisioner;
+import com.yahoo.config.provision.TenantName;
+import com.yahoo.vespa.config.server.http.SessionHandlerTest;
+import com.yahoo.vespa.config.server.http.v2.PrepareResult;
+import com.yahoo.vespa.config.server.session.PrepareParams;
+import com.yahoo.vespa.config.server.tenant.Tenant;
+import com.yahoo.vespa.config.server.tenant.Tenants;
+import com.yahoo.vespa.curator.Curator;
+import com.yahoo.vespa.curator.mock.MockCurator;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.Clock;
+import java.time.Duration;
+import java.time.Instant;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author hmusum
+ */
+public class ApplicationRepositoryTest {
+
+ private final static File testApp = new File("src/test/apps/app");
+ private final static File testAppJdiscOnly = new File("src/test/apps/app-jdisc-only");
+ private final static TenantName tenantName = TenantName.from("test");
+ private final static Clock clock = Clock.systemUTC();
+
+ private Tenant tenant;
+ private ApplicationRepository applicationRepository;
+ private TimeoutBudget timeoutBudget;
+
+ @Before
+ public void setup() {
+ Curator curator = new MockCurator();
+ Tenants tenants = new Tenants(new TestComponentRegistry.Builder()
+ .curator(curator)
+ .build());
+ tenants.addTenant(tenantName);
+ tenant = tenants.getTenant(tenantName);
+ Provisioner provisioner = new SessionHandlerTest.MockProvisioner();
+ applicationRepository = new ApplicationRepository(tenants, provisioner, clock);
+ timeoutBudget = new TimeoutBudget(clock, Duration.ofSeconds(60));
+ }
+
+ @Test
+ public void prepareAndActivate() throws IOException {
+ PrepareResult result = prepareAndActivateApp(testApp);
+ assertTrue(result.configChangeActions().getRefeedActions().isEmpty());
+ assertTrue(result.configChangeActions().getRestartActions().isEmpty());
+ }
+
+ @Test
+ public void prepareAndActivateWithRestart() throws IOException {
+ prepareAndActivateApp(testAppJdiscOnly);
+ PrepareResult result = prepareAndActivateApp(testApp);
+ assertTrue(result.configChangeActions().getRefeedActions().isEmpty());
+ assertFalse(result.configChangeActions().getRestartActions().isEmpty());
+ }
+
+ private PrepareResult prepareAndActivateApp(File application) throws IOException {
+ FilesApplicationPackage appDir = FilesApplicationPackage.fromFile(application);
+ long sessionId = applicationRepository.createSession(tenant, timeoutBudget, appDir.getAppDir(), "testapp");
+ return applicationRepository.prepareAndActivate(tenant, sessionId, prepareParams(), false, false, Instant.now());
+ }
+
+ private PrepareParams prepareParams() {
+ return new PrepareParams.Builder().build();
+ }
+
+}