summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/IdentityDocumentGenerator.java5
-rw-r--r--clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/SystemStateBroadcaster.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java1
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenants.java51
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java6
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java30
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListTenantsTest.java6
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantsTestCase.java36
-rw-r--r--container-di/src/main/scala/com/yahoo/container/di/Container.scala3
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java3
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockOrganization.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java5
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/ApplicationController.java38
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/DeploymentJobs.java9
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/JobStatus.java42
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java14
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java3
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java10
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ErrorResponse.java8
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java26
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java24
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/DeployAuthorizer.java81
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java27
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporterTest.java1
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java8
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json28
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json18
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/opsdb-tenant-with-new-id-without-applications.json6
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-without-applications.json2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/AbstractResource.java4
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/Container.java21
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/HeaderFields.java7
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/AbstractContentOutputStream.java15
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/BindingNotFoundException.java3
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/BlockingContentWriter.java13
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/BufferedContentChannel.java7
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableRequestDispatch.java7
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableResponseDispatch.java11
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/CompletionHandler.java7
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentChannel.java7
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentInputStream.java9
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentOutputStream.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentWriter.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureCompletion.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureConjunction.java3
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureResponse.java7
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/NullContent.java3
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/OverloadException.java11
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/ReadableContentChannel.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDeniedException.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDispatch.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseDispatch.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseHandler.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/ThreadedRequestHandler.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/service/AbstractServerProvider.java2
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/statistics/ActiveContainerMetrics.java2
-rw-r--r--slobrok/src/tests/oldapi/mirror.cpp12
-rw-r--r--slobrok/src/tests/oldapi/mirror.h2
-rw-r--r--slobrok/src/vespa/slobrok/sbregister.cpp47
-rw-r--r--slobrok/src/vespa/slobrok/sbregister.h2
-rw-r--r--vespalog/src/vespa/log/bufferedlogger.cpp16
-rw-r--r--yolean/src/main/java/com/yahoo/yolean/chain/After.java8
-rw-r--r--yolean/src/main/java/com/yahoo/yolean/chain/Before.java8
-rw-r--r--yolean/src/main/java/com/yahoo/yolean/chain/Chain.java1
-rw-r--r--yolean/src/main/java/com/yahoo/yolean/chain/ChainCycleException.java1
-rw-r--r--yolean/src/main/java/com/yahoo/yolean/chain/Dependencies.java1
-rw-r--r--yolean/src/main/java/com/yahoo/yolean/chain/DirectedGraph.java1
-rw-r--r--yolean/src/main/java/com/yahoo/yolean/chain/EnumeratedIdentitySet.java1
-rw-r--r--yolean/src/main/java/com/yahoo/yolean/chain/Provides.java4
74 files changed, 416 insertions, 352 deletions
diff --git a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/IdentityDocumentGenerator.java b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/IdentityDocumentGenerator.java
index 644fc929884..efb2179ff6b 100644
--- a/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/IdentityDocumentGenerator.java
+++ b/athenz-identity-provider-service/src/main/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/impl/IdentityDocumentGenerator.java
@@ -1,7 +1,6 @@
// 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.athenz.instanceproviderservice.impl;
-import com.yahoo.athenz.auth.util.Crypto;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.hosted.athenz.instanceproviderservice.config.AthenzProviderServiceConfig;
import com.yahoo.vespa.hosted.athenz.instanceproviderservice.impl.model.IdentityDocument;
@@ -27,6 +26,7 @@ public class IdentityDocumentGenerator {
private final String dnsSuffix;
private final String providerService;
private final String ztsUrl;
+ private final String providerDomain;
public IdentityDocumentGenerator(AthenzProviderServiceConfig config, NodeRepository nodeRepository, Zone zone, KeyProvider keyProvider) {
this.nodeRepository = nodeRepository;
@@ -35,6 +35,7 @@ public class IdentityDocumentGenerator {
this.dnsSuffix = config.certDnsSuffix();
this.providerService = config.serviceName();
this.ztsUrl = config.ztsUrl();
+ this.providerDomain = config.domain();
}
public String generateSignedIdentityDocument(String hostname) {
@@ -59,7 +60,7 @@ public class IdentityDocumentGenerator {
SignedIdentityDocument.DEFAULT_KEY_VERSION,
identityDocument.providerUniqueId.asString(),
dnsSuffix,
- providerService,
+ providerDomain + "." + providerService,
ztsUrl,
SignedIdentityDocument.DEFAILT_DOCUMENT_VERSION
);
diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/SystemStateBroadcaster.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/SystemStateBroadcaster.java
index 5c035a0d5a7..024c5d21607 100644
--- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/SystemStateBroadcaster.java
+++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/SystemStateBroadcaster.java
@@ -134,6 +134,7 @@ public class SystemStateBroadcaster {
if (systemState == null) return false;
if (!systemState.isOfficial()) {
+ log.log(LogLevel.INFO, String.format("Publishing cluster state version %d", systemState.getVersion()));
systemState.setOfficial(true);
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java
index 03c5a7e4a4b..db81191f0cf 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java
@@ -26,7 +26,6 @@ import java.util.*;
/**
* @author gjoranv
* @author tonytv
- * @since 5.1.9
*/
public class ContainerSearch extends ContainerSubsystem<SearchChains>
implements
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java
index b02d17a9372..46d007126c0 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/TenantHandler.java
@@ -37,7 +37,7 @@ public class TenantHandler extends HttpHandler {
protected HttpResponse handlePUT(HttpRequest request) {
TenantName tenantName = getAndValidateTenantFromRequest(request);
try {
- tenants.writeTenantPath(tenantName);
+ tenants.addTenant(tenantName);
} catch (Exception e) {
throw new InternalServerException(Exceptions.toMessageString(e));
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenants.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenants.java
index 3ad920bbff2..cf05440a1d2 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenants.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/Tenants.java
@@ -28,7 +28,6 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -42,7 +41,7 @@ import java.util.logging.Logger;
* implemented support for it).
*
* This instance is called from two different threads, the http handler threads and the zookeeper watcher threads.
- * To create or delete a tenant, the handler calls {@link Tenants#writeTenantPath} and {@link Tenants#deleteTenant} methods.
+ * To create or delete a tenant, the handler calls {@link Tenants#addTenant} and {@link Tenants#deleteTenant} methods.
* This will delete shared state from zookeeper, and return, so it does not mean a tenant is immediately deleted.
*
* Once a tenant is deleted from zookeeper, the zookeeper watcher thread will get notified on all configservers, and
@@ -73,14 +72,13 @@ public class Tenants implements ConnectionStateListener, PathChildrenCacheListen
/**
- * New instance from the tenants in the given component registry's ZooKeeper. Will set watch when reading them.
+ * New instance from the tenants in the given component registry's ZooKeeper data.
*
* @param globalComponentRegistry a {@link com.yahoo.vespa.config.server.GlobalComponentRegistry}
* @throws Exception is creating the Tenants instance fails
*/
@Inject
public Tenants(GlobalComponentRegistry globalComponentRegistry, Metrics metrics) throws Exception {
- // Note: unit tests may want to use the constructor below to avoid setting watch by calling readTenants().
this.globalComponentRegistry = globalComponentRegistry;
this.curator = globalComponentRegistry.getCurator();
metricUpdater = metrics.getOrCreateMetricUpdater(Collections.emptyMap());
@@ -94,12 +92,12 @@ public class Tenants implements ConnectionStateListener, PathChildrenCacheListen
this.directoryCache = curator.createDirectoryCache(tenantsPath.getAbsolute(), false, false, pathChildrenExecutor);
directoryCache.start();
directoryCache.addListener(this);
- tenantsChanged(readTenants());
+ createTenants();
notifyTenantsLoaded();
}
/**
- * New instance containing the given tenants. This will not watch in ZooKeeper.
+ * New instance containing the given tenants. This will not create Zookeeper watches. For testing only
* @param globalComponentRegistry a {@link com.yahoo.vespa.config.server.GlobalComponentRegistry} instance
* @param metrics a {@link com.yahoo.vespa.config.server.monitoring.Metrics} instance
* @param tenants a collection of {@link Tenant}s
@@ -131,9 +129,9 @@ public class Tenants implements ConnectionStateListener, PathChildrenCacheListen
return sessionTenants;
}
- public synchronized void addTenant(Tenant tenant) {
- tenants.put(tenant.getName(), tenant);
- metricUpdater.setTenants(tenants.size());
+ public synchronized void addTenant(TenantName tenantName) throws Exception {
+ writeTenantPath(tenantName);
+ createTenant(tenantName);
}
/**
@@ -141,7 +139,7 @@ public class Tenants implements ConnectionStateListener, PathChildrenCacheListen
*
* @return a set of tenant names
*/
- private Set<TenantName> readTenants() {
+ private Set<TenantName> readTenantsFromZooKeeper() {
Set<TenantName> tenants = new LinkedHashSet<>();
for (String tenant : curator.getChildren(tenantsPath)) {
tenants.add(TenantName.from(tenant));
@@ -149,10 +147,11 @@ public class Tenants implements ConnectionStateListener, PathChildrenCacheListen
return tenants;
}
- synchronized void tenantsChanged(Set<TenantName> newTenants) throws Exception {
- log.log(LogLevel.DEBUG, "Tenants changed: " + newTenants);
- checkForRemovedTenants(newTenants);
- checkForAddedTenants(newTenants);
+ synchronized void createTenants() throws Exception {
+ Set<TenantName> allTenants = readTenantsFromZooKeeper();
+ log.log(LogLevel.DEBUG, "Create tenants, tenants found in zookeeper: " + allTenants);
+ checkForRemovedTenants(allTenants);
+ checkForAddedTenants(allTenants);
metricUpdater.setTenants(tenants.size());
}
@@ -170,24 +169,26 @@ public class Tenants implements ConnectionStateListener, PathChildrenCacheListen
private void checkForAddedTenants(Set<TenantName> newTenants) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(globalComponentRegistry.getConfigserverConfig().numParallelTenantLoaders());
- Map<TenantName, Tenant> addedTenants = new ConcurrentHashMap<>();
for (TenantName tenantName : newTenants) {
// Note: the http handler will check if the tenant exists, and throw accordingly
if (!tenants.containsKey(tenantName)) {
executor.execute(() -> {
- try {
- Tenant tenant = TenantBuilder.create(globalComponentRegistry, tenantName, getTenantPath(tenantName)).build();
- notifyNewTenant(tenant);
- addedTenants.put(tenantName, tenant);
- } catch (Exception e) {
- log.log(LogLevel.WARNING, "Error loading tenant '" + tenantName + "', skipping.", e);
- }
+ createTenant(tenantName);
});
}
}
executor.shutdown();
executor.awaitTermination(365, TimeUnit.DAYS); // Timeout should never happen
- tenants.putAll(addedTenants);
+ }
+
+ private void createTenant(TenantName tenantName) {
+ try {
+ Tenant tenant = TenantBuilder.create(globalComponentRegistry, tenantName, getTenantPath(tenantName)).build();
+ notifyNewTenant(tenant);
+ tenants.put(tenantName, tenant);
+ } catch (Exception e) {
+ log.log(LogLevel.WARNING, "Error loading tenant '" + tenantName + "', skipping.", e);
+ }
}
/**
@@ -239,7 +240,7 @@ public class Tenants implements ConnectionStateListener, PathChildrenCacheListen
* @param name name of the tenant
* @return this Tenants
*/
- public synchronized Tenants writeTenantPath(TenantName name) {
+ synchronized Tenants writeTenantPath(TenantName name) {
Path tenantPath = getTenantPath(name);
curator.createAtomically(tenantPath, tenantPath.append(Tenant.SESSIONS), tenantPath.append(Tenant.APPLICATIONS));
return this;
@@ -316,7 +317,7 @@ public class Tenants implements ConnectionStateListener, PathChildrenCacheListen
switch (event.getType()) {
case CHILD_ADDED:
case CHILD_REMOVED:
- tenantsChanged(readTenants());
+ createTenants();
break;
}
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java
index 88d7177a51e..e0d65055f21 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java
@@ -47,9 +47,9 @@ public class ConfigServerBootstrapTest extends TestWithTenant {
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Before
- public void setup() {
- tenants.writeTenantPath(tenant1);
- tenants.writeTenantPath(tenant2);
+ public void setup() throws Exception {
+ tenants.addTenant(tenant1);
+ tenants.addTenant(tenant2);
applicationRepository = new ApplicationRepository(tenants,
new SessionHandlerTest.MockProvisioner(),
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 afe51adee20..892c821950e 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
@@ -24,8 +24,6 @@ import com.yahoo.vespa.config.server.TestComponentRegistry;
import com.yahoo.vespa.config.server.application.ApplicationConvergenceChecker;
import com.yahoo.vespa.config.server.application.HttpProxy;
import com.yahoo.vespa.config.server.application.LogServerLogGrabber;
-import com.yahoo.vespa.config.server.application.TenantApplications;
-import com.yahoo.vespa.config.server.application.ZKTenantApplications;
import com.yahoo.vespa.config.server.http.HandlerTest;
import com.yahoo.vespa.config.server.http.HttpErrorResponse;
import com.yahoo.vespa.config.server.http.StaticResponse;
@@ -40,7 +38,6 @@ import com.yahoo.vespa.config.server.session.RemoteSession;
import com.yahoo.vespa.config.server.session.SessionContext;
import com.yahoo.vespa.config.server.session.SessionZooKeeperClient;
import com.yahoo.vespa.config.server.tenant.Tenant;
-import com.yahoo.vespa.config.server.tenant.TenantBuilder;
import com.yahoo.vespa.config.server.tenant.Tenants;
import com.yahoo.vespa.curator.mock.MockCurator;
import com.yahoo.vespa.model.VespaModelFactory;
@@ -279,7 +276,7 @@ public class ApplicationHandlerTest {
tenant.getRemoteSessionRepo().addSession(new RemoteSession(tenant.getName(), sessionId, componentRegistry, new MockSessionZKClient(app), clock));
}
- static Tenants addApplication(ApplicationId applicationId, long sessionId) throws Exception {
+ private static Tenants addApplication(ApplicationId applicationId, long sessionId) throws Exception {
// This method is a good illustration of the spaghetti wiring resulting from no design
// TODO: When this setup looks sane we have refactored sufficiently that there is a design
@@ -289,18 +286,15 @@ public class ApplicationHandlerTest {
Path sessionPath = tenantPath.append(Tenant.SESSIONS).append(String.valueOf(sessionId));
MockCurator curator = new MockCurator();
- GlobalComponentRegistry globalComponents = new TestComponentRegistry.Builder().curator(curator).build();
+ GlobalComponentRegistry componentRegistry = new TestComponentRegistry.Builder()
+ .curator(curator)
+ .modelFactoryRegistry(new ModelFactoryRegistry(
+ Collections.singletonList(new VespaModelFactory(new NullConfigModelRegistry()))))
+ .build();
- Tenants tenants = new Tenants(globalComponents, Metrics.createTestMetrics()); // Creates the application path element in zk
- tenants.writeTenantPath(tenantName);
- TenantApplications tenantApplications = ZKTenantApplications.create(curator,
- tenantPath.append(Tenant.APPLICATIONS),
- new MockReloadHandler(), // TODO: Use the real one
- tenantName);
- Tenant tenant = TenantBuilder.create(globalComponents, applicationId.tenant(), tenantPath)
- .withApplicationRepo(tenantApplications)
- .build();
- tenants.addTenant(tenant);
+ Tenants tenants = new Tenants(componentRegistry, Metrics.createTestMetrics()); // Creates the application path element in zk
+ tenants.addTenant(tenantName);
+ Tenant tenant = tenants.getTenant(tenantName);
tenant.getApplicationRepo().createPutApplicationTransaction(applicationId, sessionId).commit();
ApplicationPackage app = FilesApplicationPackage.fromFile(testApp);
@@ -317,11 +311,7 @@ public class ApplicationHandlerTest {
tenant.getRemoteSessionRepo().addSession(
new RemoteSession(tenantName, sessionId,
- new TestComponentRegistry.Builder()
- .curator(curator)
- .modelFactoryRegistry(new ModelFactoryRegistry(
- Collections.singletonList(new VespaModelFactory(new NullConfigModelRegistry()))))
- .build(),
+ componentRegistry,
sessionClient,
Clock.systemUTC()));
return tenants;
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListTenantsTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListTenantsTest.java
index 189314577e4..aa27dd0783c 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListTenantsTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ListTenantsTest.java
@@ -19,9 +19,9 @@ public class ListTenantsTest extends TenantTest {
@Test
public void testListTenants() throws Exception {
- tenants.writeTenantPath(a);
- tenants.writeTenantPath(b);
- tenants.writeTenantPath(c);
+ tenants.addTenant(a);
+ tenants.addTenant(b);
+ tenants.addTenant(c);
ListTenantsHandler listTenantsHandler = new ListTenantsHandler(testExecutor(), null, tenants);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java
index cf79770ad20..ca545611e7f 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/TenantHandlerTest.java
@@ -54,7 +54,7 @@ public class TenantHandlerTest extends TenantTest {
@Test
public void testGetExisting() throws Exception {
- tenants.writeTenantPath(a);
+ tenants.addTenant(a);
TenantGetResponse response = (TenantGetResponse) handler.handleGET(
HttpRequest.createTestRequest("http://deploy.example.yahoo.com:80/application/v2/tenant/a", Method.GET));
assertResponseEquals(response, "{\"message\":\"Tenant 'a' exists.\"}");
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantsTestCase.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantsTestCase.java
index a77b7615e6d..ce16ac14f60 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantsTestCase.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantsTestCase.java
@@ -3,8 +3,6 @@ package com.yahoo.vespa.config.server.tenant;
import com.yahoo.config.model.test.MockApplicationPackage;
import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.ApplicationName;
-import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Version;
import com.yahoo.vespa.config.server.application.ApplicationSet;
@@ -12,7 +10,6 @@ import com.yahoo.vespa.config.server.ServerCache;
import com.yahoo.vespa.config.server.TestComponentRegistry;
import com.yahoo.vespa.config.server.TestWithCurator;
import com.yahoo.vespa.config.server.application.Application;
-import com.yahoo.vespa.config.server.deploy.MockDeployer;
import com.yahoo.vespa.config.server.monitoring.MetricUpdater;
import com.yahoo.vespa.config.server.monitoring.Metrics;
import com.yahoo.vespa.model.VespaModel;
@@ -52,8 +49,8 @@ public class TenantsTestCase extends TestWithCurator {
tenantListener.tenantsLoaded = false;
tenants = new Tenants(globalComponentRegistry, Metrics.createTestMetrics());
assertTrue(tenantListener.tenantsLoaded);
- tenants.writeTenantPath(tenant1);
- tenants.writeTenantPath(tenant2);
+ tenants.addTenant(tenant1);
+ tenants.addTenant(tenant2);
}
@After
@@ -79,7 +76,7 @@ public class TenantsTestCase extends TestWithCurator {
@Test
public void testTenantListenersNotified() throws Exception {
- tenants.writeTenantPath(tenant3);
+ tenants.addTenant(tenant3);
assertThat("tenant3 not the last created tenant. Tenants: " + tenants.getAllTenantNames() + ", /config/v2/tenants: " + readZKChildren("/config/v2/tenants"), tenantListener.tenantCreatedName, is(tenant3));
tenants.deleteTenant(tenant2);
assertFalse(tenants.getAllTenantNames().contains(tenant2));
@@ -91,7 +88,7 @@ public class TenantsTestCase extends TestWithCurator {
Set<TenantName> allTenants = tenants.getAllTenantNames();
assertTrue(allTenants.contains(tenant1));
assertTrue(allTenants.contains(tenant2));
- tenants.writeTenantPath(tenant3);
+ tenants.addTenant(tenant3);
allTenants = tenants.getAllTenantNames();
assertTrue(allTenants.contains(tenant1));
assertTrue(allTenants.contains(tenant2));
@@ -100,7 +97,7 @@ public class TenantsTestCase extends TestWithCurator {
@Test
public void testPutAdd() throws Exception {
- tenants.writeTenantPath(tenant3);
+ tenants.addTenant(tenant3);
assertNotNull(globalComponentRegistry.getCurator().framework().checkExists().forPath(tenants.tenantZkPath(tenant3)));
}
@@ -115,29 +112,28 @@ public class TenantsTestCase extends TestWithCurator {
public void testTenantsChanged() throws Exception {
tenants.close(); // close the Tenants instance created in setupSession, we do not want to use one with a PatchChildrenCache listener
tenants = new Tenants(globalComponentRegistry, Metrics.createTestMetrics(), new ArrayList<>());
- Set<TenantName> newTenants = new LinkedHashSet<>();
TenantName defaultTenant = TenantName.defaultName();
- newTenants.add(tenant2);
- newTenants.add(defaultTenant);
- tenants.tenantsChanged(newTenants);
+ tenants.writeTenantPath(tenant2);
+ tenants.writeTenantPath(defaultTenant);
+ tenants.createTenants();
Set<TenantName> allTenants = tenants.getAllTenantNames();
assertTrue(allTenants.contains(tenant2));
assertEquals("default", defaultTenant.value());
assertTrue(allTenants.contains(defaultTenant));
- assertFalse(allTenants.contains(tenant1));
- newTenants.clear();
- tenants.tenantsChanged(newTenants);
+ tenants.deleteTenant(tenant1);
+ tenants.deleteTenant(tenant2);
+ tenants.deleteTenant(defaultTenant);
+ tenants.createTenants();
allTenants = tenants.getAllTenantNames();
assertFalse(allTenants.contains(tenant1));
assertFalse(allTenants.contains(tenant2));
assertFalse(allTenants.contains(defaultTenant));
- newTenants.clear();
TenantName foo = TenantName.from("foo");
TenantName bar = TenantName.from("bar");
- newTenants.add(tenant2);
- newTenants.add(foo);
- newTenants.add(bar);
- tenants.tenantsChanged(newTenants);
+ tenants.writeTenantPath(tenant2);
+ tenants.writeTenantPath(foo);
+ tenants.writeTenantPath(bar);
+ tenants.createTenants();
allTenants = tenants.getAllTenantNames();
assertTrue(allTenants.contains(tenant2));
assertTrue(allTenants.contains(foo));
diff --git a/container-di/src/main/scala/com/yahoo/container/di/Container.scala b/container-di/src/main/scala/com/yahoo/container/di/Container.scala
index c82625bae3b..c6812c52242 100644
--- a/container-di/src/main/scala/com/yahoo/container/di/Container.scala
+++ b/container-di/src/main/scala/com/yahoo/container/di/Container.scala
@@ -183,6 +183,9 @@ class Container(
val graph = new ComponentGraph(generation)
val componentsConfig = getConfig(componentsConfigKey, configsIncludingBootstrapConfigs)
+ if (componentsConfig == null)
+ throw new ConfigurationRuntimeException(
+ "The set of all configs does not include a valid 'components' config. Config set: " + configsIncludingBootstrapConfigs.keySet)
addNodes(componentsConfig, graph)
injectNodes(componentsConfig, graph)
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java
index 7874fcd8c45..fdebcca6d83 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/DeploymentIssues.java
@@ -1,6 +1,7 @@
// 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.api.integration.organization;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
@@ -19,7 +20,7 @@ public interface DeploymentIssues {
IssueId fileUnlessOpen(Optional<IssueId> issueId, ApplicationId applicationId, User assignee);
- IssueId fileUnlessOpen(Collection<ApplicationId> applicationIds);
+ IssueId fileUnlessOpen(Collection<ApplicationId> applicationIds, Version version);
void escalateIfInactive(IssueId issueId, Optional<PropertyId> propertyId, Duration maxInactivity);
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockOrganization.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockOrganization.java
index 4eaca8fb642..5584f8a95fb 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockOrganization.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/organization/MockOrganization.java
@@ -85,7 +85,7 @@ public class MockOrganization implements Organization {
@Override
public List<? extends List<? extends User>> contactsFor(PropertyId propertyId) {
- return properties.get(propertyId).contacts;
+ return properties.getOrDefault(propertyId, new PropertyInfo()).contacts;
}
@Override
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java
index 62dde3efe55..783a1267e64 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/stubs/LoggingDeploymentIssues.java
@@ -3,6 +3,7 @@
package com.yahoo.vespa.hosted.controller.api.integration.stubs;
import com.google.inject.Inject;
+import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.hosted.controller.api.identifiers.PropertyId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.DeploymentIssues;
@@ -62,9 +63,9 @@ public class LoggingDeploymentIssues implements DeploymentIssues {
}
@Override
- public IssueId fileUnlessOpen(Collection<ApplicationId> applicationIds) {
+ public IssueId fileUnlessOpen(Collection<ApplicationId> applicationIds, Version version) {
if ( ! platformIssue.get())
- log.info("These applications are all failing deployment:\n" + applicationIds);
+ log.info("These applications are all failing deployment to version " + version + ":\n" + applicationIds);
platformIssue.set(true);
return null;
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java
index 6f5116a1825..ee8e1b19e58 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Application.java
@@ -155,15 +155,18 @@ public class Application {
outstandingChange);
}
- public Application withJobTriggering(JobType type, Optional<Change> change, Instant triggerTime, Controller controller) {
+ public Application withJobTriggering(long runId, JobType type, Optional<Change> change, String reason,
+ Instant triggerTime, Controller controller) {
return new Application(id,
deploymentSpec,
validationOverrides,
deployments,
deploymentJobs.withTriggering(type,
change,
+ runId,
determineTriggerVersion(type, controller),
determineTriggerRevision(type, controller),
+ reason,
triggerTime),
deploying,
outstandingChange);
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 1ff6802f0ab..3339e59d581 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
@@ -296,14 +296,17 @@ public class ApplicationController {
application = application.withProjectId(options.screwdriverBuildJob.get().screwdriverId.value());
if (application.deploying().isPresent() && application.deploying().get() instanceof Change.ApplicationChange)
application = application.withDeploying(Optional.of(Change.ApplicationChange.of(revision)));
- if ( ! triggeredWith(revision, application, jobType) && !canDeployDirectlyTo(zone, options) && jobType != null) {
- // Triggering information is used to store which changes were made or attempted
- // - For all applications, we don't have complete control over which revision is actually built,
- // so we update it here with what we actually triggered if necessary
+ if ( ! canDeployDirectlyTo(zone, options) && jobType != null) {
+ // Update with (potentially) missing information about what we triggered
+ JobStatus.JobRun triggering = getOrCreateTriggering(application, version, jobType);
application = application.with(application.deploymentJobs()
- .withTriggering(jobType, application.deploying(),
- version, Optional.of(revision),
- clock.instant()));
+ .withTriggering(jobType,
+ application.deploying(),
+ triggering.id(),
+ version,
+ Optional.of(revision),
+ triggering.reason(),
+ triggering.at()));
}
// Delete zones not listed in DeploymentSpec, if allowed
@@ -390,14 +393,21 @@ public class ApplicationController {
return application;
}
- private boolean triggeredWith(ApplicationRevision revision, Application application, DeploymentJobs.JobType jobType) {
- if (jobType == null) return false;
+ /**
+ * Returns the existing triggering of the given type from this application,
+ * or an incomplete one created in this method if none is present
+ * This is needed (only) in the case where some external entity triggers a job.
+ */
+ private JobStatus.JobRun getOrCreateTriggering(Application application, Version version, DeploymentJobs.JobType jobType) {
+ if (jobType == null) return incompleteTriggeringEvent(version);
JobStatus status = application.deploymentJobs().jobStatus().get(jobType);
- if (status == null) return false;
- if ( ! status.lastTriggered().isPresent()) return false;
- JobStatus.JobRun triggered = status.lastTriggered().get();
- if ( ! triggered.revision().isPresent()) return false;
- return triggered.revision().get().equals(revision);
+ if (status == null) return incompleteTriggeringEvent(version);
+ if ( ! status.lastTriggered().isPresent()) return incompleteTriggeringEvent(version);
+ return status.lastTriggered().get();
+ }
+
+ private JobStatus.JobRun incompleteTriggeringEvent(Version version) {
+ return new JobStatus.JobRun(-1, version, Optional.empty(), false, "", clock.instant());
}
private DeployOptions withVersion(Version version, DeployOptions options) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/DeploymentJobs.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/DeploymentJobs.java
index 68e0ce39c5c..8f654c66871 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/DeploymentJobs.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/DeploymentJobs.java
@@ -59,21 +59,26 @@ public class DeploymentJobs {
Map<JobType, JobStatus> status = new LinkedHashMap<>(this.status);
status.compute(report.jobType(), (type, job) -> {
if (job == null) job = JobStatus.initial(report.jobType());
- return job.withCompletion(report.jobError(), notificationTime, controller);
+ return job.withCompletion(report.buildNumber(), report.jobError(), notificationTime, controller);
});
return new DeploymentJobs(Optional.of(report.projectId()), status, issueId);
}
public DeploymentJobs withTriggering(JobType jobType,
Optional<Change> change,
+ long runId,
Version version,
Optional<ApplicationRevision> revision,
+ String reason,
Instant triggerTime) {
Map<JobType, JobStatus> status = new LinkedHashMap<>(this.status);
status.compute(jobType, (type, job) -> {
if (job == null) job = JobStatus.initial(jobType);
- return job.withTriggering(version, revision,
+ return job.withTriggering(runId,
+ version,
+ revision,
change.isPresent() && change.get() instanceof Change.VersionChange,
+ reason,
triggerTime);
});
return new DeploymentJobs(projectId, status, issueId);
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/JobStatus.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/JobStatus.java
index 0b81a45922c..929bf186eea 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/JobStatus.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/JobStatus.java
@@ -56,20 +56,22 @@ public class JobStatus {
return new JobStatus(type, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty());
}
- public JobStatus withTriggering(Version version, Optional<ApplicationRevision> revision, boolean upgrade,
- Instant triggerTime) {
- return new JobStatus(type, jobError, Optional.of(new JobRun(version, revision, upgrade, triggerTime)),
+ public JobStatus withTriggering(long runId, Version version, Optional<ApplicationRevision> revision,
+ boolean upgrade, String reason, Instant triggerTime) {
+ return new JobStatus(type, jobError, Optional.of(new JobRun(runId, version, revision, upgrade, reason, triggerTime)),
lastCompleted, firstFailing, lastSuccess);
}
- public JobStatus withCompletion(Optional<DeploymentJobs.JobError> jobError, Instant completionTime, Controller controller) {
+ public JobStatus withCompletion(long runId, Optional<DeploymentJobs.JobError> jobError, Instant completionTime, Controller controller) {
Version version;
Optional<ApplicationRevision> revision;
boolean upgrade;
+ String reason;
if (type == DeploymentJobs.JobType.component) { // not triggered by us
version = controller.systemVersion();
revision = Optional.empty();
upgrade = false;
+ reason = "Application commit";
}
else if (! lastTriggered.isPresent()) {
throw new IllegalStateException("Got notified about completion of " + this +
@@ -80,9 +82,10 @@ public class JobStatus {
version = lastTriggered.get().version();
revision = lastTriggered.get().revision();
upgrade = lastTriggered.get().upgrade();
+ reason = lastTriggered.get().reason();
}
- JobRun thisCompletion = new JobRun(version, revision, upgrade, completionTime);
+ JobRun thisCompletion = new JobRun(runId, version, revision, upgrade, reason, completionTime);
Optional<JobRun> firstFailing = this.firstFailing;
if (jobError.isPresent() && ! this.firstFailing.isPresent())
@@ -168,31 +171,43 @@ public class JobStatus {
/** Information about a particular triggering or completion of a run of a job. This is immutable. */
public static class JobRun {
+ private final long id;
private final Version version;
private final Optional<ApplicationRevision> revision;
- private final Instant at;
private final boolean upgrade;
+ private final String reason;
+ private final Instant at;
- public JobRun(Version version, Optional<ApplicationRevision> revision, boolean upgrade, Instant at) {
+ public JobRun(long id, Version version, Optional<ApplicationRevision> revision,
+ boolean upgrade, String reason, Instant at) {
Objects.requireNonNull(version, "version cannot be null");
Objects.requireNonNull(revision, "revision cannot be null");
+ Objects.requireNonNull(reason, "Reason cannot be null");
Objects.requireNonNull(at, "at cannot be null");
+ this.id = id;
this.version = version;
this.revision = revision;
this.upgrade = upgrade;
+ this.reason = reason;
this.at = at;
}
+
+ /** Returns the id of this run of this job, or -1 if not known */
+ public long id() { return id; }
/** Returns whether this job run was a Vespa upgrade */
public boolean upgrade() { return upgrade; }
- /** The Vespa version used on this run */
+ /** Returns the Vespa version used on this run */
public Version version() { return version; }
- /** The application revision used for this run, or empty when not known */
+ /** Returns the application revision used for this run, or empty when not known */
public Optional<ApplicationRevision> revision() { return revision; }
- /** The time if this triggering or completion */
+ /** Returns a human-readable reason for this particular job run */
+ public String reason() { return reason; }
+
+ /** Returns the time if this triggering or completion */
public Instant at() { return at; }
@Override
@@ -203,16 +218,17 @@ public class JobStatus {
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof JobRun)) return false;
+ if ( ! (o instanceof JobRun)) return false;
JobRun jobRun = (JobRun) o;
- return upgrade == jobRun.upgrade &&
+ return id == id &&
Objects.equals(version, jobRun.version) &&
Objects.equals(revision, jobRun.revision) &&
+ upgrade == jobRun.upgrade &&
Objects.equals(at, jobRun.at);
}
@Override
- public String toString() { return "job run of version " + (upgrade() ? "upgrade " : "") + version + " "
+ public String toString() { return "job run " + id + " of version " + (upgrade() ? "upgrade " : "") + version + " "
+ revision + " at " + at; }
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
index 6b37c20f2b5..11074e1a68e 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTrigger.java
@@ -243,7 +243,7 @@ public class DeploymentTrigger {
Application application = applications().require(applicationId);
if (application.deploying().isPresent() && ! application.deploymentJobs().hasFailures())
throw new IllegalArgumentException("Could not start " + change + " on " + application + ": " +
- application.deploying() + " is already in progress");
+ application.deploying().get() + " is already in progress");
application = application.withDeploying(Optional.of(change));
if (change instanceof Change.ApplicationChange)
application = application.withOutstandingChange(false);
@@ -362,27 +362,27 @@ public class DeploymentTrigger {
* @param jobType the type of the job to trigger, or null to trigger nothing
* @param application the application to trigger the job for
* @param first whether to trigger the job before other jobs
- * @param force true to diable checks which should normally prevent this triggering from happening
- * @param cause describes why the job is triggered
+ * @param force true to disable checks which should normally prevent this triggering from happening
+ * @param reason describes why the job is triggered
* @return the application in the triggered state, if actually triggered. This *must* be stored by the caller
*/
public Application triggerAllowParallel(JobType jobType, Application application,
- boolean first, boolean force, String cause, Lock lock) {
+ boolean first, boolean force, String reason, Lock lock) {
if (jobType == null) return application; // we are passed null when the last job has been reached
// Never allow untested changes to go through
// Note that this may happen because a new change catches up and prevents an older one from continuing
if ( ! application.deploymentJobs().isDeployableTo(jobType.environment(), application.deploying())) {
log.warning(String.format("Want to trigger %s for %s with reason %s, but change is untested", jobType,
- application, cause));
+ application, reason));
return application;
}
if ( ! force && ! allowedTriggering(jobType, application)) return application;
log.info(String.format("Triggering %s for %s, %s: %s", jobType, application,
application.deploying().map(d -> "deploying " + d).orElse("restarted deployment"),
- cause));
+ reason));
buildSystem.addJob(application.id(), jobType, first);
- return application.withJobTriggering(jobType, application.deploying(), clock.instant(), controller);
+ return application.withJobTriggering(-1, jobType, application.deploying(), reason, clock.instant(), controller);
}
/** Returns true if the given proposed job triggering should be effected */
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java
index 48033645573..23068b9567f 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporter.java
@@ -71,7 +71,8 @@ public class DeploymentIssueReporter extends Maintainer {
.upgradingTo(controller().systemVersion())
.asList().stream()
.map(Application::id)
- .collect(Collectors.toList()));
+ .collect(Collectors.toList()),
+ controller().systemVersion());
}
private boolean oldApplicationChangeFailuresIn(DeploymentJobs jobs) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
index fa4341b8e25..3bd1abdf607 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
@@ -78,10 +78,12 @@ public class ApplicationSerializer {
private final String lastSuccessField = "lastSuccess";
// JobRun fields
+ private final String jobRunIdField = "id";
private final String versionField = "version";
private final String revisionField = "revision";
- private final String atField = "at";
private final String upgradeField = "upgrade";
+ private final String reasonField = "reason";
+ private final String atField = "at";
// ClusterInfo fields
private final String clusterInfoField = "clusterInfo";
@@ -226,10 +228,12 @@ public class ApplicationSerializer {
private void jobRunToSlime(Optional<JobStatus.JobRun> jobRun, Cursor parent, String jobRunObjectName) {
if ( ! jobRun.isPresent()) return;
Cursor object = parent.setObject(jobRunObjectName);
+ object.setLong(jobRunIdField, jobRun.get().id());
object.setString(versionField, jobRun.get().version().toString());
if ( jobRun.get().revision().isPresent())
toSlime(jobRun.get().revision().get(), object.setObject(revisionField));
object.setBool(upgradeField, jobRun.get().upgrade());
+ object.setString(reasonField, jobRun.get().reason());
object.setLong(atField, jobRun.get().at().toEpochMilli());
}
@@ -384,9 +388,11 @@ public class ApplicationSerializer {
private Optional<JobStatus.JobRun> jobRunFromSlime(Inspector object) {
if ( ! object.valid()) return Optional.empty();
- return Optional.of(new JobStatus.JobRun(new Version(object.field(versionField).asString()),
+ return Optional.of(new JobStatus.JobRun(optionalLong(object.field(jobRunIdField)).orElse(-1L), // TODO: Make non-optional after November 2017
+ new Version(object.field(versionField).asString()),
applicationRevisionFromSlime(object.field(revisionField)),
object.field(upgradeField).asBool(),
+ optionalString(object.field(reasonField)).orElse(""), // TODO: Make non-optional after November 2017
Instant.ofEpochMilli(object.field(atField).asLong())));
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ErrorResponse.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ErrorResponse.java
index a9643e21c00..4af833baa98 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ErrorResponse.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/ErrorResponse.java
@@ -11,6 +11,7 @@ import static com.yahoo.jdisc.Response.Status.FORBIDDEN;
import static com.yahoo.jdisc.Response.Status.INTERNAL_SERVER_ERROR;
import static com.yahoo.jdisc.Response.Status.METHOD_NOT_ALLOWED;
import static com.yahoo.jdisc.Response.Status.NOT_FOUND;
+import static com.yahoo.jdisc.Response.Status.UNAUTHORIZED;
/**
* A HTTP JSON response containing an error code and a message
@@ -24,7 +25,8 @@ public class ErrorResponse extends SlimeJsonResponse {
BAD_REQUEST,
FORBIDDEN,
METHOD_NOT_ALLOWED,
- INTERNAL_SERVER_ERROR
+ INTERNAL_SERVER_ERROR,
+ UNAUTHORIZED
}
public ErrorResponse(int statusCode, String errorType, String message) {
@@ -55,6 +57,10 @@ public class ErrorResponse extends SlimeJsonResponse {
return new ErrorResponse(FORBIDDEN, errorCodes.FORBIDDEN.name(), message);
}
+ public static ErrorResponse unauthorized(String message) {
+ return new ErrorResponse(UNAUTHORIZED, errorCodes.UNAUTHORIZED.name(), message);
+ }
+
public static ErrorResponse methodNotAllowed(String message) {
return new ErrorResponse(METHOD_NOT_ALLOWED, errorCodes.METHOD_NOT_ALLOWED.name(), message);
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index 6ae9761b305..a259e221a1e 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -67,7 +67,6 @@ import com.yahoo.vespa.hosted.controller.application.DeploymentMetrics;
import com.yahoo.vespa.hosted.controller.application.JobStatus;
import com.yahoo.vespa.hosted.controller.application.SourceRevision;
import com.yahoo.vespa.hosted.controller.athenz.AthenzClientFactory;
-import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
import com.yahoo.vespa.hosted.controller.athenz.NToken;
import com.yahoo.vespa.hosted.controller.athenz.ZmsException;
import com.yahoo.vespa.hosted.controller.restapi.ErrorResponse;
@@ -82,6 +81,7 @@ import com.yahoo.yolean.Exceptions;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.ForbiddenException;
+import javax.ws.rs.NotAuthorizedException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
@@ -140,6 +140,9 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
catch (ForbiddenException e) {
return ErrorResponse.forbidden(Exceptions.toMessageString(e));
}
+ catch (NotAuthorizedException e) {
+ return ErrorResponse.unauthorized(Exceptions.toMessageString(e));
+ }
catch (NotExistsException e) {
return ErrorResponse.notFoundError(Exceptions.toMessageString(e));
}
@@ -780,25 +783,8 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
DeployAuthorizer deployAuthorizer = new DeployAuthorizer(controller.zoneRegistry(), athenzClientFactory);
Tenant tenant = controller.tenants().tenant(new TenantId(tenantName)).orElseThrow(() -> new NotExistsException(new TenantId(tenantName)));
Principal principal = authorizer.getPrincipal(request);
- if (principal instanceof AthenzPrincipal) {
- deployAuthorizer.throwIfUnauthorizedForDeploy(principal,
- Environment.from(environment),
- tenant,
- applicationId);
- } else { // In case of host-based principal
- // TODO What about other user type principals like Bouncer?
- log.log(LogLevel.WARNING,
- "Using deprecated DeployAuthorizer.throwIfUnauthorizedForDeploy. Principal=" + principal);
- UserId userId = new UserId(principal.getName());
- deployAuthorizer.throwIfUnauthorizedForDeploy(
- Environment.from(environment),
- userId,
- tenant,
- applicationId,
- optional("screwdriverBuildJob", deployOptions).map(ScrewdriverId::new));
- }
+ deployAuthorizer.throwIfUnauthorizedForDeploy(principal, Environment.from(environment), tenant, applicationId);
-
// TODO: get rid of the json object
DeployOptions deployOptionsJsonClass = new DeployOptions(screwdriverBuildJobFromSlime(deployOptions.field("screwdriverBuildJob")),
optional("vespaVersion", deployOptions).map(Version::new),
@@ -957,8 +943,10 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
}
private void toSlime(JobStatus.JobRun jobRun, Cursor object) {
+ object.setLong("id", jobRun.id());
object.setString("version", jobRun.version().toFullString());
jobRun.revision().ifPresent(revision -> toSlime(revision, object.setObject("revision")));
+ object.setString("reason", jobRun.reason());
object.setLong("at", jobRun.at().toEpochMilli());
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java
index 93dc2541385..0c808e30c2a 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/Authorizer.java
@@ -1,7 +1,6 @@
// 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.restapi.application;
-import com.google.common.collect.ImmutableSet;
import com.yahoo.config.provision.Environment;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.vespa.hosted.controller.Controller;
@@ -12,19 +11,16 @@ import com.yahoo.vespa.hosted.controller.api.identifiers.UserGroup;
import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
import com.yahoo.vespa.hosted.controller.api.integration.entity.EntityService;
import com.yahoo.vespa.hosted.controller.athenz.AthenzClientFactory;
-import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils;
import com.yahoo.vespa.hosted.controller.athenz.NToken;
import com.yahoo.vespa.hosted.controller.common.ContextAttributes;
import com.yahoo.vespa.hosted.controller.restapi.filter.NTokenRequestFilter;
-import com.yahoo.vespa.hosted.controller.restapi.filter.UnauthenticatedUserPrincipal;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.SecurityContext;
import java.security.Principal;
import java.util.Optional;
-import java.util.Set;
import java.util.logging.Logger;
@@ -41,11 +37,6 @@ public class Authorizer {
// Must be kept in sync with bouncer filter configuration.
private static final String VESPA_HOSTED_ADMIN_ROLE = "10707.A";
- private static final Set<UserId> SCREWDRIVER_USERS = ImmutableSet.of(new UserId("screwdrv"),
- new UserId("screwdriver"),
- new UserId("sdrvtest"),
- new UserId("screwdriver-test"));
-
private final Controller controller;
private final AthenzClientFactory athenzClientFactory;
private final EntityService entityService;
@@ -92,17 +83,8 @@ public class Authorizer {
}
public boolean isSuperUser(HttpRequest request) {
- // TODO Check membership of admin role in Vespa's Athenz domain
- return isMemberOfVespaBouncerGroup(request) || isScrewdriverPrincipal(getPrincipal(request));
- }
-
- public static boolean isScrewdriverPrincipal(Principal principal) {
- if (principal instanceof UnauthenticatedUserPrincipal) // Host-based authentication
- return SCREWDRIVER_USERS.contains(new UserId(principal.getName()));
- else if (principal instanceof AthenzPrincipal)
- return ((AthenzPrincipal)principal).getDomain().equals(AthenzUtils.SCREWDRIVER_DOMAIN);
- else
- return false;
+ // TODO Replace check with membership of a dedicated 'hosted Vespa super-user' role in Vespa's Athenz domain
+ return isMemberOfVespaBouncerGroup(request);
}
private static ForbiddenException loggedForbiddenException(String message, Object... args) {
@@ -149,6 +131,8 @@ public class Authorizer {
return method.equals(HttpMethod.GET) || method.equals(HttpMethod.HEAD) || method.equals(HttpMethod.OPTIONS);
}
+ @Deprecated
+ // TODO Remove this method. Stop using Bouncer for authorization and use Athenz instead
private boolean isMemberOfVespaBouncerGroup(HttpRequest request) {
Optional<SecurityContext> securityContext = securityContextOf(request);
if ( ! securityContext.isPresent() ) throw Authorizer.loggedForbiddenException("User is not authenticated");
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/DeployAuthorizer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/DeployAuthorizer.java
index 7cf19629774..71126259417 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/DeployAuthorizer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/DeployAuthorizer.java
@@ -5,23 +5,19 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Environment;
import com.yahoo.vespa.hosted.controller.api.Tenant;
import com.yahoo.vespa.hosted.controller.api.identifiers.AthenzDomain;
-import com.yahoo.vespa.hosted.controller.api.identifiers.ScrewdriverId;
-import com.yahoo.vespa.hosted.controller.api.identifiers.UserId;
import com.yahoo.vespa.hosted.controller.api.integration.zone.ZoneRegistry;
import com.yahoo.vespa.hosted.controller.athenz.ApplicationAction;
import com.yahoo.vespa.hosted.controller.athenz.AthenzClientFactory;
import com.yahoo.vespa.hosted.controller.athenz.AthenzPrincipal;
import com.yahoo.vespa.hosted.controller.athenz.AthenzUtils;
import com.yahoo.vespa.hosted.controller.athenz.ZmsException;
-import com.yahoo.vespa.hosted.controller.restapi.filter.UnauthenticatedUserPrincipal;
import javax.ws.rs.ForbiddenException;
+import javax.ws.rs.NotAuthorizedException;
import java.security.Principal;
-import java.util.Optional;
import java.util.logging.Logger;
import static com.yahoo.vespa.hosted.controller.restapi.application.Authorizer.environmentRequiresAuthorization;
-import static com.yahoo.vespa.hosted.controller.restapi.application.Authorizer.isScrewdriverPrincipal;
/**
* @author bjorncs
@@ -43,36 +39,40 @@ public class DeployAuthorizer {
Environment environment,
Tenant tenant,
ApplicationId applicationId) {
- if (athenzCredentialsRequired(environment, tenant, applicationId, principal))
- checkAthenzCredentials(principal, tenant, applicationId);
- }
-
- // TODO: inline when deployment via ssh is removed
- private boolean athenzCredentialsRequired(Environment environment, Tenant tenant, ApplicationId applicationId, Principal principal) {
- if (!environmentRequiresAuthorization(environment)) return false;
-
- if (! isScrewdriverPrincipal(principal))
- throw loggedForbiddenException(
- "Principal '%s' is not a screwdriver principal, and does not have deploy access to application '%s'",
- principal.getName(), applicationId.toShortString());
+ if (!environmentRequiresAuthorization(environment)) {
+ return;
+ }
- return tenant.isAthensTenant();
- }
+ if (principal == null) {
+ throw loggedUnauthorizedException("Principal not authenticated!");
+ }
+ if (!(principal instanceof AthenzPrincipal)) {
+ throw loggedUnauthorizedException(
+ "Principal '%s' of type '%s' is not an Athenz principal, which is required for production deployments.",
+ principal.getName(), principal.getClass().getSimpleName());
+ }
- // TODO: inline when deployment via ssh is removed
- private void checkAthenzCredentials(Principal principal, Tenant tenant, ApplicationId applicationId) {
- AthenzDomain domain = tenant.getAthensDomain().get();
- if (! (principal instanceof AthenzPrincipal))
- throw loggedForbiddenException("Principal '%s' is not authenticated.", principal.getName());
+ AthenzPrincipal athenzPrincipal = (AthenzPrincipal) principal;
+ AthenzDomain principalDomain = athenzPrincipal.getDomain();
- AthenzPrincipal athensPrincipal = (AthenzPrincipal)principal;
- if ( ! hasDeployAccessToAthenzApplication(athensPrincipal, domain, applicationId))
+ if (!principalDomain.equals(AthenzUtils.SCREWDRIVER_DOMAIN)) {
throw loggedForbiddenException(
- "Screwdriver principal '%1$s' does not have deploy access to '%2$s'. " +
- "Either the application has not been created at " + zoneRegistry.getDashboardUri() + " or " +
- "'%1$s' is not added to the application's deployer role in Athens domain '%3$s'.",
- athensPrincipal, applicationId, tenant.getAthensDomain().get());
+ "Principal '%s' is not a Screwdriver principal. Excepted principal with Athenz domain '%s', got '%s'.",
+ principal.getName(), AthenzUtils.SCREWDRIVER_DOMAIN.id(), principalDomain.id());
+ }
+
+ // NOTE: no fine-grained deploy authorization for non-Athenz tenants
+ if (tenant.isAthensTenant()) {
+ AthenzDomain tenantDomain = tenant.getAthensDomain().get();
+ if (!hasDeployAccessToAthenzApplication(athenzPrincipal, tenantDomain, applicationId)) {
+ throw loggedForbiddenException(
+ "Screwdriver principal '%1$s' does not have deploy access to '%2$s'. " +
+ "Either the application has not been created at " + zoneRegistry.getDashboardUri() + " or " +
+ "'%1$s' is not added to the application's deployer role in Athenz domain '%3$s'.",
+ athenzPrincipal.toYRN(), applicationId, tenantDomain.id());
+ }
+ }
}
private static ForbiddenException loggedForbiddenException(String message, Object... args) {
@@ -81,23 +81,10 @@ public class DeployAuthorizer {
return new ForbiddenException(formattedMessage);
}
- /**
- * @deprecated Only usable for ssh. Use the method that takes Principal instead of UserId and screwdriverId.
- */
- @Deprecated
- public void throwIfUnauthorizedForDeploy(Environment environment,
- UserId userId,
- Tenant tenant,
- ApplicationId applicationId,
- Optional<ScrewdriverId> optionalScrewdriverId) {
- Principal principal = new UnauthenticatedUserPrincipal(userId.id());
-
- if (athenzCredentialsRequired(environment, tenant, applicationId, principal)) {
- ScrewdriverId screwdriverId = optionalScrewdriverId.orElseThrow(
- () -> loggedForbiddenException("Screwdriver id must be provided when deploying from Screwdriver."));
- principal = AthenzUtils.createPrincipal(screwdriverId);
- checkAthenzCredentials(principal, tenant, applicationId);
- }
+ private static NotAuthorizedException loggedUnauthorizedException(String message, Object... args) {
+ String formattedMessage = String.format(message, args);
+ log.info(formattedMessage);
+ return new NotAuthorizedException(formattedMessage);
}
private boolean hasDeployAccessToAthenzApplication(AthenzPrincipal principal, AthenzDomain domain, ApplicationId applicationId) {
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
index 30d07bed50f..572e96edf1c 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/ControllerTest.java
@@ -104,12 +104,12 @@ public class ControllerTest {
Optional<ApplicationRevision> revision = ((Change.ApplicationChange)tester.controller().applications().require(app1.id()).deploying().get()).revision();
assertTrue("Revision has been set during deployment", revision.isPresent());
assertStatus(JobStatus.initial(stagingTest)
- .withTriggering(version1, revision, false, tester.clock().instant())
- .withCompletion(Optional.empty(), tester.clock().instant(), tester.controller()), app1.id(), tester.controller());
+ .withTriggering(-1, version1, revision, false, "", tester.clock().instant())
+ .withCompletion(-1, Optional.empty(), tester.clock().instant(), tester.controller()), app1.id(), tester.controller());
// Causes first deployment job to be triggered
assertStatus(JobStatus.initial(productionCorpUsEast1)
- .withTriggering(version1, revision, false, tester.clock().instant()), app1.id(), tester.controller());
+ .withTriggering(-1, version1, revision, false, "", tester.clock().instant()), app1.id(), tester.controller());
tester.clock().advance(Duration.ofSeconds(1));
// production job (failing)
@@ -117,9 +117,9 @@ public class ControllerTest {
assertEquals(4, applications.require(app1.id()).deploymentJobs().jobStatus().size());
JobStatus expectedJobStatus = JobStatus.initial(productionCorpUsEast1)
- .withTriggering(version1, revision, false, tester.clock().instant()) // Triggered first without revision info
- .withCompletion(Optional.of(JobError.unknown), tester.clock().instant(), tester.controller())
- .withTriggering(version1, revision, false, tester.clock().instant()); // Re-triggering (due to failure) has revision info
+ .withTriggering(-1, version1, revision, false, "", tester.clock().instant()) // Triggered first without revision info
+ .withCompletion(-1, Optional.of(JobError.unknown), tester.clock().instant(), tester.controller())
+ .withTriggering(-1, version1, revision, false, "", tester.clock().instant()); // Re-triggering (due to failure) has revision info
assertStatus(expectedJobStatus, app1.id(), tester.controller());
@@ -139,20 +139,20 @@ public class ControllerTest {
applications.notifyJobCompletion(mockReport(app1, component, true));
tester.deployAndNotify(app1, applicationPackage, true, false, systemTest);
assertStatus(JobStatus.initial(systemTest)
- .withTriggering(version1, revision, false, tester.clock().instant())
- .withCompletion(Optional.empty(), tester.clock().instant(), tester.controller()), app1.id(), tester.controller());
+ .withTriggering(-1, version1, revision, false, "", tester.clock().instant())
+ .withCompletion(-1, Optional.empty(), tester.clock().instant(), tester.controller()), app1.id(), tester.controller());
tester.deployAndNotify(app1, applicationPackage, true, stagingTest);
// production job succeeding now
tester.deployAndNotify(app1, applicationPackage, true, productionCorpUsEast1);
expectedJobStatus = expectedJobStatus
- .withTriggering(version1, revision, false, tester.clock().instant())
- .withCompletion(Optional.empty(), tester.clock().instant(), tester.controller());
+ .withTriggering(-1, version1, revision, false, "", tester.clock().instant())
+ .withCompletion(-1, Optional.empty(), tester.clock().instant(), tester.controller());
assertStatus(expectedJobStatus, app1.id(), tester.controller());
// causes triggering of next production job
assertStatus(JobStatus.initial(productionUsEast3)
- .withTriggering(version1, revision, false, tester.clock().instant()),
+ .withTriggering(-1, version1, revision, false, "", tester.clock().instant()),
app1.id(), tester.controller());
tester.deployAndNotify(app1, applicationPackage, true, productionUsEast3);
@@ -173,7 +173,10 @@ public class ControllerTest {
}
assertNotNull("Zone was not removed",
applications.require(app1.id()).deployments().get(productionCorpUsEast1.zone(SystemName.main).get()));
- assertNotNull("Deployment job was not removed", applications.require(app1.id()).deploymentJobs().jobStatus().get(productionCorpUsEast1));
+ JobStatus jobStatus = applications.require(app1.id()).deploymentJobs().jobStatus().get(productionCorpUsEast1);
+ assertNotNull("Deployment job was not removed", jobStatus);
+ assertEquals(42, jobStatus.lastCompleted().get().id());
+ assertEquals("stagingTest completed successfully in build 42", jobStatus.lastCompleted().get().reason());
// prod zone removal is allowed with override
applicationPackage = new ApplicationPackageBuilder()
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporterTest.java
index b4a2aa3fc19..afafe4be82b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporterTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/DeploymentIssueReporterTest.java
@@ -8,7 +8,6 @@ import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
import com.yahoo.vespa.hosted.controller.api.integration.stubs.LoggingDeploymentIssues;
import com.yahoo.vespa.hosted.controller.application.ApplicationPackage;
-import com.yahoo.vespa.hosted.controller.application.Change;
import com.yahoo.vespa.hosted.controller.deployment.ApplicationPackageBuilder;
import com.yahoo.vespa.hosted.controller.deployment.DeploymentTester;
import com.yahoo.vespa.hosted.controller.persistence.MockCuratorDb;
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
index f7fd7cb6fb1..f65996feac8 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
@@ -68,11 +68,11 @@ public class ApplicationSerializerTest {
List<JobStatus> statusList = new ArrayList<>();
statusList.add(JobStatus.initial(DeploymentJobs.JobType.systemTest)
- .withTriggering(Version.fromString("5.6.7"), Optional.empty(), true, Instant.ofEpochMilli(7))
- .withCompletion(Optional.empty(), Instant.ofEpochMilli(8), tester.controller()));
+ .withTriggering(37, Version.fromString("5.6.7"), Optional.empty(), true, "Test", Instant.ofEpochMilli(7))
+ .withCompletion(30, Optional.empty(), Instant.ofEpochMilli(8), tester.controller()));
statusList.add(JobStatus.initial(DeploymentJobs.JobType.stagingTest)
- .withTriggering(Version.fromString("5.6.6"), Optional.empty(), true, Instant.ofEpochMilli(5))
- .withCompletion(Optional.of(JobError.unknown), Instant.ofEpochMilli(6), tester.controller()));
+ .withTriggering(12, Version.fromString("5.6.6"), Optional.empty(), true, "Test 2", Instant.ofEpochMilli(5))
+ .withCompletion(11, Optional.of(JobError.unknown), Instant.ofEpochMilli(6), tester.controller()));
DeploymentJobs deploymentJobs = new DeploymentJobs(projectId, statusList, Optional.empty());
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index b36a88ca1d4..eeeed08c2b8 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -577,7 +577,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
entity,
Request.Method.POST,
athenzUserDomain, "mytenant"),
- "{\"error-code\":\"FORBIDDEN\",\"message\":\"Principal 'mytenant' is not a screwdriver principal, and does not have deploy access to application 'tenant1.application1'\"}",
+ "{\"error-code\":\"FORBIDDEN\",\"message\":\"Principal 'mytenant' is not a Screwdriver principal. Excepted principal with Athenz domain 'cd.screwdriver.project', got 'domain1'.\"}",
403);
// Deleting an application for an Athens domain the user is not admin for is disallowed
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json
index a82bdaa454a..fe9c373b7d5 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json
@@ -4,11 +4,15 @@
"type": "component",
"success": true,
"lastCompleted": {
+ "id": 42,
"version": "(ignore)",
+ "reason": "Application commit",
"at": "(ignore)"
},
"lastSuccess": {
+ "id": 42,
"version": "(ignore)",
+ "reason": "Application commit",
"at": "(ignore)"
}
},
@@ -16,6 +20,7 @@
"type": "system-test",
"success": true,
"lastTriggered": {
+ "id": -1,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -25,9 +30,11 @@
"gitCommit": "commit1"
}
},
+ "reason": "component completed successfully in build 42",
"at": "(ignore)"
},
"lastCompleted": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -37,9 +44,11 @@
"gitCommit": "commit1"
}
},
+ "reason": "component completed successfully in build 42",
"at": "(ignore)"
},
"lastSuccess": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -49,6 +58,7 @@
"gitCommit": "commit1"
}
},
+ "reason": "component completed successfully in build 42",
"at": "(ignore)"
}
},
@@ -56,6 +66,7 @@
"type": "staging-test",
"success": true,
"lastTriggered": {
+ "id": -1,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -65,9 +76,11 @@
"gitCommit": "commit1"
}
},
+ "reason":"systemTest completed successfully in build 42",
"at": "(ignore)"
},
"lastCompleted": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -77,9 +90,11 @@
"gitCommit": "commit1"
}
},
+ "reason":"systemTest completed successfully in build 42",
"at": "(ignore)"
},
"lastSuccess": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -89,6 +104,7 @@
"gitCommit": "commit1"
}
},
+ "reason":"systemTest completed successfully in build 42",
"at": "(ignore)"
}
},
@@ -96,6 +112,7 @@
"type": "production-us-west-1",
"success": true,
"lastTriggered": {
+ "id": -1,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -105,9 +122,11 @@
"gitCommit": "commit1"
}
},
+ "reason":"stagingTest completed successfully in build 42",
"at": "(ignore)"
},
"lastCompleted": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -117,9 +136,11 @@
"gitCommit": "commit1"
}
},
+ "reason":"stagingTest completed successfully in build 42",
"at": "(ignore)"
},
"lastSuccess": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -129,6 +150,7 @@
"gitCommit": "commit1"
}
},
+ "reason":"stagingTest completed successfully in build 42",
"at": "(ignore)"
}
},
@@ -136,6 +158,7 @@
"type": "production-us-east-3",
"success": true,
"lastTriggered": {
+ "id": -1,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -145,9 +168,11 @@
"gitCommit": "commit1"
}
},
+ "reason":"productionUsWest1 completed successfully in build 42",
"at": "(ignore)"
},
"lastCompleted": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -157,9 +182,11 @@
"gitCommit": "commit1"
}
},
+ "reason":"productionUsWest1 completed successfully in build 42",
"at": "(ignore)"
},
"lastSuccess": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -169,6 +196,7 @@
"gitCommit": "commit1"
}
},
+ "reason":"productionUsWest1 completed successfully in build 42",
"at": "(ignore)"
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json
index cc17e76642f..3dca8103ed7 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json
@@ -7,6 +7,7 @@
"type": "system-test",
"success": true,
"lastTriggered": {
+ "id": -1,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -16,9 +17,11 @@
"gitCommit": "commit1"
}
},
+ "reason": "",
"at": "(ignore)"
},
"lastCompleted": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -28,9 +31,11 @@
"gitCommit": "commit1"
}
},
+ "reason": "",
"at": "(ignore)"
},
"lastSuccess": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -40,6 +45,7 @@
"gitCommit": "commit1"
}
},
+ "reason": "",
"at": "(ignore)"
}
},
@@ -47,6 +53,7 @@
"type": "staging-test",
"success": true,
"lastTriggered": {
+ "id": -1,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -56,9 +63,11 @@
"gitCommit": "commit1"
}
},
+ "reason": "systemTest completed successfully in build 42",
"at": "(ignore)"
},
"lastCompleted": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -68,9 +77,11 @@
"gitCommit": "commit1"
}
},
+ "reason": "systemTest completed successfully in build 42",
"at": "(ignore)"
},
"lastSuccess": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -80,6 +91,7 @@
"gitCommit": "commit1"
}
},
+ "reason": "systemTest completed successfully in build 42",
"at": "(ignore)"
}
},
@@ -87,6 +99,7 @@
"type": "production-corp-us-east-1",
"success": false,
"lastTriggered": {
+ "id": -1,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -96,9 +109,11 @@
"gitCommit": "commit1"
}
},
+ "reason": "Retrying as build 42 just started failing",
"at": "(ignore)"
},
"lastCompleted": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -108,9 +123,11 @@
"gitCommit": "commit1"
}
},
+ "reason": "stagingTest completed successfully in build 42",
"at": "(ignore)"
},
"firstFailing": {
+ "id": 42,
"version": "(ignore)",
"revision": {
"hash": "(ignore)",
@@ -120,6 +137,7 @@
"gitCommit": "commit1"
}
},
+ "reason": "stagingTest completed successfully in build 42",
"at": "(ignore)"
}
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/opsdb-tenant-with-new-id-without-applications.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/opsdb-tenant-with-new-id-without-applications.json
index f00b3c5bb1a..3f4b6017971 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/opsdb-tenant-with-new-id-without-applications.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/opsdb-tenant-with-new-id-without-applications.json
@@ -5,5 +5,11 @@
"userGroup": "group1",
"applications": [
+ ],
+ "propertyUrl": "www.properties.tld/4321",
+ "contactsUrl": "www.contacts.tld/4321",
+ "issueCreationUrl": "www.issues.tld/4321",
+ "contacts": [
+
]
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-without-applications.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-without-applications.json
index 88ec5ec7d3d..69669b5dfb8 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-without-applications.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant-without-applications.json
@@ -5,4 +5,4 @@
"applications": [
]
-} \ No newline at end of file
+}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/AbstractResource.java b/jdisc_core/src/main/java/com/yahoo/jdisc/AbstractResource.java
index eddb321cce2..bc3887e2e5f 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/AbstractResource.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/AbstractResource.java
@@ -14,9 +14,9 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
- * <p>This class provides a thread-safe implementation of the {@link SharedResource} interface, and should be used for
+ * This class provides a thread-safe implementation of the {@link SharedResource} interface, and should be used for
* all subclasses of {@link RequestHandler}, {@link ClientProvider} and {@link ServerProvider}. Once the reference count
- * of this resource reaches zero, the {@link #destroy()} method is called.</p>
+ * of this resource reaches zero, the {@link #destroy()} method is called.
*
* @author Simon Thoresen
*/
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/Container.java b/jdisc_core/src/main/java/com/yahoo/jdisc/Container.java
index f98394d28cc..88e4d842bf5 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/Container.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/Container.java
@@ -26,23 +26,23 @@ import java.net.URI;
* <p>The only way to <u>create</u> a new instance of this class is to 1) create and configure a {@link
* ContainerBuilder}, and 2) pass that to the {@link ContainerActivator#activateContainer(ContainerBuilder)} method.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public interface Container extends SharedResource, Timer {
/**
- * <p>Attempts to find a {@link RequestHandler} in the current server- (if {@link Request#isServerRequest()} is
+ * Attempts to find a {@link RequestHandler} in the current server- (if {@link Request#isServerRequest()} is
* <em>true</em>) or client- (if {@link Request#isServerRequest()} is <em>false</em>) {@link BindingSet} that
- * matches the given {@link URI}. If no match can be found, this method returns null.</p>
+ * matches the given {@link URI}. If no match can be found, this method returns null.
*
* @param request The Request to match against the bound {@link RequestHandler}s.
* @return The matching RequestHandler, or null if there is no match.
*/
- public RequestHandler resolveHandler(Request request);
+ RequestHandler resolveHandler(Request request);
/**
- * <p>Returns the appropriate instance for the given injection key. When feasible, avoid using this method in favor
- * of having Guice inject your dependencies ahead of time.</p>
+ * Returns the appropriate instance for the given injection key. When feasible, avoid using this method in favor
+ * of having Guice inject your dependencies ahead of time.
*
* @param key The key of the instance to return.
* @param <T> The class of the instance to return.
@@ -50,11 +50,11 @@ public interface Container extends SharedResource, Timer {
* @throws ConfigurationException If this injector cannot find or create the provider.
* @throws ProvisionException If there was a runtime failure while providing an instance.
*/
- public <T> T getInstance(Key<T> key);
+ <T> T getInstance(Key<T> key);
/**
- * <p>Returns the appropriate instance for the given injection type. When feasible, avoid using this method in
- * favor of having Guice inject your dependencies ahead of time.</p>
+ * Returns the appropriate instance for the given injection type. When feasible, avoid using this method in
+ * favor of having Guice inject your dependencies ahead of time.
*
* @param type The class object of the instance to return.
* @param <T> The class of the instance to return.
@@ -62,5 +62,6 @@ public interface Container extends SharedResource, Timer {
* @throws ConfigurationException If this injector cannot find or create the provider.
* @throws ProvisionException If there was a runtime failure while providing an instance.
*/
- public <T> T getInstance(Class<T> type);
+ <T> T getInstance(Class<T> type);
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/HeaderFields.java b/jdisc_core/src/main/java/com/yahoo/jdisc/HeaderFields.java
index b8057370219..b24f0a24d20 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/HeaderFields.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/HeaderFields.java
@@ -6,11 +6,11 @@ import com.google.common.collect.ImmutableList;
import java.util.*;
/**
- * <p>This is an encapsulation of the header fields that belong to either a {@link Request} or a {@link Response}. It is
+ * This is an encapsulation of the header fields that belong to either a {@link Request} or a {@link Response}. It is
* a multimap from String to String, with some additional methods for convenience. The keys of this map are compared by
- * ignoring their case, so that <tt>get("foo")</tt> returns the same entry as <tt>get("FOO")</tt>.</p>
+ * ignoring their case, so that <tt>get("foo")</tt> returns the same entry as <tt>get("FOO")</tt>.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public class HeaderFields implements Map<String, List<String>> {
@@ -302,4 +302,5 @@ public class HeaderFields implements Map<String, List<String>> {
throw new UnsupportedOperationException();
}
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/AbstractContentOutputStream.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/AbstractContentOutputStream.java
index bc79acc9814..b12bf0d9fe6 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/AbstractContentOutputStream.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/AbstractContentOutputStream.java
@@ -6,7 +6,7 @@ import java.nio.ByteBuffer;
import java.util.Objects;
/**
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ * @author Simon Thoresen Hult
*/
abstract class AbstractContentOutputStream extends OutputStream {
@@ -25,24 +25,24 @@ abstract class AbstractContentOutputStream extends OutputStream {
}
@Override
- public final void write(byte[] buf, int offset, int length) {
- Objects.requireNonNull(buf, "buf");
+ public final void write(byte[] buffer, int offset, int length) {
+ Objects.requireNonNull(buffer, "buf");
if (current == null) {
current = ByteBuffer.allocate(BUFFERSIZE + length);
}
int part = Math.min(length, current.remaining());
- current.put(buf, offset, part);
+ current.put(buffer, offset, part);
if (current.remaining() == 0) {
flush();
}
if (part < length) {
- write(buf, offset + part, length - part);
+ write(buffer, offset + part, length - part);
}
}
@Override
- public final void write(byte[] buf) {
- write(buf, 0, buf.length);
+ public final void write(byte[] buffer) {
+ write(buffer, 0, buffer.length);
}
@Override
@@ -65,4 +65,5 @@ abstract class AbstractContentOutputStream extends OutputStream {
protected abstract void doFlush(ByteBuffer buf);
protected abstract void doClose();
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BindingNotFoundException.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BindingNotFoundException.java
index 151870d57dc..deeccc0472c 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BindingNotFoundException.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BindingNotFoundException.java
@@ -11,7 +11,7 @@ import java.net.URI;
* instance of this class will be thrown by the {@link Request#connect(ResponseHandler)} method when the current {@link
* BindingSet} has not binding that matches the corresponding Request's URI.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public final class BindingNotFoundException extends RuntimeException {
@@ -35,4 +35,5 @@ public final class BindingNotFoundException extends RuntimeException {
public URI uri() {
return uri;
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BlockingContentWriter.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BlockingContentWriter.java
index ab03f282c33..3a2adf60ccf 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BlockingContentWriter.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BlockingContentWriter.java
@@ -6,12 +6,12 @@ import java.util.concurrent.ExecutionException;
import java.util.Objects;
/**
- * <p>This class provides a blocking <em>write</em>-interface to a {@link ContentChannel}. Both {@link
+ * This class provides a blocking <em>write</em>-interface to a {@link ContentChannel}. Both {@link
* #write(ByteBuffer)} and {@link #close()} methods provide an internal {@link CompletionHandler} to the decorated
* {@link ContentChannel} calls, and wait for these to be called before returning. If {@link
- * CompletionHandler#failed(Throwable)} is called, the corresponding Throwable is thrown to the caller.</p>
+ * CompletionHandler#failed(Throwable)} is called, the corresponding Throwable is thrown to the caller.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
* @see FastContentWriter
*/
public final class BlockingContentWriter {
@@ -19,7 +19,7 @@ public final class BlockingContentWriter {
private final ContentChannel channel;
/**
- * <p>Creates a new BlockingContentWriter that encapsulates a given {@link ContentChannel}.</p>
+ * Creates a new BlockingContentWriter that encapsulates a given {@link ContentChannel}.
*
* @param content The ContentChannel to encapsulate.
* @throws NullPointerException If the <em>content</em> argument is null.
@@ -30,7 +30,7 @@ public final class BlockingContentWriter {
}
/**
- * <p>Writes to the underlying {@link ContentChannel} and waits for the operation to complete.</p>
+ * Writes to the underlying {@link ContentChannel} and waits for the operation to complete.
*
* @param buf The ByteBuffer to write.
* @throws InterruptedException If the thread was interrupted while waiting.
@@ -54,7 +54,7 @@ public final class BlockingContentWriter {
}
/**
- * <p>Closes the underlying {@link ContentChannel} and waits for the operation to complete.</p>
+ * Closes the underlying {@link ContentChannel} and waits for the operation to complete.
*
* @throws InterruptedException If the thread was interrupted while waiting.
* @throws RuntimeException If the operation failed to complete, see cause for details.
@@ -75,4 +75,5 @@ public final class BlockingContentWriter {
throw new RuntimeException(t);
}
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BufferedContentChannel.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BufferedContentChannel.java
index a93e4430d20..406ee0ff6e5 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BufferedContentChannel.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/BufferedContentChannel.java
@@ -7,12 +7,12 @@ import java.util.List;
import java.util.Objects;
/**
- * <p>This class implements an unlimited, non-blocking content queue. All {@link ContentChannel} methods are implemented
+ * This class implements an unlimited, non-blocking content queue. All {@link ContentChannel} methods are implemented
* by pushing to a thread-safe internal queue. All of the queued calls are forwarded to another ContentChannel when
* {@link #connectTo(ContentChannel)} is called. Once connected, this class becomes a non-buffering proxy for the
- * connected ContentChannel.</p>
+ * connected ContentChannel.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public final class BufferedContentChannel implements ContentChannel {
@@ -153,4 +153,5 @@ public final class BufferedContentChannel implements ContentChannel {
this.buf = buf;
}
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableRequestDispatch.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableRequestDispatch.java
index 88da723144a..cfbd4edcf8f 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableRequestDispatch.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableRequestDispatch.java
@@ -6,12 +6,12 @@ import com.yahoo.jdisc.Response;
import java.util.concurrent.Callable;
/**
- * <p>This is a convenient subclass of {@link RequestDispatch} that implements the {@link Callable} interface. This
+ * This is a convenient subclass of {@link RequestDispatch} that implements the {@link Callable} interface. This
* should be used in place of {@link RequestDispatch} if you intend to schedule its execution. Because {@link #call()}
* does not return until a {@link Response} becomes available, you can use the <tt>Future</tt> return value of
- * <tt>ExecutorService.submit(Callable)</tt> to wait for it.</p>
+ * <tt>ExecutorService.submit(Callable)</tt> to wait for it.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ * @author Simon Thoresen Hult
*/
public abstract class CallableRequestDispatch extends RequestDispatch implements Callable<Response> {
@@ -19,4 +19,5 @@ public abstract class CallableRequestDispatch extends RequestDispatch implements
public final Response call() throws Exception {
return dispatch().get();
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableResponseDispatch.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableResponseDispatch.java
index 0dc9b964798..0471e05a5f9 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableResponseDispatch.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CallableResponseDispatch.java
@@ -6,20 +6,20 @@ import com.yahoo.jdisc.Response;
import java.util.concurrent.Callable;
/**
- * <p>This is a convenient subclass of {@link ResponseDispatch} that implements the {@link Callable} interface. This
+ * This is a convenient subclass of {@link ResponseDispatch} that implements the {@link Callable} interface. This
* should be used in place of {@link ResponseDispatch} if you intend to schedule its execution. Because {@link #call()}
* does not return until the entirety of the {@link Response} and its content have been consumed, you can use the
- * <tt>Future</tt> return value of <tt>ExecutorService.submit(Callable)</tt> to wait for it to complete.</p>
+ * <tt>Future</tt> return value of <tt>ExecutorService.submit(Callable)</tt> to wait for it to complete.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ * @author Simon Thoresen Hult
*/
public abstract class CallableResponseDispatch extends ResponseDispatch implements Callable<Boolean> {
private final ResponseHandler handler;
/**
- * <p>Constructs a new instances of this class over the given {@link ResponseHandler}. Invoking {@link #call()} will
- * dispatch to this handler.</p>
+ * Constructs a new instances of this class over the given {@link ResponseHandler}. Invoking {@link #call()} will
+ * dispatch to this handler.
*
* @param handler The ResponseHandler to dispatch to.
*/
@@ -31,4 +31,5 @@ public abstract class CallableResponseDispatch extends ResponseDispatch implemen
public final Boolean call() throws Exception {
return dispatch(handler).get();
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CompletionHandler.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CompletionHandler.java
index 134a6aaea47..4975f32adfe 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CompletionHandler.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/CompletionHandler.java
@@ -18,7 +18,7 @@ import com.yahoo.jdisc.Container;
* throughout its lifetime. This also means that the either {@link #completed()} or {@link #failed(Throwable)} MUST be
* called in order to release that reference. Failure to do so will prevent the Container from ever shutting down.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public interface CompletionHandler {
@@ -27,7 +27,7 @@ public interface CompletionHandler {
* release the internal {@link Container} reference. Failure to do so will prevent the Container from ever shutting
* down.
*/
- public void completed();
+ void completed();
/**
* Invoked when an operation fails. Notice that you MUST call either this or {@link #completed()} to release the
@@ -35,5 +35,6 @@ public interface CompletionHandler {
*
* @param t The exception to indicate why the I/O operation failed.
*/
- public void failed(Throwable t);
+ void failed(Throwable t);
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentChannel.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentChannel.java
index 9fa78368f62..e01a3c312be 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentChannel.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentChannel.java
@@ -21,7 +21,7 @@ import java.nio.ByteBuffer;
* requirement is regardless of any errors that may occur while calling any of its other methods or its derived {@link
* CompletionHandler}s.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public interface ContentChannel {
@@ -33,7 +33,7 @@ public interface ContentChannel {
* @param buf The {@link ByteBuffer} to schedule for write. No further calls can be made to this buffer.
* @param handler The {@link CompletionHandler} to call after the write has been executed.
*/
- public void write(ByteBuffer buf, CompletionHandler handler);
+ void write(ByteBuffer buf, CompletionHandler handler);
/**
* Closes this ContentChannel. After a channel is closed, any further attempt to invoke {@link #write(ByteBuffer,
@@ -45,5 +45,6 @@ public interface ContentChannel {
*
* @param handler The {@link CompletionHandler} to call after the close has been executed.
*/
- public void close(CompletionHandler handler);
+ void close(CompletionHandler handler);
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentInputStream.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentInputStream.java
index ecc123dc095..3f89ba04aa5 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentInputStream.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ContentInputStream.java
@@ -2,15 +2,15 @@
package com.yahoo.jdisc.handler;
/**
- * <p>This class extends {@link UnsafeContentInputStream} and adds a finalizer to it that calls {@link #close()}. This
- * has a performance impact, but ensures that an unclosed stream does not prevent shutdown.</p>
+ * This class extends {@link UnsafeContentInputStream} and adds a finalizer to it that calls {@link #close()}. This
+ * has a performance impact, but ensures that an unclosed stream does not prevent shutdown.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public final class ContentInputStream extends UnsafeContentInputStream {
/**
- * <p>Constructs a new ContentInputStream that reads from the given {@link ReadableContentChannel}.</p>
+ * Constructs a new ContentInputStream that reads from the given {@link ReadableContentChannel}.
*
* @param content The content to read the stream from.
*/
@@ -26,4 +26,5 @@ public final class ContentInputStream extends UnsafeContentInputStream {
super.finalize();
}
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentOutputStream.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentOutputStream.java
index 1b6af5d7fe3..1ccbfad83c9 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentOutputStream.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentOutputStream.java
@@ -18,7 +18,7 @@ import java.util.concurrent.TimeoutException;
* <p>Please notice that the Future implementation of this class will NEVER complete unless {@link #close()} has been
* called.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ * @author Simon Thoresen Hult
*/
public class FastContentOutputStream extends AbstractContentOutputStream implements ListenableFuture<Boolean> {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentWriter.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentWriter.java
index 76cc060b961..86e9851629c 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentWriter.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FastContentWriter.java
@@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* <p>Please notice that the Future implementation of this class will NEVER complete unless {@link #close()} has been
* called; please use try-with-resources to ensure that close() is called.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ * @author Simon Thoresen Hult
*/
public class FastContentWriter implements ListenableFuture<Boolean>, AutoCloseable {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureCompletion.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureCompletion.java
index ec3fa4e3d78..e18c88382b6 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureCompletion.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureCompletion.java
@@ -11,7 +11,7 @@ import com.google.common.util.concurrent.AbstractFuture;
*
* <p>Notice that calling {@link #cancel(boolean)} throws an UnsupportedOperationException.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public final class FutureCompletion extends AbstractFuture<Boolean> implements CompletionHandler {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureConjunction.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureConjunction.java
index 15882e4fd1b..bda0f845af0 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureConjunction.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureConjunction.java
@@ -15,7 +15,7 @@ import java.util.concurrent.*;
* simply create an instance of it and add operands to it using the {@link #addOperand(ListenableFuture)} method.</p>
* TODO: consider rewriting usage of FutureConjunction to use CompletableFuture instead.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public final class FutureConjunction implements ListenableFuture<Boolean> {
@@ -94,4 +94,5 @@ public final class FutureConjunction implements ListenableFuture<Boolean> {
}
return ret;
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureResponse.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureResponse.java
index fea4f84416a..3360812864a 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureResponse.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/FutureResponse.java
@@ -5,10 +5,10 @@ import com.google.common.util.concurrent.AbstractFuture;
import com.yahoo.jdisc.Response;
/**
- * <p>This class provides an implementation of {@link ResponseHandler} that allows you to wait for a {@link Response} to
- * be returned.</p>
+ * This class provides an implementation of {@link ResponseHandler} that allows you to wait for a {@link Response} to
+ * be returned.
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public final class FutureResponse extends AbstractFuture<Response> implements ResponseHandler {
@@ -63,4 +63,5 @@ public final class FutureResponse extends AbstractFuture<Response> implements Re
public final boolean isCancelled() {
return false;
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/NullContent.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/NullContent.java
index a4476affcc5..a561823891f 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/NullContent.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/NullContent.java
@@ -13,7 +13,7 @@ import java.nio.ByteBuffer;
* <p>A {@link RequestHandler}s that does not expect content can simply return the {@link #INSTANCE} of this class for
* every invocation of its {@link RequestHandler#handleRequest(Request, ResponseHandler)}.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public final class NullContent implements ContentChannel {
@@ -39,4 +39,5 @@ public final class NullContent implements ContentChannel {
handler.completed();
}
}
+
}
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/OverloadException.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/OverloadException.java
index 20cab5eb249..ba6ff200a51 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/OverloadException.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/OverloadException.java
@@ -5,17 +5,14 @@ package com.yahoo.jdisc.handler;
* An exception to signal abort current action, as the container is overloaded.
* Just unroll state as cheaply as possible.
*
- * <p>
- * The contract of OverloadException (for Jetty) is:
- * </p>
+ * The contract of OverloadException is:
*
* <ol>
- * <li>You must set the response yourself first, or you'll get 500 internal
- * server error.</li>
- * <li>You must throw it from handleRequest synchronously.</li>
+ * <li>You must set the response yourself first, or you'll get an internal server error.
+ * <li>You must throw it from handleRequest synchronously.
* </ol>
*
- * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a>
+ * @author Steinar Knutsen
*/
public class OverloadException extends RuntimeException {
public OverloadException(String message, Throwable cause) {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ReadableContentChannel.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ReadableContentChannel.java
index 27edb619837..50cd2ab2e8c 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ReadableContentChannel.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ReadableContentChannel.java
@@ -15,7 +15,7 @@ import java.util.Queue;
* a {@link BufferedContentChannel} up front, and {@link BufferedContentChannel#connectTo(ContentChannel) connect} that
* to a ReadableContentChannel at the point where you decide to consume the data.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public final class ReadableContentChannel implements ContentChannel, Iterable<ByteBuffer> {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDeniedException.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDeniedException.java
index 8c7a0c7ca24..012ac92b057 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDeniedException.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDeniedException.java
@@ -11,7 +11,7 @@ import java.net.URI;
* or {@link RequestHandler}. There is no automation in throwing an instance of this class, but all RequestHandlers are
* encouraged to use this where appropriate.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public final class RequestDeniedException extends RuntimeException {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDispatch.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDispatch.java
index d986bc562ca..211c5474fe6 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDispatch.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/RequestDispatch.java
@@ -44,7 +44,7 @@ import java.util.List;
* }
* </pre>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ * @author Simon Thoresen Hult
*/
public abstract class RequestDispatch implements ListenableFuture<Response>, ResponseHandler {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseDispatch.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseDispatch.java
index 5fcc19de499..e5e6b752716 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseDispatch.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseDispatch.java
@@ -32,7 +32,7 @@ import java.util.concurrent.Future;
* }
* </pre>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen Hult</a>
+ * @author Simon Thoresen Hult
*/
public abstract class ResponseDispatch extends ForwardingListenableFuture<Boolean> {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseHandler.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseHandler.java
index 0b44e68aa0f..8e22192570c 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseHandler.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ResponseHandler.java
@@ -15,7 +15,7 @@ import com.yahoo.jdisc.service.ClientProvider;
* corresponding Request, but rather leave that to the implementation of context-aware ResponseHandlers. By creating
* light-weight ResponseHandlers on a per-Request basis, any necessary reference can be embedded within.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public interface ResponseHandler {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ThreadedRequestHandler.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ThreadedRequestHandler.java
index d794b2345ab..c50df27120f 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ThreadedRequestHandler.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/ThreadedRequestHandler.java
@@ -40,7 +40,7 @@ import java.util.concurrent.TimeUnit;
* }
* </pre>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public abstract class ThreadedRequestHandler extends AbstractRequestHandler {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java
index 8fb83595ff2..c895e8fe1a5 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/handler/UnsafeContentInputStream.java
@@ -13,7 +13,7 @@ import java.util.Objects;
* always call {@link #close()} before discarding it. Failure to do so will prevent the Container from ever shutting
* down.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public class UnsafeContentInputStream extends InputStream {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/service/AbstractServerProvider.java b/jdisc_core/src/main/java/com/yahoo/jdisc/service/AbstractServerProvider.java
index e8a841a8c1b..5e45fbab80b 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/service/AbstractServerProvider.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/service/AbstractServerProvider.java
@@ -12,7 +12,7 @@ import java.util.Objects;
* essential {@link #start()} and {@link #close()} methods. It requires that the {@link CurrentContainer} is injected in
* the constructor, since that interface is needed to dispatch {@link Request}s.</p>
*
- * @author <a href="mailto:simon@yahoo-inc.com">Simon Thoresen</a>
+ * @author Simon Thoresen
*/
public abstract class AbstractServerProvider extends AbstractResource implements ServerProvider {
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/statistics/ActiveContainerMetrics.java b/jdisc_core/src/main/java/com/yahoo/jdisc/statistics/ActiveContainerMetrics.java
index 9a5271fd417..440c9af6bf5 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/statistics/ActiveContainerMetrics.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/statistics/ActiveContainerMetrics.java
@@ -10,8 +10,10 @@ import com.yahoo.jdisc.core.ActiveContainer;
* @author bjorncs
*/
public interface ActiveContainerMetrics {
+
String TOTAL_DEACTIVATED_CONTAINERS = "jdisc.deactivated_containers.total";
String DEACTIVATED_CONTAINERS_WITH_RETAINED_REFERENCES = "jdisc.deactivated_containers.with_retained_refs";
void emitMetrics(Metric metric);
+
}
diff --git a/slobrok/src/tests/oldapi/mirror.cpp b/slobrok/src/tests/oldapi/mirror.cpp
index e0904fe3a00..2004620d57b 100644
--- a/slobrok/src/tests/oldapi/mirror.cpp
+++ b/slobrok/src/tests/oldapi/mirror.cpp
@@ -54,14 +54,13 @@ MirrorOld::SpecList
MirrorOld::lookup(const std::string & pattern) const
{
SpecList ret;
- _lock.Lock();
+ std::lock_guard<std::mutex> guard(_lock);
SpecList::const_iterator end = _specs.end();
for (SpecList::const_iterator it = _specs.begin(); it != end; ++it) {
if (match(it->first.c_str(), pattern.c_str())) {
ret.push_back(*it);
}
}
- _lock.Unlock();
return ret;
}
@@ -119,10 +118,11 @@ MirrorOld::PerformTask()
std::string(s[idx]._str)));
}
- _lock.Lock();
- std::swap(specs, _specs);
- _updates.add();
- _lock.Unlock();
+ {
+ std::lock_guard<std::mutex> guard(_lock);
+ std::swap(specs, _specs);
+ _updates.add();
+ }
_specsGen.setFromInt(answer[2]._intval32);
}
_backOff.reset();
diff --git a/slobrok/src/tests/oldapi/mirror.h b/slobrok/src/tests/oldapi/mirror.h
index de680641c89..fb150b5d64f 100644
--- a/slobrok/src/tests/oldapi/mirror.h
+++ b/slobrok/src/tests/oldapi/mirror.h
@@ -111,7 +111,7 @@ private:
void RequestDone(FRT_RPCRequest *req) override;
FRT_Supervisor &_orb;
- mutable FastOS_Mutex _lock;
+ mutable std::mutex _lock;
bool _reqDone;
SpecList _specs;
vespalib::GenCnt _specsGen;
diff --git a/slobrok/src/vespa/slobrok/sbregister.cpp b/slobrok/src/vespa/slobrok/sbregister.cpp
index 748ec198bc3..a2ec4a4a7b2 100644
--- a/slobrok/src/vespa/slobrok/sbregister.cpp
+++ b/slobrok/src/vespa/slobrok/sbregister.cpp
@@ -96,10 +96,9 @@ RegisterAPI::~RegisterAPI()
void
RegisterAPI::registerName(const vespalib::stringref & name)
{
- _lock.Lock();
+ std::lock_guard<std::mutex> guard(_lock);
for (uint32_t i = 0; i < _names.size(); ++i) {
if (_names[i] == name) {
- _lock.Unlock();
return;
}
}
@@ -108,20 +107,18 @@ RegisterAPI::registerName(const vespalib::stringref & name)
_pending.push_back(name);
discard(_unreg, name);
ScheduleNow();
- _lock.Unlock();
}
void
RegisterAPI::unregisterName(const vespalib::stringref & name)
{
- _lock.Lock();
+ std::lock_guard<std::mutex> guard(_lock);
_busy = true;
discard(_names, name);
discard(_pending, name);
_unreg.push_back(name);
ScheduleNow();
- _lock.Unlock();
}
// handle any request that completed
@@ -176,11 +173,12 @@ RegisterAPI::handleReconnect()
// try next possible server.
_target = _orb.GetTarget(_currSlobrok.c_str());
}
- _lock.Lock();
- // now that we have a new connection, we need to
- // immediately re-register everything.
- _pending = _names;
- _lock.Unlock();
+ {
+ std::lock_guard<std::mutex> guard(_lock);
+ // now that we have a new connection, we need to
+ // immediately re-register everything.
+ _pending = _names;
+ }
if (_target == 0) {
// we have tried all possible servers.
// start from the top after a delay,
@@ -206,18 +204,19 @@ RegisterAPI::handlePending()
bool unreg = false;
bool reg = false;
vespalib::string name;
- _lock.Lock();
- // pop off the todo stack, unregister has priority
- if (_unreg.size() > 0) {
- name = _unreg.back();
- _unreg.pop_back();
- unreg = true;
- } else if (_pending.size() > 0) {
- name = _pending.back();
- _pending.pop_back();
- reg = true;
+ {
+ std::lock_guard<std::mutex> guard(_lock);
+ // pop off the todo stack, unregister has priority
+ if (_unreg.size() > 0) {
+ name = _unreg.back();
+ _unreg.pop_back();
+ unreg = true;
+ } else if (_pending.size() > 0) {
+ name = _pending.back();
+ _pending.pop_back();
+ reg = true;
+ }
}
- _lock.Unlock();
if (unreg) {
// start a new unregister request
@@ -239,12 +238,11 @@ RegisterAPI::handlePending()
} else {
// nothing more to do right now; schedule to re-register all
// names after a long delay.
- _lock.Lock();
+ std::lock_guard<std::mutex> guard(_lock);
_pending = _names;
LOG(debug, "done, reschedule in 30s");
_busy = false;
Schedule(30.0);
- _lock.Unlock();
}
}
@@ -301,12 +299,11 @@ void
RegisterAPI::RPCHooks::rpc_listNamesServed(FRT_RPCRequest *req)
{
FRT_Values &dst = *req->GetReturn();
- _owner._lock.Lock();
+ std::lock_guard<std::mutex> guard(_owner._lock);
FRT_StringValue *names = dst.AddStringArray(_owner._names.size());
for (uint32_t i = 0; i < _owner._names.size(); ++i) {
dst.SetString(&names[i], _owner._names[i].c_str());
}
- _owner._lock.Unlock();
}
diff --git a/slobrok/src/vespa/slobrok/sbregister.h b/slobrok/src/vespa/slobrok/sbregister.h
index de9f8ed8923..d8812c0f3d0 100644
--- a/slobrok/src/vespa/slobrok/sbregister.h
+++ b/slobrok/src/vespa/slobrok/sbregister.h
@@ -84,7 +84,7 @@ private:
FRT_Supervisor &_orb;
RPCHooks _hooks;
- FastOS_Mutex _lock;
+ std::mutex _lock;
bool _reqDone;
bool _busy;
SlobrokList _slobrokSpecs;
diff --git a/vespalog/src/vespa/log/bufferedlogger.cpp b/vespalog/src/vespa/log/bufferedlogger.cpp
index 106a9bc1dba..5c243b86f86 100644
--- a/vespalog/src/vespa/log/bufferedlogger.cpp
+++ b/vespalog/src/vespa/log/bufferedlogger.cpp
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "bufferedlogger.h"
-#include <vespa/fastos/mutex.h>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
@@ -13,6 +12,7 @@
#include <sstream>
#include <vector>
#include <cstdarg>
+#include <mutex>
namespace ns_log {
@@ -23,7 +23,7 @@ class BackingBuffer {
public:
std::unique_ptr<Timer> _timer;
/** Lock needed to access cache. */
- mutable FastOS_Mutex _mutex;
+ mutable std::mutex _mutex;
static uint64_t _countFactor;
@@ -100,9 +100,8 @@ public:
* need to empty buffer before new log messages arive.
*/
void trimCache() {
- _mutex.Lock();
+ std::lock_guard<std::mutex> guard(_mutex);
trimCache(_timer->getTimestamp());
- _mutex.Unlock();
}
/**
@@ -240,7 +239,7 @@ BackingBuffer::logImpl(Logger& l, Logger::LogLevel level,
{
Entry entry(level, file, line, token, message, _timer->getTimestamp(), l);
- _mutex.Lock();
+ std::lock_guard<std::mutex> guard(_mutex);
LogCacheFrontToken::iterator it1 = _cacheFront.get<1>().find(entry);
LogCacheBackToken::iterator it2 = _cacheBack.get<1>().find(entry);
if (it1 != _cacheFront.get<1>().end()) {
@@ -257,13 +256,12 @@ BackingBuffer::logImpl(Logger& l, Logger::LogLevel level,
_cacheFront.push_back(entry);
}
trimCache(entry._timestamp);
- _mutex.Unlock();
}
void
BackingBuffer::flush()
{
- _mutex.Lock();
+ std::lock_guard<std::mutex> guard(_mutex);
for (LogCacheBack::const_iterator it = _cacheBack.begin();
it != _cacheBack.end(); ++it)
{
@@ -276,7 +274,6 @@ BackingBuffer::flush()
log(*it);
}
_cacheFront.clear();
- _mutex.Unlock();
}
void
@@ -340,7 +337,7 @@ BackingBuffer::toString() const
{
std::ostringstream ost;
ost << "Front log cache content:\n";
- _mutex.Lock();
+ std::lock_guard<std::mutex> guard(_mutex);
for (LogCacheFront::const_iterator it = _cacheFront.begin();
it != _cacheFront.end(); ++it)
{
@@ -352,7 +349,6 @@ BackingBuffer::toString() const
{
ost << " " << it->toString() << "\n";
}
- _mutex.Unlock();
return ost.str();
}
diff --git a/yolean/src/main/java/com/yahoo/yolean/chain/After.java b/yolean/src/main/java/com/yahoo/yolean/chain/After.java
index 582613765cf..cb2caccc6df 100644
--- a/yolean/src/main/java/com/yahoo/yolean/chain/After.java
+++ b/yolean/src/main/java/com/yahoo/yolean/chain/After.java
@@ -8,16 +8,16 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * <p>The component that is annotated with this must be placed later than the components or phases providing names
- * contained in the given list.</p>
+ * The component that is annotated with this must be placed later than the components or phases providing names
+ * contained in the given list.
*
* @author tonytv
- * @since 5.1.18
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface After {
- public abstract String[] value() default { };
+ String[] value() default { };
+
}
diff --git a/yolean/src/main/java/com/yahoo/yolean/chain/Before.java b/yolean/src/main/java/com/yahoo/yolean/chain/Before.java
index 00e6d6a20b9..108fbff2e21 100644
--- a/yolean/src/main/java/com/yahoo/yolean/chain/Before.java
+++ b/yolean/src/main/java/com/yahoo/yolean/chain/Before.java
@@ -8,16 +8,16 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * <p>The component that is annotated with this must be placed earlier than the components or phases providing names
- * contained in the given list.</p>
+ * The component that is annotated with this must be placed earlier than the components or phases providing names
+ * contained in the given list.
*
* @author tonytv
- * @since 5.1.18
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface Before {
- public abstract String[] value() default { };
+ String[] value() default { };
+
}
diff --git a/yolean/src/main/java/com/yahoo/yolean/chain/Chain.java b/yolean/src/main/java/com/yahoo/yolean/chain/Chain.java
index b761d2f1834..537d242374d 100644
--- a/yolean/src/main/java/com/yahoo/yolean/chain/Chain.java
+++ b/yolean/src/main/java/com/yahoo/yolean/chain/Chain.java
@@ -95,4 +95,5 @@ public final class Chain<T> implements Iterable<T> {
}
return true;
}
+
}
diff --git a/yolean/src/main/java/com/yahoo/yolean/chain/ChainCycleException.java b/yolean/src/main/java/com/yahoo/yolean/chain/ChainCycleException.java
index b4e0a6815b4..50eff4aabc4 100644
--- a/yolean/src/main/java/com/yahoo/yolean/chain/ChainCycleException.java
+++ b/yolean/src/main/java/com/yahoo/yolean/chain/ChainCycleException.java
@@ -21,4 +21,5 @@ public class ChainCycleException extends RuntimeException {
public List<?> components() {
return components;
}
+
}
diff --git a/yolean/src/main/java/com/yahoo/yolean/chain/Dependencies.java b/yolean/src/main/java/com/yahoo/yolean/chain/Dependencies.java
index 0932a847889..fca0bac753d 100644
--- a/yolean/src/main/java/com/yahoo/yolean/chain/Dependencies.java
+++ b/yolean/src/main/java/com/yahoo/yolean/chain/Dependencies.java
@@ -182,4 +182,5 @@ public class Dependencies<T> {
return new Order<>((U[])null, null, null);
}
}
+
}
diff --git a/yolean/src/main/java/com/yahoo/yolean/chain/DirectedGraph.java b/yolean/src/main/java/com/yahoo/yolean/chain/DirectedGraph.java
index 4a06badcbb0..cd1680b5722 100644
--- a/yolean/src/main/java/com/yahoo/yolean/chain/DirectedGraph.java
+++ b/yolean/src/main/java/com/yahoo/yolean/chain/DirectedGraph.java
@@ -103,4 +103,5 @@ class DirectedGraph {
Collections.<T>emptyList() :
list;
}
+
}
diff --git a/yolean/src/main/java/com/yahoo/yolean/chain/EnumeratedIdentitySet.java b/yolean/src/main/java/com/yahoo/yolean/chain/EnumeratedIdentitySet.java
index ea94b22e3ec..6cd316fb5f5 100644
--- a/yolean/src/main/java/com/yahoo/yolean/chain/EnumeratedIdentitySet.java
+++ b/yolean/src/main/java/com/yahoo/yolean/chain/EnumeratedIdentitySet.java
@@ -180,4 +180,5 @@ class EnumeratedIdentitySet<T> implements Set<T> {
return result;
}
+
}
diff --git a/yolean/src/main/java/com/yahoo/yolean/chain/Provides.java b/yolean/src/main/java/com/yahoo/yolean/chain/Provides.java
index 277fe20c224..5b02d3bf4d3 100644
--- a/yolean/src/main/java/com/yahoo/yolean/chain/Provides.java
+++ b/yolean/src/main/java/com/yahoo/yolean/chain/Provides.java
@@ -12,12 +12,12 @@ import java.lang.annotation.Target;
* and "after" the string provided here, to impose constraints on ordering.</p>
*
* @author tonytv
- * @since 5.1.18
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface Provides {
- public abstract String[] value() default { };
+ String[] value() default { };
+
}