Merge branch 'stable-2.11' into stable-2.12

* stable-2.11:
  Fetch parent groups of the authGroups

Change-Id: I9fdfccadcd14fb707676abeaedaa8a2a7455a55b
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
index 2c946a5..2743549 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/AutoReloadConfigDecorator.java
@@ -16,6 +16,7 @@
 import com.google.gerrit.common.FileUtil;
 import com.google.gerrit.server.PluginUser;
 import com.google.gerrit.server.account.GroupBackend;
+import com.google.gerrit.server.account.GroupIncludeCache;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.WorkQueue;
@@ -45,13 +46,15 @@
   private final GroupBackend groupBackend;
   private final WorkQueue workQueue;
   private final ReplicationStateListener stateLog;
+  private final GroupIncludeCache groupIncludeCache;
 
   @Inject
   public AutoReloadConfigDecorator(Injector injector, SitePaths site,
       RemoteSiteUser.Factory ruf, PluginUser pu,
       GitRepositoryManager grm, GroupBackend gb,
       WorkQueue workQueue,
-      ReplicationStateListener stateLog) throws ConfigInvalidException,
+      ReplicationStateListener stateLog,
+      GroupIncludeCache groupIncludeCache) throws ConfigInvalidException,
       IOException {
     this.injector = injector;
     this.site = site;
@@ -59,6 +62,7 @@
     this.pluginUser = pu;
     this.gitRepositoryManager = grm;
     this.groupBackend = gb;
+    this.groupIncludeCache = groupIncludeCache;
     this.currentConfig = loadConfig();
     this.currentConfigTs = getLastModified(currentConfig);
     this.workQueue = workQueue;
@@ -71,9 +75,9 @@
 
   private ReplicationFileBasedConfig loadConfig()
       throws ConfigInvalidException, IOException {
-    return new ReplicationFileBasedConfig(injector, site,
-        remoteSiteUserFactory, pluginUser, gitRepositoryManager,
-        groupBackend, stateLog);
+    return new ReplicationFileBasedConfig(injector, site, remoteSiteUserFactory,
+        pluginUser, gitRepositoryManager, groupBackend, stateLog,
+        groupIncludeCache);
   }
 
   private synchronized boolean isAutoReload() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
index 8744284..e267da3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/Destination.java
@@ -17,6 +17,7 @@
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
 import com.google.common.collect.Lists;
 import com.google.gerrit.common.data.GroupReference;
 import com.google.gerrit.extensions.config.FactoryModule;
@@ -28,6 +29,7 @@
 import com.google.gerrit.server.PluginUser;
 import com.google.gerrit.server.account.GroupBackend;
 import com.google.gerrit.server.account.GroupBackends;
+import com.google.gerrit.server.account.GroupIncludeCache;
 import com.google.gerrit.server.account.ListGroupMembership;
 import com.google.gerrit.server.config.ConfigUtil;
 import com.google.gerrit.server.config.RequestScopedReviewDbProvider;
@@ -103,7 +105,8 @@
       final PluginUser pluginUser,
       final GitRepositoryManager gitRepositoryManager,
       final GroupBackend groupBackend,
-      final ReplicationStateListener stateLog) {
+      final ReplicationStateListener stateLog,
+      final GroupIncludeCache groupIncludeCache) {
     remote = rc;
     gitManager = gitRepositoryManager;
     this.stateLog = stateLog;
@@ -136,6 +139,7 @@
         GroupReference g = GroupBackends.findExactSuggestion(groupBackend, name);
         if (g != null) {
           builder.add(g.getUUID());
+          addRecursiveParents(g.getUUID(), builder, groupIncludeCache);
         } else {
           repLog.warn(String.format(
               "Group \"%s\" not recognized, removing from authGroup", name));
@@ -188,6 +192,17 @@
     threadScoper = child.getInstance(PerThreadRequestScope.Scoper.class);
   }
 
+  private void addRecursiveParents(AccountGroup.UUID g,
+      Builder<AccountGroup.UUID> builder, GroupIncludeCache groupIncludeCache) {
+    for (AccountGroup.UUID p : groupIncludeCache.parentGroupsOf(g)) {
+      if (builder.build().contains(p)) {
+        continue;
+      }
+      builder.add(p);
+      addRecursiveParents(p, builder, groupIncludeCache);
+    }
+  }
+
   void start(WorkQueue workQueue) {
     pool = workQueue.createQueue(poolThreads, poolName);
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
index 1486f1b..f7dc733 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationFileBasedConfig.java
@@ -19,6 +19,7 @@
 import com.google.common.collect.Lists;
 import com.google.gerrit.server.PluginUser;
 import com.google.gerrit.server.account.GroupBackend;
+import com.google.gerrit.server.account.GroupIncludeCache;
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.WorkQueue;
@@ -56,14 +57,17 @@
   private final GroupBackend groupBackend;
   private final FileBasedConfig config;
   private final ReplicationStateListener stateLog;
+  private final GroupIncludeCache groupIncludeCache;
 
   @Inject
   public ReplicationFileBasedConfig(final Injector injector, final SitePaths site,
       final RemoteSiteUser.Factory ruf, final PluginUser pu,
       final GitRepositoryManager grm,
       final GroupBackend gb,
-      final ReplicationStateListener stateLog) throws ConfigInvalidException, IOException {
+      final ReplicationStateListener stateLog,
+      final GroupIncludeCache groupIncludeCache) throws ConfigInvalidException, IOException {
     this.cfgPath = site.etc_dir.resolve("replication.config");
+    this.groupIncludeCache = groupIncludeCache;
     this.injector = injector;
     this.replicationUserFactory = ruf;
     this.pluginUser = pu;
@@ -162,7 +166,7 @@
 
       Destination destination =
           new Destination(injector, c, config, replicationUserFactory,
-              pluginUser, gitRepositoryManager, groupBackend, stateLog);
+              pluginUser, gitRepositoryManager, groupBackend, stateLog, groupIncludeCache);
 
       if (!destination.isSingleProjectMatch()) {
         for (URIish u : c.getURIs()) {