Class AccountsUpdate
- java.lang.Object
-
- com.google.gerrit.server.account.AccountsUpdate
-
public class AccountsUpdate extends Object
Creates and updates accounts.This class should be used for all account updates. See
AccountDelta
for what can be updated.Batch updates of multiple different accounts can be performed atomically, see
updateBatch(List)
. Batch creation is not supported.For any account update the caller must provide a commit message, the account ID and an
AccountsUpdate.ConfigureDeltaFromState
. The account updater reads the currentAccountState
and prepares updates to the account by calling setters on the providedAccountDelta.Builder
. If the current account state is of no interest the caller may also provide aConsumer
forAccountDelta.Builder
instead of the account updater.The provided commit message is used for the update of the user branch. Using a precise and unique commit message allows to identify the code from which an update was made when looking at a commit in the user branch, and thus help debugging.
For creating a new account a new account ID can be retrieved from
Sequences.nextAccountId()
.The account updates are written to NoteDb. In NoteDb accounts are represented as user branches in the
All-Users
repository. Optionally a user branch can contain a 'account.config' file that stores account properties, such as full name, display name, preferred email, status and the active flag. The timestamp of the first commit on a user branch denotes the registration date. The initial commit on the user branch may be empty (since having an 'account.config' is optional). SeeAccountConfig
for details of the 'account.config' file format. In addition the user branch can contain a 'preferences.config' config file to store preferences (seeStoredPreferences
) and a 'watch.config' config file to store project watches (seeProjectWatches
). External IDs are stored separately in therefs/meta/external-ids
notes branch (seeExternalIdNotes
).On updating an account the account is evicted from the account cache and reindexed. The eviction from the account cache and the reindexing is done by the
ReindexAfterRefUpdate
class which receives the event about updating the user branch that is triggered by this class.If external IDs are updated, the ExternalIdCache is automatically updated by
ExternalIdNotes
. In additionExternalIdNotes
takes care about evicting and reindexing corresponding accounts. This is needed because external ID updates don't touch the user branches. Hence in this case the accounts are not evicted and reindexed viaReindexAfterRefUpdate
.Reindexing and flushing accounts from the account cache can be disabled by
- binding
GitReferenceUpdated.DISABLED
and - passing an
ExternalIdNotes.FactoryNoReindex
factory as parameter ofAccountsUpdate.Factory.create(IdentifiedUser, ExternalIdNotes.ExternalIdNotesLoader)
If there are concurrent account updates updating the user branch in NoteDb may fail with
LockFailureException
. In this case the account update is automatically retried and the account updater is invoked once more with the updated account state. This means the whole read-modify-write sequence is atomic. Retrying is limited by a timeout. If the timeout is exceeded the account update can still fail withLockFailureException
. - binding
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
AccountsUpdate.ConfigureDeltaFromState
Account updates are commonly performed by evaluating the current account state and creating a delta to be applied to it in a later step.static interface
AccountsUpdate.Factory
static class
AccountsUpdate.UpdateArguments
Data holder for the set of arguments required to update an account.
-
Constructor Summary
Constructors Constructor Description AccountsUpdate(GitRepositoryManager repoManager, GitReferenceUpdated gitRefUpdated, Optional<IdentifiedUser> currentUser, AllUsersName allUsersName, ExternalIds externalIds, com.google.inject.Provider<MetaDataUpdate.InternalFactory> metaDataUpdateInternalFactory, RetryHelper retryHelper, ExternalIdNotes.ExternalIdNotesLoader extIdNotesLoader, org.eclipse.jgit.lib.PersonIdent committerIdent, org.eclipse.jgit.lib.PersonIdent authorIdent, Runnable afterReadRevision, Runnable beforeCommit)
-
Method Summary
-
-
-
Constructor Detail
-
AccountsUpdate
public AccountsUpdate(GitRepositoryManager repoManager, GitReferenceUpdated gitRefUpdated, Optional<IdentifiedUser> currentUser, AllUsersName allUsersName, ExternalIds externalIds, com.google.inject.Provider<MetaDataUpdate.InternalFactory> metaDataUpdateInternalFactory, RetryHelper retryHelper, ExternalIdNotes.ExternalIdNotesLoader extIdNotesLoader, org.eclipse.jgit.lib.PersonIdent committerIdent, org.eclipse.jgit.lib.PersonIdent authorIdent, Runnable afterReadRevision, Runnable beforeCommit)
-
-
Method Detail
-
joinConsumers
public static AccountsUpdate.ConfigureDeltaFromState joinConsumers(List<Consumer<AccountDelta.Builder>> consumers)
Returns an instance that runs all specified consumers.
-
insert
public AccountState insert(String message, Account.Id accountId, Consumer<AccountDelta.Builder> init) throws IOException, org.eclipse.jgit.errors.ConfigInvalidException
Likeinsert(String, Account.Id, ConfigureDeltaFromState)
, but using aConsumer
instead, i.e. the update does not depend on the current account state (which, for insertion, would only contain the account ID).- Throws:
IOException
org.eclipse.jgit.errors.ConfigInvalidException
-
insert
public AccountState insert(String message, Account.Id accountId, AccountsUpdate.ConfigureDeltaFromState init) throws IOException, org.eclipse.jgit.errors.ConfigInvalidException
Inserts a new account.- Parameters:
message
- commit message for the account creation, must not benull or empty
accountId
- ID of the new accountinit
- to populate the new account- Returns:
- the newly created account
- Throws:
com.google.gerrit.exceptions.DuplicateKeyException
- if the account already existsIOException
- if creating the user branch fails due to an IO errororg.eclipse.jgit.errors.ConfigInvalidException
- if any of the account fields has an invalid value
-
update
public Optional<AccountState> update(String message, Account.Id accountId, Consumer<AccountDelta.Builder> update) throws IOException, org.eclipse.jgit.errors.ConfigInvalidException
Likeupdate(String, Account.Id, ConfigureDeltaFromState)
, but using aConsumer
instead, i.e. the update does not depend on the current account state.- Throws:
IOException
org.eclipse.jgit.errors.ConfigInvalidException
-
update
public Optional<AccountState> update(String message, Account.Id accountId, AccountsUpdate.ConfigureDeltaFromState configureDeltaFromState) throws com.google.gerrit.git.LockFailureException, IOException, org.eclipse.jgit.errors.ConfigInvalidException
Gets the account and updates it atomically.Changing the registration date of an account is not supported.
- Parameters:
message
- commit message for the account update, must not benull or empty
accountId
- ID of the accountconfigureDeltaFromState
- deltaBuilder to update the account, only invoked if the account exists- Returns:
- the updated account,
Optional.empty()
if the account doesn't exist - Throws:
IOException
- if updating the user branch fails due to an IO errorcom.google.gerrit.git.LockFailureException
- if updating the user branch still fails due to concurrent updates after the retry timeout exceededorg.eclipse.jgit.errors.ConfigInvalidException
- if any of the account fields has an invalid value
-
updateBatch
public com.google.common.collect.ImmutableList<Optional<AccountState>> updateBatch(List<AccountsUpdate.UpdateArguments> updates) throws IOException, org.eclipse.jgit.errors.ConfigInvalidException
Updates multiple different accounts atomically. This will only store a single new value (aka set of all external IDs of the host) in the external ID cache, which is important for storage economy. Allupdates
must be for different accounts.NOTE on error handling: Since updates are executed in multiple stages, with some stages resulting from the union of all individual updates, we cannot point to the update that caused the error. Callers should be aware that a single "update of death" (or a set of updates that together have this property) will always prevent the entire batch from being executed.
- Throws:
IOException
org.eclipse.jgit.errors.ConfigInvalidException
-
-