Load ProjectLevelConfig directly
Cache introduced in [1] (in 3.3.1) prevents using getAllProjects().getConfig(...)
from Gerrit Core to read serviceuser db file.
To overcome this, we need to read config directly, bypassing the cache.
[1] https://gerrit-review.googlesource.com/c/gerrit/+/275992
Change-Id: I9b4b1e66cf8e2b41059997bb53ebeeaba7ee3ea3
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetOwner.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetOwner.java
index 74b97b2..c0c245c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetOwner.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetOwner.java
@@ -14,49 +14,62 @@
package com.googlesource.gerrit.plugins.serviceuser;
+import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_OWNER;
import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.USER;
import com.google.gerrit.entities.GroupDescription;
-import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.TopLevelResource;
+import com.google.gerrit.server.config.AllProjectsName;
+import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectLevelConfig;
import com.google.gerrit.server.restapi.group.GroupJson;
import com.google.gerrit.server.restapi.group.GroupsCollection;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import com.google.inject.Singleton;
+import java.io.IOException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
@Singleton
class GetOwner implements RestReadView<ServiceUserResource> {
private final GroupsCollection groups;
- private final String pluginName;
- private final ProjectCache projectCache;
private final GroupJson json;
+ private final Provider<ProjectLevelConfig.Bare> configProvider;
+ private final MetaDataUpdate.User metaDataUpdateFactory;
+ private final AllProjectsName allProjectsName;
@Inject
GetOwner(
GroupsCollection groups,
- @PluginName String pluginName,
- ProjectCache projectCache,
+ Provider<ProjectLevelConfig.Bare> configProvider,
+ AllProjectsName allProjectsName,
+ MetaDataUpdate.User metaDataUpdateFactory,
GroupJson json) {
this.groups = groups;
- this.pluginName = pluginName;
- this.projectCache = projectCache;
+ this.configProvider = configProvider;
+ this.allProjectsName = allProjectsName;
+ this.metaDataUpdateFactory = metaDataUpdateFactory;
this.json = json;
}
@Override
public Response<GroupInfo> apply(ServiceUserResource rsrc)
- throws RestApiException, PermissionBackendException {
- ProjectLevelConfig storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
- String owner = storage.get().getString(USER, rsrc.getUser().getUserName().get(), KEY_OWNER);
+ throws IOException, RestApiException, PermissionBackendException {
+ ProjectLevelConfig.Bare storage = configProvider.get();
+ try (MetaDataUpdate md = metaDataUpdateFactory.create(allProjectsName)) {
+ storage.load(md);
+ } catch (ConfigInvalidException e) {
+ throw asRestApiException("Invalid configuration", e);
+ }
+ String owner =
+ storage.getConfig().getString(USER, rsrc.getUser().getUserName().get(), KEY_OWNER);
if (owner != null) {
GroupDescription.Basic group =
groups.parse(TopLevelResource.INSTANCE, IdString.fromDecoded(owner)).getGroup();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetServiceUser.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetServiceUser.java
index c700da8..6b08307 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetServiceUser.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetServiceUser.java
@@ -21,7 +21,6 @@
import static javax.servlet.http.HttpServletResponse.SC_OK;
import com.google.gerrit.entities.Account;
-import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
@@ -29,43 +28,54 @@
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.config.AllProjectsName;
+import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectLevelConfig;
import com.google.gerrit.server.restapi.account.GetAccount;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
+import java.io.IOException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;
@Singleton
class GetServiceUser implements RestReadView<ServiceUserResource> {
private final Provider<GetAccount> getAccount;
- private final String pluginName;
- private final ProjectCache projectCache;
private final GetOwner getOwner;
private final AccountLoader.Factory accountLoader;
+ private final Provider<ProjectLevelConfig.Bare> configProvider;
+ private final MetaDataUpdate.User metaDataUpdateFactory;
+ private final AllProjectsName allProjectsName;
@Inject
GetServiceUser(
Provider<GetAccount> getAccount,
- @PluginName String pluginName,
- ProjectCache projectCache,
+ Provider<ProjectLevelConfig.Bare> configProvider,
+ AllProjectsName allProjectsName,
+ MetaDataUpdate.User metaDataUpdateFactory,
GetOwner getOwner,
AccountLoader.Factory accountLoader) {
this.getAccount = getAccount;
- this.pluginName = pluginName;
- this.projectCache = projectCache;
+ this.configProvider = configProvider;
+ this.allProjectsName = allProjectsName;
+ this.metaDataUpdateFactory = metaDataUpdateFactory;
this.getOwner = getOwner;
this.accountLoader = accountLoader;
}
@Override
public Response<ServiceUserInfo> apply(ServiceUserResource rsrc)
- throws RestApiException, PermissionBackendException {
- ProjectLevelConfig storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
+ throws IOException, RestApiException, PermissionBackendException {
+ ProjectLevelConfig.Bare storage = configProvider.get();
+ try (MetaDataUpdate md = metaDataUpdateFactory.create(allProjectsName)) {
+ storage.load(md);
+ } catch (ConfigInvalidException e) {
+ throw asRestApiException("Invalid configuration", e);
+ }
String username = rsrc.getUser().getUserName().get();
- Config db = storage.get();
+ Config db = storage.getConfig();
if (!db.getSubsections(USER).contains(username)) {
throw new ResourceNotFoundException(username);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java
index 5e77ce2..f0f9a64 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java
@@ -18,7 +18,6 @@
import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.USER;
import com.google.common.collect.Maps;
-import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
@@ -28,9 +27,10 @@
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectLevelConfig;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -45,23 +45,26 @@
@Singleton
class ListServiceUsers implements RestReadView<ConfigResource> {
private final Provider<CurrentUser> userProvider;
- private final String pluginName;
- private final ProjectCache projectCache;
private final AccountCache accountCache;
private final Provider<ServiceUserCollection> serviceUsers;
private final Provider<GetServiceUser> getServiceUser;
+ private final Provider<ProjectLevelConfig.Bare> configProvider;
+ private final MetaDataUpdate.User metaDataUpdateFactory;
+ private final AllProjectsName allProjectsName;
@Inject
ListServiceUsers(
Provider<CurrentUser> userProvider,
- @PluginName String pluginName,
- ProjectCache projectCache,
+ Provider<ProjectLevelConfig.Bare> configProvider,
+ AllProjectsName allProjectsName,
+ MetaDataUpdate.User metaDataUpdateFactory,
AccountCache accountCache,
Provider<ServiceUserCollection> serviceUsers,
Provider<GetServiceUser> getServiceUser) {
this.userProvider = userProvider;
- this.pluginName = pluginName;
- this.projectCache = projectCache;
+ this.configProvider = configProvider;
+ this.allProjectsName = allProjectsName;
+ this.metaDataUpdateFactory = metaDataUpdateFactory;
this.accountCache = accountCache;
this.serviceUsers = serviceUsers;
this.getServiceUser = getServiceUser;
@@ -70,14 +73,19 @@
@Override
public Response<Map<String, ServiceUserInfo>> apply(ConfigResource rscr)
throws IOException, RestApiException, PermissionBackendException, ConfigInvalidException {
- ProjectLevelConfig storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
+ ProjectLevelConfig.Bare storage = configProvider.get();
+ try (MetaDataUpdate md = metaDataUpdateFactory.create(allProjectsName)) {
+ storage.load(md);
+ } catch (ConfigInvalidException e) {
+ throw asRestApiException("Invalid configuration", e);
+ }
CurrentUser user = userProvider.get();
if (user == null || !user.isIdentifiedUser()) {
throw new AuthException("Authentication required");
}
Map<String, ServiceUserInfo> accounts = Maps.newTreeMap();
- Config db = storage.get();
+ Config db = storage.getConfig();
for (String username : db.getSubsections(USER)) {
Optional<AccountState> account = accountCache.getByUsername(username);
if (account.isPresent()) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java
index c5e5d9a..5a83d41 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java
@@ -14,6 +14,7 @@
package com.googlesource.gerrit.plugins.serviceuser;
+import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_CREATOR_ID;
import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_OWNER;
@@ -21,20 +22,21 @@
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.GroupDescription;
-import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ChildCollection;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectLevelConfig;
import com.google.gerrit.server.restapi.account.AccountsCollection;
import com.google.gerrit.server.restapi.group.GroupsCollection;
@@ -50,27 +52,30 @@
private final DynamicMap<RestView<ServiceUserResource>> views;
private final Provider<ListServiceUsers> list;
private final Provider<AccountsCollection> accounts;
- private final String pluginName;
- private final ProjectCache projectCache;
private final Provider<CurrentUser> userProvider;
private final GroupsCollection groups;
private final PermissionBackend permissionBackend;
+ private final Provider<ProjectLevelConfig.Bare> configProvider;
+ private final MetaDataUpdate.User metaDataUpdateFactory;
+ private final AllProjectsName allProjectsName;
@Inject
ServiceUserCollection(
DynamicMap<RestView<ServiceUserResource>> views,
Provider<ListServiceUsers> list,
Provider<AccountsCollection> accounts,
- @PluginName String pluginName,
- ProjectCache projectCache,
+ Provider<ProjectLevelConfig.Bare> configProvider,
+ AllProjectsName allProjectsName,
+ MetaDataUpdate.User metaDataUpdateFactory,
Provider<CurrentUser> userProvider,
GroupsCollection groups,
PermissionBackend permissionBackend) {
this.views = views;
this.list = list;
this.accounts = accounts;
- this.pluginName = pluginName;
- this.projectCache = projectCache;
+ this.configProvider = configProvider;
+ this.allProjectsName = allProjectsName;
+ this.metaDataUpdateFactory = metaDataUpdateFactory;
this.userProvider = userProvider;
this.groups = groups;
this.permissionBackend = permissionBackend;
@@ -79,11 +84,16 @@
@Override
public ServiceUserResource parse(ConfigResource parent, IdString id)
throws ResourceNotFoundException, AuthException, IOException, PermissionBackendException,
- ConfigInvalidException {
- ProjectLevelConfig storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
+ ConfigInvalidException, RestApiException {
+ ProjectLevelConfig.Bare storage = configProvider.get();
+ try (MetaDataUpdate md = metaDataUpdateFactory.create(allProjectsName)) {
+ storage.load(md);
+ } catch (ConfigInvalidException e) {
+ throw asRestApiException("Invalid configuration", e);
+ }
IdentifiedUser serviceUser = accounts.get().parse(TopLevelResource.INSTANCE, id).getUser();
if (serviceUser == null
- || !storage.get().getSubsections(USER).contains(serviceUser.getUserName().get())) {
+ || !storage.getConfig().getSubsections(USER).contains(serviceUser.getUserName().get())) {
throw new ResourceNotFoundException(id);
}
CurrentUser user = userProvider.get();
@@ -92,7 +102,7 @@
}
if (!permissionBackend.user(user).testOrFalse(ADMINISTRATE_SERVER)) {
String username = serviceUser.getUserName().get();
- String owner = storage.get().getString(USER, username, KEY_OWNER);
+ String owner = storage.getConfig().getString(USER, username, KEY_OWNER);
if (owner != null) {
GroupDescription.Basic group =
groups.parse(TopLevelResource.INSTANCE, IdString.fromDecoded(owner)).getGroup();
@@ -101,7 +111,7 @@
}
} else if (!((IdentifiedUser) user)
.getAccountId()
- .equals(Account.id(storage.get().getInt(USER, username, KEY_CREATOR_ID, -1)))) {
+ .equals(Account.id(storage.getConfig().getInt(USER, username, KEY_CREATOR_ID, -1)))) {
throw new ResourceNotFoundException(id);
}
}