Remove usages of json-simple (#3060)

We should use gson wherever possible. There's no point in having
unnecessary dependencies (we'll need to keep around jackson for YAML
parsing).
This commit is contained in:
gbrodman
2026-06-01 20:16:32 +00:00
committed by GitHub
parent 5599a0eb3d
commit a5b280838c
28 changed files with 141 additions and 98 deletions
@@ -29,6 +29,7 @@ import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_INSTANT;
import static org.mockito.Mockito.verify;
import com.google.gson.reflect.TypeToken;
import google.registry.bsa.persistence.BsaTestingUtils;
import google.registry.model.tld.Tld;
import google.registry.monitoring.whitebox.CheckApiMetric;
@@ -39,10 +40,10 @@ import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.tools.GsonUtils;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -83,9 +84,9 @@ class CheckApiActionTest {
.build());
}
@SuppressWarnings("unchecked")
private Map<String, Object> getCheckResponse(String domain) {
CheckApiAction action = new CheckApiAction();
action.gson = GsonUtils.provideGson();
action.domain = domain;
action.response = new FakeResponse();
action.metricBuilder = CheckApiMetric.builder(fakeClock);
@@ -94,7 +95,8 @@ class CheckApiActionTest {
endTime = fakeClock.now();
action.run();
return (Map<String, Object>) JSONValue.parse(((FakeResponse) action.response).getPayload());
return action.gson.fromJson(
((FakeResponse) action.response).getPayload(), new TypeToken<>() {});
}
@Test
@@ -31,6 +31,8 @@ import static org.mockito.Mockito.when;
import com.google.common.base.Splitter;
import com.google.common.testing.TestLogHandler;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import google.registry.flows.EppException.UnimplementedExtensionException;
import google.registry.flows.EppTestComponent.FakeServerTridProvider;
import google.registry.flows.FlowModule.EppExceptionInProviderException;
@@ -43,6 +45,7 @@ import google.registry.monitoring.whitebox.EppMetric;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.FakeClock;
import google.registry.tools.GsonUtils;
import google.registry.util.Clock;
import google.registry.xml.ValidationMode;
import java.time.Instant;
@@ -50,7 +53,6 @@ import java.util.List;
import java.util.Map;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -82,6 +84,7 @@ class EppControllerTest {
@Mock Result result;
private static final Instant START_TIME = Instant.parse("2016-09-01T00:00:00Z");
private static final Gson GSON = GsonUtils.provideGson();
private final Clock clock = new FakeClock(START_TIME);
private final TestLogHandler logHandler = new TestLogHandler();
@@ -110,6 +113,7 @@ class EppControllerTest {
when(result.getCode()).thenReturn(Code.SUCCESS_WITH_NO_MESSAGES);
eppController = new EppController();
eppController.gson = GSON;
eppController.eppMetricBuilder = EppMetric.builderForRequest(clock);
when(flowRunner.run(eppController.eppMetricBuilder)).thenReturn(eppOutput);
eppController.flowComponentBuilder = flowComponentBuilder;
@@ -247,8 +251,7 @@ class EppControllerTest {
assertThat(logRecord.getThrown()).isInstanceOf(IllegalStateException.class);
}
@SuppressWarnings("unchecked")
private static Map<String, Object> parseJsonMap(String json) throws Exception {
return (Map<String, Object>) JSONValue.parseWithException(json);
return GSON.fromJson(json, new TypeToken<>() {});
}
}
@@ -28,6 +28,7 @@ import google.registry.flows.custom.TestCustomLogicFactory;
import google.registry.flows.domain.DomainDeletionTimeCache;
import google.registry.flows.domain.DomainFlowTmchUtils;
import google.registry.monitoring.whitebox.EppMetric;
import google.registry.request.Modules.GsonModule;
import google.registry.request.RequestScope;
import google.registry.request.lock.LockHandler;
import google.registry.testing.CloudTasksHelper;
@@ -42,7 +43,8 @@ import jakarta.inject.Singleton;
/** Dagger component for running EPP tests. */
@Singleton
@Component(modules = {ConfigModule.class, EppTestComponent.FakesAndMocksModule.class})
@Component(
modules = {ConfigModule.class, GsonModule.class, EppTestComponent.FakesAndMocksModule.class})
public interface EppTestComponent {
RequestComponent startRequest();
@@ -22,22 +22,26 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.testing.TestLogHandler;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.model.eppcommon.Trid;
import google.registry.model.eppinput.EppInput;
import google.registry.model.eppoutput.EppOutput.ResponseOrGreeting;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.tools.GsonUtils;
import google.registry.util.JdkLoggerConfig;
import java.util.Map;
import java.util.Optional;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link FlowReporter}. */
class FlowReporterTest {
private static final Gson GSON = GsonUtils.provideGson();
static class TestCommandFlow implements Flow {
@Override
public ResponseOrGreeting run() {
@@ -60,6 +64,7 @@ class FlowReporterTest {
void beforeEach() {
JdkLoggerConfig.getConfig(FlowReporter.class).addHandler(handler);
flowReporter.trid = Trid.create("client-123", "server-456");
flowReporter.gson = GSON;
flowReporter.registrarId = "TheRegistrar";
flowReporter.inputXmlBytes = "<xml/>".getBytes(UTF_8);
flowReporter.flowClass = TestCommandFlow.class;
@@ -205,8 +210,7 @@ class FlowReporterTest {
assertThat(json).containsEntry("tlds", ImmutableList.of());
}
@SuppressWarnings("unchecked")
private static Map<String, Object> parseJsonMap(String json) throws Exception {
return (Map<String, Object>) JSONValue.parseWithException(json);
return GSON.fromJson(json, new TypeToken<>() {});
}
}
@@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.testing.TestLogHandler;
import com.google.gson.Gson;
import google.registry.model.EppResource;
import google.registry.model.ForeignKeyUtils;
import google.registry.model.domain.DomainBase;
@@ -34,13 +35,13 @@ import google.registry.model.tmch.ClaimsList;
import google.registry.model.tmch.ClaimsListDao;
import google.registry.testing.DatabaseHelper;
import google.registry.testing.TestCacheExtension;
import google.registry.tools.GsonUtils;
import google.registry.util.JdkLoggerConfig;
import google.registry.util.TypeUtils.TypeInstantiator;
import java.time.Duration;
import java.time.Instant;
import java.util.logging.Level;
import javax.annotation.Nullable;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.RegisterExtension;
@@ -53,6 +54,8 @@ import org.junit.jupiter.api.extension.RegisterExtension;
public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource>
extends FlowTestCase<F> {
private static final Gson GSON = GsonUtils.provideGson();
protected final TestLogHandler logHandler = new TestLogHandler();
@RegisterExtension
@@ -108,21 +111,23 @@ public abstract class ResourceFlowTestCase<F extends Flow, R extends EppResource
.that(logHandler)
.hasLogAtLevelWithMessage(Level.INFO, "FLOW-LOG-SIGNATURE-METADATA")
.which()
.contains("\"clientId\":" + JSONValue.toJSONString(registrarId));
.contains("\"clientId\":" + GSON.toJson(registrarId));
}
protected void assertTldsFieldLogged(String... tlds) {
assertAboutLogs().that(logHandler)
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(Level.INFO, "FLOW-LOG-SIGNATURE-METADATA")
.which()
.contains("\"tlds\":" + JSONValue.toJSONString(ImmutableList.copyOf(tlds)));
.contains("\"tlds\":" + GSON.toJson(ImmutableList.copyOf(tlds)));
}
protected void assertIcannReportingActivityFieldLogged(String fieldName) {
assertAboutLogs().that(logHandler)
assertAboutLogs()
.that(logHandler)
.hasLogAtLevelWithMessage(Level.INFO, "FLOW-LOG-SIGNATURE-METADATA")
.which()
.contains("\"icannActivityReportField\":" + JSONValue.toJSONString(fieldName));
.contains("\"icannActivityReportField\":" + GSON.toJson(fieldName));
}
protected void assertLastHistoryContainsResource(EppResource resource) {
@@ -18,17 +18,21 @@ import static com.google.common.truth.Truth.assertThat;
import static google.registry.request.JsonResponse.JSON_SAFETY_PREFIX;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import google.registry.testing.FakeResponse;
import google.registry.tools.GsonUtils;
import java.time.Instant;
import java.util.Map;
import org.json.simple.JSONValue;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link JsonResponse}. */
class JsonResponseTest {
private static final Gson GSON = GsonUtils.provideGson();
private FakeResponse fakeResponse = new FakeResponse();
private JsonResponse jsonResponse = new JsonResponse(fakeResponse);
private JsonResponse jsonResponse = new JsonResponse(fakeResponse, GSON);
@Test
void testSetStatus() {
@@ -44,9 +48,8 @@ class JsonResponseTest {
jsonResponse.setPayload(responseValues);
String payload = fakeResponse.getPayload();
assertThat(payload).startsWith(JSON_SAFETY_PREFIX);
@SuppressWarnings("unchecked")
Map<String, Object> responseMap = (Map<String, Object>)
JSONValue.parse(payload.substring(JSON_SAFETY_PREFIX.length()));
Map<String, Object> responseMap =
GSON.fromJson(payload.substring(JSON_SAFETY_PREFIX.length()), new TypeToken<>() {});
assertThat(responseMap).containsExactlyEntriesIn(responseValues);
}
@@ -19,21 +19,26 @@ import static google.registry.request.RequestModule.provideJsonPayload;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import google.registry.request.HttpException.BadRequestException;
import google.registry.request.HttpException.UnsupportedMediaTypeException;
import google.registry.tools.GsonUtils;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link RequestModule}. */
final class RequestModuleTest {
private static final Gson GSON = GsonUtils.provideGson();
@Test
void testProvideJsonPayload() {
assertThat(provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":\"v\"}")).containsExactly("k", "v");
assertThat(provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":\"v\"}", GSON))
.containsExactly("k", "v");
}
@Test
void testProvideJsonPayload_contentTypeWithoutCharsetAllowed() {
assertThat(provideJsonPayload(MediaType.JSON_UTF_8.withoutParameters(), "{\"k\":\"v\"}"))
assertThat(provideJsonPayload(MediaType.JSON_UTF_8.withoutParameters(), "{\"k\":\"v\"}", GSON))
.containsExactly("k", "v");
}
@@ -41,14 +46,16 @@ final class RequestModuleTest {
void testProvideJsonPayload_malformedInput_throws500() {
BadRequestException thrown =
assertThrows(
BadRequestException.class, () -> provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":"));
BadRequestException.class,
() -> provideJsonPayload(MediaType.JSON_UTF_8, "{\"k\":", GSON));
assertThat(thrown).hasMessageThat().contains("Malformed JSON");
}
@Test
void testProvideJsonPayload_emptyInput_throws500() {
BadRequestException thrown =
assertThrows(BadRequestException.class, () -> provideJsonPayload(MediaType.JSON_UTF_8, ""));
assertThrows(
BadRequestException.class, () -> provideJsonPayload(MediaType.JSON_UTF_8, "", GSON));
assertThat(thrown).hasMessageThat().contains("Malformed JSON");
}
@@ -56,13 +63,13 @@ final class RequestModuleTest {
void testProvideJsonPayload_nonJsonContentType_throws415() {
assertThrows(
UnsupportedMediaTypeException.class,
() -> provideJsonPayload(MediaType.PLAIN_TEXT_UTF_8, "{}"));
() -> provideJsonPayload(MediaType.PLAIN_TEXT_UTF_8, "{}", GSON));
}
@Test
void testProvideJsonPayload_contentTypeWithWeirdParam_throws415() {
assertThrows(
UnsupportedMediaTypeException.class,
() -> provideJsonPayload(MediaType.JSON_UTF_8.withParameter("omg", "handel"), "{}"));
() -> provideJsonPayload(MediaType.JSON_UTF_8.withParameter("omg", "handel"), "{}", GSON));
}
}
@@ -20,21 +20,25 @@ import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.security.JsonHttp.JSON_SAFETY_PREFIX;
import com.google.common.base.Supplier;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import google.registry.tools.GsonUtils;
import java.io.BufferedReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
/**
* Helper class for testing JSON RPC servlets.
*/
public final class JsonHttpTestUtils {
private static final Gson GSON = GsonUtils.provideGson();
/** Returns JSON payload for mocked result of {@code rsp.getReader()}. */
public static BufferedReader createJsonPayload(Map<String, ?> object) {
return createJsonPayload(JSONValue.toJSONString(object));
return createJsonPayload(GSON.toJson(object));
}
/** @see #createJsonPayload(Map) */
@@ -58,10 +62,8 @@ public final class JsonHttpTestUtils {
assertThat(jsonText).startsWith(JSON_SAFETY_PREFIX);
jsonText = jsonText.substring(JSON_SAFETY_PREFIX.length());
try {
@SuppressWarnings("unchecked")
Map<String, Object> json = (Map<String, Object>) JSONValue.parseWithException(jsonText);
return json;
} catch (ClassCastException | ParseException e) {
return GSON.fromJson(jsonText, new TypeToken<>() {});
} catch (ClassCastException | JsonSyntaxException e) {
assertWithMessage("Bad JSON: %s\n%s", e.getMessage(), jsonText).fail();
throw new AssertionError();
}
@@ -15,6 +15,7 @@
package google.registry.testing;
import google.registry.request.JsonResponse;
import google.registry.tools.GsonUtils;
import java.util.Map;
/** Fake implementation of {@link JsonResponse} for testing. */
@@ -23,7 +24,7 @@ public final class FakeJsonResponse extends JsonResponse {
private Map<String, ?> responseMap;
public FakeJsonResponse() {
super(new FakeResponse());
super(new FakeResponse(), GsonUtils.provideGson());
}
@Override
@@ -85,7 +85,8 @@ final class GcpProjectConnectionTest {
when(lowLevelHttpResponse.getStatusCode()).thenReturn(200);
httpTransport = new TestHttpTransport();
connection = new ServiceConnection(false, httpTransport.createRequestFactory());
connection =
new ServiceConnection(false, httpTransport.createRequestFactory(), GsonUtils.provideGson());
}
@Test
@@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.net.InetAddresses;
import com.google.gson.Gson;
import google.registry.model.domain.Domain;
import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.eppcommon.StatusValue;
@@ -41,19 +42,19 @@ import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link GenerateDnsReportCommand}. */
class GenerateDnsReportCommandTest extends CommandTestCase<GenerateDnsReportCommand> {
private static final Gson GSON = GsonUtils.provideGson();
private Path output;
private Object getOutputAsJson() throws IOException, ParseException {
private Object getOutputAsJson() throws IOException {
try (Reader reader = Files.newBufferedReader(output, UTF_8)) {
return JSONValue.parseWithException(reader);
return GSON.fromJson(reader, Object.class);
}
}
@@ -114,6 +115,7 @@ class GenerateDnsReportCommandTest extends CommandTestCase<GenerateDnsReportComm
void beforeEach() {
output = tmpDir.resolve("out.dat");
command.clock = fakeClock;
command.gson = GSON;
createTlds("xn--q9jyb4c", "example");
nameserver1 =
@@ -26,6 +26,7 @@ import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import google.registry.request.Action.Service;
import java.io.ByteArrayInputStream;
import org.junit.jupiter.api.Test;
@@ -33,10 +34,12 @@ import org.junit.jupiter.api.Test;
/** Unit tests for {@link google.registry.tools.ServiceConnection}. */
public class ServiceConnectionTest {
private static final Gson GSON = GsonUtils.provideGson();
@Test
void testSuccess_serverUrl_notCanary() {
ServiceConnection connection =
new ServiceConnection(false, null).withService(Service.FRONTEND, false);
new ServiceConnection(false, null, GSON).withService(Service.FRONTEND, false);
String serverUrl = connection.getServer().toString();
assertThat(serverUrl).isEqualTo("https://frontend.registry.test"); // See default-config.yaml
}
@@ -52,7 +55,7 @@ public class ServiceConnectionTest {
when(request.execute()).thenReturn(response);
when(response.getContent()).thenReturn(ByteArrayInputStream.nullInputStream());
ServiceConnection connection =
new ServiceConnection(false, factory).withService(Service.PUBAPI, true);
new ServiceConnection(false, factory, GSON).withService(Service.PUBAPI, true);
String serverUrl = connection.getServer().toString();
assertThat(serverUrl).isEqualTo("https://pubapi.registry.test");
connection.sendGetRequest("/path", ImmutableMap.of());
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gson.reflect.TypeToken;
import google.registry.model.OteStatsTestHelper;
import google.registry.model.console.GlobalRole;
import google.registry.model.console.User;
@@ -44,7 +45,6 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.json.simple.JSONArray;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -131,7 +131,7 @@ class ConsoleOteActionTest extends ConsoleActionBaseTestCase {
Optional.of(new OteCreateData("theregistrar", "contact@registry.example")));
action.cloudTasksUtils = cloudTasksHelper.getTestCloudTasksUtils();
action.run();
var obsResponse = GSON.fromJson(response.getPayload(), Map.class);
Map<String, Object> obsResponse = GSON.fromJson(response.getPayload(), new TypeToken<>() {});
assertThat(
ImmutableMap.of(
"theregistrar-1", "theregistrar-sunrise",
@@ -175,7 +175,7 @@ class ConsoleOteActionTest extends ConsoleActionBaseTestCase {
Action.Method.GET, authResult, "theregistrar-1", Optional.empty(), Optional.empty());
action.run();
List<Map<String, ?>> responseMaps = GSON.fromJson(response.getPayload(), JSONArray.class);
List<Map<String, ?>> responseMaps = GSON.fromJson(response.getPayload(), new TypeToken<>() {});
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertTrue(
responseMaps.stream().allMatch(status -> Boolean.TRUE.equals(status.get("completed"))));
@@ -191,7 +191,7 @@ class ConsoleOteActionTest extends ConsoleActionBaseTestCase {
Action.Method.GET, authResult, "theregistrar-1", Optional.empty(), Optional.empty());
action.run();
List<Map<String, ?>> responseMaps = GSON.fromJson(response.getPayload(), JSONArray.class);
List<Map<String, ?>> responseMaps = GSON.fromJson(response.getPayload(), new TypeToken<>() {});
assertThat(response.getStatus()).isEqualTo(SC_OK);
assertThat(
responseMaps.stream()