HttpSession: Align project name encoding with gerrit core
In I73bd4df898d GsonProvider was extended to deserialize project name
in both forms: legacy and gerrit core form, but missed to register the
new type adapter in HttpSession instance, so that events were still
serialized in legacy form.
This incompatibility can cause a problem in zero-downtime upgrade
scenario, where the events created by gerrit 3.0 cannot be de-serialized
by second node running gerrit 3.1.
The modification in this commit supposed to be reverted when this change
is merged to stable-3.1 branch.
Bug: Issue 13825
Change-Id: Ice9b7843f5bb6adeaa42b58d66933e4bdb6f390d
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/GsonProvider.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/GsonProvider.java
index 36f0029..c600019 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/GsonProvider.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/GsonProvider.java
@@ -20,6 +20,7 @@
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.EventDeserializer;
import com.google.gerrit.server.events.SupplierDeserializer;
+import com.google.gerrit.server.events.SupplierSerializer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.inject.Provider;
@@ -31,6 +32,7 @@
return new GsonBuilder()
.registerTypeAdapter(Event.class, new EventDeserializer())
.registerTypeAdapter(Project.NameKey.class, new ProjectNameKeyAdapter())
+ .registerTypeAdapter(Supplier.class, new SupplierSerializer())
.registerTypeAdapter(Supplier.class, new SupplierDeserializer())
.create();
}
diff --git a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSession.java b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSession.java
index f2ac080..cf98aae 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSession.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSession.java
@@ -15,11 +15,9 @@
package com.ericsson.gerrit.plugins.highavailability.forwarder.rest;
import com.ericsson.gerrit.plugins.highavailability.forwarder.rest.HttpResponseHandler.HttpResult;
-import com.google.common.base.Supplier;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.net.MediaType;
-import com.google.gerrit.server.events.SupplierSerializer;
import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
import com.google.inject.Inject;
import java.io.IOException;
import java.net.URI;
@@ -32,12 +30,12 @@
class HttpSession {
private final CloseableHttpClient httpClient;
- private final Gson gson =
- new GsonBuilder().registerTypeAdapter(Supplier.class, new SupplierSerializer()).create();
+ private final Gson gson;
@Inject
- HttpSession(CloseableHttpClient httpClient) {
+ HttpSession(CloseableHttpClient httpClient, GsonProvider gsonProvider) {
this.httpClient = httpClient;
+ this.gson = gsonProvider.get();
}
HttpResult post(String uri) throws IOException {
@@ -67,7 +65,8 @@
}
}
- private String jsonEncode(Object content) {
+ @VisibleForTesting
+ String jsonEncode(Object content) {
if (content instanceof String) {
return (String) content;
}
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/event/EventDeserializerTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/event/EventDeserializerTest.java
index 8e1b5eb..2b9ee35 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/event/EventDeserializerTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/event/EventDeserializerTest.java
@@ -17,7 +17,12 @@
import static com.google.common.truth.Truth.assertThat;
import com.ericsson.gerrit.plugins.highavailability.forwarder.rest.GsonProvider;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.data.AccountAttribute;
+import com.google.gerrit.server.data.RefUpdateAttribute;
+import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gson.Gson;
import org.junit.Test;
@@ -39,4 +44,30 @@
Project.NameKey n = gson.fromJson(NEW_PROJECT_KEY, Project.NameKey.class);
assertThat(n.get()).isEqualTo("project");
}
+
+ @Test
+ public void refUpdatedEventRoundTrip() {
+ RefUpdatedEvent refUpdatedEvent = new RefUpdatedEvent();
+
+ RefUpdateAttribute refUpdatedAttribute = new RefUpdateAttribute();
+ refUpdatedAttribute.refName = "refs/heads/master";
+ refUpdatedEvent.refUpdate = createSupplier(refUpdatedAttribute);
+
+ AccountAttribute accountAttribute = new AccountAttribute();
+ accountAttribute.email = "some.user@domain.com";
+ refUpdatedEvent.submitter = createSupplier(accountAttribute);
+
+ String serializedEvent = gson.toJson(refUpdatedEvent);
+ RefUpdatedEvent e = gson.fromJson(serializedEvent, RefUpdatedEvent.class);
+
+ assertThat(e).isNotNull();
+ assertThat(e.refUpdate).isInstanceOf(Supplier.class);
+ assertThat(e.refUpdate.get().refName).isEqualTo(refUpdatedAttribute.refName);
+ assertThat(e.submitter).isInstanceOf(Supplier.class);
+ assertThat(e.submitter.get().email).isEqualTo(accountAttribute.email);
+ }
+
+ private static <T> Supplier<T> createSupplier(T value) {
+ return Suppliers.memoize(() -> value);
+ }
}
diff --git a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSessionTest.java b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSessionTest.java
index 5e0d4c9..4071363 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSessionTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/highavailability/forwarder/rest/HttpSessionTest.java
@@ -28,6 +28,7 @@
import com.github.tomakehurst.wiremock.http.Fault;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.github.tomakehurst.wiremock.stubbing.Scenario;
+import com.google.gerrit.reviewdb.client.Project;
import java.net.SocketTimeoutException;
import org.junit.Before;
import org.junit.Rule;
@@ -70,7 +71,7 @@
when(configMock.http().socketTimeout()).thenReturn(TIMEOUT);
when(configMock.http().retryInterval()).thenReturn(RETRY_INTERVAL);
- httpSession = new HttpSession(new HttpClientProvider(configMock).get());
+ httpSession = new HttpSession(new HttpClientProvider(configMock).get(), new GsonProvider());
}
@Test
@@ -170,4 +171,12 @@
assertThat(httpSession.post(uri).isSuccessful()).isFalse();
}
+
+ @Test
+ public void encodeProjectName() {
+ String projectStr = "project";
+ Project.NameKey project = Project.nameKey(projectStr);
+ String json = httpSession.jsonEncode(project);
+ assertThat(json).isEqualTo("\"" + projectStr + "\"");
+ }
}