Merge branch 'stable-3.1' into stable-3.2
* stable-3.1:
Remove unmaintained attempt to Dockerize the whole multi-site setup
Change-Id: I1204ae4d13911543de8e9a4a979a27b052a79b7c
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 9cbb332..fee8aca 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -9,6 +9,6 @@
maven_jar(
name = "events-broker",
- artifact = "com.gerritforge:events-broker:3.1.4",
- sha1 = "5672908dde0bd02cabc95efe34a8d8507d44b6ac",
+ artifact = "com.gerritforge:events-broker:3.2.0-rc4",
+ sha1 = "53e3f862ac2c2196dba716756ac9586f4b63af47",
)
diff --git a/setup_local_env/setup.sh b/setup_local_env/setup.sh
index 87af305..f3f3ae6 100755
--- a/setup_local_env/setup.sh
+++ b/setup_local_env/setup.sh
@@ -16,7 +16,7 @@
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-GERRIT_BRANCH=stable-3.1
+GERRIT_BRANCH=stable-3.2
GERRIT_CI=https://gerrit-ci.gerritforge.com/view/Plugins-$GERRIT_BRANCH/job
LAST_BUILD=lastSuccessfulBuild/artifact/bazel-bin/plugins
EVENTS_BROKER_VER=`grep 'com.gerritforge:events-broker' $(dirname $0)/../external_plugin_deps.bzl | cut -d '"' -f 2 | cut -d ':' -f 3`
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
index ebe28d4..f509cd4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/Configuration.java
@@ -61,6 +61,7 @@
private final Supplier<Cache> cache;
private final Supplier<Event> event;
private final Supplier<Index> index;
+ private final Supplier<Projects> projects;
private final Supplier<SharedRefDatabase> sharedRefDb;
private final Supplier<Collection<Message>> replicationConfigValidation;
private final Supplier<Broker> broker;
@@ -79,6 +80,7 @@
cache = memoize(() -> new Cache(lazyMultiSiteCfg));
event = memoize(() -> new Event(lazyMultiSiteCfg));
index = memoize(() -> new Index(lazyMultiSiteCfg));
+ projects = memoize(() -> new Projects(lazyMultiSiteCfg));
sharedRefDb = memoize(() -> new SharedRefDatabase(lazyMultiSiteCfg));
broker = memoize(() -> new Broker(lazyMultiSiteCfg));
}
@@ -107,6 +109,10 @@
return broker.get();
}
+ public Projects projects() {
+ return projects.get();
+ }
+
public Collection<Message> validate() {
return replicationConfigValidation.get();
}
@@ -198,6 +204,20 @@
}
}
+ public static class Projects {
+ public static final String SECTION = "projects";
+ public static final String PATTERN_KEY = "pattern";
+ public List<String> patterns;
+
+ public Projects(Supplier<Config> cfg) {
+ patterns = ImmutableList.copyOf(cfg.get().getStringList("projects", null, PATTERN_KEY));
+ }
+
+ public List<String> getPatterns() {
+ return patterns;
+ }
+ }
+
/** Common parameters to cache, event, index */
public abstract static class Forwarding {
static final boolean DEFAULT_SYNCHRONIZE = true;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilter.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilter.java
new file mode 100644
index 0000000..d6fac47
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilter.java
@@ -0,0 +1,109 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.multisite;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.Sets;
+import com.google.gerrit.common.data.AccessSection;
+import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.Project.NameKey;
+import com.google.gerrit.server.events.Event;
+import com.google.gerrit.server.events.ProjectEvent;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import java.util.List;
+import java.util.Set;
+
+@Singleton
+public class ProjectsFilter {
+ public enum PatternType {
+ REGEX,
+ WILDCARD,
+ EXACT_MATCH;
+
+ public static PatternType getPatternType(String pattern) {
+ if (pattern.startsWith(AccessSection.REGEX_PREFIX)) {
+ return REGEX;
+ } else if (pattern.endsWith("*")) {
+ return WILDCARD;
+ } else {
+ return EXACT_MATCH;
+ }
+ }
+ }
+
+ private Set<NameKey> globalProjects = Sets.newConcurrentHashSet();
+ private Set<NameKey> localProjects = Sets.newConcurrentHashSet();
+ private final List<String> projectPatterns;
+
+ @Inject
+ public ProjectsFilter(Configuration cfg) {
+ projectPatterns = cfg.projects().getPatterns();
+ }
+
+ public boolean matches(Event event) {
+ if (event == null) {
+ throw new IllegalArgumentException("Event object cannot be null");
+ }
+ if (event instanceof ProjectEvent) {
+ return matches(((ProjectEvent) event).getProjectNameKey());
+ }
+ return false;
+ }
+
+ public boolean matches(String projectName) {
+ return matches(NameKey.parse(projectName));
+ }
+
+ public boolean matches(Project.NameKey name) {
+ if (name == null || Strings.isNullOrEmpty(name.get())) {
+ throw new IllegalArgumentException(
+ String.format("Project name cannot be null or empty, but was %s", name));
+ }
+ if (projectPatterns.isEmpty() || globalProjects.contains(name)) {
+ return true;
+ }
+
+ if (localProjects.contains(name)) {
+ return false;
+ }
+
+ String projectName = name.get();
+
+ for (String pattern : projectPatterns) {
+ if (matchesPattern(projectName, pattern)) {
+ globalProjects.add(name);
+ return true;
+ }
+ }
+ localProjects.add(name);
+ return false;
+ }
+
+ private boolean matchesPattern(String projectName, String pattern) {
+ boolean match = false;
+ switch (PatternType.getPatternType(pattern)) {
+ case REGEX:
+ match = projectName.matches(pattern);
+ break;
+ case WILDCARD:
+ match = projectName.startsWith(pattern.substring(0, pattern.length() - 1));
+ break;
+ case EXACT_MATCH:
+ match = projectName.equals(pattern);
+ }
+ return match;
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
index b56f2ea..ddf9d84 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/SharedRefDatabaseWrapper.java
@@ -21,11 +21,13 @@
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.NoopSharedRefDatabase;
import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
public class SharedRefDatabaseWrapper implements GlobalRefDatabase {
+ private static final GlobalRefDatabase NOOP_REFDB = new NoopSharedRefDatabase();
@Inject(optional = true)
private DynamicItem<GlobalRefDatabase> sharedRefDbDynamicItem;
@@ -95,6 +97,6 @@
}
private GlobalRefDatabase sharedRefDb() {
- return sharedRefDbDynamicItem.get();
+ return Optional.ofNullable(sharedRefDbDynamicItem).map(di -> di.get()).orElse(NOOP_REFDB);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/CacheEvictionHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/CacheEvictionHandler.java
index 77c19c1..2990264 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/CacheEvictionHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/CacheEvictionHandler.java
@@ -20,6 +20,7 @@
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.multisite.forwarder.CacheEvictionForwarder;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.CacheEvictionEvent;
import java.util.concurrent.Executor;
@@ -45,7 +46,7 @@
}
}
- class CacheEvictionTask implements Runnable {
+ class CacheEvictionTask extends ForwarderTask {
CacheEvictionEvent cacheEvictionEvent;
CacheEvictionTask(CacheEvictionEvent cacheEvictionEvent) {
@@ -54,7 +55,7 @@
@Override
public void run() {
- forwarders.forEach(f -> f.evict(cacheEvictionEvent));
+ forwarders.forEach(f -> f.evict(this, cacheEvictionEvent));
}
@Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/CachePatternMatcher.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/CachePatternMatcher.java
index acf8df0..b8521a3 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/CachePatternMatcher.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/CachePatternMatcher.java
@@ -26,8 +26,7 @@
@Singleton
class CachePatternMatcher {
private static final List<String> DEFAULT_PATTERNS =
- ImmutableList.of(
- "accounts", "^groups.*", "ldap_groups", "ldap_usernames", "projects", "sshkeys");
+ ImmutableList.of("^groups.*", "ldap_groups", "ldap_usernames", "projects", "sshkeys");
private final Pattern pattern;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java
index 5723fbe..2e2f9de 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandler.java
@@ -20,7 +20,9 @@
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.ProjectListUpdateForwarder;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.ProjectListUpdateEvent;
import java.util.concurrent.Executor;
@@ -30,12 +32,16 @@
private final DynamicSet<ProjectListUpdateForwarder> forwarders;
private final Executor executor;
+ private final ProjectsFilter projectsFilter;
@Inject
public ProjectListUpdateHandler(
- DynamicSet<ProjectListUpdateForwarder> forwarders, @CacheExecutor Executor executor) {
+ DynamicSet<ProjectListUpdateForwarder> forwarders,
+ @CacheExecutor Executor executor,
+ ProjectsFilter filter) {
this.forwarders = forwarders;
this.executor = executor;
+ this.projectsFilter = filter;
}
@Override
@@ -51,13 +57,13 @@
}
private void process(ProjectEvent event, boolean delete) {
- if (!Context.isForwardedEvent()) {
+ if (!Context.isForwardedEvent() && projectsFilter.matches(event.getProjectName())) {
executor.execute(
new ProjectListUpdateTask(new ProjectListUpdateEvent(event.getProjectName(), delete)));
}
}
- class ProjectListUpdateTask implements Runnable {
+ class ProjectListUpdateTask extends ForwarderTask {
private final ProjectListUpdateEvent projectListUpdateEvent;
ProjectListUpdateTask(ProjectListUpdateEvent projectListUpdateEvent) {
@@ -66,7 +72,7 @@
@Override
public void run() {
- forwarders.forEach(f -> f.updateProjectList(projectListUpdateEvent));
+ forwarders.forEach(f -> f.updateProjectList(this, projectListUpdateEvent));
}
@Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java
index aafd59f..a1b7a53 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/event/EventHandler.java
@@ -19,6 +19,7 @@
import com.google.gerrit.server.events.EventListener;
import com.google.gerrit.server.events.ProjectEvent;
import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.StreamEventForwarder;
import java.util.concurrent.Executor;
@@ -26,17 +27,24 @@
class EventHandler implements EventListener {
private final Executor executor;
private final DynamicSet<StreamEventForwarder> forwarders;
+ private final ProjectsFilter projectsFilter;
@Inject
- EventHandler(DynamicSet<StreamEventForwarder> forwarders, @EventExecutor Executor executor) {
+ EventHandler(
+ DynamicSet<StreamEventForwarder> forwarders,
+ @EventExecutor Executor executor,
+ ProjectsFilter projectsFilter) {
this.forwarders = forwarders;
this.executor = executor;
+ this.projectsFilter = projectsFilter;
}
@Override
public void onEvent(Event event) {
if (!Context.isForwardedEvent() && event instanceof ProjectEvent) {
- executor.execute(new EventTask(event));
+ if (projectsFilter.matches(event)) {
+ executor.execute(new EventTask(event));
+ }
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheEvictionForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheEvictionForwarder.java
index 68921e6..2a18759 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheEvictionForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/CacheEvictionForwarder.java
@@ -20,8 +20,9 @@
/**
* Forward a cache eviction event to the other master.
*
+ * @param task that triggered the forwarding of the cache event.
* @param cacheEvictionEvent the details of the cache eviction event.
* @return true if successful, otherwise false.
*/
- boolean evict(CacheEvictionEvent cacheEvictionEvent);
+ boolean evict(ForwarderTask task, CacheEvictionEvent cacheEvictionEvent);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwarderTask.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwarderTask.java
new file mode 100644
index 0000000..329b5cb
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwarderTask.java
@@ -0,0 +1,23 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.multisite.forwarder;
+
+public abstract class ForwarderTask implements Runnable {
+ private final Thread callerThread = Thread.currentThread();
+
+ public Thread getCallerThread() {
+ return callerThread;
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/IndexEventForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/IndexEventForwarder.java
index 5c1f444..73cd9e8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/IndexEventForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/IndexEventForwarder.java
@@ -21,16 +21,18 @@
/**
* Publish an indexing event to the broker using interactive topic.
*
+ * @param task that triggered the forwarding of the index event.
* @param event the details of the index event.
* @return true if successful, otherwise false.
*/
- boolean index(IndexEvent event);
+ boolean index(ForwarderTask task, IndexEvent event);
/**
* Publish an indexing event to the broker using batch topic.
*
+ * @param task that triggered the forwarding of the index event.
* @param event the details of the index event.
* @return true if successful, otherwise false.
*/
- boolean batchIndex(IndexEvent event);
+ boolean batchIndex(ForwarderTask task, IndexEvent event);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ProjectListUpdateForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ProjectListUpdateForwarder.java
index e40ff3f..b370b260d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ProjectListUpdateForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/ProjectListUpdateForwarder.java
@@ -21,8 +21,9 @@
/**
* Forward an update the project list cache event to the other master.
*
+ * @param task that triggered the forwarding of the project list event.
* @param projectListUpdateEvent the content of project list update event
* @return true if successful, otherwise false.
*/
- boolean updateProjectList(ProjectListUpdateEvent projectListUpdateEvent);
+ boolean updateProjectList(ForwarderTask task, ProjectListUpdateEvent projectListUpdateEvent);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerCacheEvictionForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerCacheEvictionForwarder.java
index b32e5ae..1e2a48f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerCacheEvictionForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerCacheEvictionForwarder.java
@@ -19,22 +19,21 @@
import com.googlesource.gerrit.plugins.multisite.Configuration;
import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
import com.googlesource.gerrit.plugins.multisite.forwarder.CacheEvictionForwarder;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.CacheEvictionEvent;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
@Singleton
-public class BrokerCacheEvictionForwarder implements CacheEvictionForwarder {
- private final BrokerApiWrapper broker;
- private final Configuration cfg;
+public class BrokerCacheEvictionForwarder extends BrokerForwarder
+ implements CacheEvictionForwarder {
@Inject
BrokerCacheEvictionForwarder(BrokerApiWrapper broker, Configuration cfg) {
- this.broker = broker;
- this.cfg = cfg;
+ super(broker, cfg);
}
@Override
- public boolean evict(CacheEvictionEvent event) {
- return broker.send(EventTopic.CACHE_TOPIC.topic(cfg), event);
+ public boolean evict(ForwarderTask task, CacheEvictionEvent event) {
+ return send(task, EventTopic.CACHE_TOPIC, event);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerForwarder.java
new file mode 100644
index 0000000..da19fed
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerForwarder.java
@@ -0,0 +1,51 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.multisite.forwarder.broker;
+
+import com.googlesource.gerrit.plugins.multisite.Configuration;
+import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.MultiSiteEvent;
+
+public abstract class BrokerForwarder {
+ private static final CharSequence HIGH_AVAILABILITY_PLUGIN = "/plugins/high-availability/";
+ private static final CharSequence HIGH_AVAILABILITY_FORWARDER = "Forwarded-Index-Event";
+
+ private final BrokerApiWrapper broker;
+ private final Configuration cfg;
+
+ protected BrokerForwarder(BrokerApiWrapper broker, Configuration cfg) {
+ this.broker = broker;
+ this.cfg = cfg;
+ }
+
+ protected boolean currentThreadBelongsToHighAvailabilityPlugin(ForwarderTask task) {
+ String currentThreadName = task.getCallerThread().getName();
+
+ return currentThreadName.contains(HIGH_AVAILABILITY_PLUGIN)
+ || currentThreadName.contains(HIGH_AVAILABILITY_FORWARDER);
+ }
+
+ protected boolean send(ForwarderTask task, EventTopic eventTopic, MultiSiteEvent event) {
+ // Events generated by the high-availability plugin should be
+ // discarded. Sending them around would cause infinite loops.
+ if (currentThreadBelongsToHighAvailabilityPlugin(task)) {
+ return true;
+ }
+
+ return broker.send(eventTopic.topic(cfg), event);
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerIndexEventForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerIndexEventForwarder.java
index a86c62e..8321b94 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerIndexEventForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerIndexEventForwarder.java
@@ -17,27 +17,25 @@
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.multisite.Configuration;
import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.IndexEventForwarder;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.IndexEvent;
-public class BrokerIndexEventForwarder implements IndexEventForwarder {
- private final BrokerApiWrapper broker;
- private final Configuration cfg;
+public class BrokerIndexEventForwarder extends BrokerForwarder implements IndexEventForwarder {
@Inject
BrokerIndexEventForwarder(BrokerApiWrapper broker, Configuration cfg) {
- this.broker = broker;
- this.cfg = cfg;
+ super(broker, cfg);
}
@Override
- public boolean index(IndexEvent event) {
- return broker.send(EventTopic.INDEX_TOPIC.topic(cfg), event);
+ public boolean index(ForwarderTask task, IndexEvent event) {
+ return send(task, EventTopic.INDEX_TOPIC, event);
}
@Override
- public boolean batchIndex(IndexEvent event) {
- return broker.send(EventTopic.BATCH_INDEX_TOPIC.topic(cfg), event);
+ public boolean batchIndex(ForwarderTask task, IndexEvent event) {
+ return send(task, EventTopic.BATCH_INDEX_TOPIC, event);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerProjectListUpdateForwarder.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerProjectListUpdateForwarder.java
index 34e0300..dc8139d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerProjectListUpdateForwarder.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/forwarder/broker/BrokerProjectListUpdateForwarder.java
@@ -20,22 +20,21 @@
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.multisite.Configuration;
import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.ProjectListUpdateForwarder;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.ProjectListUpdateEvent;
@Singleton
-public class BrokerProjectListUpdateForwarder implements ProjectListUpdateForwarder {
- private final BrokerApiWrapper broker;
- private final Configuration cfg;
+public class BrokerProjectListUpdateForwarder extends BrokerForwarder
+ implements ProjectListUpdateForwarder {
@Inject
BrokerProjectListUpdateForwarder(BrokerApiWrapper broker, Configuration cfg) {
- this.broker = broker;
- this.cfg = cfg;
+ super(broker, cfg);
}
@Override
- public boolean updateProjectList(ProjectListUpdateEvent event) {
- return broker.send(PROJECT_LIST_TOPIC.topic(cfg), event);
+ public boolean updateProjectList(ForwarderTask task, ProjectListUpdateEvent event) {
+ return send(task, PROJECT_LIST_TOPIC, event);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
index 6ba18ed..02972b0 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ChangeCheckerImpl.java
@@ -79,7 +79,7 @@
@Override
public Optional<ChangeNotes> getChangeNotes() {
try (ManualRequestContext ctx = oneOffReqCtx.open()) {
- this.changeNotes = Optional.ofNullable(changeFinder.findOne(changeId));
+ this.changeNotes = changeFinder.findOne(changeId);
return changeNotes;
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java
index 649074b..5effd0e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandler.java
@@ -21,7 +21,9 @@
import com.google.gerrit.extensions.events.ProjectIndexedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.inject.Inject;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
+import com.googlesource.gerrit.plugins.multisite.forwarder.ForwarderTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.IndexEventForwarder;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.AccountIndexEvent;
import com.googlesource.gerrit.plugins.multisite.forwarder.events.ChangeIndexEvent;
@@ -44,6 +46,7 @@
private final DynamicSet<IndexEventForwarder> forwarders;
private final Set<IndexTask> queuedTasks = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final ChangeCheckerImpl.Factory changeChecker;
+ private final ProjectsFilter projectsFilter;
private final GroupChecker groupChecker;
@Inject
@@ -51,10 +54,12 @@
@IndexExecutor Executor executor,
DynamicSet<IndexEventForwarder> forwarders,
ChangeCheckerImpl.Factory changeChecker,
+ ProjectsFilter projectsFilter,
GroupChecker groupChecker) {
this.forwarders = forwarders;
this.executor = executor;
this.changeChecker = changeChecker;
+ this.projectsFilter = projectsFilter;
this.groupChecker = groupChecker;
}
@@ -91,7 +96,7 @@
@Override
public void onProjectIndexed(String projectName) {
- if (!Context.isForwardedEvent()) {
+ if (!Context.isForwardedEvent() && projectsFilter.matches(projectName)) {
IndexProjectTask task = new IndexProjectTask(new ProjectIndexEvent(projectName));
if (queuedTasks.add(task)) {
executor.execute(task);
@@ -100,7 +105,7 @@
}
private void executeIndexChangeTask(String projectName, int id) {
- if (!Context.isForwardedEvent()) {
+ if (!Context.isForwardedEvent() && projectsFilter.matches(projectName)) {
ChangeChecker checker = changeChecker.create(projectName + "~" + id);
try {
@@ -134,7 +139,8 @@
}
}
- abstract class IndexTask implements Runnable {
+ abstract class IndexTask extends ForwarderTask {
+
@Override
public void run() {
queuedTasks.remove(this);
@@ -153,7 +159,7 @@
@Override
public void execute() {
- forwarders.forEach(f -> f.index(changeIndexEvent));
+ forwarders.forEach(f -> f.index(this, changeIndexEvent));
}
@Override
@@ -184,7 +190,7 @@
@Override
public void execute() {
- forwarders.forEach(f -> f.batchIndex(changeIndexEvent));
+ forwarders.forEach(f -> f.batchIndex(this, changeIndexEvent));
}
@Override
@@ -215,7 +221,7 @@
@Override
public void execute() {
- forwarders.forEach(f -> f.index(accountIndexEvent));
+ forwarders.forEach(f -> f.index(this, accountIndexEvent));
}
@Override
@@ -246,7 +252,7 @@
@Override
public void execute() {
- forwarders.forEach(f -> f.index(groupIndexEvent));
+ forwarders.forEach(f -> f.index(this, groupIndexEvent));
}
@Override
@@ -277,7 +283,7 @@
@Override
public void execute() {
- forwarders.forEach(f -> f.index(projectIndexEvent));
+ forwarders.forEach(f -> f.index(this, projectIndexEvent));
}
@Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ProjectCheckerImpl.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ProjectCheckerImpl.java
index ba2a7d6..8655824 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ProjectCheckerImpl.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/index/ProjectCheckerImpl.java
@@ -30,6 +30,8 @@
@Override
public boolean isUpToDate(Optional<ProjectIndexEvent> indexEvent) {
- return indexEvent.map(e -> Project.nameKey(e.projectName)).map(projectCache::get).isPresent();
+ return indexEvent
+ .flatMap(event -> projectCache.get(Project.nameKey(event.projectName)))
+ .isPresent();
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
index 7aa3328..0afe308 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidator.java
@@ -18,6 +18,7 @@
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlesource.gerrit.plugins.multisite.LockWrapper;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.OutOfSyncException;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedRefEnforcement;
@@ -51,9 +52,17 @@
ValidationMetrics validationMetrics,
SharedRefEnforcement refEnforcement,
LockWrapper.Factory lockWrapperFactory,
+ ProjectsFilter projectsFilter,
@Assisted String projectName,
@Assisted RefDatabase refDb) {
- super(sharedRefDb, validationMetrics, refEnforcement, lockWrapperFactory, projectName, refDb);
+ super(
+ sharedRefDb,
+ validationMetrics,
+ refEnforcement,
+ lockWrapperFactory,
+ projectsFilter,
+ projectName,
+ refDb);
}
public void executeBatchUpdateWithValidation(
@@ -61,7 +70,8 @@
NoParameterVoidFunction batchRefUpdateFunction,
OneParameterVoidFunction<List<ReceiveCommand>> batchRefUpdateRollbackFunction)
throws IOException {
- if (refEnforcement.getPolicy(projectName) == EnforcePolicy.IGNORED) {
+ if (refEnforcement.getPolicy(projectName) == EnforcePolicy.IGNORED
+ || !isGlobalProject(projectName)) {
batchRefUpdateFunction.invoke();
return;
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
index 73bab49..c8ddb43 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdate.java
@@ -31,6 +31,7 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import java.io.IOException;
@@ -58,6 +59,7 @@
private final GitRepositoryManager gitRepositoryManager;
private final GitReferenceUpdated gitReferenceUpdated;
private final ProjectVersionLogger verLogger;
+ private final ProjectsFilter projectsFilter;
protected final SharedRefDatabaseWrapper sharedRefDb;
@@ -66,11 +68,13 @@
GitRepositoryManager gitRepositoryManager,
SharedRefDatabaseWrapper sharedRefDb,
GitReferenceUpdated gitReferenceUpdated,
- ProjectVersionLogger verLogger) {
+ ProjectVersionLogger verLogger,
+ ProjectsFilter projectsFilter) {
this.gitRepositoryManager = gitRepositoryManager;
this.sharedRefDb = sharedRefDb;
this.gitReferenceUpdated = gitReferenceUpdated;
this.verLogger = verLogger;
+ this.projectsFilter = projectsFilter;
}
@Override
@@ -78,7 +82,9 @@
logger.atFine().log("Processing event type: " + event.type);
// Producer of the Event use RefUpdatedEvent to trigger the version update
if (!Context.isForwardedEvent() && event instanceof RefUpdatedEvent) {
- updateProducerProjectVersionUpdate((RefUpdatedEvent) event);
+ if (projectsFilter.matches(event)) {
+ updateProducerProjectVersionUpdate((RefUpdatedEvent) event);
+ }
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
index d7fafe0..c110f0f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidator.java
@@ -21,6 +21,7 @@
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlesource.gerrit.plugins.multisite.LockWrapper;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.OutOfSyncException;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.SharedDbSplitBrainException;
@@ -46,6 +47,7 @@
private final LockWrapper.Factory lockWrapperFactory;
protected final RefDatabase refDb;
protected final SharedRefEnforcement refEnforcement;
+ protected final ProjectsFilter projectsFilter;
public static interface Factory {
RefUpdateValidator create(String projectName, RefDatabase refDb);
@@ -82,6 +84,7 @@
ValidationMetrics validationMetrics,
SharedRefEnforcement refEnforcement,
LockWrapper.Factory lockWrapperFactory,
+ ProjectsFilter projectsFilter,
@Assisted String projectName,
@Assisted RefDatabase refDb) {
this.sharedRefDb = sharedRefDb;
@@ -90,6 +93,7 @@
this.refDb = refDb;
this.projectName = projectName;
this.refEnforcement = refEnforcement;
+ this.projectsFilter = projectsFilter;
}
public RefUpdate.Result executeRefUpdate(
@@ -98,6 +102,7 @@
OneParameterFunction<ObjectId, Result> rollbackFunction)
throws IOException {
if (isProjectVersionUpdate(refUpdate.getName())
+ || !isGlobalProject(projectName)
|| refEnforcement.getPolicy(projectName) == EnforcePolicy.IGNORED) {
return refUpdateFunction.invoke();
}
@@ -123,6 +128,12 @@
}
}
+ protected Boolean isGlobalProject(String projectName) {
+ Boolean isGlobalProject = projectsFilter.matches(projectName);
+ logger.atFine().log("Is global project? " + isGlobalProject);
+ return isGlobalProject;
+ }
+
protected RefUpdate.Result doExecuteRefUpdate(
RefUpdate refUpdate,
NoParameterFunction<Result> refUpdateFunction,
@@ -256,7 +267,7 @@
}
protected Ref getCurrentRef(String refName) throws IOException {
- return MoreObjects.firstNonNull(refDb.getRef(refName), nullRef(refName));
+ return MoreObjects.firstNonNull(refDb.findRef(refName), nullRef(refName));
}
public static class CloseableSet<T extends AutoCloseable> implements AutoCloseable {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
index 481d288..4a34b7a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/multisite/validation/ValidationModule.java
@@ -14,7 +14,6 @@
package com.googlesource.gerrit.plugins.multisite.validation;
-import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.server.git.GitRepositoryManager;
@@ -33,8 +32,6 @@
import com.googlesource.gerrit.plugins.replication.ReplicationPushFilter;
public class ValidationModule extends FactoryModule {
- private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
private final Configuration cfg;
public ValidationModule(Configuration cfg) {
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 67e942f..a76545f 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -96,4 +96,28 @@
Ignore the alignment with the shared ref-database for AProject on refs/heads/feature.
- Defaults: No rules = All projects are REQUIRED to be consistent on all refs.
\ No newline at end of file
+ Defaults: No rules = All projects are REQUIRED to be consistent on all refs.
+
+```projects.pattern```
+: Specifies which projects events should be send via broker. It can be provided more
+ than once, and supports three formats: regular expressions, wildcard matching, and single
+ project matching. All three formats match case-sensitive.
+
+ Values starting with a caret `^` are treated as regular
+ expressions. For the regular expressions details please follow
+ official [java documentation](https://docs.oracle.com/javase/tutorial/essential/regex/).
+
+ Please note that regular expressions could also be used
+ with inverse match.
+
+ Values that are not regular expressions and end in `*` are
+ treated as wildcard matches. Wildcards match projects whose
+ name agrees from the beginning until the trailing `*`. So
+ `foo/b*` would match the projects `foo/b`, `foo/bar`, and
+ `foo/baz`, but neither `foobar`, nor `bar/foo/baz`.
+
+ Values that are neither regular expressions nor wildcards are
+ treated as single project matches. So `foo/bar` matches only
+ the project `foo/bar`, but no other project.
+
+ By default, all projects are matched.
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilterTest.java
new file mode 100644
index 0000000..e81c906
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/ProjectsFilterTest.java
@@ -0,0 +1,180 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.multisite;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.Lists;
+import com.google.gerrit.entities.Project.NameKey;
+import com.google.gerrit.server.events.Event;
+import com.google.gerrit.server.events.ProjectEvent;
+import com.google.gerrit.server.events.RefUpdatedEvent;
+import com.google.gerrit.testing.GerritJUnit;
+import com.googlesource.gerrit.plugins.multisite.Configuration.Projects;
+import java.util.Collections;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ProjectsFilterTest {
+
+ @Mock private Configuration configuration;
+ @Mock private Projects projects;
+
+ private ProjectsFilter objectUnderTest;
+
+ @Test
+ public void shouldMatchByExactProjectName() {
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isFalse();
+ }
+
+ @Test
+ public void shouldMatchByWildcard() {
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project*"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("2test_project"))).isFalse();
+ }
+
+ @Test
+ public void shouldMatchByRegex() {
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("^test_(project|project2)"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project3"))).isFalse();
+ }
+
+ @Test
+ public void shouldExcludeByRegex() {
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("^(?:(?!test_project3).)*$"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project3"))).isFalse();
+ }
+
+ @Test
+ public void shouldExcludeByMultipleProjectsRegexPattern() {
+ when(projects.getPatterns())
+ .thenReturn(Lists.newArrayList("^(?:(?!(test_project3|test_project4)).)*$"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project2"))).isTrue();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project3"))).isFalse();
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project4"))).isFalse();
+ }
+
+ @Test
+ public void shouldMatchWhenNoPatternProvided() {
+ when(projects.getPatterns()).thenReturn(Collections.emptyList());
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(NameKey.parse("test_project"))).isTrue();
+ }
+
+ @Test
+ public void shouldMatchProjectEvent() {
+ ProjectEvent event = mock(ProjectEvent.class);
+ when(event.getProjectNameKey()).thenReturn(NameKey.parse("test_project"));
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(event)).isTrue();
+ }
+
+ @Test
+ public void shouldMatchRefUpdatedEvent() {
+ RefUpdatedEvent event = mock(RefUpdatedEvent.class);
+ when(event.getProjectNameKey()).thenReturn(NameKey.parse("test_project"));
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(event)).isTrue();
+ }
+
+ @Test
+ public void shouldExcludedNonProjectEvents() {
+ Event event = mock(Event.class);
+ when(projects.getPatterns()).thenReturn(Lists.newArrayList("test_project)"));
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ assertThat(objectUnderTest.matches(event)).isFalse();
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenProjecNameIsNull() {
+ when(projects.getPatterns()).thenReturn(Collections.emptyList());
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ GerritJUnit.assertThrows(
+ IllegalArgumentException.class, () -> objectUnderTest.matches((NameKey) null));
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenProjecNameIsEmpty() {
+ when(projects.getPatterns()).thenReturn(Collections.emptyList());
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ GerritJUnit.assertThrows(
+ IllegalArgumentException.class, () -> objectUnderTest.matches(NameKey.parse("")));
+ }
+
+ @Test
+ public void shouldThrowExceptionWhenEventIsNull() {
+ when(projects.getPatterns()).thenReturn(Collections.emptyList());
+ when(configuration.projects()).thenReturn(projects);
+
+ objectUnderTest = new ProjectsFilter(configuration);
+
+ GerritJUnit.assertThrows(
+ IllegalArgumentException.class, () -> objectUnderTest.matches((Event) null));
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/CacheEvictionHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/CacheEvictionHandlerTest.java
new file mode 100644
index 0000000..67be583
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/CacheEvictionHandlerTest.java
@@ -0,0 +1,48 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.multisite.cache;
+
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import com.google.common.cache.RemovalCause;
+import com.google.common.cache.RemovalNotification;
+import com.google.gerrit.extensions.registration.DynamicSet;
+import com.googlesource.gerrit.plugins.multisite.Configuration;
+import java.util.concurrent.Executor;
+import org.eclipse.jgit.lib.Config;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class CacheEvictionHandlerTest {
+
+ @Mock private Executor executorMock;
+ private CachePatternMatcher defaultCacheMatcher =
+ new CachePatternMatcher(new Configuration(new Config(), new Config()));
+
+ @Test
+ public void shouldNotPublishAccountsCacheEvictions() {
+
+ final CacheEvictionHandler<String, String> handler =
+ new CacheEvictionHandler<>(DynamicSet.emptySet(), executorMock, defaultCacheMatcher);
+
+ handler.onRemoval(
+ "test", "accounts", RemovalNotification.create("test", "accounts", RemovalCause.EXPLICIT));
+
+ verifyZeroInteractions(executorMock);
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/CachePattenMatcherTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/CachePattenMatcherTest.java
index 052a9ae..b35e862 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/CachePattenMatcherTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/CachePattenMatcherTest.java
@@ -37,7 +37,6 @@
CachePatternMatcher matcher = new CachePatternMatcher(configurationMock);
for (String cache :
ImmutableList.of(
- "accounts",
"groups",
"groups_byinclude",
"groups_byname",
@@ -55,6 +54,7 @@
}
for (String cache :
ImmutableList.of(
+ "accounts",
"adv_bases",
"change_kind",
"change_notes",
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java
index bf4b4cf..2a25c37 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/cache/ProjectListUpdateHandlerTest.java
@@ -15,7 +15,10 @@
package com.googlesource.gerrit.plugins.multisite.cache;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@@ -24,6 +27,7 @@
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
import com.google.gerrit.extensions.events.ProjectDeletedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.cache.ProjectListUpdateHandler.ProjectListUpdateTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.ProjectListUpdateForwarder;
@@ -40,10 +44,14 @@
private ProjectListUpdateHandler handler;
@Mock private ProjectListUpdateForwarder forwarder;
+ @Mock private ProjectsFilter projectsFilter;
@Before
public void setUp() {
- handler = new ProjectListUpdateHandler(asDynamicSet(forwarder), MoreExecutors.directExecutor());
+ when(projectsFilter.matches(any(String.class))).thenReturn(true);
+ handler =
+ new ProjectListUpdateHandler(
+ asDynamicSet(forwarder), MoreExecutors.directExecutor(), projectsFilter);
}
private DynamicSet<ProjectListUpdateForwarder> asDynamicSet(
@@ -59,7 +67,9 @@
NewProjectCreatedListener.Event event = mock(NewProjectCreatedListener.Event.class);
when(event.getProjectName()).thenReturn(projectName);
handler.onNewProjectCreated(event);
- verify(forwarder).updateProjectList(new ProjectListUpdateEvent(projectName, false));
+ verify(forwarder)
+ .updateProjectList(
+ any(ProjectListUpdateTask.class), eq(new ProjectListUpdateEvent(projectName, false)));
}
@Test
@@ -68,7 +78,9 @@
ProjectDeletedListener.Event event = mock(ProjectDeletedListener.Event.class);
when(event.getProjectName()).thenReturn(projectName);
handler.onProjectDeleted(event);
- verify(forwarder).updateProjectList(new ProjectListUpdateEvent(projectName, true));
+ verify(forwarder)
+ .updateProjectList(
+ any(ProjectListUpdateTask.class), eq(new ProjectListUpdateEvent(projectName, true)));
}
@Test
@@ -81,6 +93,18 @@
}
@Test
+ public void shouldNotForwardIfFilteredOutByProjectName() throws Exception {
+ when(projectsFilter.matches(any(String.class))).thenReturn(false);
+ String projectName = "projectToAdd";
+ NewProjectCreatedListener.Event event = mock(NewProjectCreatedListener.Event.class);
+ when(event.getProjectName()).thenReturn(projectName);
+ handler.onNewProjectCreated(event);
+ verify(forwarder, never())
+ .updateProjectList(
+ any(ProjectListUpdateTask.class), eq(new ProjectListUpdateEvent(projectName, true)));
+ }
+
+ @Test
public void testProjectUpdateTaskToString() throws Exception {
String projectName = "someProjectName";
ProjectListUpdateTask task =
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java
index 990a03f..bac0851 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/event/EventHandlerTest.java
@@ -15,15 +15,19 @@
package com.googlesource.gerrit.plugins.multisite.event;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.ProjectEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.event.EventHandler.EventTask;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.forwarder.StreamEventForwarder;
@@ -39,10 +43,13 @@
private EventHandler eventHandler;
@Mock private StreamEventForwarder forwarder;
+ @Mock private ProjectsFilter projectsFilter;
@Before
public void setUp() {
- eventHandler = new EventHandler(asDynamicSet(forwarder), MoreExecutors.directExecutor());
+ when(projectsFilter.matches(any(ProjectEvent.class))).thenReturn(true);
+ eventHandler =
+ new EventHandler(asDynamicSet(forwarder), MoreExecutors.directExecutor(), projectsFilter);
}
private DynamicSet<StreamEventForwarder> asDynamicSet(StreamEventForwarder forwarder) {
@@ -53,7 +60,7 @@
@Test
public void shouldForwardAnyProjectEvent() throws Exception {
- Event event = mock(ProjectEvent.class);
+ ProjectEvent event = mock(ProjectEvent.class);
eventHandler.onEvent(event);
verify(forwarder).send(event);
}
@@ -73,6 +80,16 @@
}
@Test
+ public void shouldNotForwardIfFilteredOutByProjectName() throws Exception {
+ when(projectsFilter.matches(any(ProjectEvent.class))).thenReturn(false);
+
+ ProjectEvent event = mock(ProjectEvent.class);
+
+ eventHandler.onEvent(event);
+ verify(forwarder, never()).send(event);
+ }
+
+ @Test
public void tesEventTaskToString() throws Exception {
Event event = new RefUpdatedEvent();
EventTask task = eventHandler.new EventTask(event);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/BrokerForwarderTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/BrokerForwarderTest.java
new file mode 100644
index 0000000..5e2fc05
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/BrokerForwarderTest.java
@@ -0,0 +1,132 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.multisite.forwarder;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import com.googlesource.gerrit.plugins.multisite.Configuration;
+import com.googlesource.gerrit.plugins.multisite.broker.BrokerApiWrapper;
+import com.googlesource.gerrit.plugins.multisite.forwarder.broker.BrokerForwarder;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.EventTopic;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.MultiSiteEvent;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.eclipse.jgit.lib.Config;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class BrokerForwarderTest {
+ private static final String HIGH_AVAILABILITY_PLUGIN = "/plugins/high-availability/";
+ private static final String HIGH_AVAILABILITY_FORWARDED = "Forwarded-Index-Event";
+ private static final long TEST_TIMEOUT_SEC = 5L;
+
+ @Mock private BrokerApiWrapper brokerMock;
+
+ private TestBrokerForwarder brokerForwarder;
+
+ private Configuration cfg;
+
+ private EventTopic testTopic;
+
+ private String testTopicName;
+
+ private TestEvent testEvent;
+
+ private ExecutorService executor;
+
+ public class TestBrokerForwarder extends BrokerForwarder {
+
+ TestBrokerForwarder() {
+ super(brokerMock, cfg);
+ }
+
+ public void send(ForwarderTask task, EventTopic eventTopic, TestEvent testEvent) {
+ super.send(task, eventTopic, testEvent);
+ }
+ }
+
+ public class TestEvent extends MultiSiteEvent {
+
+ protected TestEvent() {
+ super("test");
+ }
+ }
+
+ @Before
+ public void setup() {
+ cfg = new Configuration(new Config(), new Config());
+ testTopic = EventTopic.INDEX_TOPIC;
+ testTopicName = testTopic.topic(cfg);
+ testEvent = new TestEvent();
+ brokerForwarder = new TestBrokerForwarder();
+ executor = Executors.newSingleThreadExecutor();
+ }
+
+ @After
+ public void teardown() {
+ executor.shutdown();
+ }
+
+ @Test
+ public void shouldSendEventToBrokerFromGenericSourceThread() {
+ brokerForwarder.send(newForwarderTask(), testTopic, testEvent);
+ verify(brokerMock).send(eq(testTopicName), eq(testEvent));
+ }
+
+ @Test
+ public void shouldSkipEventFromHighAvailabilityPluginThread() {
+ brokerForwarder.send(newForwarderTask(HIGH_AVAILABILITY_PLUGIN), testTopic, testEvent);
+ verifyZeroInteractions(brokerMock);
+ }
+
+ @Test
+ public void shouldSkipEventFromHighAvailabilityPluginForwardedThread() {
+ brokerForwarder.send(newForwarderTask(HIGH_AVAILABILITY_FORWARDED), testTopic, testEvent);
+
+ verifyZeroInteractions(brokerMock);
+ }
+
+ private ForwarderTask newForwarderTask(String threadName) {
+ try {
+ return executor
+ .submit(
+ () -> {
+ Thread.currentThread().setName(threadName);
+ return newForwarderTask();
+ })
+ .get(TEST_TIMEOUT_SEC, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private ForwarderTask newForwarderTask() {
+ return new ForwarderTask() {
+
+ @Override
+ public void run() {}
+ };
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedCacheEvictionHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedCacheEvictionHandlerTest.java
index 747da79..90ae8da 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedCacheEvictionHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/forwarder/ForwardedCacheEvictionHandlerTest.java
@@ -15,11 +15,10 @@
package com.googlesource.gerrit.plugins.multisite.forwarder;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
import com.google.gerrit.entities.Account;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.googlesource.gerrit.plugins.multisite.cache.Constants;
@@ -30,19 +29,19 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
-import org.mockito.stubbing.Answer;
@RunWith(MockitoJUnitRunner.class)
public class ForwardedCacheEvictionHandlerTest {
@Rule public ExpectedException exception = ExpectedException.none();
@Mock private DynamicMap<Cache<?, ?>> cacheMapMock;
- @Mock private Cache<?, ?> cacheMock;
+ private Cache<Object, Object> cacheUnderTest;
private ForwardedCacheEvictionHandler handler;
@Before
public void setUp() throws Exception {
handler = new ForwardedCacheEvictionHandler(cacheMapMock);
+ cacheUnderTest = CacheBuilder.newBuilder().build();
}
@Test
@@ -58,65 +57,22 @@
@Test
public void testSuccessfulCacheEviction() throws Exception {
CacheEntry entry = new CacheEntry(Constants.GERRIT, Constants.ACCOUNTS, Account.id(123));
- doReturn(cacheMock).when(cacheMapMock).get(entry.getPluginName(), entry.getCacheName());
+ cacheUnderTest.put(entry.getKey(), new Object());
+ doReturn(cacheUnderTest).when(cacheMapMock).get(entry.getPluginName(), entry.getCacheName());
handler.evict(entry);
- verify(cacheMock).invalidate(entry.getKey());
+ assertThat(cacheUnderTest.getIfPresent(entry.getKey())).isNull();
}
@Test
public void testSuccessfulProjectListCacheEviction() throws Exception {
CacheEntry entry = new CacheEntry(Constants.GERRIT, Constants.PROJECT_LIST, null);
- doReturn(cacheMock).when(cacheMapMock).get(entry.getPluginName(), entry.getCacheName());
+ cacheUnderTest.put("foo", new Object());
+ cacheUnderTest.put("bar", new Object());
+ doReturn(cacheUnderTest).when(cacheMapMock).get(entry.getPluginName(), entry.getCacheName());
handler.evict(entry);
- verify(cacheMock).invalidateAll();
- }
-
- @Test
- public void shouldSetAndUnsetForwardedContext() throws Exception {
- CacheEntry entry = new CacheEntry(Constants.GERRIT, Constants.ACCOUNTS, Account.id(456));
- doReturn(cacheMock).when(cacheMapMock).get(entry.getPluginName(), entry.getCacheName());
-
- // this doAnswer is to allow to assert that context is set to forwarded
- // while cache eviction is called.
- doAnswer(
- (Answer<Void>)
- invocation -> {
- assertThat(Context.isForwardedEvent()).isTrue();
- return null;
- })
- .when(cacheMock)
- .invalidate(entry.getKey());
-
- assertThat(Context.isForwardedEvent()).isFalse();
- handler.evict(entry);
- assertThat(Context.isForwardedEvent()).isFalse();
-
- verify(cacheMock).invalidate(entry.getKey());
- }
-
- @Test
- public void shouldSetAndUnsetForwardedContextEvenIfExceptionIsThrown() throws Exception {
- CacheEntry entry = new CacheEntry(Constants.GERRIT, Constants.ACCOUNTS, Account.id(789));
- doReturn(cacheMock).when(cacheMapMock).get(entry.getPluginName(), entry.getCacheName());
-
- doAnswer(
- (Answer<Void>)
- invocation -> {
- assertThat(Context.isForwardedEvent()).isTrue();
- throw new RuntimeException();
- })
- .when(cacheMock)
- .invalidate(entry.getKey());
-
- assertThat(Context.isForwardedEvent()).isFalse();
- try {
- handler.evict(entry);
- } catch (RuntimeException e) {
- }
- assertThat(Context.isForwardedEvent()).isFalse();
-
- verify(cacheMock).invalidate(entry.getKey());
+ assertThat(cacheUnderTest.getIfPresent("foo")).isNull();
+ assertThat(cacheUnderTest.getIfPresent("bar")).isNull();
}
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java
new file mode 100644
index 0000000..022dec5
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/index/IndexEventHandlerTest.java
@@ -0,0 +1,79 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.googlesource.gerrit.plugins.multisite.index;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.gerrit.extensions.registration.DynamicSet;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
+import com.googlesource.gerrit.plugins.multisite.forwarder.IndexEventForwarder;
+import com.googlesource.gerrit.plugins.multisite.forwarder.events.ProjectIndexEvent;
+import com.googlesource.gerrit.plugins.multisite.index.IndexEventHandler.IndexProjectTask;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class IndexEventHandlerTest {
+
+ private IndexEventHandler eventHandler;
+
+ @Mock private ProjectsFilter projectsFilter;
+ @Mock private IndexEventForwarder forwarder;
+ @Mock private ChangeCheckerImpl.Factory changeChecker;
+
+ @Before
+ public void setUp() {
+ eventHandler =
+ new IndexEventHandler(
+ MoreExecutors.directExecutor(),
+ asDynamicSet(forwarder),
+ changeChecker,
+ projectsFilter,
+ new TestGroupChecker(true));
+ }
+
+ private DynamicSet<IndexEventForwarder> asDynamicSet(IndexEventForwarder forwarder) {
+ DynamicSet<IndexEventForwarder> result = new DynamicSet<>();
+ result.add("multi-site", forwarder);
+ return result;
+ }
+
+ @Test
+ public void shouldNotForwardProjectIndexedIfFilteredOutByProjectName() throws Exception {
+ when(projectsFilter.matches(any(String.class))).thenReturn(false);
+
+ eventHandler.onProjectIndexed("test_project");
+ verify(forwarder, never())
+ .index(any(IndexProjectTask.class), eq(new ProjectIndexEvent("test_project")));
+ }
+
+ @Test
+ public void shouldNotForwardIndexChangeIfFilteredOutByProjectName() throws Exception {
+ int changeId = 1;
+ when(projectsFilter.matches(any(String.class))).thenReturn(false);
+
+ eventHandler.onChangeIndexed("test_project", changeId);
+ verifyZeroInteractions(changeChecker);
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
index b79740d..41bebc2 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/BatchRefUpdateValidatorTest.java
@@ -16,14 +16,17 @@
import static com.google.common.truth.Truth.assertThat;
import static org.eclipse.jgit.transport.ReceiveCommand.Type.UPDATE;
-import static org.mockito.Mockito.any;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import com.google.gerrit.entities.Project;
import com.google.gerrit.metrics.DisabledMetricMaker;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.OneParameterVoidFunction;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
@@ -66,12 +69,15 @@
@Mock SharedRefDatabaseWrapper sharedRefDatabase;
@Mock SharedRefEnforcement tmpRefEnforcement;
+
+ @Mock ProjectsFilter projectsFilter;
+
@Mock OneParameterVoidFunction<List<ReceiveCommand>> rollbackFunction;
@Before
public void setup() throws Exception {
super.setUp();
-
+ when(projectsFilter.matches(anyString())).thenReturn(true);
gitRepoSetup();
}
@@ -142,6 +148,24 @@
(command) -> assertThat(command.getResult()).isEqualTo(ReceiveCommand.Result.LOCK_FAILURE));
}
+ @Test
+ public void shouldNotUpdateSharedRefDbWhenProjectIsLocal() throws Exception {
+ when(projectsFilter.matches(anyString())).thenReturn(false);
+
+ String AN_OUT_OF_SYNC_REF = "refs/changes/01/1/1";
+ BatchRefUpdate batchRefUpdate =
+ newBatchUpdate(
+ Collections.singletonList(new ReceiveCommand(A, B, AN_OUT_OF_SYNC_REF, UPDATE)));
+ BatchRefUpdateValidator batchRefUpdateValidator =
+ getRefValidatorForEnforcement(A_TEST_PROJECT_NAME, tmpRefEnforcement);
+
+ batchRefUpdateValidator.executeBatchUpdateWithValidation(
+ batchRefUpdate, () -> execute(batchRefUpdate), this::defaultRollback);
+
+ verify(sharedRefDatabase, never())
+ .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
+ }
+
private BatchRefUpdateValidator newDefaultValidator(String projectName) {
return getRefValidatorForEnforcement(projectName, new DefaultSharedRefEnforcement());
}
@@ -153,6 +177,7 @@
new ValidationMetrics(new DisabledMetricMaker()),
sharedRefEnforcement,
new DummyLockWrapper(),
+ projectsFilter,
projectName,
diskRepo.getRefDatabase());
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
index e9651fb..4aa4ba1 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteBatchRefUpdateTest.java
@@ -15,6 +15,7 @@
package com.googlesource.gerrit.plugins.multisite.validation;
import static java.util.Arrays.asList;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
@@ -24,6 +25,7 @@
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.OneParameterVoidFunction;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
@@ -40,6 +42,7 @@
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.transport.ReceiveCommand.Result;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
@@ -58,6 +61,7 @@
@Mock RevWalk revWalk;
@Mock ProgressMonitor progressMonitor;
@Mock ValidationMetrics validationMetrics;
+ @Mock ProjectsFilter projectsFilter;
@Mock OneParameterVoidFunction<List<ReceiveCommand>> rollbackFunction;
private final Ref oldRef =
@@ -94,6 +98,11 @@
return "branch_" + nameRule.getMethodName();
}
+ @Before
+ public void setup() {
+ when(projectsFilter.matches(anyString())).thenReturn(true);
+ }
+
@SuppressWarnings("deprecation")
private void setMockRequiredReturnValues() throws IOException {
@@ -170,6 +179,7 @@
validationMetrics,
new DefaultSharedRefEnforcement(),
new DummyLockWrapper(),
+ projectsFilter,
projectName,
refDb);
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
index 9e75c8f..029a4c6 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/MultiSiteRefUpdateTest.java
@@ -16,11 +16,14 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.Factory;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
@@ -33,6 +36,7 @@
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -49,6 +53,7 @@
@Mock SharedRefDatabaseWrapper sharedRefDb;
@Mock ValidationMetrics validationMetrics;
@Mock RefDatabase refDb;
+ @Mock ProjectsFilter projectsFilter;
private final Ref oldRef =
new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, A_TEST_REF_NAME, AN_OBJECT_ID_1);
@@ -62,6 +67,11 @@
return "branch_" + nameRule.getMethodName();
}
+ @Before
+ public void setup() {
+ when(projectsFilter.matches(anyString())).thenReturn(true);
+ }
+
@Test
public void newUpdateShouldValidateAndSucceed() throws Exception {
@@ -92,7 +102,7 @@
}
@Test
- public void newUpdateShouldIncreaseRefUpdateFailureCountWhenFailing() throws IOException {
+ public void newUpdateShouldIncreaseRefUpdateFailureCountWhenFailing() {
doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
@@ -106,8 +116,7 @@
}
@Test
- public void newUpdateShouldNotIncreaseSplitBrainPreventedCounterIfFailingSharedDbPostUpdate()
- throws IOException {
+ public void newUpdateShouldNotIncreaseSplitBrainPreventedCounterIfFailingSharedDbPostUpdate() {
doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
doReturn(false)
@@ -124,8 +133,7 @@
}
@Test
- public void newUpdateShouldtIncreaseSplitBrainCounterIfFailingSharedDbPostUpdate()
- throws IOException {
+ public void newUpdateShouldtIncreaseSplitBrainCounterIfFailingSharedDbPostUpdate() {
doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
doReturn(false)
@@ -159,7 +167,7 @@
}
@Test
- public void deleteShouldIncreaseRefUpdateFailureCountWhenFailing() throws IOException {
+ public void deleteShouldIncreaseRefUpdateFailureCountWhenFailing() {
doReturn(false).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, oldRef);
@@ -184,6 +192,7 @@
validationMetrics,
new DefaultSharedRefEnforcement(),
new DummyLockWrapper(),
+ projectsFilter,
projectName,
refDb);
return RefUpdateValidator;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
index 2eefb5a..d437a73 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/ProjectVersionRefUpdateTest.java
@@ -26,6 +26,7 @@
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
+import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.project.ProjectConfig;
@@ -33,6 +34,7 @@
import com.google.gerrit.testing.InMemoryTestEnvironment;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.multisite.ProjectVersionLogger;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
import com.googlesource.gerrit.plugins.multisite.forwarder.Context;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
@@ -63,6 +65,7 @@
@Mock SharedRefDatabaseWrapper sharedRefDb;
@Mock GitReferenceUpdated gitReferenceUpdated;
@Mock ProjectVersionLogger verLogger;
+ @Mock ProjectsFilter projectsFilter;
@Inject private ProjectConfig.Factory projectConfigFactory;
@Inject private InMemoryRepositoryManager repoManager;
@@ -73,6 +76,7 @@
@Before
public void setUp() throws Exception {
+ when(projectsFilter.matches(any(Event.class))).thenReturn(true);
InMemoryRepository inMemoryRepo = repoManager.createRepository(A_TEST_PROJECT_NAME_KEY);
project = projectConfigFactory.create(A_TEST_PROJECT_NAME_KEY);
project.load(inMemoryRepo);
@@ -105,7 +109,8 @@
when(refUpdatedEvent.getProjectNameKey()).thenReturn(A_TEST_PROJECT_NAME_KEY);
when(refUpdatedEvent.getRefName()).thenReturn(A_TEST_REF_NAME);
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -150,7 +155,8 @@
when(refUpdatedEvent.getProjectNameKey()).thenReturn(A_TEST_PROJECT_NAME_KEY);
when(refUpdatedEvent.getRefName()).thenReturn(A_TEST_REF_NAME);
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -190,7 +196,8 @@
when(refUpdatedEvent.getProjectNameKey()).thenReturn(A_TEST_PROJECT_NAME_KEY);
when(refUpdatedEvent.getRefName()).thenReturn(A_TEST_REF_NAME);
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -227,7 +234,8 @@
when(refUpdatedEvent.getRefName()).thenReturn(magicRefName);
repo.branch(magicRefName).commit().create();
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -242,7 +250,30 @@
when(refUpdatedEvent.getProjectNameKey()).thenReturn(Project.nameKey("aNonExistentProject"));
when(refUpdatedEvent.getRefName()).thenReturn(A_TEST_REF_NAME);
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
+ .onEvent(refUpdatedEvent);
+
+ Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
+ assertThat(ref).isNull();
+
+ verifyZeroInteractions(verLogger);
+ }
+
+ @Test
+ public void shouldNotUpdateProjectVersionWhenProjectFilteredOut() throws Exception {
+ when(projectsFilter.matches(any(Event.class))).thenReturn(false);
+
+ Context.setForwardedEvent(false);
+
+ Thread.sleep(1000L);
+ repo.branch("master").commit().create();
+
+ Thread.sleep(1000L);
+ repo.branch("master").update(masterCommit);
+
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.onEvent(refUpdatedEvent);
Ref ref = repo.getRepository().findRef(MULTI_SITE_VERSIONING_REF);
@@ -257,7 +288,8 @@
.thenReturn(Optional.of("123"));
Optional<Long> version =
- new ProjectVersionRefUpdate(repoManager, sharedRefDb, gitReferenceUpdated, verLogger)
+ new ProjectVersionRefUpdate(
+ repoManager, sharedRefDb, gitReferenceUpdated, verLogger, projectsFilter)
.getProjectRemoteVersion(A_TEST_PROJECT_NAME);
assertThat(version.isPresent()).isTrue();
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
index 323db63..b9b07bd 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/RefUpdateValidatorTest.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.never;
@@ -23,9 +24,10 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import com.gerritforge.gerrit.globalrefdb.GlobalRefDbSystemError;
import com.google.gerrit.entities.Project;
+import com.googlesource.gerrit.plugins.multisite.ProjectsFilter;
import com.googlesource.gerrit.plugins.multisite.SharedRefDatabaseWrapper;
+import com.googlesource.gerrit.plugins.multisite.SharedRefLogger;
import com.googlesource.gerrit.plugins.multisite.validation.RefUpdateValidator.OneParameterFunction;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.DefaultSharedRefEnforcement;
import com.googlesource.gerrit.plugins.multisite.validation.dfsrefdb.RefFixture;
@@ -47,12 +49,16 @@
@Mock SharedRefDatabaseWrapper sharedRefDb;
+ @Mock SharedRefLogger sharedRefLogger;
+
@Mock RefDatabase localRefDb;
@Mock ValidationMetrics validationMetrics;
@Mock RefUpdate refUpdate;
+ @Mock ProjectsFilter projectsFilter;
+
@Mock OneParameterFunction<ObjectId, Result> rollbackFunction;
String refName;
@@ -69,21 +75,26 @@
newUpdateRef = newRef(refName, AN_OBJECT_ID_2);
localRef = newRef(refName, AN_OBJECT_ID_3);
- doReturn(localRef).when(localRefDb).getRef(refName);
+ doReturn(localRef).when(localRefDb).findRef(refName);
doReturn(localRef).when(localRefDb).exactRef(refName);
doReturn(newUpdateRef.getObjectId()).when(refUpdate).getNewObjectId();
doReturn(refName).when(refUpdate).getName();
lenient().doReturn(oldUpdateRef.getObjectId()).when(refUpdate).getOldObjectId();
doReturn(Result.FAST_FORWARD).when(rollbackFunction).invoke(any());
- refUpdateValidator =
- new RefUpdateValidator(
- sharedRefDb,
- validationMetrics,
- defaultRefEnforcement,
- new DummyLockWrapper(),
- A_TEST_PROJECT_NAME,
- localRefDb);
+ doReturn(true).when(projectsFilter).matches(anyString());
+
+ refUpdateValidator = newRefUpdateValidator(sharedRefDb);
+ }
+
+ @Test
+ public void validationShouldSucceedWhenSharedRefDbIsNoop() throws Exception {
+ SharedRefDatabaseWrapper noopSharedRefDbWrapper = new SharedRefDatabaseWrapper(sharedRefLogger);
+
+ Result result =
+ newRefUpdateValidator(noopSharedRefDbWrapper)
+ .executeRefUpdate(refUpdate, () -> RefUpdate.Result.NEW, this::defaultRollback);
+ assertThat(result).isEqualTo(RefUpdate.Result.NEW);
}
@Test
@@ -119,7 +130,7 @@
doReturn(true)
.when(sharedRefDb)
.compareAndPut(A_TEST_PROJECT_NAME_KEY, localRef, ObjectId.zeroId());
- doReturn(localRef).doReturn(null).when(localRefDb).getRef(refName);
+ doReturn(localRef).doReturn(null).when(localRefDb).findRef(refName);
Result result =
refUpdateValidator.executeRefUpdate(
@@ -140,7 +151,7 @@
doReturn(true)
.when(sharedRefDb)
.compareAndPut(A_TEST_PROJECT_NAME_KEY, localNullRef, newUpdateRef.getObjectId());
- doReturn(localNullRef).doReturn(newUpdateRef).when(localRefDb).getRef(refName);
+ doReturn(localNullRef).doReturn(newUpdateRef).when(localRefDb).findRef(refName);
Result result =
refUpdateValidator.executeRefUpdate(
@@ -206,20 +217,25 @@
}
@Test
- public void shouldRollbackRefUpdateWhenCompareAndPutIsFailing() throws Exception {
- lenient()
- .doReturn(false)
- .when(sharedRefDb)
- .isUpToDate(any(Project.NameKey.class), any(Ref.class));
- doReturn(true).when(sharedRefDb).isUpToDate(A_TEST_PROJECT_NAME_KEY, localRef);
+ public void shouldNotUpdateSharedRefDbWhenProjectIsLocal() throws Exception {
+ when(projectsFilter.matches(anyString())).thenReturn(false);
- when(sharedRefDb.compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class)))
- .thenThrow(GlobalRefDbSystemError.class);
- when(rollbackFunction.invoke(any())).thenReturn(Result.LOCK_FAILURE);
+ refUpdateValidator.executeRefUpdate(
+ refUpdate, () -> RefUpdate.Result.NEW, this::defaultRollback);
- refUpdateValidator.executeRefUpdate(refUpdate, () -> Result.NEW, rollbackFunction);
+ verify(sharedRefDb, never())
+ .compareAndPut(any(Project.NameKey.class), any(Ref.class), any(ObjectId.class));
+ }
- verify(rollbackFunction, times(1)).invoke(any());
+ private RefUpdateValidator newRefUpdateValidator(SharedRefDatabaseWrapper refDbWrapper) {
+ return new RefUpdateValidator(
+ refDbWrapper,
+ validationMetrics,
+ defaultRefEnforcement,
+ new DummyLockWrapper(),
+ projectsFilter,
+ A_TEST_PROJECT_NAME,
+ localRefDb);
}
private Result defaultRollback(ObjectId objectId) {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java
index 7e4593b..f2b57a1 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/multisite/validation/dfsrefdb/MultisiteReplicationPushFilterTest.java
@@ -68,7 +68,7 @@
private TestRepository<InMemoryRepository> repo;
@Before
- public void setUp() throws Exception {
+ public void setupTestRepo() throws Exception {
InMemoryRepository inMemoryRepo =
gitRepositoryManager.createRepository(A_TEST_PROJECT_NAME_KEY);
repo = new TestRepository<>(inMemoryRepo);