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() {