summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <jonbratseth@yahoo.com>2017-12-05 14:08:08 -0800
committerGitHub <noreply@github.com>2017-12-05 14:08:08 -0800
commit19a7d1c0469fa8222b009ac985bc2740aea922a5 (patch)
tree08b04645b475c33de3cef91ba8993a0fc31459c0
parent40c4c765975f11b03da614c91a7e22c35e1d19bf (diff)
parentc2961c66705780d8819329debfce3487a792ad86 (diff)
Merge pull request #4360 from vespa-engine/mpolden/curator-lock-for-rotation-repository
Use curator lock when assigning rotation
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java26
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java22
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/rotation/RotationLock.java25
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/rotation/RotationRepository.java23
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerClientMock.java37
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerProxyMock.java3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializerTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java12
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java10
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/rotation/RotationTest.java14
10 files changed, 108 insertions, 66 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
index a489b0f4e91..9767ae57bf0 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java
@@ -48,6 +48,7 @@ import com.yahoo.vespa.hosted.controller.maintenance.DeploymentExpirer;
import com.yahoo.vespa.hosted.controller.persistence.ControllerDb;
import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
import com.yahoo.vespa.hosted.controller.rotation.Rotation;
+import com.yahoo.vespa.hosted.controller.rotation.RotationLock;
import com.yahoo.vespa.hosted.controller.rotation.RotationRepository;
import com.yahoo.vespa.hosted.rotation.config.RotationsConfig;
import com.yahoo.yolean.Exceptions;
@@ -96,8 +97,6 @@ public class ApplicationController {
private final DeploymentTrigger deploymentTrigger;
- private final Object monitor = new Object();
-
ApplicationController(Controller controller, ControllerDb db, CuratorDb curator,
AthenzClientFactory zmsClientFactory, RotationsConfig rotationsConfig,
NameService nameService, ConfigServerClient configserverClient,
@@ -111,7 +110,7 @@ public class ApplicationController {
this.routingGenerator = routingGenerator;
this.clock = clock;
- this.rotationRepository = new RotationRepository(rotationsConfig, this);
+ this.rotationRepository = new RotationRepository(rotationsConfig, this, curator);
this.deploymentTrigger = new DeploymentTrigger(controller, curator, clock);
for (Application application : db.listApplications()) {
@@ -330,15 +329,13 @@ public class ApplicationController {
" the current version " + existingDeployment.version());
}
- // Synchronize rotation assignment. Rotation can only be considered assigned once application has been
- // persisted.
Optional<Rotation> rotation;
- synchronized (monitor) {
- rotation = getRotation(application, zone);
+ try (RotationLock rotationLock = rotationRepository.lock()) {
+ rotation = getRotation(application, zone, rotationLock);
if (rotation.isPresent()) {
application = application.with(rotation.get().id());
store(application); // store assigned rotation even if deployment fails
- registerRotationInDns(application.rotation().get(), rotation.get());
+ registerRotationInDns(rotation.get(), application.rotation().get().dnsName());
}
}
@@ -453,14 +450,13 @@ public class ApplicationController {
}
/** Register a DNS name for rotation */
- private void registerRotationInDns(ApplicationRotation applicationRotation, Rotation rotation) {
- String dnsName = applicationRotation.dnsName();
+ private void registerRotationInDns(Rotation rotation, String dnsName) {
try {
Optional<Record> record = nameService.findRecord(Record.Type.CNAME, dnsName);
if (!record.isPresent()) {
- RecordId recordId = nameService.createCname(dnsName, rotation.name());
- log.info("Registered mapping with record ID " + recordId.asString() + ": " +
- dnsName + " -> " + rotation.name());
+ RecordId id = nameService.createCname(dnsName, rotation.name());
+ log.info("Registered mapping with record ID " + id.asString() + ": " + dnsName + " -> "
+ + rotation.name());
}
} catch (RuntimeException e) {
log.log(Level.WARNING, "Failed to register CNAME", e);
@@ -468,12 +464,12 @@ public class ApplicationController {
}
/** Get an available rotation, if deploying to a production zone and a service ID is specified */
- private Optional<Rotation> getRotation(Application application, Zone zone) {
+ private Optional<Rotation> getRotation(Application application, Zone zone, RotationLock lock) {
if (zone.environment() != Environment.prod ||
!application.deploymentSpec().globalServiceId().isPresent()) {
return Optional.empty();
}
- return Optional.of(rotationRepository.getRotation(application));
+ return Optional.of(rotationRepository.getRotation(application, lock));
}
/** Returns the endpoints of the deployment, or empty if obtaining them failed */
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java
index 95db401d15b..a3bb191fc38 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/CuratorDb.java
@@ -39,6 +39,8 @@ public class CuratorDb {
private static final Path root = Path.fromString("/controller/v1");
+ private static final Path lockRoot = root.append("locks");
+
private static final Duration defaultLockTimeout = Duration.ofMinutes(5);
private final StringSetSerializer stringSetSerializer = new StringSetSerializer();
@@ -67,6 +69,10 @@ public class CuratorDb {
return lock(lockPath(id), timeout);
}
+ public Lock lockRotations() {
+ return lock(lockRoot.append("rotations"), defaultLockTimeout);
+ }
+
/** Create a reentrant lock */
private Lock lock(Path path, Duration timeout) {
Lock lock = locks.computeIfAbsent(path, (pathArg) -> new Lock(pathArg.getAbsolute(), curator));
@@ -75,18 +81,18 @@ public class CuratorDb {
}
public Lock lockInactiveJobs() {
- return lock(root.append("locks").append("inactiveJobsLock"), defaultLockTimeout);
+ return lock(lockRoot.append("inactiveJobsLock"), defaultLockTimeout);
}
public Lock lockJobQueues() {
- return lock(root.append("locks").append("jobQueuesLock"), defaultLockTimeout);
+ return lock(lockRoot.append("jobQueuesLock"), defaultLockTimeout);
}
public Lock lockMaintenanceJob(String jobName) {
// Use a short timeout such that if maintenance jobs are started at about the same time on different nodes
// and the maintenance job takes a long time to complete, only one of the nodes will run the job
// in each maintenance interval
- return lock(root.append("locks").append("maintenanceJobLocks").append(jobName), Duration.ofSeconds(1));
+ return lock(lockRoot.append("maintenanceJobLocks").append(jobName), Duration.ofSeconds(1));
}
public Lock lockProvisionState(String provisionStateId) {
@@ -94,11 +100,11 @@ public class CuratorDb {
}
public Lock lockVespaServerPool() {
- return lock(root.append("locks").append("vespaServerPoolLock"), Duration.ofSeconds(1));
+ return lock(lockRoot.append("vespaServerPoolLock"), Duration.ofSeconds(1));
}
public Lock lockOpenStackServerPool() {
- return lock(root.append("locks").append("openStackServerPoolLock"), Duration.ofSeconds(1));
+ return lock(lockRoot.append("openStackServerPoolLock"), Duration.ofSeconds(1));
}
// -------------- Read and write --------------------------------------------------
@@ -223,14 +229,14 @@ public class CuratorDb {
// -------------- Paths --------------------------------------------------
private Path lockPath(TenantId tenant) {
- Path lockPath = root.append("locks")
+ Path lockPath = lockRoot
.append(tenant.id());
curator.create(lockPath);
return lockPath;
}
private Path lockPath(ApplicationId application) {
- Path lockPath = root.append("locks")
+ Path lockPath = lockRoot
.append(application.tenant().value())
.append(application.application().value())
.append(application.instance().value());
@@ -239,7 +245,7 @@ public class CuratorDb {
}
private Path lockPath(String provisionId) {
- Path lockPath = root.append("locks")
+ Path lockPath = lockRoot
.append(provisionStatePath())
.append(provisionId);
curator.create(lockPath);
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/rotation/RotationLock.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/rotation/RotationLock.java
new file mode 100644
index 00000000000..508df263837
--- /dev/null
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/rotation/RotationLock.java
@@ -0,0 +1,25 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.controller.rotation;
+
+import com.yahoo.vespa.curator.Lock;
+
+import java.util.Objects;
+
+/**
+ * A lock for the rotation repository. This is a type-safe wrapper for a curator lock.
+ *
+ * @author mpolden
+ */
+public class RotationLock implements AutoCloseable {
+
+ private final Lock lock;
+
+ RotationLock(Lock lock) {
+ this.lock = Objects.requireNonNull(lock, "lock cannot be null");
+ }
+
+ @Override
+ public void close() {
+ lock.close();
+ }
+}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/rotation/RotationRepository.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/rotation/RotationRepository.java
index 70836232417..e70d177a641 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/rotation/RotationRepository.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/rotation/RotationRepository.java
@@ -5,6 +5,7 @@ import com.yahoo.config.application.api.DeploymentSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.ApplicationController;
+import com.yahoo.vespa.hosted.controller.persistence.CuratorDb;
import com.yahoo.vespa.hosted.rotation.config.RotationsConfig;
import java.util.ArrayList;
@@ -32,10 +33,17 @@ public class RotationRepository {
private final Map<RotationId, Rotation> allRotations;
private final ApplicationController applications;
+ private final CuratorDb curator;
- public RotationRepository(RotationsConfig rotationsConfig, ApplicationController applications) {
+ public RotationRepository(RotationsConfig rotationsConfig, ApplicationController applications, CuratorDb curator) {
this.allRotations = from(rotationsConfig);
this.applications = applications;
+ this.curator = curator;
+ }
+
+ /** Acquire a exclusive lock for this */
+ public RotationLock lock() {
+ return new RotationLock(curator.lockRotations());
}
/**
@@ -44,9 +52,10 @@ public class RotationRepository {
* If a rotation is already assigned to the application, that rotation will be returned.
* If no rotation is assigned, return an available rotation. The caller is responsible for assigning the rotation.
*
- * @param application The application to get a rotation for
+ * @param application The application requesting a rotation
+ * @param lock Lock which must be acquired by the caller
*/
- public Rotation getRotation(Application application) {
+ public Rotation getRotation(Application application, @SuppressWarnings("unused") RotationLock lock) {
if (application.rotation().isPresent()) {
return allRotations.get(application.rotation().get().id());
}
@@ -54,10 +63,10 @@ public class RotationRepository {
throw new IllegalArgumentException("global-service-id is not set in deployment spec");
}
long productionZones = application.deploymentSpec().zones().stream()
- .filter(zone -> zone.deploysTo(Environment.prod))
- // Global rotations don't work for nodes in corp network
- .filter(zone -> !isCorp(zone))
- .count();
+ .filter(zone -> zone.deploysTo(Environment.prod))
+ // Global rotations don't work for nodes in corp network
+ .filter(zone -> !isCorp(zone))
+ .count();
if (productionZones < 2) {
throw new IllegalArgumentException("global-service-id is set but less than 2 prod zones are defined");
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerClientMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerClientMock.java
index 9228e83bbc6..bf7f19a996c 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerClientMock.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerClientMock.java
@@ -22,7 +22,6 @@ import com.yahoo.vespa.serviceview.bindings.ApplicationView;
import com.yahoo.vespa.serviceview.bindings.ClusterView;
import com.yahoo.vespa.serviceview.bindings.ServiceView;
-import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
@@ -43,16 +42,14 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
private final Map<ApplicationId, Boolean> applicationActivated = new HashMap<>();
private final Map<String, EndpointStatus> endpoints = new HashMap<>();
private final Map<URI, Version> versions = new HashMap<>();
- private Version defaultVersion = new Version(6, 1, 0);
- /** The exception to throw on the next prepare run, or null to continue normally */
+ private Version defaultVersion = new Version(6, 1, 0);
private RuntimeException prepareException = null;
-
- private Optional<Version> lastPrepareVersion = Optional.empty();
+ private Version lastPrepareVersion = null;
/** The version given in the previous prepare call, or empty if no call has been made */
public Optional<Version> lastPrepareVersion() {
- return lastPrepareVersion;
+ return Optional.ofNullable(lastPrepareVersion);
}
/** Return map of applications that may have been activated */
@@ -60,6 +57,7 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
return Collections.unmodifiableMap(applicationActivated);
}
+ /** The exception to throw on the next prepare run, or null to continue normally */
public void throwOnNextPrepare(RuntimeException prepareException) {
this.prepareException = prepareException;
}
@@ -71,10 +69,16 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
public Map<URI, Version> versions() {
return versions;
}
+
+ /** Set the default config server version */
+ public void setDefaultVersion(Version version) {
+ this.defaultVersion = version;
+ }
@Override
- public PreparedApplication prepare(DeploymentId deployment, DeployOptions deployOptions, Set<String> rotationCnames, Set<Rotation> rotations, byte[] content) {
- lastPrepareVersion = deployOptions.vespaVersion.map(Version::new);
+ public PreparedApplication prepare(DeploymentId deployment, DeployOptions deployOptions, Set<String> rotationCnames,
+ Set<Rotation> rotations, byte[] content) {
+ lastPrepareVersion = deployOptions.vespaVersion.map(Version::new).orElse(null);
if (prepareException != null) {
RuntimeException prepareException = this.prepareException;
this.prepareException = null;
@@ -108,23 +112,20 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
public PrepareResponse prepareResponse() {
PrepareResponse prepareResponse = new PrepareResponse();
prepareResponse.message = "foo";
- prepareResponse.configChangeActions = new ConfigChangeActions(Collections.emptyList(), Collections.emptyList());
+ prepareResponse.configChangeActions = new ConfigChangeActions(Collections.emptyList(),
+ Collections.emptyList());
prepareResponse.tenant = new TenantId("tenant");
return prepareResponse;
}
};
}
-
- /** Set the default config server version */
- public void setDefaultVersion(Version version) { this.defaultVersion = version; }
@Override
public List<String> getNodeQueryHost(DeploymentId deployment, String type) {
if (applicationInstances.containsKey(deployment.applicationId())) {
return Collections.singletonList(applicationInstances.get(deployment.applicationId()));
- } else {
- return Collections.emptyList();
}
+ return Collections.emptyList();
}
@Override
@@ -151,7 +152,8 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
// Returns a canned example response
@Override
- public ApplicationView getApplicationView(String tenantName, String applicationName, String instanceName, String environment, String region) {
+ public ApplicationView getApplicationView(String tenantName, String applicationName, String instanceName,
+ String environment, String region) {
ApplicationView applicationView = new ApplicationView();
ClusterView cluster = new ClusterView();
cluster.name = "cluster1";
@@ -172,7 +174,8 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
// Returns a canned example response
@Override
- public Map<?,?> getServiceApiResponse(String tenantName, String applicationName, String instanceName, String environment, String region, String serviceName, String restPath) {
+ public Map<?,?> getServiceApiResponse(String tenantName, String applicationName, String instanceName,
+ String environment, String region, String serviceName, String restPath) {
Map<String,List<?>> root = new HashMap<>();
List<Map<?,?>> resources = new ArrayList<>();
Map<String,String> resource = new HashMap<>();
@@ -199,7 +202,7 @@ public class ConfigServerClientMock extends AbstractComponent implements ConfigS
}
@Override
- public NodeList getNodeList(DeploymentId deployment) throws IOException {
+ public NodeList getNodeList(DeploymentId deployment) {
NodeList list = new NodeList();
list.nodes = new ArrayList<>();
NodeList.Node hostA = new NodeList.Node();
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerProxyMock.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerProxyMock.java
index cc915d4d9a1..02b33e4640a 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerProxyMock.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ConfigServerProxyMock.java
@@ -4,7 +4,6 @@ package com.yahoo.vespa.hosted.controller;
import com.yahoo.component.AbstractComponent;
import com.yahoo.container.jdisc.HttpResponse;
import com.yahoo.vespa.hosted.controller.proxy.ConfigServerRestExecutor;
-import com.yahoo.vespa.hosted.controller.proxy.ProxyException;
import com.yahoo.vespa.hosted.controller.proxy.ProxyRequest;
import com.yahoo.vespa.hosted.controller.restapi.StringResponse;
@@ -21,7 +20,7 @@ public class ConfigServerProxyMock extends AbstractComponent implements ConfigSe
private volatile String requestBody = null;
@Override
- public HttpResponse handle(ProxyRequest proxyRequest) throws ProxyException {
+ public HttpResponse handle(ProxyRequest proxyRequest) {
lastReceived = proxyRequest;
// Copy request body as the input stream is drained once the request completes
requestBody = asString(proxyRequest.getData());
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializerTest.java
index 189b3a97a80..c668bde0d40 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializerTest.java
@@ -21,7 +21,7 @@ import static org.junit.Assert.assertEquals;
public class VersionStatusSerializerTest {
@Test
- public void testSerialization() throws Exception {
+ public void testSerialization() {
List<VespaVersion> vespaVersions = new ArrayList<>();
DeploymentStatistics statistics = new DeploymentStatistics(
Version.fromString("5.0"),
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
index fb0adcd3152..9f5de1e460b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerControllerTester.java
@@ -45,18 +45,16 @@ import java.util.Optional;
public class ContainerControllerTester {
private final ContainerTester containerTester;
- private final Controller controller;
private final Upgrader upgrader;
public ContainerControllerTester(JDisc container, String responseFilePath) {
containerTester = new ContainerTester(container, responseFilePath);
- controller = (Controller)container.components().getComponent("com.yahoo.vespa.hosted.controller.Controller");
CuratorDb curatorDb = new MockCuratorDb();
curatorDb.writeUpgradesPerMinute(100);
- upgrader = new Upgrader(controller, Duration.ofDays(1), new JobControl(curatorDb), curatorDb);
+ upgrader = new Upgrader(controller(), Duration.ofDays(1), new JobControl(curatorDb), curatorDb);
}
- public Controller controller() { return controller; }
+ public Controller controller() { return containerTester.controller(); }
public Upgrader upgrader() { return upgrader; }
@@ -70,18 +68,18 @@ public class ContainerControllerTester {
public Application createApplication(String athensDomain, String tenant, String application) {
AthenzDomain domain1 = addTenantAthenzDomain(athensDomain, "mytenant");
- controller.tenants().addTenant(Tenant.createAthensTenant(new TenantId(tenant), domain1,
+ controller().tenants().addTenant(Tenant.createAthensTenant(new TenantId(tenant), domain1,
new Property("property1"),
Optional.of(new PropertyId("1234"))),
Optional.of(TestIdentities.userNToken));
ApplicationId app = ApplicationId.from(tenant, application, "default");
- return controller.applications().createApplication(app, Optional.of(TestIdentities.userNToken));
+ return controller().applications().createApplication(app, Optional.of(TestIdentities.userNToken));
}
public Application deploy(Application application, ApplicationPackage applicationPackage, Zone zone, long projectId) {
ScrewdriverId app1ScrewdriverId = new ScrewdriverId(String.valueOf(projectId));
GitRevision app1RevisionId = new GitRevision(new GitRepository("repo"), new GitBranch("master"), new GitCommit("commit1"));
- controller.applications().deployApplication(application.id(),
+ controller().applications().deployApplication(application.id(),
zone,
applicationPackage,
new DeployOptions(Optional.of(new ScrewdriverBuildJob(app1ScrewdriverId, app1RevisionId)), Optional.empty(), false, false));
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java
index c0e8b48f821..95810e90cdb 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java
@@ -43,14 +43,16 @@ public class ContainerTester {
public JDisc container() { return container; }
+ public Controller controller() {
+ return (Controller) container.components().getComponent(Controller.class.getName());
+ }
+
public void updateSystemVersion() {
- Controller controller = (Controller)container.components().getComponent("com.yahoo.vespa.hosted.controller.Controller");
- controller.updateVersionStatus(VersionStatus.compute(controller));
+ controller().updateVersionStatus(VersionStatus.compute(controller()));
}
public void updateSystemVersion(Version version) {
- Controller controller = (Controller)container.components().getComponent("com.yahoo.vespa.hosted.controller.Controller");
- controller.updateVersionStatus(VersionStatus.compute(controller, version));
+ controller().updateVersionStatus(VersionStatus.compute(controller(), version));
}
public void assertResponse(Supplier<Request> request, File responseFile) throws IOException {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/rotation/RotationTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/rotation/RotationTest.java
index 8fc41b8daa6..c259ae0ca60 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/rotation/RotationTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/rotation/RotationTest.java
@@ -67,8 +67,10 @@ public class RotationTest {
assertEquals(expected.id(), application.rotation().get().id());
assertEquals(URI.create("http://app1.tenant1.global.vespa.yahooapis.com:4080/"),
application.rotation().get().url());
- Rotation rotation = repository.getRotation(tester.applications().require(application.id()));
- assertEquals(expected, rotation);
+ try (RotationLock lock = repository.lock()) {
+ Rotation rotation = repository.getRotation(tester.applications().require(application.id()), lock);
+ assertEquals(expected, rotation);
+ }
// Deploying once more assigns same rotation
ApplicationPackage applicationPackage = new ApplicationPackageBuilder()
@@ -90,9 +92,11 @@ public class RotationTest {
tester.deployCompletely(application, applicationPackage);
application = tester.applications().require(application.id());
- Rotation rotation = repository.getRotation(application);
- Rotation assignedRotation = new Rotation(new RotationId("foo-1"), "foo-1.com");
- assertEquals(assignedRotation, rotation);
+ try (RotationLock lock = repository.lock()) {
+ Rotation rotation = repository.getRotation(application, lock);
+ Rotation assignedRotation = new Rotation(new RotationId("foo-1"), "foo-1.com");
+ assertEquals(assignedRotation, rotation);
+ }
}