add renameTenant back to TenantAPI after rebase

This commit is contained in:
Jon Fu 2022-06-28 11:41:06 -07:00
parent c9065b50bb
commit 5fee5e1a73
3 changed files with 64 additions and 4 deletions

View File

@ -25,6 +25,7 @@
#include "fdbclient/IClientApi.h"
#include "fdbclient/Knobs.h"
#include "fdbclient/ManagementAPI.actor.h"
#include "fdbclient/TenantManagement.actor.h"
#include "fdbclient/Schemas.h"
#include "flow/Arena.h"
@ -291,7 +292,7 @@ ACTOR Future<bool> renameTenantCommandActor(Reference<IDatabase> db, std::vector
printUsage(tokens[0]);
return false;
}
wait(safeThreadFutureToFuture(ManagementAPI::renameTenant(db, tokens[1], tokens[2])));
wait(safeThreadFutureToFuture(TenantAPI::renameTenant(db, tokens[1], tokens[2])));
printf("The tenant `%s' has been renamed to `%s'\n", printable(tokens[1]).c_str(), printable(tokens[2]).c_str());
return true;

View File

@ -284,6 +284,65 @@ Future<std::map<TenantName, TenantMapEntry>> listTenants(Reference<DB> db,
}
}
}
ACTOR template <class DB>
Future<Void> renameTenant(Reference<DB> db, TenantName oldName, TenantName newName) {
state Reference<typename DB::TransactionT> tr = db->createTransaction();
state Key oldNameKey = oldName.withPrefix(tenantMapPrefix);
state Key newNameKey = newName.withPrefix(tenantMapPrefix);
state bool firstTry = true;
state int64_t id;
loop {
try {
tr->setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS);
state Optional<TenantMapEntry> oldEntry = wait(tryGetTenantTransaction(tr, oldName));
state Optional<TenantMapEntry> newEntry = wait(tryGetTenantTransaction(tr, newName));
if (firstTry) {
if (!oldEntry.present()) {
throw tenant_not_found();
}
if (newEntry.present()) {
throw tenant_already_exists();
}
// Store the id we see when first reading this key
id = oldEntry.get().id;
firstTry = false;
} else {
// If we got commit_unknown_result, the rename may have already occurred.
if (newEntry.present()) {
int64_t checkId = newEntry.get().id;
if (id == checkId) {
ASSERT(!oldEntry.present() || oldEntry.get().id != id);
return Void();
}
// If the new entry is present but does not match, then
// the rename should fail, so we throw an error.
throw tenant_already_exists();
}
if (!oldEntry.present()) {
throw tenant_not_found();
}
if (newEntry.present()) {
throw tenant_already_exists();
}
int64_t checkId = oldEntry.get().id;
// Assert that the id has not changed since we first read this
if (id != checkId) {
throw tenant_not_found();
}
}
tr->clear(oldNameKey);
tr->set(newNameKey, encodeTenantEntry(oldEntry.get()));
wait(safeThreadFutureToFuture(tr->commit()));
TraceEvent("RenameTenantSuccess").detail("OldName", oldName).detail("NewName", newName);
return Void();
} catch (Error& e) {
wait(safeThreadFutureToFuture(tr->onError(e)));
}
}
}
} // namespace TenantAPI
#include "flow/unactorcompiler.h"

View File

@ -588,12 +588,12 @@ struct TenantManagementWorkload : TestWorkload {
state TenantName oldTenantName = oldTenantNames[tenantIndex];
state TenantName newTenantName = newTenantNames[tenantIndex];
// Perform rename, then check against the DB for the new results
wait(ManagementAPI::renameTenant(cx.getReference(), oldTenantName, newTenantName));
wait(TenantAPI::renameTenant(cx.getReference(), oldTenantName, newTenantName));
ASSERT(!tenantNotFound && !tenantExists);
state Optional<TenantMapEntry> oldTenantEntry =
wait(ManagementAPI::tryGetTenant(cx.getReference(), oldTenantName));
wait(TenantAPI::tryGetTenant(cx.getReference(), oldTenantName));
state Optional<TenantMapEntry> newTenantEntry =
wait(ManagementAPI::tryGetTenant(cx.getReference(), newTenantName));
wait(TenantAPI::tryGetTenant(cx.getReference(), newTenantName));
ASSERT(!oldTenantEntry.present());
ASSERT(newTenantEntry.present());