Create a user-context if not propagated by Gerrit
Because of (Bug: Issue 10941), the user context could be
absent and thus all the subsequent operations performed on
the change would fail.
Provide a one-off context using the updater's identity
so that even when Gerrit isn't providing a valid context
the overall OWNERS processing logic would still succeed.
Change-Id: If9f2087519180baddd996f41bdda56942b3f6886
diff --git a/owners-autoassign/src/main/java/com/vmware/gerrit/owners/common/GitRefListener.java b/owners-autoassign/src/main/java/com/vmware/gerrit/owners/common/GitRefListener.java
index 2cfd54d..eae0cb8 100644
--- a/owners-autoassign/src/main/java/com/vmware/gerrit/owners/common/GitRefListener.java
+++ b/owners-autoassign/src/main/java/com/vmware/gerrit/owners/common/GitRefListener.java
@@ -23,6 +23,7 @@
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.Changes;
+import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.restapi.RestApiException;
@@ -30,12 +31,17 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchListKey;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
+import com.google.gerrit.server.util.ManualRequestContext;
+import com.google.gerrit.server.util.OneOffRequestContext;
+import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import java.io.IOException;
import java.util.Set;
import org.eclipse.jgit.lib.ObjectId;
@@ -57,22 +63,58 @@
private final ReviewerManager reviewerManager;
+ private final OneOffRequestContext oneOffReqCtx;
+
+ private Provider<CurrentUser> currentUserProvider;
+
@Inject
public GitRefListener(
GerritApi api,
PatchListCache patchListCache,
GitRepositoryManager repositoryManager,
Accounts accounts,
- ReviewerManager reviewerManager) {
+ ReviewerManager reviewerManager,
+ OneOffRequestContext oneOffReqCtx,
+ Provider<CurrentUser> currentUserProvider) {
this.api = api;
this.patchListCache = patchListCache;
this.repositoryManager = repositoryManager;
this.accounts = accounts;
this.reviewerManager = reviewerManager;
+ this.oneOffReqCtx = oneOffReqCtx;
+ this.currentUserProvider = currentUserProvider;
}
@Override
public void onGitReferenceUpdated(Event event) {
+ AccountInfo updaterAccountInfo = event.getUpdater();
+ CurrentUser currentUser = currentUserProvider.get();
+ if (currentUser.isIdentifiedUser()) {
+ handleGitReferenceUpdated(event);
+ } else if (updaterAccountInfo != null) {
+ handleGitReferenceUpdatedAsUser(event, new Account.Id(updaterAccountInfo._accountId));
+ } else {
+ handleGitReferenceUpdatedAsServer(event);
+ }
+ }
+
+ private void handleGitReferenceUpdatedAsUser(Event event, Account.Id updaterAccountId) {
+ try (ManualRequestContext ctx = oneOffReqCtx.openAs(updaterAccountId)) {
+ handleGitReferenceUpdated(event);
+ } catch (OrmException e) {
+ logger.warn("Unable to process event {} on project {}", event, event.getProjectName(), e);
+ }
+ }
+
+ private void handleGitReferenceUpdatedAsServer(Event event) {
+ try (ManualRequestContext ctx = oneOffReqCtx.open()) {
+ handleGitReferenceUpdated(event);
+ } catch (OrmException e) {
+ logger.warn("Unable to process event {} on project {}", event, event.getProjectName(), e);
+ }
+ }
+
+ private void handleGitReferenceUpdated(Event event) {
String projectName = event.getProjectName();
Repository repository;
try {
diff --git a/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/GitRefListenerIT.java b/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/GitRefListenerIT.java
index aa6db4f..f009bde 100644
--- a/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/GitRefListenerIT.java
+++ b/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/GitRefListenerIT.java
@@ -21,7 +21,13 @@
import com.google.gerrit.acceptance.TestPlugin;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.AnonymousUser;
+import com.google.gerrit.server.util.ManualRequestContext;
+import com.google.gerrit.server.util.ThreadLocalRequestContext;
+import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.AbstractModule;
+import com.google.inject.Inject;
import org.eclipse.jgit.transport.ReceiveCommand.Type;
import org.junit.Test;
@@ -30,6 +36,14 @@
sysModule = "com.vmware.gerrit.owners.common.GitRefListenerIT$TestModule")
public class GitRefListenerIT extends LightweightPluginDaemonTest {
+ @Inject GitRefListenerTest gitRefListener;
+ @Inject SchemaFactory<ReviewDb> schemaFactory;
+ @Inject ThreadLocalRequestContext requestContext;
+
+ String aRefChange = RefNames.REFS_CHANGES + "01/01/01";
+ String anOldObjectId = "anOldRef";
+ String aNewObjectId = "aNewRef";
+
public static class TestModule extends AbstractModule {
@Override
protected void configure() {
@@ -39,15 +53,14 @@
@Test
public void shouldNotProcessNoteDbOnlyRefs() {
- GitRefListenerTest gitRefListener = getPluginInstance(GitRefListenerTest.class);
-
- String aRefChange = RefNames.REFS_CHANGES + "01/01" + RefNames.META_SUFFIX;
- String anOldObjectId = "anOldRef";
- String aNewObjectId = "aNewRef";
-
ReferenceUpdatedEventTest refUpdatedEvent =
new ReferenceUpdatedEventTest(
- project, aRefChange, anOldObjectId, aNewObjectId, Type.CREATE);
+ project,
+ RefNames.REFS_CHANGES + "01/01" + RefNames.META_SUFFIX,
+ anOldObjectId,
+ aNewObjectId,
+ Type.CREATE,
+ admin.id);
gitRefListener.onGitReferenceUpdated(refUpdatedEvent);
assertEquals(0, gitRefListener.getProcessedEvents());
@@ -55,21 +68,33 @@
@Test
public void shouldProcessRefChanges() {
- GitRefListenerTest gitRefListener = getPluginInstance(GitRefListenerTest.class);
-
- String aRefChange = RefNames.REFS_CHANGES + "01/01/01";
- String anOldObjectId = "anOldRef";
- String aNewObjectId = "aNewRef";
-
- ReferenceUpdatedEventTest refUpdatedEvent =
- new ReferenceUpdatedEventTest(
- project, aRefChange, anOldObjectId, aNewObjectId, Type.CREATE);
-
- gitRefListener.onGitReferenceUpdated(refUpdatedEvent);
+ gitRefListener.onGitReferenceUpdated(newRefUpdateEvent());
assertEquals(1, gitRefListener.getProcessedEvents());
}
- private <T> T getPluginInstance(Class<T> clazz) {
- return plugin.getSysInjector().getInstance(clazz);
+ @Test
+ public void shouldRetrieveChangeFromAnonymousContext() throws Exception {
+ try (ManualRequestContext ctx =
+ new ManualRequestContext(new AnonymousUser(), schemaFactory, requestContext)) {
+ gitRefListener.onGitReferenceUpdated(newRefUpdateEvent());
+ assertEquals(1, gitRefListener.getProcessedEvents());
+ }
+ }
+
+ @Test
+ public void shouldRetrieveChangeFromAnonymousContextWithoutAccountId() throws Exception {
+ ReferenceUpdatedEventTest refUpdateWithoutAccountId =
+ new ReferenceUpdatedEventTest(
+ project, aRefChange, anOldObjectId, aNewObjectId, Type.CREATE, null);
+ try (ManualRequestContext ctx =
+ new ManualRequestContext(new AnonymousUser(), schemaFactory, requestContext)) {
+ gitRefListener.onGitReferenceUpdated(refUpdateWithoutAccountId);
+ assertEquals(1, gitRefListener.getProcessedEvents());
+ }
+ }
+
+ private ReferenceUpdatedEventTest newRefUpdateEvent() {
+ return new ReferenceUpdatedEventTest(
+ project, aRefChange, anOldObjectId, aNewObjectId, Type.CREATE, admin.id);
}
}
diff --git a/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/GitRefListenerTest.java b/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/GitRefListenerTest.java
index ac6b579..8fb940c 100644
--- a/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/GitRefListenerTest.java
+++ b/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/GitRefListenerTest.java
@@ -16,9 +16,12 @@
package com.vmware.gerrit.owners.common;
import com.google.gerrit.extensions.api.GerritApi;
+import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.PatchListCache;
+import com.google.gerrit.server.util.OneOffRequestContext;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import org.eclipse.jgit.lib.Repository;
import org.junit.Ignore;
@@ -32,8 +35,17 @@
PatchListCache patchListCache,
GitRepositoryManager repositoryManager,
Accounts accounts,
- ReviewerManager reviewerManager) {
- super(api, patchListCache, repositoryManager, accounts, reviewerManager);
+ ReviewerManager reviewerManager,
+ OneOffRequestContext oneOffReqCtx,
+ Provider<CurrentUser> currentUserProvider) {
+ super(
+ api,
+ patchListCache,
+ repositoryManager,
+ accounts,
+ reviewerManager,
+ oneOffReqCtx,
+ currentUserProvider);
}
@Override
diff --git a/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/ReferenceUpdatedEventTest.java b/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/ReferenceUpdatedEventTest.java
index 446a8bb..9946502 100644
--- a/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/ReferenceUpdatedEventTest.java
+++ b/owners-autoassign/src/test/java/com/vmware/gerrit/owners/common/ReferenceUpdatedEventTest.java
@@ -18,6 +18,8 @@
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Account.Id;
import com.google.gerrit.reviewdb.client.Project;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.junit.Ignore;
@@ -30,18 +32,21 @@
private final String oldObjectId;
private final String newObjectId;
private final ReceiveCommand.Type type;
+ private final Id eventAccountId;
public ReferenceUpdatedEventTest(
Project.NameKey project,
String ref,
String oldObjectId,
String newObjectId,
- ReceiveCommand.Type type) {
+ ReceiveCommand.Type type,
+ Account.Id eventAccountId) {
this.projectName = project.get();
this.ref = ref;
this.oldObjectId = oldObjectId;
this.newObjectId = newObjectId;
this.type = type;
+ this.eventAccountId = eventAccountId;
}
@Override
@@ -81,7 +86,11 @@
@Override
public AccountInfo getUpdater() {
- return null;
+ if (eventAccountId == null) {
+ return null;
+ }
+
+ return new AccountInfo(eventAccountId.get());
}
@Override