Process events before scheduling
It's confusing for admins to see tasks scheduled for event types that
listeners haven't configured (or that haven't been globally allowed).
There's very little additional work done in the processing step and the
work saved by not scheduling unwanted events probably more than makes up
for it.
Release-Notes: Skip scheduling tasks for events that should not be processed
Change-Id: I8471a29662d1b88a15e29c5cb6e7e40e25b242f3
diff --git a/src/main/java/com/googlesource/gerrit/plugins/webhooks/EventHandler.java b/src/main/java/com/googlesource/gerrit/plugins/webhooks/EventHandler.java
index 3cf1f9c..489bec8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/webhooks/EventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/webhooks/EventHandler.java
@@ -25,6 +25,7 @@
import com.google.gerrit.server.events.ProjectEvent;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.inject.Inject;
+import java.util.Optional;
import org.eclipse.jgit.lib.Config;
class EventHandler implements EventListener {
@@ -35,6 +36,7 @@
private final String pluginName;
private final RemoteConfig.Factory remoteFactory;
private final PostTask.Factory taskFactory;
+ private final EventProcessor processor;
@Inject
EventHandler(
@@ -42,12 +44,14 @@
PluginConfigFactory configFactory,
@PluginName String pluginName,
RemoteConfig.Factory remoteFactory,
- PostTask.Factory taskFactory) {
+ PostTask.Factory taskFactory,
+ EventProcessor processor) {
this.global = global;
this.configFactory = configFactory;
this.pluginName = pluginName;
this.remoteFactory = remoteFactory;
this.taskFactory = taskFactory;
+ this.processor = processor;
}
@Override
@@ -80,7 +84,13 @@
"remote.%s.url does not match any allowed URL patterns, skipping this remote", name);
continue;
}
- taskFactory.create(projectEvent, remote).schedule();
+ Optional<EventProcessor.Request> content = processor.process(projectEvent, remote);
+ if (content.isEmpty()) {
+ log.atFine().log(
+ "No content (rejected by processing). Webhook [%s] skipped.", remote.getUrl());
+ continue;
+ }
+ taskFactory.create(projectEvent, remote, content.get()).schedule();
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/webhooks/PostTask.java b/src/main/java/com/googlesource/gerrit/plugins/webhooks/PostTask.java
index 844f87a..4eea44d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/webhooks/PostTask.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/webhooks/PostTask.java
@@ -22,7 +22,6 @@
import com.google.inject.assistedinject.AssistedInject;
import com.googlesource.gerrit.plugins.webhooks.HttpResponseHandler.HttpResult;
import java.io.IOException;
-import java.util.Optional;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -32,30 +31,30 @@
private static final FluentLogger log = FluentLogger.forEnclosingClass();
interface Factory {
- PostTask create(ProjectEvent event, RemoteConfig remote);
+ PostTask create(ProjectEvent event, RemoteConfig remote, EventProcessor.Request content);
}
private final ScheduledExecutorService executor;
private final Supplier<HttpSession> session;
private final RemoteConfig remote;
private final ProjectEvent event;
- private final Supplier<Optional<EventProcessor.Request>> processor;
+ private final EventProcessor.Request content;
private int execCnt;
@AssistedInject
public PostTask(
@WebHooksExecutor ScheduledExecutorService executor,
HttpSession.Factory session,
- EventProcessor processor,
@Assisted ProjectEvent event,
- @Assisted RemoteConfig remote) {
+ @Assisted RemoteConfig remote,
+ @Assisted EventProcessor.Request content) {
this.executor = executor;
this.event = event;
this.remote = remote;
+ this.content = content;
// postpone creation of HttpSession so that it is obtained only when processor
// returns non-empty content
this.session = Suppliers.memoize(() -> session.create(remote));
- this.processor = Suppliers.memoize(() -> processor.process(event, remote));
}
void schedule() {
@@ -71,14 +70,8 @@
@Override
public void run() {
try {
- Optional<EventProcessor.Request> content = processor.get();
- if (!content.isPresent()) {
- log.atFine().log("No content. Webhook [%s] skipped.", remote.getUrl());
- return;
- }
-
execCnt++;
- HttpResult result = session.get().post(remote, content.get());
+ HttpResult result = session.get().post(remote, content);
if (!result.successful) {
if (execCnt < remote.getMaxTries()) {
logRetry(result.message);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/webhooks/EventHandlerTest.java b/src/test/java/com/googlesource/gerrit/plugins/webhooks/EventHandlerTest.java
index 2aae9af..5d4eaf4 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/webhooks/EventHandlerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/webhooks/EventHandlerTest.java
@@ -27,6 +27,7 @@
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.ProjectCreatedEvent;
import com.google.gerrit.server.project.NoSuchProjectException;
+import java.util.Optional;
import java.util.regex.Pattern;
import org.eclipse.jgit.lib.Config;
import org.junit.Before;
@@ -59,6 +60,10 @@
@Mock private Config config;
+ @Mock private EventProcessor processor;
+
+ @Mock private EventProcessor.Request content;
+
private EventHandler eventHandler;
@Before
@@ -67,8 +72,10 @@
when(configFactory.getProjectPluginConfigWithInheritance(PROJECT_NAME, PLUGIN))
.thenReturn(config);
when(remoteFactory.create(eq(config), eq(FOO))).thenReturn(remote);
- when(taskFactory.create(eq(projectCreated), eq(remote))).thenReturn(postTask);
- eventHandler = new EventHandler(global, configFactory, PLUGIN, remoteFactory, taskFactory);
+ when(processor.process(eq(projectCreated), eq(remote))).thenReturn(Optional.of(content));
+ when(taskFactory.create(eq(projectCreated), eq(remote), eq(content))).thenReturn(postTask);
+ eventHandler =
+ new EventHandler(global, configFactory, PLUGIN, remoteFactory, taskFactory, processor);
}
@Test
@@ -85,7 +92,7 @@
when(remote.getUrl()).thenReturn(FOO_URL);
eventHandler.onEvent(projectCreated);
- verify(taskFactory, times(1)).create(eq(projectCreated), eq(remote));
+ verify(taskFactory, times(1)).create(eq(projectCreated), eq(remote), eq(content));
verify(postTask, times(1)).schedule();
}
@@ -105,7 +112,7 @@
when(remote.getUrl()).thenReturn(FOO_URL);
eventHandler.onEvent(projectCreated);
- verify(taskFactory, times(1)).create(eq(projectCreated), eq(remote));
+ verify(taskFactory, times(1)).create(eq(projectCreated), eq(remote), eq(content));
verify(postTask, times(1)).schedule();
}
@@ -120,4 +127,15 @@
verifyNoInteractions(taskFactory);
verifyNoInteractions(postTask);
}
+
+ @Test
+ public void noScheduleOnEmptyBody() throws Exception {
+ when(config.getSubsections(eq(REMOTE))).thenReturn(ImmutableSet.of(FOO));
+ when(remote.getUrl()).thenReturn(FOO_URL);
+ when(processor.process(eq(projectCreated), eq(remote))).thenReturn(Optional.empty());
+
+ eventHandler.onEvent(projectCreated);
+ verifyNoInteractions(taskFactory);
+ verifyNoInteractions(postTask);
+ }
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/webhooks/PostTaskTest.java b/src/test/java/com/googlesource/gerrit/plugins/webhooks/PostTaskTest.java
index 54aac2f..572ebe8 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/webhooks/PostTaskTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/webhooks/PostTaskTest.java
@@ -24,7 +24,6 @@
import com.google.gerrit.server.events.ProjectCreatedEvent;
import com.googlesource.gerrit.plugins.webhooks.HttpResponseHandler.HttpResult;
import java.io.IOException;
-import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@@ -54,8 +53,6 @@
@Mock private ScheduledThreadPoolExecutor executor;
- @Mock private EventProcessor processor;
-
@Mock private EventProcessor.Request content;
private PostTask task;
@@ -65,18 +62,9 @@
when(remote.getRetryInterval()).thenReturn(RETRY_INTERVAL);
when(remote.getMaxTries()).thenReturn(MAX_TRIES);
when(remote.getUrl()).thenReturn(WEBHOOK_URL);
- when(processor.process(eq(projectCreated), eq(remote))).thenReturn(Optional.of(content));
when(sessionFactory.create(eq(remote))).thenReturn(session);
when(projectCreated.getProjectNameKey()).thenReturn(Project.nameKey("test"));
- task = new PostTask(executor, sessionFactory, processor, projectCreated, remote);
- }
-
- @Test
- public void noScheduleOnEmptyBody() throws Exception {
- when(processor.process(eq(projectCreated), eq(remote))).thenReturn(Optional.empty());
- task.run();
- verifyNoInteractions(session);
- verifyNoInteractions(executor);
+ task = new PostTask(executor, sessionFactory, projectCreated, remote, content);
}
@Test