ChangeControl.GenericFactory#validateFor: Don't load change from db

All callers of ChangeControl.GenericFactory#validateFor(Change.Id,
CurrentUser) cannot provide the project name, which we would need to
load the change through ChangeNotes.Factory. Hence we need to lookup
the change from the index. Since we request no fields when looking up
the change from the index, rereading it is enforced, hence the change
we get back is not stale.

Move the methods to find changes from ChangeUtil into a separate
class. This is needed because ChangeUtil with all its dependencies
cannot be injected into ChangeControl.GenericFactory, but all those
dependencies are not needed for looking up changes from the index.

Change-Id: I9c2ee58486046f3a2ae80b588613b708a66d8306
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2016-02-04 16:53:24 +01:00
parent 4b2384b582
commit f64ef68bcd
7 changed files with 128 additions and 92 deletions

View File

@@ -15,10 +15,7 @@
package com.google.gerrit.server;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
@@ -29,7 +26,6 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.ChangeInserter;
import com.google.gerrit.server.change.ChangeMessages;
import com.google.gerrit.server.change.ChangeTriplet;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.UpdateException;
@@ -39,8 +35,6 @@ import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.util.IdGenerator;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -65,9 +59,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@Singleton
@@ -163,7 +155,6 @@ public class ChangeUtil {
private final Provider<CurrentUser> user;
private final Provider<ReviewDb> db;
private final Sequences seq;
private final Provider<InternalChangeQuery> queryProvider;
private final PatchSetUtil psUtil;
private final RevertedSender.Factory revertedSenderFactory;
private final ChangeInserter.Factory changeInserterFactory;
@@ -176,7 +167,6 @@ public class ChangeUtil {
ChangeUtil(Provider<CurrentUser> user,
Provider<ReviewDb> db,
Sequences seq,
Provider<InternalChangeQuery> queryProvider,
PatchSetUtil psUtil,
RevertedSender.Factory revertedSenderFactory,
ChangeInserter.Factory changeInserterFactory,
@@ -187,7 +177,6 @@ public class ChangeUtil {
this.user = user;
this.db = db;
this.seq = seq;
this.queryProvider = queryProvider;
this.psUtil = psUtil;
this.revertedSenderFactory = revertedSenderFactory;
this.changeInserterFactory = changeInserterFactory;
@@ -315,66 +304,6 @@ public class ChangeUtil {
}
}
/**
* Find changes matching the given identifier.
*
* @param id change identifier, either a numeric ID, a Change-Id, or
* project~branch~id triplet.
* @param user user to wrap in controls.
* @return possibly-empty list of controls for all matching changes,
* corresponding to the given user; may or may not be visible.
* @throws OrmException if an error occurred querying the database.
*/
public List<ChangeControl> findChanges(String id, CurrentUser user)
throws OrmException {
// Use the index to search for changes, but don't return any stored fields,
// to force rereading in case the index is stale.
InternalChangeQuery query = queryProvider.get()
.setRequestedFields(ImmutableSet.<String> of());
// Try legacy id
if (!id.isEmpty() && id.charAt(0) != '0') {
Integer n = Ints.tryParse(id);
if (n != null) {
return asChangeControls(query.byLegacyChangeId(new Change.Id(n)), user);
}
}
// Try isolated changeId
if (!id.contains("~")) {
return asChangeControls(query.byKeyPrefix(id), user);
}
// Try change triplet
Optional<ChangeTriplet> triplet = ChangeTriplet.parse(id);
if (triplet.isPresent()) {
return asChangeControls(query.byBranchKey(
triplet.get().branch(),
triplet.get().id()),
user);
}
return Collections.emptyList();
}
public List<ChangeControl> findChanges(Change.Id id, CurrentUser user)
throws OrmException {
// Use the index to search for changes, but don't return any stored fields,
// to force rereading in case the index is stale.
InternalChangeQuery query = queryProvider.get()
.setRequestedFields(ImmutableSet.<String> of());
return asChangeControls(query.byLegacyChangeId(id), user);
}
private List<ChangeControl> asChangeControls(List<ChangeData> cds,
CurrentUser user) throws OrmException {
List<ChangeControl> ctls = new ArrayList<>(cds.size());
for (ChangeData cd : cds) {
ctls.add(cd.changeControl(user));
}
return ctls;
}
public static PatchSet.Id nextPatchSetId(PatchSet.Id id) {
return new PatchSet.Id(id.getParentKey(), id.get() + 1);
}