Merge "Merge branch 'stable-3.3' into stable-3.4" into stable-3.4
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index a144a67..b4baff4 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -2300,7 +2300,7 @@
 
 Record actual peer IP address in ref log entry for identified user.
 
-Defaults to true.
+Defaults to false.
 
 [[gerrit.secureStoreClass]]gerrit.secureStoreClass::
 +
diff --git a/java/com/google/gerrit/server/config/EnablePeerIPInReflogRecordProvider.java b/java/com/google/gerrit/server/config/EnablePeerIPInReflogRecordProvider.java
index 07c1b4e..c274b84 100644
--- a/java/com/google/gerrit/server/config/EnablePeerIPInReflogRecordProvider.java
+++ b/java/com/google/gerrit/server/config/EnablePeerIPInReflogRecordProvider.java
@@ -24,7 +24,7 @@
   @Inject
   EnablePeerIPInReflogRecordProvider(@GerritServerConfig Config config) {
     enablePeerIPInReflogRecord =
-        config.getBoolean("gerrit", null, "enablePeerIPInReflogRecord", true);
+        config.getBoolean("gerrit", null, "enablePeerIPInReflogRecord", false);
   }
 
   @Override
diff --git a/java/com/google/gerrit/server/events/EventGsonProvider.java b/java/com/google/gerrit/server/events/EventGsonProvider.java
index 72cf7be3..27be2f3 100644
--- a/java/com/google/gerrit/server/events/EventGsonProvider.java
+++ b/java/com/google/gerrit/server/events/EventGsonProvider.java
@@ -25,6 +25,7 @@
   @Override
   public Gson get() {
     return new GsonBuilder()
+        .registerTypeAdapter(Event.class, new EventSerializer())
         .registerTypeAdapter(Event.class, new EventDeserializer())
         .registerTypeAdapter(Supplier.class, new SupplierSerializer())
         .registerTypeAdapter(Supplier.class, new SupplierDeserializer())
diff --git a/java/com/google/gerrit/server/events/EventSerializer.java b/java/com/google/gerrit/server/events/EventSerializer.java
new file mode 100644
index 0000000..7322ef3
--- /dev/null
+++ b/java/com/google/gerrit/server/events/EventSerializer.java
@@ -0,0 +1,37 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.events;
+
+import com.google.gerrit.common.UsedAt;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Type;
+
+@UsedAt(UsedAt.Project.PLUGIN_MULTI_SITE)
+class EventSerializer implements JsonSerializer<Event> {
+  @Override
+  public JsonElement serialize(Event src, Type typeOfSrc, JsonSerializationContext context) {
+    String type = src.getType();
+
+    Class<?> cls = EventTypes.getClass(type);
+    if (cls == null) {
+      throw new JsonParseException("Unknown event type: " + type);
+    }
+
+    return context.serialize(src, cls);
+  }
+}
diff --git a/javatests/com/google/gerrit/acceptance/server/project/ReflogIT.java b/javatests/com/google/gerrit/acceptance/server/project/ReflogIT.java
index a927ea4..df668a5 100644
--- a/javatests/com/google/gerrit/acceptance/server/project/ReflogIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/project/ReflogIT.java
@@ -66,6 +66,7 @@
   }
 
   @Test
+  @GerritConfig(name = "gerrit.enablePeerIPInReflogRecord", value = "true")
   public void peerIPIncludedInReflogRecord() throws Exception {
     PushOneCommit.Result r = createChange();
     Change.Id id = r.getChange().getId();
@@ -85,7 +86,6 @@
   }
 
   @Test
-  @GerritConfig(name = "gerrit.enablePeerIPInReflogRecord", value = "false")
   public void emaiIncludedInReflogRecord() throws Exception {
     PushOneCommit.Result r = createChange();
     Change.Id id = r.getChange().getId();
diff --git a/javatests/com/google/gerrit/server/IdentifiedUserTest.java b/javatests/com/google/gerrit/server/IdentifiedUserTest.java
index 217bec1..463af35 100644
--- a/javatests/com/google/gerrit/server/IdentifiedUserTest.java
+++ b/javatests/com/google/gerrit/server/IdentifiedUserTest.java
@@ -81,7 +81,7 @@
           protected void configure() {
             bind(Boolean.class)
                 .annotatedWith(EnablePeerIPInReflogRecord.class)
-                .toInstance(Boolean.TRUE);
+                .toInstance(Boolean.FALSE);
             bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(config);
             bind(String.class)
                 .annotatedWith(AnonymousCowardName.class)
diff --git a/javatests/com/google/gerrit/server/events/EventJsonTest.java b/javatests/com/google/gerrit/server/events/EventJsonTest.java
index 6163ea7..8e4f436 100644
--- a/javatests/com/google/gerrit/server/events/EventJsonTest.java
+++ b/javatests/com/google/gerrit/server/events/EventJsonTest.java
@@ -52,12 +52,45 @@
 
   private final Gson gson = new EventGsonProvider().get();
 
+  static class CustomEvent extends Event {
+    static String TYPE = "custom-type";
+
+    public String customField;
+
+    protected CustomEvent() {
+      super(TYPE);
+    }
+  }
+
   @Before
   public void setTimeForTesting() {
     TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS);
   }
 
   @Test
+  public void customEvent() {
+    CustomEvent event = new CustomEvent();
+    event.customField = "customValue";
+    String json = gson.toJson(event);
+    CustomEvent resullt = gson.fromJson(json, CustomEvent.class);
+    assertThat(resullt.type).isEqualTo(CustomEvent.TYPE);
+    assertThat(resullt.customField).isEqualTo(event.customField);
+  }
+
+  @Test
+  public void customEventSimulateClassloaderIssue() {
+    EventTypes.register(CustomEvent.TYPE, CustomEvent.class);
+    CustomEvent event = new CustomEvent();
+    event.customField = "customValue";
+    // Need to serialise using the Event interface instead of json.getClass()
+    // for simulating the serialisation of an object owned by another class loader
+    String json = gson.toJson(event, Event.class);
+    CustomEvent resullt = gson.fromJson(json, CustomEvent.class);
+    assertThat(resullt.type).isEqualTo(CustomEvent.TYPE);
+    assertThat(resullt.customField).isEqualTo(event.customField);
+  }
+
+  @Test
   public void refUpdatedEvent() {
     RefUpdatedEvent event = new RefUpdatedEvent();
 
diff --git a/javatests/com/google/gerrit/server/notedb/AbstractChangeNotesTest.java b/javatests/com/google/gerrit/server/notedb/AbstractChangeNotesTest.java
index 94b6a19..a5cb456 100644
--- a/javatests/com/google/gerrit/server/notedb/AbstractChangeNotesTest.java
+++ b/javatests/com/google/gerrit/server/notedb/AbstractChangeNotesTest.java
@@ -154,7 +154,7 @@
                     .toInstance("http://localhost:8080/");
                 bind(Boolean.class)
                     .annotatedWith(EnablePeerIPInReflogRecord.class)
-                    .toInstance(Boolean.TRUE);
+                    .toInstance(Boolean.FALSE);
                 bind(Realm.class).to(FakeRealm.class);
                 bind(GroupBackend.class).to(SystemGroupBackend.class).in(SINGLETON);
                 bind(AccountCache.class).toInstance(accountCache);
diff --git a/plugins/codemirror-editor b/plugins/codemirror-editor
index 30c774f..7c94eb2 160000
--- a/plugins/codemirror-editor
+++ b/plugins/codemirror-editor
@@ -1 +1 @@
-Subproject commit 30c774f30c1709f71efc250a195dd6fb50c7503b
+Subproject commit 7c94eb2fd3cdea33a200ae7c73c19777ca865a41
diff --git a/tools/bzl/js.bzl b/tools/bzl/js.bzl
index 04464d0..b792991 100644
--- a/tools/bzl/js.bzl
+++ b/tools/bzl/js.bzl
@@ -439,17 +439,15 @@
     """Combine html, js, css files and optionally split into js and html bundles."""
     _bundle_rule(pkg = native.package_name(), *args, **kwargs)
 
-def polygerrit_plugin(name, app, assets = [], plugin_name = None):
-    """Produces plugin file set with minified javascript and assets.
+def polygerrit_plugin(name, app, plugin_name = None):
+    """Produces plugin file set with minified javascript.
 
     This rule minifies a plugin javascript file, potentially renames it, and produces a file set.
-    Run-time dependencies (e.g. JS libraries loaded after plugin starts) should be provided using "assets" property.
-    Output of this rule is a FileSet with "${plugin_name}.js" and assets.
+    Output of this rule is a FileSet with "${plugin_name}.js".
 
     Args:
       name: String, rule name.
       app: String, the main or root source file. This must be single JavaScript file.
-      assets: Fileset, additional files to be used by plugin in runtime.
       plugin_name: String, plugin name. ${name} is used if not provided.
     """
     if not plugin_name:
@@ -471,5 +469,5 @@
 
     native.filegroup(
         name = name,
-        srcs = [plugin_name + ".js"] + assets,
+        srcs = [plugin_name + ".js"],
     )