Class GroupNameNotes
- java.lang.Object
-
- com.google.gerrit.server.git.meta.VersionedMetaData
-
- com.google.gerrit.server.group.db.GroupNameNotes
-
public class GroupNameNotes extends VersionedMetaData
An enforcer of unique names for groups in NoteDb.The way groups are stored in NoteDb (see
GroupConfig
) doesn't enforce unique names, even though groups in Gerrit must not have duplicate names. The storage format doesn't allow to quickly look up whether a name has already been used either. That's why we additionally keep a map of name/UUID pairs and manage it with this class.To claim the name for a new group, create an instance of
GroupNameNotes
viaforNewGroup(Project.NameKey, Repository, AccountGroup.UUID, AccountGroup.NameKey)
and callcommit(MetaDataUpdate)
on it. For renaming, callforRename(Project.NameKey, Repository, AccountGroup.UUID, AccountGroup.NameKey, AccountGroup.NameKey)
and also commit the returnedGroupNameNotes
. Both times, the creation of theGroupNameNotes
will fail if the (new) name is already used. Committing theGroupNameNotes
is necessary to make the adjustments for real.The map has an additional benefit: We can quickly iterate over all group name/UUID pairs without having to load all groups completely (which is costly).
Internal details
The map of names is represented by Git
notes
. They are stored on the branchRefNames.REFS_GROUPNAMES
. Each commit on the branch reflects one moment in time of the complete map.As key for the notes, we use the SHA-1 of the name. As data, they contain a text version of a JGit
Config
file. That config file has two entries:- the name of the group (as clear text)
- the UUID of the group which currently has this name
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class com.google.gerrit.server.git.meta.VersionedMetaData
VersionedMetaData.BatchMetaDataUpdate, VersionedMetaData.PathInfo
-
-
Field Summary
-
Fields inherited from class com.google.gerrit.server.git.meta.VersionedMetaData
inserter, newTree, projectName, reader, revision, rw
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static GroupNameNotes
forNewGroup(Project.NameKey projectName, org.eclipse.jgit.lib.Repository repository, AccountGroup.UUID groupUuid, AccountGroup.NameKey groupName)
Creates an instance ofGroupNameNotes
for use when creating a new group.static GroupNameNotes
forRename(Project.NameKey projectName, org.eclipse.jgit.lib.Repository repository, AccountGroup.UUID groupUuid, AccountGroup.NameKey oldName, AccountGroup.NameKey newName)
Creates an instance ofGroupNameNotes
for use when renaming a group.static org.eclipse.jgit.lib.ObjectId
getNoteKey(AccountGroup.NameKey groupName)
protected String
getRefName()
Returns name of the reference storing this configuration.static com.google.common.collect.ImmutableList<GroupReference>
loadAllGroups(org.eclipse.jgit.lib.Repository repository)
Loads theGroupReference
s (name/UUID pairs) for all groups.static Optional<GroupReference>
loadGroup(org.eclipse.jgit.lib.Repository repository, AccountGroup.NameKey groupName)
Loads theGroupReference
(name/UUID pair) for the group with the specified name.protected void
onLoad()
Set up the metadata, parsing any state from the loaded revision.protected boolean
onSave(org.eclipse.jgit.lib.CommitBuilder commit)
Save any changes to the metadata in a commit.static void
updateAllGroups(org.eclipse.jgit.lib.Repository repository, org.eclipse.jgit.lib.ObjectInserter inserter, org.eclipse.jgit.lib.BatchRefUpdate bru, Collection<GroupReference> groupReferences, org.eclipse.jgit.lib.PersonIdent ident)
Replaces the map of name/UUID pairs with a new version which matches exactly the passedGroupReference
s.-
Methods inherited from class com.google.gerrit.server.git.meta.VersionedMetaData
commit, commit, commitToNewRef, getObjectId, getPathInfos, getRevision, load, load, load, load, load, openUpdate, openUpdate, readConfig, readConfig, readFile, readTree, readUTF8, saveConfig, saveFile, saveUTF8, set, set, set
-
-
-
-
Method Detail
-
forRename
public static GroupNameNotes forRename(Project.NameKey projectName, org.eclipse.jgit.lib.Repository repository, AccountGroup.UUID groupUuid, AccountGroup.NameKey oldName, AccountGroup.NameKey newName) throws IOException, org.eclipse.jgit.errors.ConfigInvalidException, com.google.gerrit.exceptions.DuplicateKeyException
Creates an instance ofGroupNameNotes
for use when renaming a group.Note: The returned instance of
GroupNameNotes
has to be committed viacommit(MetaDataUpdate)
in order to claim the new name and free up the old one.- Parameters:
projectName
- the name of the project which holds the commits of the notesrepository
- the repository which holds the commits of the notesgroupUuid
- the UUID of the group which is renamedoldName
- the current name of the groupnewName
- the new name of the group- Returns:
- an instance of
GroupNameNotes
configured for a specific renaming of a group - Throws:
IOException
- if the repository can't be accessed for some reasonorg.eclipse.jgit.errors.ConfigInvalidException
- if the note for the specified group doesn't exist or is in an invalid statecom.google.gerrit.exceptions.DuplicateKeyException
- if a group with the new name already exists
-
forNewGroup
public static GroupNameNotes forNewGroup(Project.NameKey projectName, org.eclipse.jgit.lib.Repository repository, AccountGroup.UUID groupUuid, AccountGroup.NameKey groupName) throws IOException, org.eclipse.jgit.errors.ConfigInvalidException, com.google.gerrit.exceptions.DuplicateKeyException
Creates an instance ofGroupNameNotes
for use when creating a new group.Note: The returned instance of
GroupNameNotes
has to be committed viacommit(MetaDataUpdate)
in order to claim the new name.- Parameters:
projectName
- the name of the project which holds the commits of the notesrepository
- the repository which holds the commits of the notesgroupUuid
- the UUID of the new groupgroupName
- the name of the new group- Returns:
- an instance of
GroupNameNotes
configured for a specific group creation - Throws:
IOException
- if the repository can't be accessed for some reasonorg.eclipse.jgit.errors.ConfigInvalidException
- in no case so farcom.google.gerrit.exceptions.DuplicateKeyException
- if a group with the new name already exists
-
loadGroup
public static Optional<GroupReference> loadGroup(org.eclipse.jgit.lib.Repository repository, AccountGroup.NameKey groupName) throws IOException, org.eclipse.jgit.errors.ConfigInvalidException
Loads theGroupReference
(name/UUID pair) for the group with the specified name.- Parameters:
repository
- the repository which holds the commits of the notesgroupName
- the name of the group- Returns:
- the corresponding
GroupReference
if a group/note with the given name exists - Throws:
IOException
- if the repository can't be accessed for some reasonorg.eclipse.jgit.errors.ConfigInvalidException
- if the note for the specified group is in an invalid state
-
loadAllGroups
public static com.google.common.collect.ImmutableList<GroupReference> loadAllGroups(org.eclipse.jgit.lib.Repository repository) throws IOException, org.eclipse.jgit.errors.ConfigInvalidException
Loads theGroupReference
s (name/UUID pairs) for all groups.Even though group UUIDs should be unique, this class doesn't enforce it. For this reason, it's technically possible that two of the
GroupReference
s have a duplicate UUID but a different name. In practice, this shouldn't occur unless we introduce a bug in the future.- Parameters:
repository
- the repository which holds the commits of the notes- Returns:
- the
GroupReference
s of all existing groups/notes - Throws:
IOException
- if the repository can't be accessed for some reasonorg.eclipse.jgit.errors.ConfigInvalidException
- if one of the notes is in an invalid state
-
updateAllGroups
public static void updateAllGroups(org.eclipse.jgit.lib.Repository repository, org.eclipse.jgit.lib.ObjectInserter inserter, org.eclipse.jgit.lib.BatchRefUpdate bru, Collection<GroupReference> groupReferences, org.eclipse.jgit.lib.PersonIdent ident) throws IOException
Replaces the map of name/UUID pairs with a new version which matches exactly the passedGroupReference
s.All old entries are discarded and replaced by the new ones.
This operation also works if the previous map has invalid entries or can't be read anymore.
Note: This method doesn't flush the
ObjectInserter
. It doesn't execute theBatchRefUpdate
either.- Parameters:
repository
- the repository which holds the commits of the notesinserter
- anObjectInserter
for that repositorybru
- aBatchRefUpdate
to which this method adds commandsgroupReferences
- allGroupReference
s (name/UUID pairs) which should be contained in the map of name/UUID pairsident
- thePersonIdent
which is used as author and committer for commits- Throws:
IOException
- if the repository can't be accessed for some reason
-
getRefName
protected String getRefName()
Description copied from class:VersionedMetaData
Returns name of the reference storing this configuration.- Specified by:
getRefName
in classVersionedMetaData
-
onLoad
protected void onLoad() throws IOException, org.eclipse.jgit.errors.ConfigInvalidException
Description copied from class:VersionedMetaData
Set up the metadata, parsing any state from the loaded revision.- Specified by:
onLoad
in classVersionedMetaData
- Throws:
IOException
org.eclipse.jgit.errors.ConfigInvalidException
-
onSave
protected boolean onSave(org.eclipse.jgit.lib.CommitBuilder commit) throws IOException, org.eclipse.jgit.errors.ConfigInvalidException
Description copied from class:VersionedMetaData
Save any changes to the metadata in a commit.- Specified by:
onSave
in classVersionedMetaData
- Returns:
- true if the commit should proceed, false to abort.
- Throws:
IOException
org.eclipse.jgit.errors.ConfigInvalidException
-
getNoteKey
public static org.eclipse.jgit.lib.ObjectId getNoteKey(AccountGroup.NameKey groupName)
-
-