Make compatible with Gerrit stable-3.3 branch

In I2379e28b4 `ProjectLevelConfig`'s inheritence was changed to not
extend `VersionedMetaData`. As a result it no longer has a `.commit()`
method on it.

Instead, read the config directly from the git repo and manipulate it
there. This probably makes some subtle cache bugs go away as a side
effect, but it likely isn't important since it would only matter in a
high contention service user creation situation. Such a situation is
difficult to imagine.

Change-Id: I4c7c94dd4db189c4a5e818ac184ddb2c318ebcb4
diff --git a/WORKSPACE b/WORKSPACE
index a8d8194..33be205 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "0f81174e3d1b892a1342ebc75bb4bbb158ae0efe",
+    commit = "a511f3c90129d7de7ae67c0637001162980c08d5",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
@@ -12,4 +12,4 @@
     "gerrit_api",
 )
 
-gerrit_api(version = "3.3.0-SNAPSHOT")
+gerrit_api(version = "3.3.2-SNAPSHOT")
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..defb457 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 String pluginName;
   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;
@@ -100,6 +100,7 @@
       Provider<GetConfig> getConfig,
       AccountLoader.Factory accountLoader) {
     this.cfg = cfgFactory.getFromGerritConfig(pluginName);
+    this.pluginName = pluginName;
     this.createAccount = createAccount;
     this.blockedNames =
         Lists.transform(
@@ -112,7 +113,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 +178,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 = new ProjectLevelConfig.Bare(pluginName + ".db");
+      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/PutOwner.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java
index eb7dbc0..065e2ea 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java
@@ -47,6 +47,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
@@ -58,7 +59,6 @@
   private final Provider<GetConfig> getConfig;
   private final GroupsCollection groups;
   private final String pluginName;
-  private final ProjectCache projectCache;
   private final Project.NameKey allProjects;
   private final MetaDataUpdate.User metaDataUpdateFactory;
   private final GroupJson json;
@@ -78,7 +78,6 @@
     this.getConfig = getConfig;
     this.groups = groups;
     this.pluginName = pluginName;
-    this.projectCache = projectCache;
     this.allProjects = projectCache.getAllProjects().getProject().getNameKey();
     this.metaDataUpdateFactory = metaDataUpdateFactory;
     this.json = json;
@@ -89,7 +88,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 +101,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 = new ProjectLevelConfig.Bare(pluginName + ".db");
+      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))