Write debug log that shows up in trace when meta data file is read/saved

Reading/saving meta data files is a rather expensive operation. E.g. if
a request leads to excessive reads of meta data files we want to see
that in the trace. Reading of meta data files e.g. happens on cache
misses (account cache, group cache etc).

Unfortunately VersionedMetaData has no reference to the project name
so we must pass this in from a lot of places.

Example logs:
[2018-08-10 15:27:29,333] [HTTP-75] DEBUG com.google.gerrit.server.git.meta.VersionedMetaData : Read file 'group.config' from ref 'refs/groups/ca/ca1fd42646e71d8081add52fbb0171a8504c97cd' of project 'All-Users' from revision '919687c42e13f76552fb186f36d43f447544e64b' [CONTEXT forced=true TRACE_ID="1533907649289-2d0c7a5d" ]
[2018-08-10 15:27:29,334] [HTTP-75] DEBUG com.google.gerrit.server.git.meta.VersionedMetaData : Read file 'members' from ref 'refs/groups/ca/ca1fd42646e71d8081add52fbb0171a8504c97cd' of project 'All-Users' from revision '919687c42e13f76552fb186f36d43f447544e64b' [CONTEXT forced=true TRACE_ID="1533907649289-2d0c7a5d" ]
[2018-08-10 15:27:29,336] [HTTP-75] DEBUG com.google.gerrit.server.git.meta.VersionedMetaData : Read file 'subgroups' from ref 'refs/groups/ca/ca1fd42646e71d8081add52fbb0171a8504c97cd' of project 'All-Users' from revision '919687c42e13f76552fb186f36d43f447544e64b' [CONTEXT forced=true TRACE_ID="1533907649289-2d0c7a5d" ]

Change-Id: Ibb438213b01b0a5cf67fd277d298a0359b65bb1d
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin 2018-08-10 15:28:29 +02:00
parent 944cd404ac
commit 6b4d94b60f
49 changed files with 346 additions and 193 deletions

View File

@ -16,10 +16,10 @@ package com.google.gerrit.pgm.init;
import com.google.gerrit.pgm.init.api.AllUsersNameOnInitProvider;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.GerritPersonIdentProvider;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIdNotes;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
@ -39,13 +39,13 @@ import org.eclipse.jgit.util.FS;
public class ExternalIdsOnInit {
private final InitFlags flags;
private final SitePaths site;
private final String allUsers;
private final AllUsersName allUsers;
@Inject
public ExternalIdsOnInit(InitFlags flags, SitePaths site, AllUsersNameOnInitProvider allUsers) {
this.flags = flags;
this.site = site;
this.allUsers = allUsers.get();
this.allUsers = new AllUsersName(allUsers.get());
}
public synchronized void insert(String commitMessage, Collection<ExternalId> extIds)
@ -53,11 +53,10 @@ public class ExternalIdsOnInit {
File path = getPath();
if (path != null) {
try (Repository allUsersRepo = new FileRepository(path)) {
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(allUsersRepo);
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(allUsers, allUsersRepo);
extIdNotes.insert(extIds);
try (MetaDataUpdate metaDataUpdate =
new MetaDataUpdate(
GitReferenceUpdated.DISABLED, new Project.NameKey(allUsers), allUsersRepo)) {
new MetaDataUpdate(GitReferenceUpdated.DISABLED, allUsers, allUsersRepo)) {
PersonIdent serverIdent = new GerritPersonIdentProvider(flags.cfg).get();
metaDataUpdate.getCommitBuilder().setAuthor(serverIdent);
metaDataUpdate.getCommitBuilder().setCommitter(serverIdent);
@ -73,6 +72,6 @@ public class ExternalIdsOnInit {
if (basePath == null) {
throw new IllegalStateException("gerrit.basePath must be configured");
}
return FileKey.resolve(basePath.resolve(allUsers).toFile(), FS.DETECTED);
return FileKey.resolve(basePath.resolve(allUsers.get()).toFile(), FS.DETECTED);
}
}

View File

@ -25,9 +25,9 @@ import com.google.gerrit.pgm.init.api.AllUsersNameOnInitProvider;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.GerritPersonIdentProvider;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.GerritServerIdProvider;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
@ -64,13 +64,13 @@ public class GroupsOnInit {
private final InitFlags flags;
private final SitePaths site;
private final String allUsers;
private final AllUsersName allUsers;
@Inject
public GroupsOnInit(InitFlags flags, SitePaths site, AllUsersNameOnInitProvider allUsers) {
this.flags = flags;
this.site = site;
this.allUsers = allUsers.get();
this.allUsers = new AllUsersName(allUsers.get());
}
/**
@ -90,7 +90,7 @@ public class GroupsOnInit {
if (allUsersRepoPath != null) {
try (Repository allUsersRepo = new FileRepository(allUsersRepoPath)) {
AccountGroup.UUID groupUuid = groupReference.getUUID();
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsersRepo, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsers, allUsersRepo, groupUuid);
return groupConfig
.getLoadedGroup()
.orElseThrow(() -> new NoSuchGroupException(groupReference.getUUID()));
@ -145,7 +145,7 @@ public class GroupsOnInit {
private void addGroupMemberInNoteDb(
Repository repository, AccountGroup.UUID groupUuid, Account account)
throws IOException, ConfigInvalidException, NoSuchGroupException {
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsers, repository, groupUuid);
InternalGroup group =
groupConfig.getLoadedGroup().orElseThrow(() -> new NoSuchGroupException(groupUuid));
@ -160,7 +160,7 @@ public class GroupsOnInit {
private File getPathToAllUsersRepository() {
Path basePath = site.resolve(flags.cfg.getString("gerrit", null, "basePath"));
checkArgument(basePath != null, "gerrit.basePath must be configured");
return RepositoryCache.FileKey.resolve(basePath.resolve(allUsers).toFile(), FS.DETECTED);
return RepositoryCache.FileKey.resolve(basePath.resolve(allUsers.get()).toFile(), FS.DETECTED);
}
private static InternalGroupUpdate getMemberAdditionUpdate(Account account) {
@ -186,7 +186,7 @@ public class GroupsOnInit {
private MetaDataUpdate createMetaDataUpdate(Repository repository, PersonIdent personIdent) {
MetaDataUpdate metaDataUpdate =
new MetaDataUpdate(GitReferenceUpdated.DISABLED, new Project.NameKey(allUsers), repository);
new MetaDataUpdate(GitReferenceUpdated.DISABLED, allUsers, repository);
metaDataUpdate.getCommitBuilder().setAuthor(personIdent);
metaDataUpdate.getCommitBuilder().setCommitter(personIdent);
return metaDataUpdate;

View File

@ -14,6 +14,7 @@
package com.google.gerrit.pgm.init.api;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.GerritPersonIdentProvider;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.meta.VersionedMetaData;
@ -57,7 +58,7 @@ public abstract class VersionedMetaDataOnInit extends VersionedMetaData {
File path = getPath();
if (path != null) {
try (Repository repo = new FileRepository(path)) {
load(repo);
load(new Project.NameKey(project), repo);
}
}
return this;

View File

@ -30,6 +30,7 @@ import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.account.ProjectWatches.NotifyType;
import com.google.gerrit.server.account.ProjectWatches.ProjectWatchKey;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.ValidationError;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.git.meta.VersionedMetaData;
@ -77,6 +78,7 @@ import org.eclipse.jgit.revwalk.RevSort;
*/
public class AccountConfig extends VersionedMetaData implements ValidationError.Sink {
private final Account.Id accountId;
private final AllUsersName allUsersName;
private final Repository repo;
private final String ref;
@ -87,8 +89,9 @@ public class AccountConfig extends VersionedMetaData implements ValidationError.
private Optional<InternalAccountUpdate> accountUpdate = Optional.empty();
private List<ValidationError> validationErrors;
public AccountConfig(Account.Id accountId, Repository allUsersRepo) {
public AccountConfig(Account.Id accountId, AllUsersName allUsersName, Repository allUsersRepo) {
this.accountId = checkNotNull(accountId, "accountId");
this.allUsersName = checkNotNull(allUsersName, "allUsersName");
this.repo = checkNotNull(allUsersRepo, "allUsersRepo");
this.ref = RefNames.refsUsers(accountId);
}
@ -99,7 +102,7 @@ public class AccountConfig extends VersionedMetaData implements ValidationError.
}
public AccountConfig load() throws IOException, ConfigInvalidException {
load(repo);
load(allUsersName, repo);
return this;
}
@ -242,7 +245,7 @@ public class AccountConfig extends VersionedMetaData implements ValidationError.
new Preferences(
accountId,
readConfig(Preferences.PREFERENCES_CONFIG),
Preferences.readDefaultConfig(repo),
Preferences.readDefaultConfig(allUsersName, repo),
this);
projectWatches.parse();
@ -253,7 +256,8 @@ public class AccountConfig extends VersionedMetaData implements ValidationError.
projectWatches = new ProjectWatches(accountId, new Config(), this);
preferences =
new Preferences(accountId, new Config(), Preferences.readDefaultConfig(repo), this);
new Preferences(
accountId, new Config(), Preferences.readDefaultConfig(allUsersName, repo), this);
}
Ref externalIdsRef = repo.exactRef(RefNames.REFS_EXTERNAL_IDS);

View File

@ -134,7 +134,9 @@ public class Accounts {
private Optional<AccountState> read(Repository allUsersRepository, Account.Id accountId)
throws IOException, ConfigInvalidException {
return AccountState.fromAccountConfig(
allUsersName, externalIds, new AccountConfig(accountId, allUsersRepository).load());
allUsersName,
externalIds,
new AccountConfig(accountId, allUsersName, allUsersRepository).load());
}
public static Stream<Account.Id> readUserRefs(Repository repo) throws IOException {

View File

@ -368,7 +368,7 @@ public class AccountsUpdate {
private AccountConfig read(Repository allUsersRepo, Account.Id accountId)
throws IOException, ConfigInvalidException {
AccountConfig accountConfig = new AccountConfig(accountId, allUsersRepo).load();
AccountConfig accountConfig = new AccountConfig(accountId, allUsersName, allUsersRepo).load();
afterReadRevision.run();
return accountConfig;
}

View File

@ -39,6 +39,7 @@ import com.google.gerrit.extensions.client.MenuItem;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.UserConfigSections;
import com.google.gerrit.server.git.ValidationError;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
@ -414,25 +415,28 @@ public class Preferences {
return urlAliases;
}
public static GeneralPreferencesInfo readDefaultGeneralPreferences(Repository allUsersRepo)
public static GeneralPreferencesInfo readDefaultGeneralPreferences(
AllUsersName allUsersName, Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return parseGeneralPreferences(readDefaultConfig(allUsersRepo), null, null);
return parseGeneralPreferences(readDefaultConfig(allUsersName, allUsersRepo), null, null);
}
public static DiffPreferencesInfo readDefaultDiffPreferences(Repository allUsersRepo)
public static DiffPreferencesInfo readDefaultDiffPreferences(
AllUsersName allUsersName, Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return parseDiffPreferences(readDefaultConfig(allUsersRepo), null, null);
return parseDiffPreferences(readDefaultConfig(allUsersName, allUsersRepo), null, null);
}
public static EditPreferencesInfo readDefaultEditPreferences(Repository allUsersRepo)
public static EditPreferencesInfo readDefaultEditPreferences(
AllUsersName allUsersName, Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return parseEditPreferences(readDefaultConfig(allUsersRepo), null, null);
return parseEditPreferences(readDefaultConfig(allUsersName, allUsersRepo), null, null);
}
static Config readDefaultConfig(Repository allUsersRepo)
static Config readDefaultConfig(AllUsersName allUsersName, Repository allUsersRepo)
throws IOException, ConfigInvalidException {
VersionedDefaultPreferences defaultPrefs = new VersionedDefaultPreferences();
defaultPrefs.load(allUsersRepo);
defaultPrefs.load(allUsersName, allUsersRepo);
return defaultPrefs.getConfig();
}

View File

@ -121,7 +121,7 @@ public class VersionedAuthorizedKeys extends VersionedMetaData {
throws IOException, ConfigInvalidException {
try (Repository git = repoManager.openRepository(allUsersName)) {
VersionedAuthorizedKeys authorizedKeys = authorizedKeysFactory.create(accountId);
authorizedKeys.load(git);
authorizedKeys.load(allUsersName, git);
return authorizedKeys;
}
}

View File

@ -35,6 +35,7 @@ import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.git.meta.VersionedMetaData;
import com.google.gerrit.server.index.account.AccountIndexer;
@ -117,24 +118,32 @@ public class ExternalIdNotes extends VersionedMetaData {
private final AccountCache accountCache;
private final Provider<AccountIndexer> accountIndexer;
private final MetricMaker metricMaker;
private final AllUsersName allUsersName;
@Inject
Factory(
ExternalIdCache externalIdCache,
AccountCache accountCache,
Provider<AccountIndexer> accountIndexer,
MetricMaker metricMaker) {
MetricMaker metricMaker,
AllUsersName allUsersName) {
this.externalIdCache = externalIdCache;
this.accountCache = accountCache;
this.accountIndexer = accountIndexer;
this.metricMaker = metricMaker;
this.allUsersName = allUsersName;
}
@Override
public ExternalIdNotes load(Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return new ExternalIdNotes(
externalIdCache, accountCache, accountIndexer, metricMaker, allUsersRepo)
externalIdCache,
accountCache,
accountIndexer,
metricMaker,
allUsersName,
allUsersRepo)
.load();
}
@ -142,7 +151,12 @@ public class ExternalIdNotes extends VersionedMetaData {
public ExternalIdNotes load(Repository allUsersRepo, @Nullable ObjectId rev)
throws IOException, ConfigInvalidException {
return new ExternalIdNotes(
externalIdCache, accountCache, accountIndexer, metricMaker, allUsersRepo)
externalIdCache,
accountCache,
accountIndexer,
metricMaker,
allUsersName,
allUsersRepo)
.load(rev);
}
}
@ -151,23 +165,30 @@ public class ExternalIdNotes extends VersionedMetaData {
public static class FactoryNoReindex implements ExternalIdNotesLoader {
private final ExternalIdCache externalIdCache;
private final MetricMaker metricMaker;
private final AllUsersName allUsersName;
@Inject
FactoryNoReindex(ExternalIdCache externalIdCache, MetricMaker metricMaker) {
FactoryNoReindex(
ExternalIdCache externalIdCache, MetricMaker metricMaker, AllUsersName allUsersName) {
this.externalIdCache = externalIdCache;
this.metricMaker = metricMaker;
this.allUsersName = allUsersName;
}
@Override
public ExternalIdNotes load(Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return new ExternalIdNotes(externalIdCache, null, null, metricMaker, allUsersRepo).load();
return new ExternalIdNotes(
externalIdCache, null, null, metricMaker, allUsersName, allUsersRepo)
.load();
}
@Override
public ExternalIdNotes load(Repository allUsersRepo, @Nullable ObjectId rev)
throws IOException, ConfigInvalidException {
return new ExternalIdNotes(externalIdCache, null, null, metricMaker, allUsersRepo).load(rev);
return new ExternalIdNotes(
externalIdCache, null, null, metricMaker, allUsersName, allUsersRepo)
.load(rev);
}
}
@ -177,10 +198,15 @@ public class ExternalIdNotes extends VersionedMetaData {
*
* @return read-only {@link ExternalIdNotes} instance
*/
public static ExternalIdNotes loadReadOnly(Repository allUsersRepo)
public static ExternalIdNotes loadReadOnly(AllUsersName allUsersName, Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return new ExternalIdNotes(
new DisabledExternalIdCache(), null, null, new DisabledMetricMaker(), allUsersRepo)
new DisabledExternalIdCache(),
null,
null,
new DisabledMetricMaker(),
allUsersName,
allUsersRepo)
.setReadOnly()
.load();
}
@ -195,10 +221,16 @@ public class ExternalIdNotes extends VersionedMetaData {
* external IDs will be empty
* @return read-only {@link ExternalIdNotes} instance
*/
public static ExternalIdNotes loadReadOnly(Repository allUsersRepo, @Nullable ObjectId rev)
public static ExternalIdNotes loadReadOnly(
AllUsersName allUsersName, Repository allUsersRepo, @Nullable ObjectId rev)
throws IOException, ConfigInvalidException {
return new ExternalIdNotes(
new DisabledExternalIdCache(), null, null, new DisabledMetricMaker(), allUsersRepo)
new DisabledExternalIdCache(),
null,
null,
new DisabledMetricMaker(),
allUsersName,
allUsersRepo)
.setReadOnly()
.load(rev);
}
@ -213,16 +245,23 @@ public class ExternalIdNotes extends VersionedMetaData {
*
* @return {@link ExternalIdNotes} instance that doesn't updates caches on save
*/
public static ExternalIdNotes loadNoCacheUpdate(Repository allUsersRepo)
public static ExternalIdNotes loadNoCacheUpdate(
AllUsersName allUsersName, Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return new ExternalIdNotes(
new DisabledExternalIdCache(), null, null, new DisabledMetricMaker(), allUsersRepo)
new DisabledExternalIdCache(),
null,
null,
new DisabledMetricMaker(),
allUsersName,
allUsersRepo)
.load();
}
private final ExternalIdCache externalIdCache;
@Nullable private final AccountCache accountCache;
@Nullable private final Provider<AccountIndexer> accountIndexer;
private final AllUsersName allUsersName;
private final Counter0 updateCount;
private final Repository repo;
@ -243,6 +282,7 @@ public class ExternalIdNotes extends VersionedMetaData {
@Nullable AccountCache accountCache,
@Nullable Provider<AccountIndexer> accountIndexer,
MetricMaker metricMaker,
AllUsersName allUsersName,
Repository allUsersRepo) {
this.externalIdCache = checkNotNull(externalIdCache, "externalIdCache");
this.accountCache = accountCache;
@ -251,6 +291,7 @@ public class ExternalIdNotes extends VersionedMetaData {
metricMaker.newCounter(
"notedb/external_id_update_count",
new Description("Total number of external ID updates.").setRate().setUnit("updates"));
this.allUsersName = checkNotNull(allUsersName, "allUsersRepo");
this.repo = checkNotNull(allUsersRepo, "allUsersRepo");
}
@ -279,7 +320,7 @@ public class ExternalIdNotes extends VersionedMetaData {
* @return {@link ExternalIdNotes} instance for chaining
*/
private ExternalIdNotes load() throws IOException, ConfigInvalidException {
load(repo);
load(allUsersName, repo);
return this;
}
@ -298,10 +339,10 @@ public class ExternalIdNotes extends VersionedMetaData {
return load();
}
if (ObjectId.zeroId().equals(rev)) {
load(repo, null);
load(allUsersName, repo, null);
return this;
}
load(repo, rev);
load(allUsersName, repo, rev);
return this;
}
@ -636,7 +677,7 @@ public class ExternalIdNotes extends VersionedMetaData {
*
* <p>Must only be called after committing changes.
*
* <p>No-op if this instance was created by {@link #loadNoCacheUpdate(Repository)}.
* <p>No-op if this instance was created by {@link #loadNoCacheUpdate(AllUsersName, Repository)}.
*
* <p>No eviction from account cache and no reindex if this instance was created by {@link
* FactoryNoReindex}.
@ -651,7 +692,7 @@ public class ExternalIdNotes extends VersionedMetaData {
*
* <p>Must only be called after committing changes.
*
* <p>No-op if this instance was created by {@link #loadNoCacheUpdate(Repository)}.
* <p>No-op if this instance was created by {@link #loadNoCacheUpdate(AllUsersName, Repository)}.
*
* <p>No eviction from account cache if this instance was created by {@link FactoryNoReindex}.
*

View File

@ -99,7 +99,7 @@ public class ExternalIdReader {
try (Timer0.Context ctx = readAllLatency.start();
Repository repo = repoManager.openRepository(allUsersName)) {
return ExternalIdNotes.loadReadOnly(repo).all();
return ExternalIdNotes.loadReadOnly(allUsersName, repo).all();
}
}
@ -118,7 +118,7 @@ public class ExternalIdReader {
try (Timer0.Context ctx = readAllLatency.start();
Repository repo = repoManager.openRepository(allUsersName)) {
return ExternalIdNotes.loadReadOnly(repo, rev).all();
return ExternalIdNotes.loadReadOnly(allUsersName, repo, rev).all();
}
}
@ -127,7 +127,7 @@ public class ExternalIdReader {
checkReadEnabled();
try (Repository repo = repoManager.openRepository(allUsersName)) {
return ExternalIdNotes.loadReadOnly(repo).get(key);
return ExternalIdNotes.loadReadOnly(allUsersName, repo).get(key);
}
}
@ -137,7 +137,7 @@ public class ExternalIdReader {
checkReadEnabled();
try (Repository repo = repoManager.openRepository(allUsersName)) {
return ExternalIdNotes.loadReadOnly(repo, rev).get(key);
return ExternalIdNotes.loadReadOnly(allUsersName, repo, rev).get(key);
}
}

View File

@ -59,14 +59,14 @@ public class ExternalIdsConsistencyChecker {
public List<ConsistencyProblemInfo> check() throws IOException, ConfigInvalidException {
try (Repository repo = repoManager.openRepository(allUsers)) {
return check(ExternalIdNotes.loadReadOnly(repo));
return check(ExternalIdNotes.loadReadOnly(allUsers, repo));
}
}
public List<ConsistencyProblemInfo> check(ObjectId rev)
throws IOException, ConfigInvalidException {
try (Repository repo = repoManager.openRepository(allUsers)) {
return check(ExternalIdNotes.loadReadOnly(repo, rev));
return check(ExternalIdNotes.loadReadOnly(allUsers, repo, rev));
}
}

View File

@ -17,7 +17,9 @@ package com.google.gerrit.server.git.meta;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.MoreObjects;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.LockFailureException;
import java.io.BufferedReader;
import java.io.IOException;
@ -62,6 +64,8 @@ import org.eclipse.jgit.util.RawParseUtils;
* read from the repository, or format an update that can later be written back to the repository.
*/
public abstract class VersionedMetaData {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
/**
* Path information that does not hold references to any repository data structures, allowing the
* application to retain this object for long periods of time.
@ -81,6 +85,7 @@ public abstract class VersionedMetaData {
/** The revision at which the data was loaded. Is null for data yet to be created. */
@Nullable protected RevCommit revision;
protected Project.NameKey projectName;
protected RevWalk rw;
protected ObjectReader reader;
protected ObjectInserter inserter;
@ -114,13 +119,15 @@ public abstract class VersionedMetaData {
* <p>The repository is not held after the call completes, allowing the application to retain this
* object for long periods of time.
*
* @param projectName the name of the project
* @param db repository to access.
* @throws IOException
* @throws ConfigInvalidException
*/
public void load(Repository db) throws IOException, ConfigInvalidException {
public void load(Project.NameKey projectName, Repository db)
throws IOException, ConfigInvalidException {
Ref ref = db.getRefDatabase().exactRef(getRefName());
load(db, ref != null ? ref.getObjectId() : null);
load(projectName, db, ref != null ? ref.getObjectId() : null);
}
/**
@ -133,15 +140,16 @@ public abstract class VersionedMetaData {
* <p>The repository is not held after the call completes, allowing the application to retain this
* object for long periods of time.
*
* @param projectName the name of the project
* @param db repository to access.
* @param id revision to load.
* @throws IOException
* @throws ConfigInvalidException
*/
public void load(Repository db, @Nullable ObjectId id)
public void load(Project.NameKey projectName, Repository db, @Nullable ObjectId id)
throws IOException, ConfigInvalidException {
try (RevWalk walk = new RevWalk(db)) {
load(walk, id);
load(projectName, walk, id);
}
}
@ -156,12 +164,15 @@ public abstract class VersionedMetaData {
* instance does not hold a reference to the walk or the repository after the call completes,
* allowing the application to retain this object for long periods of time.
*
* @param projectName the name of the project
* @param walk open walk to access to access.
* @param id revision to load.
* @throws IOException
* @throws ConfigInvalidException
*/
public void load(RevWalk walk, ObjectId id) throws IOException, ConfigInvalidException {
public void load(Project.NameKey projectName, RevWalk walk, ObjectId id)
throws IOException, ConfigInvalidException {
this.projectName = projectName;
this.rw = walk;
this.reader = walk.getObjectReader();
try {
@ -174,11 +185,11 @@ public abstract class VersionedMetaData {
}
public void load(MetaDataUpdate update) throws IOException, ConfigInvalidException {
load(update.getRepository());
load(update.getProjectName(), update.getRepository());
}
public void load(MetaDataUpdate update, ObjectId id) throws IOException, ConfigInvalidException {
load(update.getRepository(), id);
load(update.getProjectName(), update.getRepository(), id);
}
/**
@ -481,6 +492,9 @@ public abstract class VersionedMetaData {
return new byte[] {};
}
logger.atFine().log(
"Read file '%s' from ref '%s' of project '%s' from revision '%s'",
fileName, getRefName(), projectName, revision.name());
try (TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree())) {
if (tw != null) {
ObjectLoader obj = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB);
@ -553,6 +567,8 @@ public abstract class VersionedMetaData {
}
protected void saveFile(String fileName, byte[] raw) throws IOException {
logger.atFine().log(
"Save file '%s' in ref '%s' of project '%s'", fileName, getRefName(), projectName);
DirCacheEditor editor = newTree.editor();
if (raw != null && 0 < raw.length) {
final ObjectId blobId = inserter.insert(Constants.OBJ_BLOB, raw);

View File

@ -972,7 +972,7 @@ class ReceiveCommits {
case UPDATE_NONFASTFORWARD:
try {
ProjectConfig cfg = new ProjectConfig(project.getNameKey());
cfg.load(receivePack.getRevWalk(), cmd.getNewId());
cfg.load(project.getNameKey(), receivePack.getRevWalk(), cmd.getNewId());
if (!cfg.getValidationErrors().isEmpty()) {
addError("Invalid project configuration:");
for (ValidationError err : cfg.getValidationErrors()) {

View File

@ -22,6 +22,7 @@ import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountConfig;
import com.google.gerrit.server.account.AccountProperties;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.ValidationError;
import com.google.gerrit.server.mail.send.OutgoingEmailValidator;
import com.google.inject.Inject;
@ -38,21 +39,30 @@ import org.eclipse.jgit.revwalk.RevWalk;
public class AccountValidator {
private final Provider<IdentifiedUser> self;
private final AllUsersName allUsersName;
private final OutgoingEmailValidator emailValidator;
@Inject
public AccountValidator(Provider<IdentifiedUser> self, OutgoingEmailValidator emailValidator) {
public AccountValidator(
Provider<IdentifiedUser> self,
AllUsersName allUsersName,
OutgoingEmailValidator emailValidator) {
this.self = self;
this.allUsersName = allUsersName;
this.emailValidator = emailValidator;
}
public List<String> validate(
Account.Id accountId, Repository repo, RevWalk rw, @Nullable ObjectId oldId, ObjectId newId)
Account.Id accountId,
Repository allUsersRepo,
RevWalk rw,
@Nullable ObjectId oldId,
ObjectId newId)
throws IOException {
Optional<Account> oldAccount = Optional.empty();
if (oldId != null && !ObjectId.zeroId().equals(oldId)) {
try {
oldAccount = loadAccount(accountId, repo, rw, oldId, null);
oldAccount = loadAccount(accountId, allUsersRepo, rw, oldId, null);
} catch (ConfigInvalidException e) {
// ignore, maybe the new commit is repairing it now
}
@ -61,7 +71,7 @@ public class AccountValidator {
List<String> messages = new ArrayList<>();
Optional<Account> newAccount;
try {
newAccount = loadAccount(accountId, repo, rw, newId, messages);
newAccount = loadAccount(accountId, allUsersRepo, rw, newId, messages);
} catch (ConfigInvalidException e) {
return ImmutableList.of(
String.format(
@ -94,14 +104,14 @@ public class AccountValidator {
private Optional<Account> loadAccount(
Account.Id accountId,
Repository repo,
Repository allUsersRepo,
RevWalk rw,
ObjectId commit,
@Nullable List<String> messages)
throws IOException, ConfigInvalidException {
rw.reset();
AccountConfig accountConfig = new AccountConfig(accountId, repo);
accountConfig.load(rw, commit);
AccountConfig accountConfig = new AccountConfig(accountId, allUsersName, allUsersRepo);
accountConfig.load(allUsersName, rw, commit);
if (messages != null) {
messages.addAll(
accountConfig

View File

@ -152,7 +152,7 @@ public class MergeValidators {
final Project.NameKey newParent;
try {
ProjectConfig cfg = new ProjectConfig(destProject.getNameKey());
cfg.load(repo, commit);
cfg.load(destProject.getNameKey(), repo, commit);
newParent = cfg.getProject().getParent(allProjectsName);
final Project.NameKey oldParent = destProject.getProject().getParent(allProjectsName);
if (oldParent == null) {

View File

@ -24,6 +24,7 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.GerritServerId;
import com.google.gerrit.server.notedb.NoteDbUtil;
import com.google.inject.Inject;
@ -49,10 +50,12 @@ public class AuditLogReader {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private final String serverId;
private final AllUsersName allUsersName;
@Inject
public AuditLogReader(@GerritServerId String serverId) {
public AuditLogReader(@GerritServerId String serverId, AllUsersName allUsersName) {
this.serverId = serverId;
this.allUsersName = allUsersName;
}
// Having separate methods for reading the two types of audit records mirrors the split in
@ -60,8 +63,8 @@ public class AuditLogReader {
// revisit this, e.g. to do only a single walk, or even change the record types.
public ImmutableList<AccountGroupMemberAudit> getMembersAudit(
Repository repo, AccountGroup.UUID uuid) throws IOException, ConfigInvalidException {
return getMembersAudit(getGroupId(repo, uuid), parseCommits(repo, uuid));
Repository allUsersRepo, AccountGroup.UUID uuid) throws IOException, ConfigInvalidException {
return getMembersAudit(getGroupId(allUsersRepo, uuid), parseCommits(allUsersRepo, uuid));
}
private ImmutableList<AccountGroupMemberAudit> getMembersAudit(
@ -211,10 +214,13 @@ public class AuditLogReader {
}
}
private AccountGroup.Id getGroupId(Repository repo, AccountGroup.UUID uuid)
private AccountGroup.Id getGroupId(Repository allUsersRepo, AccountGroup.UUID uuid)
throws ConfigInvalidException, IOException {
// TODO(dborowitz): This re-walks all commits just to find createdOn, which we don't need.
return GroupConfig.loadForGroup(repo, uuid).getLoadedGroup().get().getId();
return GroupConfig.loadForGroup(allUsersName, allUsersRepo, uuid)
.getLoadedGroup()
.get()
.getId();
}
@AutoValue

View File

@ -27,6 +27,7 @@ import com.google.common.collect.Streams;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.git.meta.VersionedMetaData;
@ -51,9 +52,10 @@ import org.eclipse.jgit.revwalk.RevSort;
* A representation of a group in NoteDb.
*
* <p>Groups in NoteDb can be created by following the descriptions of {@link
* #createForNewGroup(Repository, InternalGroupCreation)}. For reading groups from NoteDb or
* updating them, refer to {@link #loadForGroup(Repository, AccountGroup.UUID)} or {@link
* #loadForGroupSnapshot(Repository, AccountGroup.UUID, ObjectId)}.
* #createForNewGroup(Project.NameKey, Repository, InternalGroupCreation)}. For reading groups from
* NoteDb or updating them, refer to {@link #loadForGroup(Project.NameKey, Repository,
* AccountGroup.UUID)} or {@link #loadForGroupSnapshot(Project.NameKey, Repository,
* AccountGroup.UUID, ObjectId)}.
*
* <p><strong>Note: </strong>Any modification (group creation or update) only becomes permanent (and
* hence written to NoteDb) if {@link #commit(MetaDataUpdate)} is called.
@ -100,6 +102,7 @@ public class GroupConfig extends VersionedMetaData {
* <p><strong>Note: </strong>The returned {@code GroupConfig} has to be committed via {@link
* #commit(MetaDataUpdate)} in order to create the group for real.
*
* @param projectName the name of the project which holds the NoteDb commits for groups
* @param repository the repository which holds the NoteDb commits for groups
* @param groupCreation an {@code InternalGroupCreation} specifying all properties which are
* required for a new group
@ -110,10 +113,10 @@ public class GroupConfig extends VersionedMetaData {
* @throws OrmDuplicateKeyException if a group with the same UUID already exists
*/
public static GroupConfig createForNewGroup(
Repository repository, InternalGroupCreation groupCreation)
Project.NameKey projectName, Repository repository, InternalGroupCreation groupCreation)
throws IOException, ConfigInvalidException, OrmDuplicateKeyException {
GroupConfig groupConfig = new GroupConfig(groupCreation.getGroupUUID());
groupConfig.load(repository);
groupConfig.load(projectName, repository);
groupConfig.setGroupCreation(groupCreation);
return groupConfig;
}
@ -131,27 +134,30 @@ public class GroupConfig extends VersionedMetaData {
* {@code InternalGroupUpdate} via {@link #setGroupUpdate(InternalGroupUpdate, AuditLogFormatter)}
* and committing the {@code GroupConfig} via {@link #commit(MetaDataUpdate)}.
*
* @param projectName the name of the project which holds the NoteDb commits for groups
* @param repository the repository which holds the NoteDb commits for groups
* @param groupUuid the UUID of the group
* @return a {@code GroupConfig} for the group with the specified UUID
* @throws IOException if the repository can't be accessed for some reason
* @throws ConfigInvalidException if the group exists but can't be read due to an invalid format
*/
public static GroupConfig loadForGroup(Repository repository, AccountGroup.UUID groupUuid)
public static GroupConfig loadForGroup(
Project.NameKey projectName, Repository repository, AccountGroup.UUID groupUuid)
throws IOException, ConfigInvalidException {
GroupConfig groupConfig = new GroupConfig(groupUuid);
groupConfig.load(repository);
groupConfig.load(projectName, repository);
return groupConfig;
}
/**
* Creates a {@code GroupConfig} for an existing group at a specific revision of the repository.
*
* <p>This method behaves nearly the same as {@link #loadForGroup(Repository, AccountGroup.UUID)}.
* The only difference is that {@link #loadForGroup(Repository, AccountGroup.UUID)} loads the
* group from the current state of the repository whereas this method loads the group at a
* specific (maybe past) revision.
* <p>This method behaves nearly the same as {@link #loadForGroup(Project.NameKey, Repository,
* AccountGroup.UUID)}. The only difference is that {@link #loadForGroup(Project.NameKey,
* Repository, AccountGroup.UUID)} loads the group from the current state of the repository
* whereas this method loads the group at a specific (maybe past) revision.
*
* @param projectName the name of the project which holds the NoteDb commits for groups
* @param repository the repository which holds the NoteDb commits for groups
* @param groupUuid the UUID of the group
* @param commitId the revision of the repository at which the group should be loaded
@ -160,10 +166,13 @@ public class GroupConfig extends VersionedMetaData {
* @throws ConfigInvalidException if the group exists but can't be read due to an invalid format
*/
public static GroupConfig loadForGroupSnapshot(
Repository repository, AccountGroup.UUID groupUuid, ObjectId commitId)
Project.NameKey projectName,
Repository repository,
AccountGroup.UUID groupUuid,
ObjectId commitId)
throws IOException, ConfigInvalidException {
GroupConfig groupConfig = new GroupConfig(groupUuid);
groupConfig.load(repository, commitId);
groupConfig.load(projectName, repository, commitId);
return groupConfig;
}

View File

@ -29,6 +29,7 @@ import com.google.common.hash.Hashing;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.meta.VersionedMetaData;
import com.google.gwtorm.server.OrmDuplicateKeyException;
@ -62,12 +63,12 @@ import org.eclipse.jgit.transport.ReceiveCommand;
* map of name/UUID pairs and manage it with this class.
*
* <p>To claim the name for a new group, create an instance of {@code GroupNameNotes} via {@link
* #forNewGroup(Repository, AccountGroup.UUID, AccountGroup.NameKey)} and call {@link
* #commit(com.google.gerrit.server.git.meta.MetaDataUpdate) commit(MetaDataUpdate)} on it. For
* renaming, call {@link #forRename(Repository, AccountGroup.UUID, AccountGroup.NameKey,
* AccountGroup.NameKey)} and also commit the returned {@code GroupNameNotes}. Both times, the
* creation of the {@code GroupNameNotes} will fail if the (new) name is already used. Committing
* the {@code GroupNameNotes} is necessary to make the adjustments for real.
* #forNewGroup(Project.NameKey, Repository, AccountGroup.UUID, AccountGroup.NameKey)} and call
* {@link #commit(com.google.gerrit.server.git.meta.MetaDataUpdate) commit(MetaDataUpdate)} on it.
* For renaming, call {@link #forRename(Project.NameKey, Repository, AccountGroup.UUID,
* AccountGroup.NameKey, AccountGroup.NameKey)} and also commit the returned {@code GroupNameNotes}.
* Both times, the creation of the {@code GroupNameNotes} will fail if the (new) name is already
* used. Committing the {@code GroupNameNotes} is necessary to make the adjustments for real.
*
* <p>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).
@ -101,6 +102,7 @@ public class GroupNameNotes extends VersionedMetaData {
* via {@link #commit(com.google.gerrit.server.git.meta.MetaDataUpdate) commit(MetaDataUpdate)} in
* order to claim the new name and free up the old one.
*
* @param projectName the name of the project which holds the commits of the notes
* @param repository the repository which holds the commits of the notes
* @param groupUuid the UUID of the group which is renamed
* @param oldName the current name of the group
@ -112,6 +114,7 @@ public class GroupNameNotes extends VersionedMetaData {
* @throws OrmDuplicateKeyException if a group with the new name already exists
*/
public static GroupNameNotes forRename(
Project.NameKey projectName,
Repository repository,
AccountGroup.UUID groupUuid,
AccountGroup.NameKey oldName,
@ -121,7 +124,7 @@ public class GroupNameNotes extends VersionedMetaData {
checkNotNull(newName);
GroupNameNotes groupNameNotes = new GroupNameNotes(groupUuid, oldName, newName);
groupNameNotes.load(repository);
groupNameNotes.load(projectName, repository);
groupNameNotes.ensureNewNameIsNotUsed();
return groupNameNotes;
}
@ -133,6 +136,7 @@ public class GroupNameNotes extends VersionedMetaData {
* via {@link #commit(com.google.gerrit.server.git.meta.MetaDataUpdate) commit(MetaDataUpdate)} in
* order to claim the new name.
*
* @param projectName the name of the project which holds the commits of the notes
* @param repository the repository which holds the commits of the notes
* @param groupUuid the UUID of the new group
* @param groupName the name of the new group
@ -142,12 +146,15 @@ public class GroupNameNotes extends VersionedMetaData {
* @throws OrmDuplicateKeyException if a group with the new name already exists
*/
public static GroupNameNotes forNewGroup(
Repository repository, AccountGroup.UUID groupUuid, AccountGroup.NameKey groupName)
Project.NameKey projectName,
Repository repository,
AccountGroup.UUID groupUuid,
AccountGroup.NameKey groupName)
throws IOException, ConfigInvalidException, OrmDuplicateKeyException {
checkNotNull(groupName);
GroupNameNotes groupNameNotes = new GroupNameNotes(groupUuid, null, groupName);
groupNameNotes.load(repository);
groupNameNotes.load(projectName, repository);
groupNameNotes.ensureNewNameIsNotUsed();
return groupNameNotes;
}

View File

@ -70,14 +70,14 @@ public class Groups {
public Optional<InternalGroup> getGroup(AccountGroup.UUID groupUuid)
throws IOException, ConfigInvalidException {
try (Repository allUsersRepo = repoManager.openRepository(allUsersName)) {
return getGroupFromNoteDb(allUsersRepo, groupUuid);
return getGroupFromNoteDb(allUsersName, allUsersRepo, groupUuid);
}
}
private static Optional<InternalGroup> getGroupFromNoteDb(
Repository allUsersRepository, AccountGroup.UUID groupUuid)
AllUsersName allUsersName, Repository allUsersRepository, AccountGroup.UUID groupUuid)
throws IOException, ConfigInvalidException {
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsersRepository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsersName, allUsersRepository, groupUuid);
Optional<InternalGroup> loadedGroup = groupConfig.getLoadedGroup();
if (loadedGroup.isPresent()) {
// Check consistency with group name notes.
@ -110,16 +110,18 @@ public class Groups {
*/
public Stream<AccountGroup.UUID> getExternalGroups() throws IOException, ConfigInvalidException {
try (Repository allUsersRepo = repoManager.openRepository(allUsersName)) {
return getExternalGroupsFromNoteDb(allUsersRepo);
return getExternalGroupsFromNoteDb(allUsersName, allUsersRepo);
}
}
private static Stream<AccountGroup.UUID> getExternalGroupsFromNoteDb(Repository allUsersRepo)
private static Stream<AccountGroup.UUID> getExternalGroupsFromNoteDb(
AllUsersName allUsersName, Repository allUsersRepo)
throws IOException, ConfigInvalidException {
ImmutableList<GroupReference> allInternalGroups = GroupNameNotes.loadAllGroups(allUsersRepo);
ImmutableSet.Builder<AccountGroup.UUID> allSubgroups = ImmutableSet.builder();
for (GroupReference internalGroup : allInternalGroups) {
Optional<InternalGroup> group = getGroupFromNoteDb(allUsersRepo, internalGroup.getUUID());
Optional<InternalGroup> group =
getGroupFromNoteDb(allUsersName, allUsersRepo, internalGroup.getUUID());
group.map(InternalGroup::getSubgroups).ifPresent(allSubgroups::addAll);
}
return allSubgroups
@ -131,15 +133,16 @@ public class Groups {
/**
* Returns the membership audit records for a given group.
*
* @param repo All-Users repository.
* @param allUsersRepo All-Users repository.
* @param groupUuid the UUID of the group
* @return the audit records, in arbitrary order; empty if the group does not exist
* @throws IOException if an error occurs while reading from NoteDb
* @throws ConfigInvalidException if the group couldn't be retrieved from NoteDb
*/
public List<AccountGroupMemberAudit> getMembersAudit(Repository repo, AccountGroup.UUID groupUuid)
public List<AccountGroupMemberAudit> getMembersAudit(
Repository allUsersRepo, AccountGroup.UUID groupUuid)
throws IOException, ConfigInvalidException {
return auditLogReader.getMembersAudit(repo, groupUuid);
return auditLogReader.getMembersAudit(allUsersRepo, groupUuid);
}
/**

View File

@ -28,7 +28,9 @@ import com.google.gerrit.extensions.api.config.ConsistencyCheckInfo;
import com.google.gerrit.extensions.api.config.ConsistencyCheckInfo.ConsistencyProblemInfo;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.group.InternalGroup;
import com.google.inject.Inject;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -53,6 +55,13 @@ import org.eclipse.jgit.revwalk.RevWalk;
public class GroupsNoteDbConsistencyChecker {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private final AllUsersName allUsersName;
@Inject
GroupsNoteDbConsistencyChecker(AllUsersName allUsersName) {
this.allUsersName = allUsersName;
}
/**
* The result of a consistency check. The UUID map is only non-null if no problems were detected.
*/
@ -63,15 +72,15 @@ public class GroupsNoteDbConsistencyChecker {
}
/** Checks for problems with the given All-Users repo. */
public Result check(Repository repo) throws IOException {
Result r = doCheck(repo);
public Result check(Repository allUsersRepo) throws IOException {
Result r = doCheck(allUsersRepo);
if (!r.problems.isEmpty()) {
r.uuidToGroupMap = null;
}
return r;
}
private Result doCheck(Repository repo) throws IOException {
private Result doCheck(Repository allUsersRepo) throws IOException {
Result result = new Result();
result.problems = new ArrayList<>();
result.uuidToGroupMap = new HashMap<>();
@ -79,9 +88,9 @@ public class GroupsNoteDbConsistencyChecker {
BiMap<AccountGroup.UUID, String> uuidNameBiMap = HashBiMap.create();
// Get all refs in an attempt to avoid seeing half committed group updates.
Map<String, Ref> refs = repo.getAllRefs();
readGroups(repo, refs, result);
readGroupNames(repo, refs, result, uuidNameBiMap);
Map<String, Ref> refs = allUsersRepo.getAllRefs();
readGroups(allUsersRepo, refs, result);
readGroupNames(allUsersRepo, refs, result, uuidNameBiMap);
// The sequential IDs are not keys in NoteDb, so no need to check them.
if (!result.problems.isEmpty()) {
@ -94,7 +103,7 @@ public class GroupsNoteDbConsistencyChecker {
return result;
}
private void readGroups(Repository repo, Map<String, Ref> refs, Result result)
private void readGroups(Repository allUsersRepo, Map<String, Ref> refs, Result result)
throws IOException {
for (Map.Entry<String, Ref> entry : refs.entrySet()) {
if (!entry.getKey().startsWith(RefNames.REFS_GROUPS)) {
@ -108,7 +117,8 @@ public class GroupsNoteDbConsistencyChecker {
}
try {
GroupConfig cfg =
GroupConfig.loadForGroupSnapshot(repo, uuid, entry.getValue().getObjectId());
GroupConfig.loadForGroupSnapshot(
allUsersName, allUsersRepo, uuid, entry.getValue().getObjectId());
result.uuidToGroupMap.put(uuid, cfg.getLoadedGroup().get());
} catch (ConfigInvalidException e) {
result.problems.add(error("group %s does not parse: %s", uuid, e.getMessage()));

View File

@ -232,9 +232,11 @@ public class GroupsUpdate {
try (Repository allUsersRepo = repoManager.openRepository(allUsersName)) {
AccountGroup.NameKey groupName = groupUpdate.getName().orElseGet(groupCreation::getNameKey);
GroupNameNotes groupNameNotes =
GroupNameNotes.forNewGroup(allUsersRepo, groupCreation.getGroupUUID(), groupName);
GroupNameNotes.forNewGroup(
allUsersName, allUsersRepo, groupCreation.getGroupUUID(), groupName);
GroupConfig groupConfig = GroupConfig.createForNewGroup(allUsersRepo, groupCreation);
GroupConfig groupConfig =
GroupConfig.createForNewGroup(allUsersName, allUsersRepo, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
commit(allUsersRepo, groupConfig, groupNameNotes);
@ -269,7 +271,7 @@ public class GroupsUpdate {
AccountGroup.UUID groupUuid, InternalGroupUpdate groupUpdate)
throws IOException, ConfigInvalidException, OrmDuplicateKeyException, NoSuchGroupException {
try (Repository allUsersRepo = repoManager.openRepository(allUsersName)) {
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsersRepo, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsersName, allUsersRepo, groupUuid);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
if (!groupConfig.getLoadedGroup().isPresent()) {
throw new NoSuchGroupException(groupUuid);
@ -280,7 +282,8 @@ public class GroupsUpdate {
if (groupUpdate.getName().isPresent()) {
AccountGroup.NameKey oldName = originalGroup.getNameKey();
AccountGroup.NameKey newName = groupUpdate.getName().get();
groupNameNotes = GroupNameNotes.forRename(allUsersRepo, groupUuid, oldName, newName);
groupNameNotes =
GroupNameNotes.forRename(allUsersName, allUsersRepo, groupUuid, oldName, newName);
}
commit(allUsersRepo, groupConfig, groupNameNotes);

View File

@ -274,7 +274,7 @@ public class ProjectCacheImpl implements ProjectCache {
Project.NameKey key = new Project.NameKey(projectName);
try (Repository git = mgr.openRepository(key)) {
ProjectConfig cfg = new ProjectConfig(key);
cfg.load(git);
cfg.load(key, git);
ProjectState state = projectStateFactory.create(cfg);
state.initLastCheck(now);

View File

@ -25,6 +25,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.primitives.Shorts;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.ContributorAgreement;
import com.google.gerrit.common.data.GlobalCapability;
@ -77,6 +78,8 @@ import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.RefSpec;
public class ProjectConfig extends VersionedMetaData implements ValidationError.Sink {
@ -158,7 +161,6 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError.
private static final Pattern EXCLUSIVE_PERMISSIONS_SPLIT_PATTERN = Pattern.compile("[, \t]{1,}");
private Project.NameKey projectName;
private Project project;
private AccountsSection accountsSection;
private GroupList groupList;
@ -239,6 +241,20 @@ public class ProjectConfig extends VersionedMetaData implements ValidationError.
this.projectName = projectName;
}
public void load(Repository repo) throws IOException, ConfigInvalidException {
super.load(projectName, repo);
}
public void load(Repository repo, @Nullable ObjectId revision)
throws IOException, ConfigInvalidException {
super.load(projectName, repo, revision);
}
public void load(RevWalk rw, @Nullable ObjectId revision)
throws IOException, ConfigInvalidException {
super.load(projectName, rw, revision);
}
public Project.NameKey getName() {
return projectName;
}

View File

@ -225,7 +225,7 @@ public class ProjectState {
ProjectLevelConfig cfg = new ProjectLevelConfig(fileName, this);
try (Repository git = gitMgr.openRepository(getNameKey())) {
cfg.load(git, config.getRevision());
cfg.load(getNameKey(), git, config.getRevision());
} catch (IOException | ConfigInvalidException e) {
logger.atWarning().withCause(e).log("Failed to load %s for %s", fileName, getName());
}

View File

@ -1107,7 +1107,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
public Predicate<ChangeData> query(String name) throws QueryParseException {
try (Repository git = args.repoManager.openRepository(args.allUsersName)) {
VersionedAccountQueries q = VersionedAccountQueries.forUser(self());
q.load(git);
q.load(args.allUsersName, git);
String query = q.getQueryList().getQuery(name);
if (query != null) {
return parse(query);
@ -1131,7 +1131,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
public Predicate<ChangeData> destination(String name) throws QueryParseException {
try (Repository git = args.repoManager.openRepository(args.allUsersName)) {
VersionedAccountDestinations d = VersionedAccountDestinations.forUser(self());
d.load(git);
d.load(args.allUsersName, git);
Set<Branch.NameKey> destinations = d.getDestinationList().getDestinations(name);
if (destinations != null && !destinations.isEmpty()) {
return new DestinationPredicate(destinations, name);

View File

@ -44,7 +44,7 @@ public class GetDiffPreferences implements RestReadView<ConfigResource> {
public DiffPreferencesInfo apply(ConfigResource configResource)
throws BadRequestException, ResourceConflictException, IOException, ConfigInvalidException {
try (Repository git = gitManager.openRepository(allUsersName)) {
return Preferences.readDefaultDiffPreferences(git);
return Preferences.readDefaultDiffPreferences(allUsersName, git);
}
}
}

View File

@ -43,7 +43,7 @@ public class GetEditPreferences implements RestReadView<ConfigResource> {
public EditPreferencesInfo apply(ConfigResource configResource)
throws BadRequestException, ResourceConflictException, IOException, ConfigInvalidException {
try (Repository git = gitManager.openRepository(allUsersName)) {
return Preferences.readDefaultEditPreferences(git);
return Preferences.readDefaultEditPreferences(allUsersName, git);
}
}
}

View File

@ -41,7 +41,7 @@ public class GetPreferences implements RestReadView<ConfigResource> {
public GeneralPreferencesInfo apply(ConfigResource rsrc)
throws IOException, ConfigInvalidException {
try (Repository git = gitMgr.openRepository(allUsersName)) {
return Preferences.readDefaultGeneralPreferences(git);
return Preferences.readDefaultGeneralPreferences(allUsersName, git);
}
}
}

View File

@ -38,6 +38,7 @@ import com.google.gerrit.reviewdb.client.AccountGroupById;
import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
import com.google.gerrit.reviewdb.client.AccountGroupMember;
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.reviewdb.server.ReviewDbWrapper;
import com.google.gerrit.server.group.InternalGroup;
@ -118,9 +119,10 @@ abstract class GroupBundle {
this.auditLogReader = auditLogReader;
}
public GroupBundle fromNoteDb(Repository repo, AccountGroup.UUID uuid)
public GroupBundle fromNoteDb(
Project.NameKey projectName, Repository repo, AccountGroup.UUID uuid)
throws ConfigInvalidException, IOException {
GroupConfig groupConfig = GroupConfig.loadForGroup(repo, uuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repo, uuid);
InternalGroup internalGroup = groupConfig.getLoadedGroup().get();
AccountGroup.Id groupId = internalGroup.getId();

View File

@ -81,7 +81,7 @@ class GroupRebuilder {
.setNameKey(group.getNameKey())
.setGroupUUID(group.getGroupUUID())
.build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(allUsersRepo, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(allUsers, allUsersRepo, groupCreation);
groupConfig.setAllowSaveEmptyName();
InternalGroupUpdate.Builder updateBuilder =

View File

@ -214,12 +214,14 @@ public class SchemaCreator {
AuditLogFormatter auditLogFormatter =
AuditLogFormatter.createBackedBy(ImmutableSet.of(), ImmutableSet.of(), serverId);
GroupConfig groupConfig = GroupConfig.createForNewGroup(allUsersRepo, groupCreation);
GroupConfig groupConfig =
GroupConfig.createForNewGroup(allUsersName, allUsersRepo, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
AccountGroup.NameKey groupName = groupUpdate.getName().orElseGet(groupCreation::getNameKey);
GroupNameNotes groupNameNotes =
GroupNameNotes.forNewGroup(allUsersRepo, groupCreation.getGroupUUID(), groupName);
GroupNameNotes.forNewGroup(
allUsersName, allUsersRepo, groupCreation.getGroupUUID(), groupName);
commit(allUsersRepo, groupConfig, groupNameNotes);

View File

@ -148,7 +148,7 @@ public class Schema_139 extends SchemaVersion {
md.getCommitBuilder().setCommitter(serverUser);
md.setMessage(MSG);
AccountConfig accountConfig = new AccountConfig(e.getKey(), git);
AccountConfig accountConfig = new AccountConfig(e.getKey(), allUsersName, git);
accountConfig.load(md);
accountConfig.setAccountUpdate(
InternalAccountUpdate.builder()

View File

@ -80,7 +80,7 @@ public class Schema_144 extends SchemaVersion {
try {
try (Repository repo = repoManager.openRepository(allUsersName)) {
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(repo);
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(allUsersName, repo);
extIdNotes.upsert(toAdd);
try (MetaDataUpdate metaDataUpdate =
new MetaDataUpdate(GitReferenceUpdated.DISABLED, allUsersName, repo)) {

View File

@ -55,7 +55,7 @@ public class Schema_148 extends SchemaVersion {
@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException {
try (Repository repo = repoManager.openRepository(allUsersName)) {
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(repo);
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(allUsersName, repo);
for (ExternalId extId : extIdNotes.all()) {
if (needsUpdate(extId)) {
extIdNotes.upsert(extId);

View File

@ -139,7 +139,10 @@ public class Schema_154 extends SchemaVersion {
PersonIdent ident = serverIdent.get();
md.getCommitBuilder().setAuthor(ident);
md.getCommitBuilder().setCommitter(ident);
new AccountConfig(account.getId(), allUsersRepo).load().setAccount(account).commit(md);
new AccountConfig(account.getId(), allUsersName, allUsersRepo)
.load()
.setAccount(account)
.commit(md);
}
@FunctionalInterface

View File

@ -110,7 +110,7 @@ public class Schema_160 extends SchemaVersion {
md.getCommitBuilder().setAuthor(ident);
md.getCommitBuilder().setCommitter(ident);
Prefs prefs = new Prefs(ref);
prefs.load(repo);
prefs.load(allUsersName, repo);
prefs.removeMyDrafts();
prefs.commit(md);
if (prefs.dirty()) {

View File

@ -150,7 +150,8 @@ public class Schema_167 extends SchemaVersion {
ReviewDb db, Repository allUsersRepo, Config gerritConfig, SitePaths sitePaths)
throws IOException, ConfigInvalidException {
String serverId = new GerritServerIdProvider(gerritConfig, sitePaths).get();
SimpleInMemoryAccountCache accountCache = new SimpleInMemoryAccountCache(allUsersRepo);
SimpleInMemoryAccountCache accountCache =
new SimpleInMemoryAccountCache(allUsersName, allUsersRepo);
SimpleInMemoryGroupCache groupCache = new SimpleInMemoryGroupCache(db);
return AuditLogFormatter.create(
accountCache::get,
@ -178,10 +179,12 @@ public class Schema_167 extends SchemaVersion {
// The regular account cache isn't available during init. -> Use a simple replacement which tries
// to load every account only once from disk.
private static class SimpleInMemoryAccountCache {
private final AllUsersName allUsersName;
private final Repository allUsersRepo;
private Map<Account.Id, Optional<Account>> accounts = new HashMap<>();
public SimpleInMemoryAccountCache(Repository allUsersRepo) {
public SimpleInMemoryAccountCache(AllUsersName allUsersName, Repository allUsersRepo) {
this.allUsersName = allUsersName;
this.allUsersRepo = allUsersRepo;
}
@ -192,7 +195,8 @@ public class Schema_167 extends SchemaVersion {
private Optional<Account> load(Account.Id accountId) {
try {
AccountConfig accountConfig = new AccountConfig(accountId, allUsersRepo).load();
AccountConfig accountConfig =
new AccountConfig(accountId, allUsersName, allUsersRepo).load();
return accountConfig.getLoadedAccount();
} catch (IOException | ConfigInvalidException ignored) {
logger.atWarning().withCause(ignored).log(

View File

@ -2508,7 +2508,7 @@ public class AccountIT extends AbstractDaemonTest {
// Manually inserting/updating/deleting an external ID of the user makes the index document
// stale.
try (Repository repo = repoManager.openRepository(allUsers)) {
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(repo);
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(allUsers, repo);
ExternalId.Key key = ExternalId.Key.create("foo", "foo");
extIdNotes.insert(ExternalId.create(key, accountId));

View File

@ -162,7 +162,7 @@ public class AccountIndexerIT {
md.getCommitBuilder().setAuthor(ident);
md.getCommitBuilder().setCommitter(ident);
AccountConfig accountConfig = new AccountConfig(accountId, allUsersRepo).load();
AccountConfig accountConfig = new AccountConfig(accountId, allUsersName, allUsersRepo).load();
accountConfig.setAccountUpdate(accountUpdate);
accountConfig.commit(md);
}

View File

@ -927,7 +927,7 @@ public class ExternalIdIT extends AbstractDaemonTest {
private void insertExtIdBehindGerritsBack(ExternalId extId) throws Exception {
try (Repository repo = repoManager.openRepository(allUsers)) {
// Inserting an external ID "behind Gerrit's back" means that the caches are not updated.
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(repo);
ExternalIdNotes extIdNotes = ExternalIdNotes.loadNoCacheUpdate(allUsers, repo);
extIdNotes.insert(extId);
try (MetaDataUpdate metaDataUpdate =
new MetaDataUpdate(GitReferenceUpdated.DISABLED, null, repo)) {

View File

@ -203,7 +203,7 @@ public class VersionedMetaDataTest {
private MyMetaData load(String ref, int expectedValue) throws Exception {
MyMetaData d = new MyMetaData(ref);
d.load(repo);
d.load(project, repo);
assertThat(d.getValue()).isEqualTo(expectedValue);
return d;
}

View File

@ -140,7 +140,7 @@ public class AbstractGroupTest extends GerritBaseTests {
@Override
public String getName() {
try {
return GroupConfig.loadForGroup(allUsersRepo, uuid)
return GroupConfig.loadForGroup(allUsersName, allUsersRepo, uuid)
.getLoadedGroup()
.map(InternalGroup::getName)
.orElse("Group " + uuid);

View File

@ -37,7 +37,7 @@ public final class AuditLogReaderTest extends AbstractGroupTest {
@Before
public void setUp() throws Exception {
auditLogReader = new AuditLogReader(SERVER_ID);
auditLogReader = new AuditLogReader(SERVER_ID, allUsersName);
}
@Test
@ -250,7 +250,8 @@ public final class AuditLogReaderTest extends AbstractGroupTest {
.setMemberModification(members -> ImmutableSet.of(authorId))
.build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(allUsersRepo, groupCreation);
GroupConfig groupConfig =
GroupConfig.createForNewGroup(allUsersName, allUsersRepo, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, getAuditLogFormatter());
groupConfig.commit(createMetaDataUpdate(authorIdent));
@ -261,7 +262,7 @@ public final class AuditLogReaderTest extends AbstractGroupTest {
private void updateGroup(AccountGroup.UUID uuid, InternalGroupUpdate groupUpdate)
throws Exception {
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsersRepo, uuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(allUsersName, allUsersRepo, uuid);
groupConfig.setGroupUpdate(groupUpdate, getAuditLogFormatter());
groupConfig.commit(createMetaDataUpdate(userIdent));
}

View File

@ -65,6 +65,7 @@ public class GroupConfigTest {
@Rule public ExpectedException expectedException = ExpectedException.none();
private Project.NameKey projectName;
private Repository repository;
private TestRepository<?> testRepository;
private final AccountGroup.UUID groupUuid = new AccountGroup.UUID("users-XYZ");
@ -76,6 +77,7 @@ public class GroupConfigTest {
@Before
public void setUp() throws Exception {
projectName = new Project.NameKey("Test Repository");
repository = new InMemoryRepository(new DfsRepositoryDescription("Test Repository"));
testRepository = new TestRepository<>(repository);
}
@ -117,7 +119,7 @@ public class GroupConfigTest {
public void nameOfNewGroupMustNotBeEmpty() throws Exception {
InternalGroupCreation groupCreation =
getPrefilledGroupCreationBuilder().setNameKey(new AccountGroup.NameKey("")).build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
expectedException.expectCause(instanceOf(ConfigInvalidException.class));
@ -130,7 +132,7 @@ public class GroupConfigTest {
public void nameOfNewGroupMustNotBeNull() throws Exception {
InternalGroupCreation groupCreation =
getPrefilledGroupCreationBuilder().setNameKey(new AccountGroup.NameKey(null)).build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
expectedException.expectCause(instanceOf(ConfigInvalidException.class));
@ -152,7 +154,7 @@ public class GroupConfigTest {
public void idOfNewGroupMustNotBeNegative() throws Exception {
InternalGroupCreation groupCreation =
getPrefilledGroupCreationBuilder().setId(new AccountGroup.Id(-2)).build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
expectedException.expectCause(instanceOf(ConfigInvalidException.class));
@ -230,7 +232,7 @@ public class GroupConfigTest {
InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build();
InternalGroupUpdate groupUpdate =
InternalGroupUpdate.builder().setOwnerGroupUUID(new AccountGroup.UUID(null)).build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
@ -245,7 +247,7 @@ public class GroupConfigTest {
InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build();
InternalGroupUpdate groupUpdate =
InternalGroupUpdate.builder().setOwnerGroupUUID(new AccountGroup.UUID("")).build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
@ -362,7 +364,7 @@ public class GroupConfigTest {
expectedException.expect(ConfigInvalidException.class);
expectedException.expectMessage("ID of the group " + groupUuid);
GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig.loadForGroup(projectName, repository, groupUuid);
}
@Test
@ -372,7 +374,7 @@ public class GroupConfigTest {
expectedException.expect(ConfigInvalidException.class);
expectedException.expectMessage("ID of the group " + groupUuid);
GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig.loadForGroup(projectName, repository, groupUuid);
}
@Test
@ -398,7 +400,7 @@ public class GroupConfigTest {
expectedException.expect(ConfigInvalidException.class);
expectedException.expectMessage("Owner UUID of the group " + groupUuid);
GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig.loadForGroup(projectName, repository, groupUuid);
}
@Test
@ -546,7 +548,7 @@ public class GroupConfigTest {
public void nameCannotBeUpdatedToNull() throws Exception {
createArbitraryGroup(groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid);
InternalGroupUpdate groupUpdate =
InternalGroupUpdate.builder().setName(new AccountGroup.NameKey(null)).build();
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
@ -562,7 +564,7 @@ public class GroupConfigTest {
public void nameCannotBeUpdatedToEmptyString() throws Exception {
createArbitraryGroup(groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid);
InternalGroupUpdate groupUpdate =
InternalGroupUpdate.builder().setName(new AccountGroup.NameKey("")).build();
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
@ -579,7 +581,7 @@ public class GroupConfigTest {
createArbitraryGroup(groupUuid);
AccountGroup.NameKey emptyName = new AccountGroup.NameKey("");
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid);
groupConfig.setAllowSaveEmptyName();
InternalGroupUpdate groupUpdate = InternalGroupUpdate.builder().setName(emptyName).build();
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
@ -629,7 +631,7 @@ public class GroupConfigTest {
public void ownerGroupUuidCannotBeUpdatedToNull() throws Exception {
createArbitraryGroup(groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid);
InternalGroupUpdate groupUpdate =
InternalGroupUpdate.builder().setOwnerGroupUUID(new AccountGroup.UUID(null)).build();
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
@ -645,7 +647,7 @@ public class GroupConfigTest {
public void ownerGroupUuidCannotBeUpdatedToEmptyString() throws Exception {
createArbitraryGroup(groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid);
InternalGroupUpdate groupUpdate =
InternalGroupUpdate.builder().setOwnerGroupUUID(new AccountGroup.UUID("")).build();
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
@ -874,7 +876,7 @@ public class GroupConfigTest {
public void groupConfigMayBeReusedForFurtherUpdates() throws Exception {
InternalGroupCreation groupCreation =
getPrefilledGroupCreationBuilder().setGroupUUID(groupUuid).setId(groupId).build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
commit(groupConfig);
AccountGroup.NameKey name = new AccountGroup.NameKey("Robots");
@ -1054,7 +1056,7 @@ public class GroupConfigTest {
InternalGroupUpdate groupUpdate =
InternalGroupUpdate.builder().setName(new AccountGroup.NameKey("Another name")).build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
commit(groupConfig);
@ -1072,7 +1074,7 @@ public class GroupConfigTest {
InternalGroupUpdate groupUpdate =
InternalGroupUpdate.builder().setDescription("A test group").build();
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
commit(groupConfig);
@ -1138,7 +1140,7 @@ public class GroupConfigTest {
.setName(new AccountGroup.NameKey("Another name"))
.setUpdatedOn(createdOn)
.build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
PersonIdent committerIdent =
@ -1171,7 +1173,7 @@ public class GroupConfigTest {
.setName(new AccountGroup.NameKey("Another name"))
.setUpdatedOn(createdOn)
.build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
PersonIdent authorIdent =
@ -1230,7 +1232,7 @@ public class GroupConfigTest {
.setName(new AccountGroup.NameKey("Another name"))
.setUpdatedOn(updatedOn)
.build();
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
PersonIdent committerIdent =
@ -1258,7 +1260,7 @@ public class GroupConfigTest {
.setName(new AccountGroup.NameKey("Another name"))
.setUpdatedOn(updatedOn)
.build();
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, groupUuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
PersonIdent authorIdent =
@ -1299,7 +1301,8 @@ public class GroupConfigTest {
updateGroup(groupUuid, groupUpdate2);
GroupConfig groupConfig =
GroupConfig.loadForGroupSnapshot(repository, groupUuid, commitAfterUpdate1.copy());
GroupConfig.loadForGroupSnapshot(
projectName, repository, groupUuid, commitAfterUpdate1.copy());
Optional<InternalGroup> group = groupConfig.getLoadedGroup();
assertThatGroup(group).value().nameKey().isEqualTo(firstName);
assertThatGroup(group).value().refState().isEqualTo(commitAfterUpdate1.copy());
@ -1344,7 +1347,7 @@ public class GroupConfigTest {
.setMemberModification(members -> ImmutableSet.of(account13.getId(), account7.getId()))
.build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
commit(groupConfig);
@ -1369,7 +1372,7 @@ public class GroupConfigTest {
.setSubgroupModification(
subgroups -> ImmutableSet.of(group1.getGroupUUID(), group2.getGroupUUID()))
.build();
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
commit(groupConfig);
@ -1584,14 +1587,14 @@ public class GroupConfigTest {
private Optional<InternalGroup> createGroup(InternalGroupCreation groupCreation)
throws Exception {
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
commit(groupConfig);
return groupConfig.getLoadedGroup();
}
private Optional<InternalGroup> createGroup(
InternalGroupCreation groupCreation, InternalGroupUpdate groupUpdate) throws Exception {
GroupConfig groupConfig = GroupConfig.createForNewGroup(repository, groupCreation);
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
commit(groupConfig);
return groupConfig.getLoadedGroup();
@ -1605,14 +1608,14 @@ public class GroupConfigTest {
private Optional<InternalGroup> updateGroup(
AccountGroup.UUID uuid, InternalGroupUpdate groupUpdate, AuditLogFormatter auditLogFormatter)
throws Exception {
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, uuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, uuid);
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
commit(groupConfig);
return groupConfig.getLoadedGroup();
}
private Optional<InternalGroup> loadGroup(AccountGroup.UUID uuid) throws Exception {
GroupConfig groupConfig = GroupConfig.loadForGroup(repository, uuid);
GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, uuid);
return groupConfig.getLoadedGroup();
}

View File

@ -31,6 +31,7 @@ import com.google.gerrit.extensions.common.testing.CommitInfoSubject;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
@ -84,12 +85,14 @@ public class GroupNameNotesTest {
private final AccountGroup.NameKey groupName = new AccountGroup.NameKey("users");
private AtomicInteger idCounter;
private AllUsersName allUsersName;
private Repository repo;
@Before
public void setUp() {
TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS);
idCounter = new AtomicInteger();
allUsersName = new AllUsersName(AllUsersNameProvider.DEFAULT);
repo = new InMemoryRepository(new DfsRepositoryDescription(AllUsersNameProvider.DEFAULT));
}
@ -110,13 +113,13 @@ public class GroupNameNotesTest {
@Test
public void uuidOfNewGroupMustNotBeNull() throws Exception {
expectedException.expect(NullPointerException.class);
GroupNameNotes.forNewGroup(repo, null, groupName);
GroupNameNotes.forNewGroup(allUsersName, repo, null, groupName);
}
@Test
public void nameOfNewGroupMustNotBeNull() throws Exception {
expectedException.expect(NullPointerException.class);
GroupNameNotes.forNewGroup(repo, groupUuid, null);
GroupNameNotes.forNewGroup(allUsersName, repo, groupUuid, null);
}
@Test
@ -135,7 +138,7 @@ public class GroupNameNotesTest {
AccountGroup.UUID anotherGroupUuid = new AccountGroup.UUID("AnotherGroup");
expectedException.expect(OrmDuplicateKeyException.class);
expectedException.expectMessage(groupName.get());
GroupNameNotes.forNewGroup(repo, anotherGroupUuid, groupName);
GroupNameNotes.forNewGroup(allUsersName, repo, anotherGroupUuid, groupName);
}
@Test
@ -179,7 +182,7 @@ public class GroupNameNotesTest {
createGroup(groupUuid, groupName);
expectedException.expect(NullPointerException.class);
GroupNameNotes.forRename(repo, groupUuid, groupName, null);
GroupNameNotes.forRename(allUsersName, repo, groupUuid, groupName, null);
}
@Test
@ -188,7 +191,7 @@ public class GroupNameNotesTest {
AccountGroup.NameKey anotherName = new AccountGroup.NameKey("admins");
expectedException.expect(NullPointerException.class);
GroupNameNotes.forRename(repo, groupUuid, null, anotherName);
GroupNameNotes.forRename(allUsersName, repo, groupUuid, null, anotherName);
}
@Test
@ -199,7 +202,7 @@ public class GroupNameNotesTest {
AccountGroup.NameKey anotherName = new AccountGroup.NameKey("admins");
expectedException.expect(ConfigInvalidException.class);
expectedException.expectMessage(anotherOldName.get());
GroupNameNotes.forRename(repo, groupUuid, anotherOldName, anotherName);
GroupNameNotes.forRename(allUsersName, repo, groupUuid, anotherOldName, anotherName);
}
@Test
@ -211,7 +214,7 @@ public class GroupNameNotesTest {
expectedException.expect(OrmDuplicateKeyException.class);
expectedException.expectMessage(anotherGroupName.get());
GroupNameNotes.forRename(repo, groupUuid, groupName, anotherGroupName);
GroupNameNotes.forRename(allUsersName, repo, groupUuid, groupName, anotherGroupName);
}
@Test
@ -220,7 +223,7 @@ public class GroupNameNotesTest {
AccountGroup.NameKey anotherName = new AccountGroup.NameKey("admins");
expectedException.expect(NullPointerException.class);
GroupNameNotes.forRename(repo, null, groupName, anotherName);
GroupNameNotes.forRename(allUsersName, repo, null, groupName, anotherName);
}
@Test
@ -231,7 +234,7 @@ public class GroupNameNotesTest {
AccountGroup.NameKey anotherName = new AccountGroup.NameKey("admins");
expectedException.expect(ConfigInvalidException.class);
expectedException.expectMessage(groupUuid.get());
GroupNameNotes.forRename(repo, anotherGroupUuid, groupName, anotherName);
GroupNameNotes.forRename(allUsersName, repo, anotherGroupUuid, groupName, anotherName);
}
@Test
@ -287,7 +290,8 @@ public class GroupNameNotesTest {
@Test
public void newCommitIsNotCreatedWhenCommittingGroupCreationTwice() throws Exception {
GroupNameNotes groupNameNotes = GroupNameNotes.forNewGroup(repo, groupUuid, groupName);
GroupNameNotes groupNameNotes =
GroupNameNotes.forNewGroup(allUsersName, repo, groupUuid, groupName);
commit(groupNameNotes);
ImmutableList<CommitInfo> commitsAfterFirstCommit = log();
@ -303,7 +307,7 @@ public class GroupNameNotesTest {
AccountGroup.NameKey anotherName = new AccountGroup.NameKey("admins");
GroupNameNotes groupNameNotes =
GroupNameNotes.forRename(repo, groupUuid, groupName, anotherName);
GroupNameNotes.forRename(allUsersName, repo, groupUuid, groupName, anotherName);
commit(groupNameNotes);
ImmutableList<CommitInfo> commitsAfterFirstCommit = log();
@ -504,14 +508,16 @@ public class GroupNameNotesTest {
private void createGroup(AccountGroup.UUID groupUuid, AccountGroup.NameKey groupName)
throws Exception {
GroupNameNotes groupNameNotes = GroupNameNotes.forNewGroup(repo, groupUuid, groupName);
GroupNameNotes groupNameNotes =
GroupNameNotes.forNewGroup(allUsersName, repo, groupUuid, groupName);
commit(groupNameNotes);
}
private void renameGroup(
AccountGroup.UUID groupUuid, AccountGroup.NameKey oldName, AccountGroup.NameKey newName)
throws Exception {
GroupNameNotes groupNameNotes = GroupNameNotes.forRename(repo, groupUuid, oldName, newName);
GroupNameNotes groupNameNotes =
GroupNameNotes.forRename(allUsersName, repo, groupUuid, oldName, newName);
commit(groupNameNotes);
}

View File

@ -579,7 +579,7 @@ public abstract class AbstractQueryAccountsTest extends GerritServerTests {
PersonIdent ident = serverIdent.get();
md.getCommitBuilder().setAuthor(ident);
md.getCommitBuilder().setCommitter(ident);
new AccountConfig(accountId, repo)
new AccountConfig(accountId, allUsers, repo)
.load()
.setAccountUpdate(InternalAccountUpdate.builder().setFullName(newName).build())
.commit(md);

View File

@ -66,6 +66,7 @@ public class GroupRebuilderTest extends GerritBaseTests {
private static final String SERVER_EMAIL = "noreply@gerritcodereview.com";
private AtomicInteger idCounter;
private AllUsersName allUsersName;
private Repository repo;
private GroupRebuilder rebuilder;
private GroupBundle.Factory bundleFactory;
@ -74,7 +75,7 @@ public class GroupRebuilderTest extends GerritBaseTests {
public void setUp() throws Exception {
TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS);
idCounter = new AtomicInteger();
AllUsersName allUsersName = new AllUsersName(AllUsersNameProvider.DEFAULT);
allUsersName = new AllUsersName(AllUsersNameProvider.DEFAULT);
repo = new InMemoryRepositoryManager().createRepository(allUsersName);
rebuilder =
new GroupRebuilder(
@ -83,7 +84,7 @@ public class GroupRebuilderTest extends GerritBaseTests {
// Note that the expected name/email values in tests are not necessarily realistic,
// since they use these trivial name/email functions.
getAuditLogFormatter());
bundleFactory = new GroupBundle.Factory(new AuditLogReader(SERVER_ID));
bundleFactory = new GroupBundle.Factory(new AuditLogReader(SERVER_ID, allUsersName));
}
@After
@ -606,7 +607,7 @@ public class GroupRebuilderTest extends GerritBaseTests {
}
private GroupBundle reload(AccountGroup g) throws Exception {
return bundleFactory.fromNoteDb(repo, g.getGroupUUID());
return bundleFactory.fromNoteDb(allUsersName, repo, g.getGroupUUID());
}
private void assertMigratedCleanly(GroupBundle noteDbBundle, GroupBundle expectedReviewDbBundle) {

View File

@ -189,7 +189,7 @@ public class Schema_159_to_160_Test {
Supplier<VersionedAccountPreferences> prefsSupplier) throws Exception {
try (Repository repo = repoManager.openRepository(allUsersName)) {
VersionedAccountPreferences prefs = prefsSupplier.get();
prefs.load(repo);
prefs.load(allUsersName, repo);
Config cfg = prefs.getConfig();
return cfg.getSubsections(MY)
.stream()

View File

@ -916,7 +916,7 @@ public class Schema_166_to_167_WithGroupsInReviewDbTest {
private GroupBundle readGroupBundleFromNoteDb(AccountGroup.UUID groupUuid) throws Exception {
try (Repository allUsersRepo = gitRepoManager.openRepository(allUsersName)) {
return groupBundleFactory.fromNoteDb(allUsersRepo, groupUuid);
return groupBundleFactory.fromNoteDb(allUsersName, allUsersRepo, groupUuid);
}
}
@ -985,7 +985,7 @@ public class Schema_166_to_167_WithGroupsInReviewDbTest {
private Optional<InternalGroup> getGroupFromNoteDb(AccountGroup.UUID groupUuid) throws Exception {
try (Repository allUsersRepo = gitRepoManager.openRepository(allUsersName)) {
return GroupConfig.loadForGroup(allUsersRepo, groupUuid).getLoadedGroup();
return GroupConfig.loadForGroup(allUsersName, allUsersRepo, groupUuid).getLoadedGroup();
}
}