Merge branch 'stable-2.13' into stable-2.14

* stable-2.13:
  Enhance UploadValidators to allow listening to negotation start

Change-Id: I38f1031dd04c5d47be7919ca11ae7751d3ec8cea
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/UploadValidationListener.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/UploadValidationListener.java
index 971f455..65e9c99 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/UploadValidationListener.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/UploadValidationListener.java
@@ -39,6 +39,7 @@
    * @param repository The repository
    * @param project The project
    * @param remoteHost Remote address/hostname of the user
+   * @param up the UploadPack instance being processed.
    * @param wants The list of wanted objects. These may be RevObject or RevCommit if the processor
    *     parsed them. Implementors should not rely on the values being parsed.
    * @param haves The list of common objects. Empty on an initial clone request. These may be
@@ -55,4 +56,26 @@
       Collection<? extends ObjectId> wants,
       Collection<? extends ObjectId> haves)
       throws ValidationException;
+
+  /**
+   * Invoked before negotiation round is started.
+   *
+   * @param repository The repository
+   * @param project The project
+   * @param remoteHost Remote address/hostname of the user
+   * @param up the UploadPack instance being processed
+   * @param wants The list of wanted objects. These may be RevObject or RevCommit if the processor
+   *     parsed them. Implementors should not rely on the values being parsed.
+   * @param cntOffered number of objects the client has offered.
+   * @throws ValidationException to block the upload and send a message back to the end-user over
+   *     the client's protocol connection.
+   */
+  void onBeginNegotiate(
+      Repository repository,
+      Project project,
+      String remoteHost,
+      UploadPack up,
+      Collection<? extends ObjectId> wants,
+      int cntOffered)
+      throws ValidationException;
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/UploadValidators.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/UploadValidators.java
index 52b76e8..84d4586 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/UploadValidators.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/UploadValidators.java
@@ -65,7 +65,15 @@
   @Override
   public void onBeginNegotiateRound(
       UploadPack up, Collection<? extends ObjectId> wants, int cntOffered)
-      throws ServiceMayNotContinueException {}
+      throws ServiceMayNotContinueException {
+    for (UploadValidationListener validator : uploadValidationListeners) {
+      try {
+        validator.onBeginNegotiate(repository, project, remoteHost, up, wants, cntOffered);
+      } catch (ValidationException e) {
+        throw new UploadValidationException(e.getMessage());
+      }
+    }
+  }
 
   @Override
   public void onEndNegotiateRound(