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