Make ChangeHooks expose postEvent method to send stream event

Add method ChangeHooks.postEvent(), plugins can now easily send a
stream event, for example, in replication plugin, after a patchset
is replicated, it can send a patchset replicated event.

Change-Id: Ie66497ae8fd9e8ede540754719c3f71fa85bf81a
Signed-off-by: David Pursehouse <david.pursehouse@sonymobile.com>
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index 5d57862..fe1062f 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -334,6 +334,17 @@
 +
 Project deletion
 
+[[stream-events]]
+Sending Events to the Events Stream
+-----------------------------------
+
+Plugins may send events to the events stream where consumers of
+Gerrit's `stream-events` ssh command will receive them.
+
+To send an event, the plugin must invoke one of the `postEvent`
+methods in the `ChangeHookRunner` class, passing an instance of
+its own custom event class derived from `ChangeEvent`.
+
 [[ssh]]
 SSH Commands
 ------------
diff --git a/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHookRunner.java b/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHookRunner.java
index 9cf6c28..984b55f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHookRunner.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHookRunner.java
@@ -600,6 +600,18 @@
       }
     }
 
+    @Override
+    public void postEvent(final Change change, final ChangeEvent event,
+        final ReviewDb db) throws OrmException {
+      fireEvent(change, event, db);
+    }
+
+    @Override
+    public void postEvent(final Branch.NameKey branchName,
+        final ChangeEvent event) throws OrmException {
+      fireEvent(branchName, event);
+    }
+
     private void fireEventForUnrestrictedListeners(final ChangeEvent event) {
       for (ChangeListener listener : unrestrictedListeners) {
           listener.onChangeEvent(event);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHooks.java b/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHooks.java
index 1d37002..97c0bdf 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHooks.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/common/ChangeHooks.java
@@ -23,6 +23,7 @@
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.events.ChangeEvent;
 import com.google.gwtorm.server.OrmException;
 
 import org.eclipse.jgit.lib.ObjectId;
@@ -170,4 +171,25 @@
    */
   public HookResult doRefUpdateHook(Project project,  String refName,
        Account uploader, ObjectId oldId, ObjectId newId);
+
+  /**
+   * Post a stream event that is related to a change
+   *
+   * @param change The change that the event is related to
+   * @param event The event to post
+   * @param db The database
+   * @throws OrmException
+   */
+  public void postEvent(Change change, ChangeEvent event, ReviewDb db)
+      throws OrmException;
+
+  /**
+   * Post a stream event that is related to a branch
+   *
+   * @param branchName The branch that the event is related to
+   * @param event The event to post
+   * @throws OrmException
+   */
+  public void postEvent(Branch.NameKey branchName, ChangeEvent event)
+      throws OrmException;
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/common/DisabledChangeHooks.java b/gerrit-server/src/main/java/com/google/gerrit/common/DisabledChangeHooks.java
index 021d1d2..dd68296 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/common/DisabledChangeHooks.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/common/DisabledChangeHooks.java
@@ -18,11 +18,13 @@
 import com.google.gerrit.common.data.ContributorAgreement;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.Branch.NameKey;
+import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.events.ChangeEvent;
 
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.RefUpdate;
@@ -104,4 +106,12 @@
       Account uploader, ObjectId oldId, ObjectId newId) {
     return null;
   }
+
+  @Override
+  public void postEvent(Change change, ChangeEvent event, ReviewDb db) {
+  }
+
+  @Override
+  public void postEvent(Branch.NameKey branchName, ChangeEvent event) {
+  }
 }