SubscriptionGraph: Inject SubscriptionGraph.Factory

Use Guice to inject SubscriptionGraph.Factory instead of calling
constructor directly, which allows an alternative implementation of
SubmoduleGraph.Factory being injected easily.

Change-Id: I689998da72e3787bf36a2c854c40f206fabacf9e
This commit is contained in:
Yunjie Li
2020-05-19 19:34:11 -07:00
parent 0a633ea1cf
commit 3313e5f4b9
5 changed files with 50 additions and 40 deletions

View File

@@ -107,6 +107,7 @@ import com.google.gerrit.server.ssh.NoSshKeyCache;
import com.google.gerrit.server.ssh.NoSshModule; import com.google.gerrit.server.ssh.NoSshModule;
import com.google.gerrit.server.ssh.SshAddressesModule; import com.google.gerrit.server.ssh.SshAddressesModule;
import com.google.gerrit.server.submit.LocalMergeSuperSetComputation; import com.google.gerrit.server.submit.LocalMergeSuperSetComputation;
import com.google.gerrit.server.submit.SubscriptionGraph;
import com.google.gerrit.sshd.SshHostKeyModule; import com.google.gerrit.sshd.SshHostKeyModule;
import com.google.gerrit.sshd.SshKeyCacheImpl; import com.google.gerrit.sshd.SshKeyCacheImpl;
import com.google.gerrit.sshd.SshModule; import com.google.gerrit.sshd.SshModule;
@@ -411,6 +412,7 @@ public class Daemon extends SiteProgram {
// work queue can get stuck waiting on index futures that will never return. // work queue can get stuck waiting on index futures that will never return.
modules.add(createIndexModule()); modules.add(createIndexModule());
modules.add(new SubscriptionGraph.Module());
modules.add(new WorkQueue.Module()); modules.add(new WorkQueue.Module());
modules.add(new StreamEventsApiListener.Module()); modules.add(new StreamEventsApiListener.Module());
modules.add(new EventBroker.Module()); modules.add(new EventBroker.Module());

View File

@@ -30,7 +30,6 @@ import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.VerboseSuperprojectUpdate; import com.google.gerrit.server.config.VerboseSuperprojectUpdate;
import com.google.gerrit.server.git.CodeReviewCommit; import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.submit.MergeOpRepoManager.OpenRepo; import com.google.gerrit.server.submit.MergeOpRepoManager.OpenRepo;
import com.google.gerrit.server.update.BatchUpdate; import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateListener; import com.google.gerrit.server.update.BatchUpdateListener;
@@ -89,27 +88,24 @@ public class SubmoduleOp {
@Singleton @Singleton
public static class Factory { public static class Factory {
private final GitModules.Factory gitmodulesFactory; private final SubscriptionGraph.Factory subscriptionGraphFactory;
private final Provider<PersonIdent> serverIdent; private final Provider<PersonIdent> serverIdent;
private final Config cfg; private final Config cfg;
private final ProjectCache projectCache;
@Inject @Inject
Factory( Factory(
GitModules.Factory gitmodulesFactory, SubscriptionGraph.Factory subscriptionGraphFactory,
@GerritPersonIdent Provider<PersonIdent> serverIdent, @GerritPersonIdent Provider<PersonIdent> serverIdent,
@GerritServerConfig Config cfg, @GerritServerConfig Config cfg) {
ProjectCache projectCache) { this.subscriptionGraphFactory = subscriptionGraphFactory;
this.gitmodulesFactory = gitmodulesFactory;
this.serverIdent = serverIdent; this.serverIdent = serverIdent;
this.cfg = cfg; this.cfg = cfg;
this.projectCache = projectCache;
} }
public SubmoduleOp create(Set<BranchNameKey> updatedBranches, MergeOpRepoManager orm) public SubmoduleOp create(Set<BranchNameKey> updatedBranches, MergeOpRepoManager orm)
throws SubmoduleConflictException { throws SubmoduleConflictException {
return new SubmoduleOp( return new SubmoduleOp(
gitmodulesFactory, serverIdent.get(), cfg, projectCache, updatedBranches, orm); subscriptionGraphFactory, serverIdent.get(), cfg, updatedBranches, orm);
} }
} }
@@ -118,16 +114,14 @@ public class SubmoduleOp {
private final long maxCombinedCommitMessageSize; private final long maxCombinedCommitMessageSize;
private final long maxCommitMessages; private final long maxCommitMessages;
private final MergeOpRepoManager orm; private final MergeOpRepoManager orm;
private final SubscriptionGraph.Factory subscriptionGraphFactory;
private final SubscriptionGraph subscriptionGraph; private final SubscriptionGraph subscriptionGraph;
private final BranchTips branchTips = new BranchTips(); private final BranchTips branchTips = new BranchTips();
private SubmoduleOp( private SubmoduleOp(
GitModules.Factory gitmodulesFactory, SubscriptionGraph.Factory subscriptionGraphFactory,
PersonIdent myIdent, PersonIdent myIdent,
Config cfg, Config cfg,
ProjectCache projectCache,
Set<BranchNameKey> updatedBranches, Set<BranchNameKey> updatedBranches,
MergeOpRepoManager orm) MergeOpRepoManager orm)
throws SubmoduleConflictException { throws SubmoduleConflictException {
@@ -138,10 +132,8 @@ public class SubmoduleOp {
cfg.getLong("submodule", "maxCombinedCommitMessageSize", 256 << 10); cfg.getLong("submodule", "maxCombinedCommitMessageSize", 256 << 10);
this.maxCommitMessages = cfg.getLong("submodule", "maxCommitMessages", 1000); this.maxCommitMessages = cfg.getLong("submodule", "maxCommitMessages", 1000);
this.orm = orm; this.orm = orm;
this.subscriptionGraphFactory =
new SubscriptionGraph.DefaultFactory(gitmodulesFactory, projectCache, orm);
if (cfg.getBoolean("submodule", "enableSuperProjectSubscriptions", true)) { if (cfg.getBoolean("submodule", "enableSuperProjectSubscriptions", true)) {
this.subscriptionGraph = subscriptionGraphFactory.compute(updatedBranches); this.subscriptionGraph = subscriptionGraphFactory.compute(updatedBranches, orm);
} else { } else {
logger.atFine().log("Updating superprojects disabled"); logger.atFine().log("Updating superprojects disabled");
this.subscriptionGraph = this.subscriptionGraph =

View File

@@ -31,6 +31,8 @@ import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.server.project.NoSuchProjectException; import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache; import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.submit.MergeOpRepoManager.OpenRepo; import com.google.gerrit.server.submit.MergeOpRepoManager.OpenRepo;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
@@ -150,24 +152,30 @@ public class SubscriptionGraph {
} }
public interface Factory { public interface Factory {
SubscriptionGraph compute(Set<BranchNameKey> updatedBranches) throws SubmoduleConflictException; SubscriptionGraph compute(Set<BranchNameKey> updatedBranches, MergeOpRepoManager orm)
throws SubmoduleConflictException;
}
public static class Module extends AbstractModule {
@Override
protected void configure() {
bind(Factory.class).to(DefaultFactory.class);
}
} }
static class DefaultFactory implements Factory { static class DefaultFactory implements Factory {
private static final FluentLogger logger = FluentLogger.forEnclosingClass(); private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private final ProjectCache projectCache; private final ProjectCache projectCache;
private final GitModules.Factory gitmodulesFactory; private final GitModules.Factory gitmodulesFactory;
private final MergeOpRepoManager orm;
DefaultFactory( @Inject
GitModules.Factory gitmodulesFactory, ProjectCache projectCache, MergeOpRepoManager orm) { DefaultFactory(GitModules.Factory gitmodulesFactory, ProjectCache projectCache) {
this.gitmodulesFactory = gitmodulesFactory; this.gitmodulesFactory = gitmodulesFactory;
this.projectCache = projectCache; this.projectCache = projectCache;
this.orm = orm;
} }
@Override @Override
public SubscriptionGraph compute(Set<BranchNameKey> updatedBranches) public SubscriptionGraph compute(Set<BranchNameKey> updatedBranches, MergeOpRepoManager orm)
throws SubmoduleConflictException { throws SubmoduleConflictException {
Map<BranchNameKey, GitModules> branchGitModules = new HashMap<>(); Map<BranchNameKey, GitModules> branchGitModules = new HashMap<>();
// All affected branches, including those in superprojects and submodules. // All affected branches, including those in superprojects and submodules.
@@ -191,7 +199,8 @@ public class SubscriptionGraph {
targets, targets,
branchesByProject, branchesByProject,
subscribedBranches, subscribedBranches,
branchGitModules); branchGitModules,
orm);
return new SubscriptionGraph( return new SubscriptionGraph(
updatedBranches, targets, branchesByProject, subscribedBranches, sortedBranches); updatedBranches, targets, branchesByProject, subscribedBranches, sortedBranches);
@@ -217,7 +226,8 @@ public class SubscriptionGraph {
SetMultimap<BranchNameKey, SubmoduleSubscription> targets, SetMultimap<BranchNameKey, SubmoduleSubscription> targets,
SetMultimap<Project.NameKey, BranchNameKey> branchesByProject, SetMultimap<Project.NameKey, BranchNameKey> branchesByProject,
Set<BranchNameKey> subscribedBranches, Set<BranchNameKey> subscribedBranches,
Map<BranchNameKey, GitModules> branchGitModules) Map<BranchNameKey, GitModules> branchGitModules,
MergeOpRepoManager orm)
throws SubmoduleConflictException { throws SubmoduleConflictException {
logger.atFine().log("Calculating superprojects - submodules map"); logger.atFine().log("Calculating superprojects - submodules map");
LinkedHashSet<BranchNameKey> allVisited = new LinkedHashSet<>(); LinkedHashSet<BranchNameKey> allVisited = new LinkedHashSet<>();
@@ -234,7 +244,8 @@ public class SubscriptionGraph {
targets, targets,
branchesByProject, branchesByProject,
subscribedBranches, subscribedBranches,
branchGitModules); branchGitModules,
orm);
} }
// Since the searchForSuperprojects will add all branches (related or // Since the searchForSuperprojects will add all branches (related or
@@ -254,7 +265,8 @@ public class SubscriptionGraph {
SetMultimap<BranchNameKey, SubmoduleSubscription> targets, SetMultimap<BranchNameKey, SubmoduleSubscription> targets,
SetMultimap<Project.NameKey, BranchNameKey> branchesByProject, SetMultimap<Project.NameKey, BranchNameKey> branchesByProject,
Set<BranchNameKey> subscribedBranches, Set<BranchNameKey> subscribedBranches,
Map<BranchNameKey, GitModules> branchGitModules) Map<BranchNameKey, GitModules> branchGitModules,
MergeOpRepoManager orm)
throws SubmoduleConflictException { throws SubmoduleConflictException {
logger.atFine().log("Now processing %s", current); logger.atFine().log("Now processing %s", current);
@@ -271,7 +283,7 @@ public class SubscriptionGraph {
currentVisited.add(current); currentVisited.add(current);
try { try {
Collection<SubmoduleSubscription> subscriptions = Collection<SubmoduleSubscription> subscriptions =
superProjectSubscriptionsForSubmoduleBranch(current, branchGitModules); superProjectSubscriptionsForSubmoduleBranch(current, branchGitModules, orm);
for (SubmoduleSubscription sub : subscriptions) { for (SubmoduleSubscription sub : subscriptions) {
BranchNameKey superBranch = sub.getSuperProject(); BranchNameKey superBranch = sub.getSuperProject();
searchForSuperprojects( searchForSuperprojects(
@@ -282,7 +294,8 @@ public class SubscriptionGraph {
targets, targets,
branchesByProject, branchesByProject,
subscribedBranches, subscribedBranches,
branchGitModules); branchGitModules,
orm);
targets.put(superBranch, sub); targets.put(superBranch, sub);
branchesByProject.put(superBranch.project(), superBranch); branchesByProject.put(superBranch.project(), superBranch);
affectedBranches.add(superBranch); affectedBranches.add(superBranch);
@@ -296,8 +309,8 @@ public class SubscriptionGraph {
allVisited.add(current); allVisited.add(current);
} }
private Collection<BranchNameKey> getDestinationBranches(BranchNameKey src, SubscribeSection s) private Collection<BranchNameKey> getDestinationBranches(
throws IOException { BranchNameKey src, SubscribeSection s, MergeOpRepoManager orm) throws IOException {
OpenRepo or; OpenRepo or;
try { try {
or = orm.getRepo(s.project()); or = orm.getRepo(s.project());
@@ -313,7 +326,9 @@ public class SubscriptionGraph {
} }
private Collection<SubmoduleSubscription> superProjectSubscriptionsForSubmoduleBranch( private Collection<SubmoduleSubscription> superProjectSubscriptionsForSubmoduleBranch(
BranchNameKey srcBranch, Map<BranchNameKey, GitModules> branchGitModules) BranchNameKey srcBranch,
Map<BranchNameKey, GitModules> branchGitModules,
MergeOpRepoManager orm)
throws IOException { throws IOException {
logger.atFine().log("Calculating possible superprojects for %s", srcBranch); logger.atFine().log("Calculating possible superprojects for %s", srcBranch);
Collection<SubmoduleSubscription> ret = new ArrayList<>(); Collection<SubmoduleSubscription> ret = new ArrayList<>();
@@ -324,7 +339,7 @@ public class SubscriptionGraph {
.orElseThrow(illegalState(srcProject)) .orElseThrow(illegalState(srcProject))
.getSubscribeSections(srcBranch)) { .getSubscribeSections(srcBranch)) {
logger.atFine().log("Checking subscribe section %s", s); logger.atFine().log("Checking subscribe section %s", s);
Collection<BranchNameKey> branches = getDestinationBranches(srcBranch, s); Collection<BranchNameKey> branches = getDestinationBranches(srcBranch, s, orm);
for (BranchNameKey targetBranch : branches) { for (BranchNameKey targetBranch : branches) {
Project.NameKey targetProject = targetBranch.project(); Project.NameKey targetProject = targetBranch.project();
try { try {

View File

@@ -87,6 +87,7 @@ import com.google.gerrit.server.securestore.DefaultSecureStore;
import com.google.gerrit.server.securestore.SecureStore; import com.google.gerrit.server.securestore.SecureStore;
import com.google.gerrit.server.ssh.NoSshKeyCache; import com.google.gerrit.server.ssh.NoSshKeyCache;
import com.google.gerrit.server.submit.LocalMergeSuperSetComputation; import com.google.gerrit.server.submit.LocalMergeSuperSetComputation;
import com.google.gerrit.server.submit.SubscriptionGraph;
import com.google.gerrit.server.util.ReplicaUtil; import com.google.gerrit.server.util.ReplicaUtil;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Guice; import com.google.inject.Guice;
@@ -175,6 +176,7 @@ public class InMemoryModule extends FactoryModule {
install(new SearchingChangeCacheImpl.Module()); install(new SearchingChangeCacheImpl.Module());
factory(GarbageCollection.Factory.class); factory(GarbageCollection.Factory.class);
install(new AuditModule()); install(new AuditModule());
install(new SubscriptionGraph.Module());
bindScope(RequestScoped.class, PerThreadRequestScope.REQUEST); bindScope(RequestScoped.class, PerThreadRequestScope.REQUEST);

View File

@@ -81,9 +81,9 @@ public class SubscriptionGraphTest {
@Test @Test
public void oneSuperprojectOneSubmodule() throws Exception { public void oneSuperprojectOneSubmodule() throws Exception {
SubscriptionGraph.Factory factory = SubscriptionGraph.Factory factory = new DefaultFactory(mockGitModulesFactory, mockProjectCache);
new DefaultFactory(mockGitModulesFactory, mockProjectCache, mergeOpRepoManager); SubscriptionGraph subscriptionGraph =
SubscriptionGraph subscriptionGraph = factory.compute(ImmutableSet.of(SUB_BRANCH)); factory.compute(ImmutableSet.of(SUB_BRANCH), mergeOpRepoManager);
assertThat(subscriptionGraph.getAffectedSuperProjects()).containsExactly(SUPER_PROJECT); assertThat(subscriptionGraph.getAffectedSuperProjects()).containsExactly(SUPER_PROJECT);
assertThat(subscriptionGraph.getAffectedSuperBranches(SUPER_PROJECT)) assertThat(subscriptionGraph.getAffectedSuperBranches(SUPER_PROJECT))
@@ -98,12 +98,12 @@ public class SubscriptionGraphTest {
@Test @Test
public void circularSubscription() throws Exception { public void circularSubscription() throws Exception {
SubscriptionGraph.Factory factory = SubscriptionGraph.Factory factory = new DefaultFactory(mockGitModulesFactory, mockProjectCache);
new DefaultFactory(mockGitModulesFactory, mockProjectCache, mergeOpRepoManager);
setSubscription(SUPER_BRANCH, ImmutableList.of(SUB_BRANCH)); setSubscription(SUPER_BRANCH, ImmutableList.of(SUB_BRANCH));
SubmoduleConflictException e = SubmoduleConflictException e =
assertThrows( assertThrows(
SubmoduleConflictException.class, () -> factory.compute(ImmutableSet.of(SUB_BRANCH))); SubmoduleConflictException.class,
() -> factory.compute(ImmutableSet.of(SUB_BRANCH), mergeOpRepoManager));
String expectedErrorMessage = String expectedErrorMessage =
"Subproject,refs/heads/one->Superproject,refs/heads/one->Subproject,refs/heads/one"; "Subproject,refs/heads/one->Superproject,refs/heads/one->Subproject,refs/heads/one";
@@ -154,10 +154,9 @@ public class SubscriptionGraphTest {
setSubscription(submoduleBranch2, ImmutableList.of(superBranch1)); setSubscription(submoduleBranch2, ImmutableList.of(superBranch1));
setSubscription(submoduleBranch3, ImmutableList.of(superBranch1, superBranch2)); setSubscription(submoduleBranch3, ImmutableList.of(superBranch1, superBranch2));
SubscriptionGraph.Factory factory = SubscriptionGraph.Factory factory = new DefaultFactory(mockGitModulesFactory, mockProjectCache);
new DefaultFactory(mockGitModulesFactory, mockProjectCache, mergeOpRepoManager);
SubscriptionGraph subscriptionGraph = SubscriptionGraph subscriptionGraph =
factory.compute(ImmutableSet.of(submoduleBranch1, submoduleBranch2)); factory.compute(ImmutableSet.of(submoduleBranch1, submoduleBranch2), mergeOpRepoManager);
assertThat(subscriptionGraph.getAffectedSuperProjects()) assertThat(subscriptionGraph.getAffectedSuperProjects())
.containsExactly(superProject1, superProject2); .containsExactly(superProject1, superProject2);