Merge branch 'stable-2.13' into stable-2.14

* stable-2.13:
  Make uploadpack rate limit exceeded message configurable
  Make configuration examples consistent
  Fix code block in documentation

Change-Id: I41c4c03973f08a1a479fa673005446e49263cf53
diff --git a/src/main/java/com/googlesource/gerrit/plugins/quota/RateLimitUploadListener.java b/src/main/java/com/googlesource/gerrit/plugins/quota/RateLimitUploadListener.java
index 64ec2b1..8d5a9b9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/quota/RateLimitUploadListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/quota/RateLimitUploadListener.java
@@ -20,9 +20,11 @@
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.cache.LoadingCache;
 import com.google.common.util.concurrent.RateLimiter;
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.git.validators.UploadValidationListener;
 import com.google.gerrit.server.validators.ValidationException;
 import com.google.inject.Inject;
@@ -50,6 +52,9 @@
       LoggerFactory.getLogger(RateLimitUploadListener.class);
   private static final Method createStopwatchMethod;
   private static final Constructor<?> constructor;
+  private static final String RATE_LIMIT_TOKEN = "${rateLimit}";
+  private static final String DEFAULT_RATE_LIMIT_EXCEEDED_MSG =
+      "Exceeded rate limit of " + RATE_LIMIT_TOKEN + " fetch requests/hour";
 
   static {
     try {
@@ -118,14 +123,20 @@
   private final Provider<CurrentUser> user;
   private final LoadingCache<Account.Id, Holder> limitsPerAccount;
   private final LoadingCache<String, Holder> limitsPerRemoteHost;
+  private final String limitExceededMsg;
 
   @Inject
   RateLimitUploadListener(Provider<CurrentUser> user,
       @Named(CACHE_NAME_ACCOUNTID) LoadingCache<Account.Id, Holder> limitsPerAccount,
-      @Named(CACHE_NAME_REMOTEHOST) LoadingCache<String, Holder> limitsPerRemoteHost) {
+      @Named(CACHE_NAME_REMOTEHOST) LoadingCache<String, Holder> limitsPerRemoteHost,
+      PluginConfigFactory cfg,
+      @PluginName String pluginName) {
     this.user = user;
     this.limitsPerAccount = limitsPerAccount;
     this.limitsPerRemoteHost = limitsPerRemoteHost;
+    String msg = cfg.getFromGerritConfig(pluginName).getString(
+        "uploadpackLimitExceededMsg", DEFAULT_RATE_LIMIT_EXCEEDED_MSG);
+    limitExceededMsg = msg.replace(RATE_LIMIT_TOKEN, "{0,number,##.##}");
   }
 
   @Override
@@ -155,7 +166,7 @@
     }
     if (limiter != null && !limiter.tryAcquire()) {
       throw new RateLimitException(
-          MessageFormat.format("Exceeded rate limit of {0,number,##.##} fetch requests/hour",
+          MessageFormat.format(limitExceededMsg,
               limiter.getRate() * SECONDS_PER_HOUR));
     }
   }
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index 8bf28c1..61e4a77 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -124,7 +124,7 @@
 
 ```
   [plugin "quota"]
-        useGitObjectCount = true
+    useGitObjectCount = true
 ```
 
 <a id="useGitObjectCount">
@@ -141,14 +141,15 @@
 limits are defined per user group and rate limit type:
 
 Example:
+
 ```
-[group "buildserver"]
+  [group "buildserver"]
     uploadpack = 10 / min burst 500
 
-[group "Registered Users"]
+  [group "Registered Users"]
     uploadpack = 1 /min burst 180
 
-[group "Anonymous Users"]
+  [group "Anonymous Users"]
     uploadpack = 6/h burst 12
 ```
 
@@ -168,7 +169,7 @@
 
 Format of the rate limit entries in `quota.config`:
 ```
-[group "<groupName>"]
+  [group "<groupName>"]
     <rateLimitType> = <rateLimit> <rateUnit> burst <storedRequests>
 ```
 
@@ -213,9 +214,15 @@
 of requests above the maximum request rate.
 
 ```
-[group "Registered Users"]
-	uploadpack = 30/hour burst 60
+  [group "Registered Users"]
+    uploadpack = 30/hour burst 60
 ```
+The rate limit exceeded message can be configured by setting parameter
+`uploadpackLimitExceededMsg` in the `plugin.quota` subsection of the
+`gerrit.config` file. `${rateLimit}` token is supported in the message and
+will be replaced by effective rate limit per hour.
+
+Defaults to `Exceeded rate limit of ${rateLimit} fetch requests/hour`
 
 Publication Schedule
 --------------------