aboutsummaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2020-08-26 12:38:49 +0200
committerGitHub <noreply@github.com>2020-08-26 12:38:49 +0200
commit186b336732dd2c6d5a03001e45cb8f497cbe66e7 (patch)
treefdd33c21a0239be47ea985f4e1640479e7084a5b /configserver
parentf454184d22c6c46d23710f7cfda988ee40efa641 (diff)
Revert "Revert "Add timestamp when creating tenant to TenantMetaData""
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java19
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantMetaData.java49
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java34
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java4
4 files changed, 82 insertions, 24 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
index 137d0f1889e..73120e90a3e 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
@@ -25,7 +25,6 @@ import com.yahoo.io.IOUtils;
import com.yahoo.jdisc.Metric;
import com.yahoo.path.Path;
import com.yahoo.slime.Slime;
-import com.yahoo.text.Utf8;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.transaction.Transaction;
import com.yahoo.vespa.config.server.application.Application;
@@ -65,8 +64,6 @@ import com.yahoo.vespa.config.server.tenant.TenantMetaData;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import com.yahoo.vespa.curator.Curator;
import com.yahoo.vespa.curator.Lock;
-import com.yahoo.vespa.curator.transaction.CuratorOperations;
-import com.yahoo.vespa.curator.transaction.CuratorTransaction;
import com.yahoo.vespa.defaults.Defaults;
import com.yahoo.vespa.flags.BooleanFlag;
import com.yahoo.vespa.flags.FlagSource;
@@ -415,24 +412,18 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
}
if (useTenantMetaData.value())
- transaction.add(writeTenantMetaData(tenant).operations());
+ transaction.add(updateMetaDataWithDeployTimestamp(tenant, clock.instant()));
return transaction;
}
- private byte[] createMetaData(Tenant tenant) {
- return new TenantMetaData(tenant.getSessionRepository().clock().instant()).asJsonBytes();
+ private List<Transaction.Operation> updateMetaDataWithDeployTimestamp(Tenant tenant, Instant deployTimestamp) {
+ TenantMetaData tenantMetaData = getTenantMetaData(tenant).withLastDeployTimestamp(deployTimestamp);
+ return tenantRepository.createWriteTenantMetaDataTransaction(tenantMetaData).operations();
}
TenantMetaData getTenantMetaData(Tenant tenant) {
- Optional<byte[]> data = tenantRepository.getCurator().getData(TenantRepository.getTenantPath(tenant.getName()));
- return data.map(bytes -> TenantMetaData.fromJsonString(Utf8.toString(bytes))).orElse(new TenantMetaData(tenant.getCreatedTime()));
- }
-
- private Transaction writeTenantMetaData(Tenant tenant) {
- return new CuratorTransaction(tenantRepository.getCurator())
- .add(CuratorOperations.setData(TenantRepository.getTenantPath(tenant.getName()).getAbsolute(),
- createMetaData(tenant)));
+ return tenantRepository.getTenantMetaData(tenant);
}
static void checkIfActiveHasChanged(LocalSession session, Session currentActiveSession, boolean ignoreStaleSessionFailure) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantMetaData.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantMetaData.java
index 24862b82fb0..b8db47e371f 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantMetaData.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantMetaData.java
@@ -1,30 +1,50 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.tenant;
+import com.yahoo.config.provision.TenantName;
import com.yahoo.slime.Cursor;
import com.yahoo.slime.Inspector;
import com.yahoo.slime.Slime;
import com.yahoo.slime.SlimeUtils;
+import com.yahoo.text.Utf8;
import java.io.IOException;
import java.time.Instant;
/**
- * Metadata for a tenant. At the moment only stores last deploy time, to be used by TenantsMaintainer
- * to GC unused tenants
+ * Meta data for a tenant like tenant name, tenant creation time and last deployment time, stored in ZooKeeper
*
* @author hmusum
*/
public class TenantMetaData {
- private final Instant lastDeployTimestamp;
+ private static final String createTimestampKey = "createTimestampKey";
+ private static final String lastDeployTimestampKey = "lastDeployTimestamp";
- public TenantMetaData(Instant instant) {
- this.lastDeployTimestamp = instant;
+ private final TenantName tenantName;
+ private final Instant created;
+ private final Instant lastDeployed;
+
+ public TenantMetaData(TenantName tenantName, Instant lastDeployed, Instant created) {
+ this.tenantName = tenantName;
+ this.created = created;
+ this.lastDeployed = lastDeployed;
+ }
+
+ public TenantMetaData withLastDeployTimestamp(Instant deployTimestamp) {
+ return new TenantMetaData(tenantName, deployTimestamp, created);
+ }
+
+ public TenantName tenantName() {
+ return tenantName;
}
public Instant lastDeployTimestamp() {
- return lastDeployTimestamp;
+ return lastDeployed;
+ }
+
+ public Instant createdTimestamp() {
+ return created;
}
public byte[] asJsonBytes() {
@@ -35,13 +55,16 @@ public class TenantMetaData {
}
}
- public static TenantMetaData fromJsonString(String jsonString) {
+ public static TenantMetaData fromJsonString(TenantName tenantName, String jsonString) {
try {
Slime data = SlimeUtils.jsonToSlime(jsonString);
Inspector root = data.get();
- Inspector lastDeployTimestamp = root.field("lastDeployTimestamp");
+ Inspector created = root.field(createTimestampKey);
+ Inspector lastDeployTimestamp = root.field(lastDeployTimestampKey);
- return new TenantMetaData(Instant.ofEpochMilli(lastDeployTimestamp.asLong()));
+ return new TenantMetaData(tenantName,
+ Instant.ofEpochMilli(lastDeployTimestamp.asLong()),
+ Instant.ofEpochMilli(created.asLong()));
} catch (Exception e) {
throw new IllegalArgumentException("Error parsing json metadata", e);
}
@@ -50,8 +73,14 @@ public class TenantMetaData {
private Slime getSlime() {
Slime slime = new Slime();
Cursor meta = slime.setObject();
- meta.setLong("lastDeployTimestamp", lastDeployTimestamp.toEpochMilli());
+ meta.setLong(createTimestampKey, created.toEpochMilli());
+ meta.setLong(lastDeployTimestampKey, lastDeployed.toEpochMilli());
return slime;
}
+ @Override
+ public String toString() {
+ return tenantName + ": " + Utf8.toString(asJsonBytes());
+ }
+
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java
index d6e3c6905fb..2f05b7e7fe8 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java
@@ -8,12 +8,18 @@ import com.yahoo.concurrent.StripedExecutor;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.TenantName;
import com.yahoo.path.Path;
+import com.yahoo.text.Utf8;
+import com.yahoo.transaction.Transaction;
import com.yahoo.vespa.config.server.GlobalComponentRegistry;
import com.yahoo.vespa.config.server.application.TenantApplications;
import com.yahoo.vespa.config.server.deploy.TenantFileSystemDirs;
import com.yahoo.vespa.config.server.monitoring.MetricUpdater;
import com.yahoo.vespa.config.server.session.SessionRepository;
import com.yahoo.vespa.curator.Curator;
+import com.yahoo.vespa.curator.transaction.CuratorOperations;
+import com.yahoo.vespa.curator.transaction.CuratorTransaction;
+import com.yahoo.vespa.flags.BooleanFlag;
+import com.yahoo.vespa.flags.Flags;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.state.ConnectionState;
@@ -82,6 +88,7 @@ public class TenantRepository {
private final ExecutorService bootstrapExecutor;
private final ScheduledExecutorService checkForRemovedApplicationsService = new ScheduledThreadPoolExecutor(1);
private final Optional<Curator.DirectoryCache> directoryCache;
+ private final BooleanFlag useTenantMetaData;
/**
* Creates a new tenant repository
@@ -109,6 +116,7 @@ public class TenantRepository {
this.tenantListeners.add(componentRegistry.getTenantListener());
this.zkCacheExecutor = componentRegistry.getZkCacheExecutor();
this.zkWatcherExecutor = componentRegistry.getZkWatcherExecutor();
+ this.useTenantMetaData = Flags.USE_TENANT_META_DATA.bindTo(componentRegistry.getFlagSource());
curator.framework().getConnectionStateListenable().addListener(this::stateChanged);
curator.create(tenantsPath);
@@ -142,6 +150,30 @@ public class TenantRepository {
createTenant(tenantName, componentRegistry.getClock().instant());
}
+ public void createAndWriteTenantMetaData(Tenant tenant) {
+ createWriteTenantMetaDataTransaction(createMetaData(tenant)).commit();
+ }
+
+ public Transaction createWriteTenantMetaDataTransaction(TenantMetaData tenantMetaData) {
+ return new CuratorTransaction(curator).add(
+ CuratorOperations.setData(TenantRepository.getTenantPath(tenantMetaData.tenantName()).getAbsolute(),
+ tenantMetaData.asJsonBytes()));
+ }
+
+ private TenantMetaData createMetaData(Tenant tenant) {
+ Instant deployTime = tenant.getSessionRepository().clock().instant();
+ Instant createdTime = getTenantMetaData(tenant).createdTimestamp();
+ if (createdTime.equals(Instant.EPOCH))
+ createdTime = deployTime;
+ return new TenantMetaData(tenant.getName(), deployTime, createdTime);
+ }
+
+ public TenantMetaData getTenantMetaData(Tenant tenant) {
+ Optional<byte[]> data = getCurator().getData(TenantRepository.getTenantPath(tenant.getName()));
+ return data.map(bytes -> TenantMetaData.fromJsonString(tenant.getName(), Utf8.toString(bytes)))
+ .orElse(new TenantMetaData(tenant.getName(), tenant.getCreatedTime(), tenant.getCreatedTime()));
+ }
+
private static Set<TenantName> readTenantsFromZooKeeper(Curator curator) {
return curator.getChildren(tenantsPath).stream().map(TenantName::from).collect(Collectors.toSet());
}
@@ -226,6 +258,8 @@ public class TenantRepository {
Tenant tenant = new Tenant(tenantName, sessionRepository, applicationRepo, applicationRepo, created);
notifyNewTenant(tenant);
tenants.putIfAbsent(tenantName, tenant);
+ if (useTenantMetaData.value())
+ createAndWriteTenantMetaData(tenant);
}
/**
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
index beac308cf77..cb43e80e82d 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
@@ -167,6 +167,7 @@ public class ApplicationRepositoryTest {
session.getAllocatedHosts();
assertEquals(Instant.EPOCH, applicationRepository.getTenantMetaData(tenant).lastDeployTimestamp());
+ assertEquals(Instant.EPOCH, applicationRepository.getTenantMetaData(tenant).createdTimestamp());
}
@Test
@@ -174,6 +175,7 @@ public class ApplicationRepositoryTest {
FlagSource flagSource = new InMemoryFlagSource().withBooleanFlag(Flags.USE_TENANT_META_DATA.id(), true);
setup(flagSource);
+ Instant startTime = clock.instant();
Duration duration = Duration.ofHours(1);
clock.advance(duration);
Instant deployTime = clock.instant();
@@ -188,6 +190,8 @@ public class ApplicationRepositoryTest {
assertEquals(deployTime.toEpochMilli(),
applicationRepository.getTenantMetaData(tenant).lastDeployTimestamp().toEpochMilli());
+ assertEquals(startTime.toEpochMilli(),
+ applicationRepository.getTenantMetaData(tenant).createdTimestamp().toEpochMilli());
}
@Test