AccountsUpdate#update: Return Optional<AccountState> instead of AccountState

This makes it more explicit that callers must handle the case where the
returned AccountState is absent.

Change-Id: Id301678f97d2a8827c3a23d85cbc5f6da97abc7c
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2018-01-12 10:52:25 +01:00
parent 5c37073931
commit d40d81482d
8 changed files with 103 additions and 112 deletions

View File

@@ -238,16 +238,14 @@ public class AccountManager {
}
if (!accountUpdates.isEmpty()) {
AccountState accountState =
accountsUpdateFactory
.create()
.update(
"Update Account on Login",
user.getAccountId(),
AccountUpdater.joinConsumers(accountUpdates));
if (accountState == null) {
throw new OrmException("Account " + user.getAccountId() + " has been deleted");
}
accountsUpdateFactory
.create()
.update(
"Update Account on Login",
user.getAccountId(),
AccountUpdater.joinConsumers(accountUpdates))
.orElseThrow(
() -> new OrmException("Account " + user.getAccountId() + " has been deleted"));
}
}

View File

@@ -378,23 +378,24 @@ public class AccountsUpdate {
public AccountState insert(String message, Account.Id accountId, AccountUpdater updater)
throws OrmException, IOException, ConfigInvalidException {
return updateAccount(
r -> {
AccountConfig accountConfig = read(r, accountId);
Account account =
accountConfig.getNewAccount(new Timestamp(committerIdent.getWhen().getTime()));
AccountState accountState = AccountState.forAccount(allUsersName, account);
InternalAccountUpdate.Builder updateBuilder = InternalAccountUpdate.builder();
updater.update(accountState, updateBuilder);
r -> {
AccountConfig accountConfig = read(r, accountId);
Account account =
accountConfig.getNewAccount(new Timestamp(committerIdent.getWhen().getTime()));
AccountState accountState = AccountState.forAccount(allUsersName, account);
InternalAccountUpdate.Builder updateBuilder = InternalAccountUpdate.builder();
updater.update(accountState, updateBuilder);
InternalAccountUpdate update = updateBuilder.build();
accountConfig.setAccountUpdate(update);
ExternalIdNotes extIdNotes =
createExternalIdNotes(r, accountConfig.getExternalIdsRev(), accountId, update);
UpdatedAccount updatedAccounts =
new UpdatedAccount(allUsersName, externalIds, message, accountConfig, extIdNotes);
updatedAccounts.setCreated(true);
return updatedAccounts;
});
InternalAccountUpdate update = updateBuilder.build();
accountConfig.setAccountUpdate(update);
ExternalIdNotes extIdNotes =
createExternalIdNotes(r, accountConfig.getExternalIdsRev(), accountId, update);
UpdatedAccount updatedAccounts =
new UpdatedAccount(allUsersName, externalIds, message, accountConfig, extIdNotes);
updatedAccounts.setCreated(true);
return updatedAccounts;
})
.get();
}
/**
@@ -405,12 +406,12 @@ public class AccountsUpdate {
* @param message commit message for the account update, must not be {@code null or empty}
* @param accountId ID of the account
* @param update consumer to update the account, only invoked if the account exists
* @return the updated account, {@code null} if the account doesn't exist
* @return the updated account, {@link Optional#empty()} if the account doesn't exist
* @throws IOException if updating the user branch fails due to an IO error
* @throws OrmException if updating the user branch fails
* @throws ConfigInvalidException if any of the account fields has an invalid value
*/
public AccountState update(
public Optional<AccountState> update(
String message, Account.Id accountId, Consumer<InternalAccountUpdate.Builder> update)
throws OrmException, IOException, ConfigInvalidException {
return update(message, accountId, AccountUpdater.fromConsumer(update));
@@ -424,13 +425,12 @@ public class AccountsUpdate {
* @param message commit message for the account update, must not be {@code null or empty}
* @param accountId ID of the account
* @param updater updater to update the account, only invoked if the account exists
* @return the updated account, {@code null} if the account doesn't exist
* @return the updated account, {@link Optional#empty} if the account doesn't exist
* @throws IOException if updating the user branch fails due to an IO error
* @throws OrmException if updating the user branch fails
* @throws ConfigInvalidException if any of the account fields has an invalid value
*/
@Nullable
public AccountState update(String message, Account.Id accountId, AccountUpdater updater)
public Optional<AccountState> update(String message, Account.Id accountId, AccountUpdater updater)
throws OrmException, IOException, ConfigInvalidException {
return updateAccount(
r -> {
@@ -461,7 +461,7 @@ public class AccountsUpdate {
return accountConfig;
}
private AccountState updateAccount(AccountUpdate accountUpdate)
private Optional<AccountState> updateAccount(AccountUpdate accountUpdate)
throws IOException, ConfigInvalidException, OrmException {
return retryHelper.execute(
ActionType.ACCOUNT_UPDATE,
@@ -469,11 +469,11 @@ public class AccountsUpdate {
try (Repository allUsersRepo = repoManager.openRepository(allUsersName)) {
UpdatedAccount updatedAccount = accountUpdate.update(allUsersRepo);
if (updatedAccount == null) {
return null;
return Optional.empty();
}
commit(allUsersRepo, updatedAccount);
return updatedAccount.getAccount();
return Optional.of(updatedAccount.getAccount());
}
});
}

View File

@@ -39,22 +39,19 @@ public class SetInactiveFlag {
public Response<?> deactivate(Account.Id accountId)
throws RestApiException, IOException, ConfigInvalidException, OrmException {
AtomicBoolean alreadyInactive = new AtomicBoolean(false);
AccountState accountState =
accountsUpdate
.create()
.update(
"Deactivate Account via API",
accountId,
(a, u) -> {
if (!a.getAccount().isActive()) {
alreadyInactive.set(true);
} else {
u.setActive(false);
}
});
if (accountState == null) {
throw new ResourceNotFoundException("account not found");
}
accountsUpdate
.create()
.update(
"Deactivate Account via API",
accountId,
(a, u) -> {
if (!a.getAccount().isActive()) {
alreadyInactive.set(true);
} else {
u.setActive(false);
}
})
.orElseThrow(() -> new ResourceNotFoundException("account not found"));
if (alreadyInactive.get()) {
throw new ResourceConflictException("account not active");
}
@@ -64,22 +61,19 @@ public class SetInactiveFlag {
public Response<String> activate(Account.Id accountId)
throws ResourceNotFoundException, IOException, ConfigInvalidException, OrmException {
AtomicBoolean alreadyActive = new AtomicBoolean(false);
AccountState accountState =
accountsUpdate
.create()
.update(
"Activate Account via API",
accountId,
(a, u) -> {
if (a.getAccount().isActive()) {
alreadyActive.set(true);
} else {
u.setActive(true);
}
});
if (accountState == null) {
throw new ResourceNotFoundException("account not found");
}
accountsUpdate
.create()
.update(
"Activate Account via API",
accountId,
(a, u) -> {
if (a.getAccount().isActive()) {
alreadyActive.set(true);
} else {
u.setActive(true);
}
})
.orElseThrow(() -> new ResourceNotFoundException("account not found"));
return alreadyActive.get() ? Response.ok("") : Response.created("");
}
}

View File

@@ -2981,7 +2981,7 @@ class ReceiveCommits {
}
logDebug("Updating full name of caller");
try {
AccountState accountState =
Optional<AccountState> accountState =
accountsUpdate
.create()
.update(
@@ -2992,9 +2992,9 @@ class ReceiveCommits {
u.setFullName(setFullNameTo);
}
});
if (accountState != null) {
user.getAccount().setFullName(accountState.getAccount().getFullName());
}
accountState
.map(AccountState::getAccount)
.ifPresent(a -> user.getAccount().setFullName(a.getFullName()));
} catch (OrmException | IOException | ConfigInvalidException e) {
logWarn("Failed to update full name of caller", e);
}

View File

@@ -82,10 +82,8 @@ public class PutName implements RestModifyView<AccountResource, NameInput> {
AccountState accountState =
accountsUpdate
.create()
.update("Set Full Name via API", user.getAccountId(), u -> u.setFullName(newName));
if (accountState == null) {
throw new ResourceNotFoundException("account not found");
}
.update("Set Full Name via API", user.getAccountId(), u -> u.setFullName(newName))
.orElseThrow(() -> new ResourceNotFoundException("account not found"));
return Strings.isNullOrEmpty(accountState.getAccount().getFullName())
? Response.none()
: Response.ok(accountState.getAccount().getFullName());

View File

@@ -22,7 +22,6 @@ import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
@@ -65,22 +64,19 @@ public class PutPreferred implements RestModifyView<AccountResource.Email, Input
public Response<String> apply(IdentifiedUser user, String email)
throws ResourceNotFoundException, IOException, ConfigInvalidException, OrmException {
AtomicBoolean alreadyPreferred = new AtomicBoolean(false);
AccountState accountState =
accountsUpdate
.create()
.update(
"Set Preferred Email via API",
user.getAccountId(),
(a, u) -> {
if (email.equals(a.getAccount().getPreferredEmail())) {
alreadyPreferred.set(true);
} else {
u.setPreferredEmail(email);
}
});
if (accountState == null) {
throw new ResourceNotFoundException("account not found");
}
accountsUpdate
.create()
.update(
"Set Preferred Email via API",
user.getAccountId(),
(a, u) -> {
if (email.equals(a.getAccount().getPreferredEmail())) {
alreadyPreferred.set(true);
} else {
u.setPreferredEmail(email);
}
})
.orElseThrow(() -> new ResourceNotFoundException("account not found"));
return alreadyPreferred.get() ? Response.ok("") : Response.created("");
}
}

View File

@@ -71,10 +71,8 @@ public class PutStatus implements RestModifyView<AccountResource, StatusInput> {
AccountState accountState =
accountsUpdate
.create()
.update("Set Status via API", user.getAccountId(), u -> u.setStatus(newStatus));
if (accountState == null) {
throw new ResourceNotFoundException("account not found");
}
.update("Set Status via API", user.getAccountId(), u -> u.setStatus(newStatus))
.orElseThrow(() -> new ResourceNotFoundException("account not found"));
return Strings.isNullOrEmpty(accountState.getAccount().getStatus())
? Response.none()
: Response.ok(accountState.getAccount().getStatus());

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.acceptance.api.accounts;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.acceptance.GitUtil.deleteRef;
import static com.google.gerrit.acceptance.GitUtil.fetch;
import static com.google.gerrit.gpg.PublicKeyStore.REFS_GPG_KEYS;
@@ -401,12 +402,12 @@ public class AccountIT extends AbstractDaemonTest {
public void updateNonExistingAccount() throws Exception {
Account.Id nonExistingAccountId = new Account.Id(999999);
AtomicBoolean consumerCalled = new AtomicBoolean();
AccountState accountState =
Optional<AccountState> accountState =
accountsUpdate
.create()
.update(
"Update Non-Existing Account", nonExistingAccountId, a -> consumerCalled.set(true));
assertThat(accountState).isNull();
assertThat(accountState).isEmpty();
assertThat(consumerCalled.get()).isFalse();
}
@@ -416,13 +417,14 @@ public class AccountIT extends AbstractDaemonTest {
assertUserBranchWithoutAccountConfig(anonymousCoward.getId());
String status = "OOO";
AccountState accountState =
Optional<AccountState> accountState =
accountsUpdate
.create()
.update("Set status", anonymousCoward.getId(), u -> u.setStatus(status));
assertThat(accountState).isNotNull();
assertThat(accountState.getAccount().getFullName()).isNull();
assertThat(accountState.getAccount().getStatus()).isEqualTo(status);
assertThat(accountState).isPresent();
Account account = accountState.get().getAccount();
assertThat(account.getFullName()).isNull();
assertThat(account.getStatus()).isEqualTo(status);
assertUserBranch(anonymousCoward.getId(), null, status);
}
@@ -1946,11 +1948,12 @@ public class AccountIT extends AbstractDaemonTest {
assertThat(accountState.getAccount().getMetaId()).isEqualTo(getMetaId(accountId));
// metaId is set when account is updated
AccountState updatedAccountState =
Optional<AccountState> updatedAccountState =
au.update("Set Full Name", accountId, u -> u.setFullName("foo"));
assertThat(accountState.getAccount().getMetaId())
.isNotEqualTo(updatedAccountState.getAccount().getMetaId());
assertThat(updatedAccountState.getAccount().getMetaId()).isEqualTo(getMetaId(accountId));
assertThat(updatedAccountState.isPresent()).isTrue();
Account updatedAccount = updatedAccountState.get().getAccount();
assertThat(accountState.getAccount().getMetaId()).isNotEqualTo(updatedAccount.getMetaId());
assertThat(updatedAccount.getMetaId()).isEqualTo(getMetaId(accountId));
}
private EmailInput newEmailInput(String email, boolean noConfirmation) {
@@ -2051,12 +2054,14 @@ public class AccountIT extends AbstractDaemonTest {
assertThat(accountInfo.status).isNull();
assertThat(accountInfo.name).isNotEqualTo(fullName);
AccountState updatedAccountState =
Optional<AccountState> updatedAccountState =
update.update("Set Full Name", admin.id, u -> u.setFullName(fullName));
assertThat(doneBgUpdate.get()).isTrue();
assertThat(updatedAccountState.getAccount().getStatus()).isEqualTo(status);
assertThat(updatedAccountState.getAccount().getFullName()).isEqualTo(fullName);
assertThat(updatedAccountState.isPresent()).isTrue();
Account updatedAccount = updatedAccountState.get().getAccount();
assertThat(updatedAccount.getStatus()).isEqualTo(status);
assertThat(updatedAccount.getFullName()).isEqualTo(fullName);
accountInfo = gApi.accounts().id(admin.id.get()).get();
assertThat(accountInfo.status).isEqualTo(status);
@@ -2161,7 +2166,7 @@ public class AccountIT extends AbstractDaemonTest {
assertThat(bgCounterA2.get()).isEqualTo(0);
assertThat(gApi.accounts().id(admin.id.get()).get().status).isEqualTo("A-1");
AccountState updatedAccountState =
Optional<AccountState> updatedAccountState =
update.update(
"Set Status",
admin.id,
@@ -2180,7 +2185,8 @@ public class AccountIT extends AbstractDaemonTest {
assertThat(bgCounterA1.get()).isEqualTo(1);
assertThat(bgCounterA2.get()).isEqualTo(1);
assertThat(updatedAccountState.getAccount().getStatus()).isEqualTo("B-2");
assertThat(updatedAccountState.isPresent()).isTrue();
assertThat(updatedAccountState.get().getAccount().getStatus()).isEqualTo("B-2");
assertThat(accounts.get(admin.id).get().getAccount().getStatus()).isEqualTo("B-2");
assertThat(gApi.accounts().id(admin.id.get()).get().status).isEqualTo("B-2");
}
@@ -2241,7 +2247,7 @@ public class AccountIT extends AbstractDaemonTest {
ExternalId extIdB1 = ExternalId.create("foo", "B-1", accountId);
ExternalId extIdB2 = ExternalId.create("foo", "B-2", accountId);
AccountState updatedAccount =
Optional<AccountState> updatedAccount =
update.update(
"Update External ID",
accountId,
@@ -2260,7 +2266,8 @@ public class AccountIT extends AbstractDaemonTest {
assertThat(bgCounterA1.get()).isEqualTo(1);
assertThat(bgCounterA2.get()).isEqualTo(1);
assertThat(updatedAccount.getExternalIds()).containsExactly(extIdB2);
assertThat(updatedAccount.isPresent()).isTrue();
assertThat(updatedAccount.get().getExternalIds()).containsExactly(extIdB2);
assertThat(accounts.get(accountId).get().getExternalIds()).containsExactly(extIdB2);
assertThat(
gApi.accounts()