Class 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 current AccountState and prepares updates to the account by calling setters on the provided AccountDelta.Builder. If the current account state is of no interest the caller may also provide a Consumer for AccountDelta.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). See AccountConfig for details of the 'account.config' file format. In addition the user branch can contain a 'preferences.config' config file to store preferences (see StoredPreferences) and a 'watch.config' config file to store project watches (see ProjectWatches). External IDs are stored separately in the refs/meta/external-ids notes branch (see ExternalIdNotes).

    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 addition ExternalIdNotes 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 via ReindexAfterRefUpdate.

    Reindexing and flushing accounts from the account cache can be disabled by

    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 with LockFailureException.

    • Method Detail

      • 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 be null or empty
        accountId - ID of the new account
        init - to populate the new account
        Returns:
        the newly created account
        Throws:
        com.google.gerrit.exceptions.DuplicateKeyException - if the account already exists
        IOException - if creating the user branch fails due to an IO error
        org.eclipse.jgit.errors.ConfigInvalidException - if any of the account fields has an invalid value
      • 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 be null or empty
        accountId - ID of the account
        configureDeltaFromState - 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 error
        com.google.gerrit.git.LockFailureException - if updating the user branch still fails due to concurrent updates after the retry timeout exceeded
        org.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. All updates 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