Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Upgrade bazlets to latest stable-2.14 to build with 2.14.21 API

Change-Id: I7797f9061a7ecedc8c30fd28159339775f34c1a9
diff --git a/WORKSPACE b/WORKSPACE
index b610dc5..c95334c 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "78c35a7eb33ee5ea0980923e246c7dba37347193",
+    commit = "f53f51fb660552d0581aa0ba52c3836ed63d56a3",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index fd37795..790d564 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -3,8 +3,8 @@
 def external_plugin_deps():
     maven_jar(
         name = "mockito",
-        artifact = "org.mockito:mockito-core:2.27.0",
-        sha1 = "835fc3283b481f4758b8ef464cd560c649c08b00",
+        artifact = "org.mockito:mockito-core:2.28.2",
+        sha1 = "91110215a8cb9b77a46e045ee758f77d79167cc0",
         deps = [
             "@byte-buddy//jar",
             "@byte-buddy-agent//jar",
diff --git a/src/main/java/com/googlesource/gerrit/plugins/quota/ListQuotas.java b/src/main/java/com/googlesource/gerrit/plugins/quota/ListQuotas.java
index 1d8061c..fccad96 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/quota/ListQuotas.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/quota/ListQuotas.java
@@ -15,17 +15,17 @@
 package com.googlesource.gerrit.plugins.quota;
 
 import com.google.common.collect.Maps;
-import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.extensions.restapi.BadRequestException;
-import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.ListProjects;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.googlesource.gerrit.plugins.quota.GetQuota.QuotaInfo;
 import java.util.Map;
+import java.util.concurrent.ExecutionException;
 import org.kohsuke.args4j.Option;
 
 public class ListQuotas implements RestReadView<ConfigResource> {
@@ -51,7 +51,7 @@
 
   @Override
   public Map<String, QuotaInfo> apply(ConfigResource resource)
-      throws AuthException, BadRequestException, ResourceConflictException, Exception {
+      throws RestApiException, ExecutionException, PermissionBackendException {
     Map<String, QuotaInfo> result = Maps.newTreeMap();
     ListProjects lister = listProjects.get();
     lister.setMatchPrefix(matchPrefix);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/quota/MaxRepositorySizeQuota.java b/src/main/java/com/googlesource/gerrit/plugins/quota/MaxRepositorySizeQuota.java
index f01255a..d1f1505 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/quota/MaxRepositorySizeQuota.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/quota/MaxRepositorySizeQuota.java
@@ -36,6 +36,7 @@
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Collection;
+import java.util.Optional;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
@@ -51,7 +52,8 @@
 import org.slf4j.LoggerFactory;
 
 @Singleton
-class MaxRepositorySizeQuota implements ReceivePackInitializer, PostReceiveHook, RepoSizeCache {
+public class MaxRepositorySizeQuota
+    implements ReceivePackInitializer, PostReceiveHook, RepoSizeCache {
   private static final Logger log = LoggerFactory.getLogger(MaxRepositorySizeQuota.class);
 
   static final String REPO_SIZE_CACHE = "repo_size";
@@ -68,13 +70,13 @@
     };
   }
 
+  protected final LoadingCache<Project.NameKey, AtomicLong> cache;
   private final QuotaFinder quotaFinder;
-  private final LoadingCache<Project.NameKey, AtomicLong> cache;
   private final ProjectCache projectCache;
   private final ProjectNameResolver projectNameResolver;
 
   @Inject
-  MaxRepositorySizeQuota(
+  protected MaxRepositorySizeQuota(
       QuotaFinder quotaFinder,
       @Named(REPO_SIZE_CACHE) LoadingCache<Project.NameKey, AtomicLong> cache,
       ProjectCache projectCache,
@@ -87,15 +89,22 @@
 
   @Override
   public void init(Project.NameKey project, ReceivePack rp) {
+    Optional<Long> maxPackSize = getMaxPackSize(project);
+    if (maxPackSize.isPresent()) {
+      rp.setMaxPackSizeLimit(maxPackSize.get());
+    }
+  }
+
+  protected Optional<Long> getMaxPackSize(Project.NameKey project) {
     QuotaSection quotaSection = quotaFinder.firstMatching(project);
     if (quotaSection == null) {
-      return;
+      return Optional.empty();
     }
 
     Long maxRepoSize = quotaSection.getMaxRepoSize();
     Long maxTotalSize = quotaSection.getMaxTotalSize();
     if (maxRepoSize == null && maxTotalSize == null) {
-      return;
+      return Optional.empty();
     }
 
     try {
@@ -115,10 +124,11 @@
         maxPackSize2 = Math.max(0, maxTotalSize - totalSize);
       }
 
-      long maxPackSize = Ordering.<Long>natural().nullsLast().min(maxPackSize1, maxPackSize2);
-      rp.setMaxPackSizeLimit(maxPackSize);
+      return Optional.ofNullable(
+          Ordering.<Long>natural().nullsLast().min(maxPackSize1, maxPackSize2));
     } catch (ExecutionException e) {
-      log.warn("Couldn't setMaxPackSizeLimit on receive-pack for {}", project, e);
+      log.warn("Couldn't calculate maxPackSize for {}", project, e);
+      return Optional.empty();
     }
   }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/quota/Module.java b/src/main/java/com/googlesource/gerrit/plugins/quota/Module.java
index a762579..e514334 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/quota/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/quota/Module.java
@@ -76,6 +76,7 @@
     DynamicSet.bind(binder(), ProjectDeletedListener.class).to(DeletionListener.class);
     DynamicSet.bind(binder(), GarbageCollectorListener.class).to(GCListener.class);
     DynamicSet.setOf(binder(), UsageDataEventCreator.class);
+    DynamicSet.bind(binder(), UsageDataEventCreator.class).to(RepoSizeEventCreator.class);
     install(MaxRepositorySizeQuota.module());
     install(
         new RestApiModule() {