Preserve instanceId on event when already set

Plugins can inject external events into Gerrit
also coming from other remote instances. Preserve
the instanceId contained in the forwarded event
if set and do not overwrite with the local Gerrit one.

Only events that are locally generated in Gerrit
can set the intanceId but not the forwarded ones.

Failing to preserve the original instanceId of the
forwarded events may cause events duplication, like
the use-case of the high-availability plugin not
recognising a remote event because it is re-stamped
with the local instanceId.

Bug: Issue 13307
Change-Id: I324a48a6f2ffca59bad059e18550a8dc44224f34
This commit is contained in:
Luca Milanesio
2020-08-28 22:26:26 +01:00
parent 23a99d9013
commit c862d29ece
2 changed files with 56 additions and 6 deletions

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.server.events;
import com.google.common.base.Strings;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.BranchNameKey;
@@ -111,7 +112,7 @@ public class EventBroker implements EventDispatcher {
}
protected void fireEvent(Change change, ChangeEvent event) throws PermissionBackendException {
setInstanceId(event);
setInstanceIdWhenEmpty(event);
for (PluginSetEntryContext<UserScopedEventListener> c : listeners) {
CurrentUser user = c.call(UserScopedEventListener::getUser);
if (isVisibleTo(change, user)) {
@@ -122,7 +123,7 @@ public class EventBroker implements EventDispatcher {
}
protected void fireEvent(Project.NameKey project, ProjectEvent event) {
setInstanceId(event);
setInstanceIdWhenEmpty(event);
for (PluginSetEntryContext<UserScopedEventListener> c : listeners) {
CurrentUser user = c.call(UserScopedEventListener::getUser);
@@ -135,7 +136,7 @@ public class EventBroker implements EventDispatcher {
protected void fireEvent(BranchNameKey branchName, RefEvent event)
throws PermissionBackendException {
setInstanceId(event);
setInstanceIdWhenEmpty(event);
for (PluginSetEntryContext<UserScopedEventListener> c : listeners) {
CurrentUser user = c.call(UserScopedEventListener::getUser);
if (isVisibleTo(branchName, user)) {
@@ -146,7 +147,7 @@ public class EventBroker implements EventDispatcher {
}
protected void fireEvent(Event event) throws PermissionBackendException {
setInstanceId(event);
setInstanceIdWhenEmpty(event);
for (PluginSetEntryContext<UserScopedEventListener> c : listeners) {
CurrentUser user = c.call(UserScopedEventListener::getUser);
if (isVisibleTo(event, user)) {
@@ -156,8 +157,10 @@ public class EventBroker implements EventDispatcher {
fireEventForUnrestrictedListeners(event);
}
protected void setInstanceId(Event event) {
event.instanceId = gerritInstanceId;
protected void setInstanceIdWhenEmpty(Event event) {
if (Strings.isNullOrEmpty(event.instanceId)) {
event.instanceId = gerritInstanceId;
}
}
protected boolean isVisibleTo(Project.NameKey project, CurrentUser user) {