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 + "\""); + } }