Cache the resolution of allowed listeners
Avoid checking if an event listener is allowed every time
by caching the result of the resolution.
Change-Id: I75cfaaf9e1182e292ab6884584aff993c0e4fea9
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/ConfigurableAllowedEventListeners.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/ConfigurableAllowedEventListeners.java
index f7d0755..ea5f69c 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/ConfigurableAllowedEventListeners.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/ConfigurableAllowedEventListeners.java
@@ -18,18 +18,25 @@
import com.google.gerrit.server.events.EventListener;
import com.google.inject.Inject;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/** Configure the allowed listeners in high-availability.config */
public class ConfigurableAllowedEventListeners implements AllowedForwardedEventListener {
private final Set<String> allowedListenerClasses;
+ private final ConcurrentHashMap<EventListener, Boolean> cachedAllowedListeners;
@Inject
ConfigurableAllowedEventListeners(Configuration config) {
allowedListenerClasses = config.event().allowedListeners();
+ cachedAllowedListeners = new ConcurrentHashMap<>();
}
@Override
public boolean isAllowed(EventListener listener) {
+ return cachedAllowedListeners.computeIfAbsent(listener, this::computeIsAllowed);
+ }
+
+ protected Boolean computeIsAllowed(EventListener listener) {
String listenerClassName = listener.getClass().getName();
boolean allowed = false;
while (!allowed && !listenerClassName.isEmpty()) {
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
index 1ad69c3..fb1b8d0 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/ConfigurationTest.java
@@ -76,6 +76,7 @@
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jgit.lib.Config;
import org.junit.Before;
import org.junit.Test;
@@ -369,6 +370,36 @@
}
@Test
+ public void testConfiguredListenerAllowedShouldBeCached() throws Exception {
+ AtomicInteger allowedListenerResolutionCount = new AtomicInteger();
+ EventListener listener =
+ new EventListener() {
+
+ @Override
+ public void onEvent(Event event) {}
+ };
+ assertThat(new ConfigurableAllowedEventListeners(getConfiguration()).isAllowed(listener))
+ .isFalse();
+
+ globalPluginConfig.setString(
+ EVENT_SECTION, null, ALLOWED_LISTENERS, listener.getClass().getName());
+
+ ConfigurableAllowedEventListeners allowedEventListener =
+ new ConfigurableAllowedEventListeners(getConfiguration()) {
+ @Override
+ protected Boolean computeIsAllowed(EventListener listener) {
+ allowedListenerResolutionCount.incrementAndGet();
+ return super.computeIsAllowed(listener);
+ }
+ };
+
+ for (int i = 0; i < 2; i++) {
+ assertThat(allowedEventListener.isAllowed(listener)).isTrue();
+ assertThat(allowedListenerResolutionCount.get()).isEqualTo(1);
+ }
+ }
+
+ @Test
public void testConfiguredPackageOfListenerShouldBeAllowed() throws Exception {
EventListener listener =
new EventListener() {