Extract event posting task into own class

This is a preparation step for improving the retry logic where
thread sleep will be replaced by rescheduling the task. This should
make it easier to write tests for the retry logic.

Change-Id: Ided1d30f530fbd09cfa48d186e0d7f7ea9ac1cf1
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 0947f38..b0a39e5 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/webhooks/EventHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/webhooks/EventHandler.java
@@ -14,49 +14,34 @@
 
 package com.googlesource.gerrit.plugins.webhooks;
 
-import java.io.IOException;
-import java.util.concurrent.Executor;
-
 import org.eclipse.jgit.lib.Config;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Strings;
-import com.google.common.base.Supplier;
 import com.google.gerrit.common.EventListener;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.events.Event;
 import com.google.gerrit.server.events.ProjectEvent;
-import com.google.gerrit.server.events.SupplierSerializer;
 import com.google.gerrit.server.project.NoSuchProjectException;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
 import com.google.inject.Inject;
 
 class EventHandler implements EventListener {
   private static final Logger log = LoggerFactory
       .getLogger(EventHandler.class);
 
-  private final HttpSession session;
   private final PluginConfigFactory configFactory;
   private final String pluginName;
-  private final Executor executor;
-
-  private final Gson gson;
+  private final PostEventTask.Factory taskFactory;
 
   @Inject
-  EventHandler(HttpSession session,
-      PluginConfigFactory configFactory,
+  EventHandler(PluginConfigFactory configFactory,
       @PluginName String pluginName,
-      @WebHooksExecutor Executor executor) {
-    this.session = session;
+      PostEventTask.Factory taskFactory) {
     this.configFactory = configFactory;
     this.pluginName = pluginName;
-    this.executor = executor;
-    this.gson = new GsonBuilder()
-        .registerTypeAdapter(Supplier.class, new SupplierSerializer())
-        .create();
+    this.taskFactory = taskFactory;
   }
 
   @Override
@@ -100,22 +85,6 @@
   }
 
   private void post(final String url, final ProjectEvent projectEvent) {
-    executor.execute(new Runnable() {
-      @Override
-      public void run() {
-        String serializedEvent = gson.toJson(projectEvent);
-        try {
-          session.post(url, serializedEvent);
-        } catch (IOException e) {
-          log.error("Coulnd't post event: " + projectEvent, e);
-        }
-      }
-
-      @Override
-      public String toString() {
-        return String.format("%s:%s > %s",
-            projectEvent.type, projectEvent.getProjectNameKey().get(), url);
-      }
-    });
+    taskFactory.create(url, projectEvent).schedule();
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/webhooks/Module.java b/src/main/java/com/googlesource/gerrit/plugins/webhooks/Module.java
index d749e9c..7681b0f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/webhooks/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/webhooks/Module.java
@@ -19,11 +19,11 @@
 import org.apache.http.impl.client.CloseableHttpClient;
 
 import com.google.gerrit.common.EventListener;
+import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.extensions.registration.DynamicSet;
-import com.google.inject.AbstractModule;
 import com.google.inject.Scopes;
 
-public class Module extends AbstractModule {
+public class Module extends FactoryModule {
 
   @Override
   protected void configure() {
@@ -33,6 +33,7 @@
     bind(Configuration.class).in(Scopes.SINGLETON);
     bind(CloseableHttpClient.class).toProvider(HttpClientProvider.class)
         .in(Scopes.SINGLETON);
+    factory(PostEventTask.Factory.class);
     DynamicSet.bind(binder(), EventListener.class).to(EventHandler.class);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/webhooks/PostEventTask.java b/src/main/java/com/googlesource/gerrit/plugins/webhooks/PostEventTask.java
new file mode 100644
index 0000000..88b9101
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/webhooks/PostEventTask.java
@@ -0,0 +1,78 @@
+// Copyright (C) 2017 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.webhooks;
+
+import java.io.IOException;
+import java.util.concurrent.Executor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Supplier;
+import com.google.gerrit.server.events.ProjectEvent;
+import com.google.gerrit.server.events.SupplierSerializer;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+
+class PostEventTask implements Runnable {
+  private static final Logger log = LoggerFactory
+      .getLogger(PostEventTask.class);
+
+  private static Gson GSON = new GsonBuilder()
+      .registerTypeAdapter(Supplier.class, new SupplierSerializer())
+      .create();
+
+  interface Factory {
+    PostEventTask create(String url, ProjectEvent projectEvent);
+  }
+
+  private final Executor executor;
+  private final HttpSession session;
+  private final String url;
+  private final ProjectEvent projectEvent;
+
+  @AssistedInject
+  public PostEventTask(@WebHooksExecutor Executor executor,
+      HttpSession session,
+      @Assisted String url,
+      @Assisted ProjectEvent projectEvent) {
+    this.executor = executor;
+    this.session = session;
+    this.url = url;
+    this.projectEvent = projectEvent;
+  }
+
+  void schedule() {
+    executor.execute(this);
+  }
+
+  @Override
+  public void run() {
+    String serializedEvent = GSON.toJson(projectEvent);
+    try {
+      session.post(url, serializedEvent);
+    } catch (IOException e) {
+      log.error("Couldn't post event: " + projectEvent, e);
+    }
+  }
+
+  @Override
+  public String toString() {
+    return String.format("%s:%s > %s",
+        projectEvent.type, projectEvent.getProjectNameKey().get(), url);
+  }
+}