Merge branch 'stable-3.3'

* stable-3.3:
  Remove standalone build mode
  Remove unnecessary public qualifier from GetConfig.ConfigInfo
  Fix errorprone errors
  Define Provider<ProjectLevelConfig.Bare>, reduce code repetition
  Stop using deprecated JGit API getAllRefs
  Make compatible with Gerrit stable-3.3 branch
  Upgrade bazlets to latest stable-3.2 to build with 3.2.5.1 API
  Upgrade bazlets to latest stable-3.1 to build with 3.1.10 API
  Bump Bazel version to 3.7.0
  Upgrade bazlets to latest stable-3.0 to build with 3.0.13 API
  Bump Bazel version to 3.5.0

Change-Id: Icc5a7f9f0e8b0a7d3af60c640e184f98947a3b86
diff --git a/.bazelrc b/.bazelrc
deleted file mode 100644
index 3ae03ff..0000000
--- a/.bazelrc
+++ /dev/null
@@ -1,2 +0,0 @@
-build --workspace_status_command="python ./tools/workspace_status.py"
-test --build_tests_only
diff --git a/.bazelversion b/.bazelversion
index 47b322c..7c69a55 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-3.4.1
+3.7.0
diff --git a/.gitignore b/.gitignore
index acae119..a94d0d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
-/bazel-*
 /eclipse-out
 /target
 /.classpath
diff --git a/WORKSPACE b/WORKSPACE
deleted file mode 100644
index a8d8194..0000000
--- a/WORKSPACE
+++ /dev/null
@@ -1,15 +0,0 @@
-workspace(name = "serviceuser")
-
-load("//:bazlets.bzl", "load_bazlets")
-
-load_bazlets(
-    commit = "0f81174e3d1b892a1342ebc75bb4bbb158ae0efe",
-    #local_path = "/home/<user>/projects/bazlets",
-)
-
-load(
-    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
-    "gerrit_api",
-)
-
-gerrit_api(version = "3.3.0-SNAPSHOT")
diff --git a/bazlets.bzl b/bazlets.bzl
deleted file mode 100644
index f089af4..0000000
--- a/bazlets.bzl
+++ /dev/null
@@ -1,18 +0,0 @@
-load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
-
-NAME = "com_googlesource_gerrit_bazlets"
-
-def load_bazlets(
-        commit,
-        local_path = None):
-    if not local_path:
-        git_repository(
-            name = NAME,
-            remote = "https://gerrit.googlesource.com/bazlets",
-            commit = commit,
-        )
-    else:
-        native.local_repository(
-            name = NAME,
-            path = local_path,
-        )
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java
index 50fc6a0..13ff20c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java
@@ -78,12 +78,12 @@
   }
 
   private final PluginConfig cfg;
+  private final Provider<ProjectLevelConfig.Bare> configProvider;
   private final CreateAccount createAccount;
   private final List<String> blockedNames;
   private final Provider<CurrentUser> userProvider;
   private final MetaDataUpdate.User metaDataUpdateFactory;
   private final Project.NameKey allProjects;
-  private final ProjectLevelConfig storage;
   private final DateFormat rfc2822DateFormatter;
   private final Provider<GetConfig> getConfig;
   private final AccountLoader.Factory accountLoader;
@@ -91,6 +91,7 @@
   @Inject
   CreateServiceUser(
       PluginConfigFactory cfgFactory,
+      Provider<ProjectLevelConfig.Bare> configProvider,
       @PluginName String pluginName,
       CreateAccount createAccount,
       Provider<CurrentUser> userProvider,
@@ -100,6 +101,7 @@
       Provider<GetConfig> getConfig,
       AccountLoader.Factory accountLoader) {
     this.cfg = cfgFactory.getFromGerritConfig(pluginName);
+    this.configProvider = configProvider;
     this.createAccount = createAccount;
     this.blockedNames =
         Lists.transform(
@@ -112,7 +114,6 @@
             });
     this.userProvider = userProvider;
     this.metaDataUpdateFactory = metaDataUpdateFactory;
-    this.storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
     this.allProjects = projectCache.getAllProjects().getProject().getNameKey();
     this.rfc2822DateFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
     this.rfc2822DateFormatter.setCalendar(
@@ -178,16 +179,20 @@
     Account.Id creatorId = ((IdentifiedUser) user).getAccountId();
     String creationDate = rfc2822DateFormatter.format(new Date());
 
-    Config db = storage.get();
-    db.setInt(USER, username, KEY_CREATOR_ID, creatorId.get());
-    if (creator != null) {
-      db.setString(USER, username, KEY_CREATED_BY, creator);
-    }
-    db.setString(USER, username, KEY_CREATED_AT, creationDate);
+    try (MetaDataUpdate md = metaDataUpdateFactory.create(allProjects)) {
+      ProjectLevelConfig.Bare update = configProvider.get();
+      update.load(md);
 
-    MetaDataUpdate md = metaDataUpdateFactory.create(allProjects);
-    md.setMessage("Create service user '" + username + "'\n");
-    storage.commit(md);
+      Config db = update.getConfig();
+      db.setInt(USER, username, KEY_CREATOR_ID, creatorId.get());
+      if (creator != null) {
+        db.setString(USER, username, KEY_CREATED_BY, creator);
+      }
+      db.setString(USER, username, KEY_CREATED_AT, creationDate);
+
+      md.setMessage("Create service user '" + username + "'\n");
+      update.commit(md);
+    }
     ServiceUserInfo info = new ServiceUserInfo(response);
     AccountLoader al = accountLoader.create(true);
     info.createdBy = al.get(creatorId);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserNotes.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserNotes.java
index 93fc84c..d60203b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserNotes.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserNotes.java
@@ -131,8 +131,9 @@
     }
   }
 
-  private void markUninteresting(Repository git, String branch, RevWalk rw, ObjectId oldObjectId) {
-    for (Ref r : git.getAllRefs().values()) {
+  private void markUninteresting(Repository git, String branch, RevWalk rw, ObjectId oldObjectId)
+      throws IOException {
+    for (Ref r : git.getRefDatabase().getRefs()) {
       try {
         if (r.getName().equals(branch)) {
           if (!ObjectId.zeroId().equals(oldObjectId)) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java
index f89f047..3cca663 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java
@@ -95,7 +95,7 @@
     return v ? v : null;
   }
 
-  public class ConfigInfo {
+  static class ConfigInfo {
     public String info;
     public String onSuccess;
     public Boolean allowEmail;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/Module.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/Module.java
index 56d14e1..9dc32a4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/Module.java
@@ -19,13 +19,16 @@
 import static com.googlesource.gerrit.plugins.serviceuser.ServiceUserResource.SERVICE_USER_SSH_KEY_KIND;
 
 import com.google.gerrit.extensions.annotations.Exports;
+import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.config.CapabilityDefinition;
 import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.extensions.registration.DynamicMap;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.extensions.restapi.RestApiModule;
 import com.google.gerrit.server.git.validators.CommitValidationListener;
+import com.google.gerrit.server.project.ProjectLevelConfig;
 import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
 import com.google.inject.assistedinject.FactoryModuleBuilder;
 
 class Module extends AbstractModule {
@@ -72,4 +75,9 @@
         });
     install(new HttpModule());
   }
+
+  @Provides
+  ProjectLevelConfig.Bare createProjectLevelConfig(@PluginName String pluginName) {
+    return new ProjectLevelConfig.Bare(pluginName + ".db");
+  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java
index eb7dbc0..120c464 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java
@@ -24,7 +24,6 @@
 import com.google.gerrit.entities.AccountGroup.UUID;
 import com.google.gerrit.entities.GroupDescription;
 import com.google.gerrit.entities.Project;
-import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.extensions.restapi.DefaultInput;
 import com.google.gerrit.extensions.restapi.IdString;
@@ -47,6 +46,7 @@
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.serviceuser.PutOwner.Input;
 import java.io.IOException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
 
 @Singleton
@@ -57,8 +57,7 @@
 
   private final Provider<GetConfig> getConfig;
   private final GroupsCollection groups;
-  private final String pluginName;
-  private final ProjectCache projectCache;
+  private final Provider<ProjectLevelConfig.Bare> configProvider;
   private final Project.NameKey allProjects;
   private final MetaDataUpdate.User metaDataUpdateFactory;
   private final GroupJson json;
@@ -69,7 +68,7 @@
   PutOwner(
       Provider<GetConfig> getConfig,
       GroupsCollection groups,
-      @PluginName String pluginName,
+      Provider<ProjectLevelConfig.Bare> configProvider,
       ProjectCache projectCache,
       MetaDataUpdate.User metaDataUpdateFactory,
       GroupJson json,
@@ -77,8 +76,7 @@
       PermissionBackend permissionBackend) {
     this.getConfig = getConfig;
     this.groups = groups;
-    this.pluginName = pluginName;
-    this.projectCache = projectCache;
+    this.configProvider = configProvider;
     this.allProjects = projectCache.getAllProjects().getProject().getNameKey();
     this.metaDataUpdateFactory = metaDataUpdateFactory;
     this.json = json;
@@ -89,7 +87,6 @@
   @Override
   public Response<GroupInfo> apply(ServiceUserResource rsrc, Input input)
       throws RestApiException, IOException, PermissionBackendException {
-    ProjectLevelConfig storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
     Boolean ownerAllowed;
     try {
       ownerAllowed = getConfig.get().apply(new ConfigResource()).value().allowOwner;
@@ -103,22 +100,32 @@
     if (input == null) {
       input = new Input();
     }
-    Config db = storage.get();
-    String oldGroup = db.getString(USER, rsrc.getUser().getUserName().get(), KEY_OWNER);
+
     GroupDescription.Basic group = null;
-    if (Strings.isNullOrEmpty(input.group)) {
-      db.unset(USER, rsrc.getUser().getUserName().get(), KEY_OWNER);
-    } else {
-      group = groups.parse(TopLevelResource.INSTANCE, IdString.fromDecoded(input.group)).getGroup();
-      UUID groupUUID = group.getGroupUUID();
-      if (!AccountGroup.uuid(groupUUID.get()).isInternalGroup()) {
-        throw new MethodNotAllowedException("Group with UUID '" + groupUUID + "' is external");
+    String oldGroup;
+    try (MetaDataUpdate md = metaDataUpdateFactory.create(allProjects)) {
+      ProjectLevelConfig.Bare update = configProvider.get();
+      update.load(md);
+
+      Config db = update.getConfig();
+      oldGroup = db.getString(USER, rsrc.getUser().getUserName().get(), KEY_OWNER);
+      if (Strings.isNullOrEmpty(input.group)) {
+        db.unset(USER, rsrc.getUser().getUserName().get(), KEY_OWNER);
+      } else {
+        group =
+            groups.parse(TopLevelResource.INSTANCE, IdString.fromDecoded(input.group)).getGroup();
+        UUID groupUUID = group.getGroupUUID();
+        if (!AccountGroup.uuid(groupUUID.get()).isInternalGroup()) {
+          throw new MethodNotAllowedException("Group with UUID '" + groupUUID + "' is external");
+        }
+        db.setString(USER, rsrc.getUser().getUserName().get(), KEY_OWNER, groupUUID.get());
       }
-      db.setString(USER, rsrc.getUser().getUserName().get(), KEY_OWNER, groupUUID.get());
+      md.setMessage("Set owner for service user '" + rsrc.getUser().getUserName() + "'\n");
+      update.commit(md);
+    } catch (ConfigInvalidException e) {
+      throw asRestApiException("Invalid configuration", e);
     }
-    MetaDataUpdate md = metaDataUpdateFactory.create(allProjects);
-    md.setMessage("Set owner for service user '" + rsrc.getUser().getUserName() + "'\n");
-    storage.commit(md);
+
     return group != null
         ? (oldGroup != null
             ? Response.ok(json.format(group))
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/RefUpdateListener.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/RefUpdateListener.java
index 31d1a56..fef0bc7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/RefUpdateListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/RefUpdateListener.java
@@ -26,6 +26,8 @@
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
+import java.util.concurrent.Future;
+
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
 import org.slf4j.Logger;
@@ -90,7 +92,8 @@
           }
         };
     if (cfg.getBoolean("createNotesAsync", false)) {
-      workQueue.getDefaultQueue().submit(task);
+      @SuppressWarnings("unused")
+      Future<?> possiblyIgnoredError = workQueue.getDefaultQueue().submit(task);
     } else {
       task.run();
     }
diff --git a/tools/BUILD b/tools/BUILD
deleted file mode 100644
index cc10083..0000000
--- a/tools/BUILD
+++ /dev/null
@@ -1 +0,0 @@
-# Empty file - bazel treat directories with BUILD file as a package
diff --git a/tools/bzl/BUILD b/tools/bzl/BUILD
deleted file mode 100644
index c5ed0b7..0000000
--- a/tools/bzl/BUILD
+++ /dev/null
@@ -1 +0,0 @@
-# Empty file required by Bazel
diff --git a/tools/bzl/classpath.bzl b/tools/bzl/classpath.bzl
deleted file mode 100644
index c921d01..0000000
--- a/tools/bzl/classpath.bzl
+++ /dev/null
@@ -1,6 +0,0 @@
-load(
-    "@com_googlesource_gerrit_bazlets//tools:classpath.bzl",
-    _classpath_collector = "classpath_collector",
-)
-
-classpath_collector = _classpath_collector
diff --git a/tools/bzl/junit.bzl b/tools/bzl/junit.bzl
deleted file mode 100644
index 240c448..0000000
--- a/tools/bzl/junit.bzl
+++ /dev/null
@@ -1,5 +0,0 @@
-load(
-    "@com_googlesource_gerrit_bazlets//tools:junit.bzl",
-    _junit_tests = "junit_tests",
-)
-junit_tests = _junit_tests
diff --git a/tools/bzl/maven_jar.bzl b/tools/bzl/maven_jar.bzl
deleted file mode 100644
index 35ea8ce..0000000
--- a/tools/bzl/maven_jar.bzl
+++ /dev/null
@@ -1,3 +0,0 @@
-load("@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl", _maven_jar = "maven_jar")
-
-maven_jar = _maven_jar
diff --git a/tools/bzl/plugin.bzl b/tools/bzl/plugin.bzl
deleted file mode 100644
index 4d2dbdd..0000000
--- a/tools/bzl/plugin.bzl
+++ /dev/null
@@ -1,10 +0,0 @@
-load(
-    "@com_googlesource_gerrit_bazlets//:gerrit_plugin.bzl",
-    _gerrit_plugin = "gerrit_plugin",
-    _plugin_deps = "PLUGIN_DEPS",
-    _plugin_test_deps = "PLUGIN_TEST_DEPS",
-)
-
-gerrit_plugin = _gerrit_plugin
-PLUGIN_DEPS = _plugin_deps
-PLUGIN_TEST_DEPS = _plugin_test_deps
diff --git a/tools/eclipse/BUILD b/tools/eclipse/BUILD
deleted file mode 100644
index a38b222..0000000
--- a/tools/eclipse/BUILD
+++ /dev/null
@@ -1,10 +0,0 @@
-load("//tools/bzl:classpath.bzl", "classpath_collector")
-load("//tools/bzl:plugin.bzl", "PLUGIN_DEPS")
-
-classpath_collector(
-    name = "main_classpath_collect",
-    testonly = 1,
-    deps = PLUGIN_DEPS + [
-        "//:serviceuser__plugin",
-    ],
-)
diff --git a/tools/eclipse/project.sh b/tools/eclipse/project.sh
deleted file mode 100755
index 79282cf..0000000
--- a/tools/eclipse/project.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2018 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.
-`bazel query @com_googlesource_gerrit_bazlets//tools/eclipse:project --output location | sed s/BUILD:.*//`project.py -n serviceuser -r .
diff --git a/tools/workspace_status.py b/tools/workspace_status.py
deleted file mode 100644
index 8574d17..0000000
--- a/tools/workspace_status.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-
-# This script will be run by bazel when the build process starts to
-# generate key-value information that represents the status of the
-# workspace. The output should be like
-#
-# KEY1 VALUE1
-# KEY2 VALUE2
-#
-# If the script exits with non-zero code, it's considered as a failure
-# and the output will be discarded.
-
-from __future__ import print_function
-import subprocess
-import sys
-
-CMD = ['git', 'describe', '--always', '--match', 'v[0-9].*', '--dirty']
-
-
-def revision():
-    try:
-        return subprocess.check_output(CMD).strip().decode("utf-8")
-    except OSError as err:
-        print('could not invoke git: %s' % err, file=sys.stderr)
-        sys.exit(1)
-    except subprocess.CalledProcessError as err:
-        print('error using git: %s' % err, file=sys.stderr)
-        sys.exit(1)
-
-
-print("STABLE_BUILD_SERVICEUSER_LABEL %s" % revision())