Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ dependencies {
implementation deps['com.google.oauth-client:google-oauth-client-servlet']
implementation deps['com.google.re2j:re2j']
implementation deps['org.freemarker:freemarker']
implementation deps['com.googlecode.json-simple:json-simple']
implementation deps['com.github.mwiede:jsch']
implementation deps['com.zaxxer:HikariCP']
implementation deps['com.squareup.okhttp3:okhttp']
Expand Down
1 change: 0 additions & 1 deletion core/gradle.lockfile
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ com.google.protobuf:protobuf-java:4.33.2=annotationProcessor,nonprodAnnotationPr
com.google.protobuf:protobuf-java:4.35.0=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.re2j:re2j:1.8=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.truth:truth:1.4.5=deploy_jar,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.googlecode.json-simple:json-simple:1.1.1=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.ibm.icu:icu4j:73.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.lmax:disruptor:3.4.2=compileClasspath,deploy_jar,nonprodCompileClasspath,nonprodRuntimeClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.puppycrawl.tools:checkstyle:10.24.0=checkstyle
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/java/google/registry/flows/CheckApiAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@
import static google.registry.persistence.transaction.TransactionManagerFactory.replicaTm;
import static google.registry.pricing.PricingEngineProxy.isDomainPremium;
import static google.registry.util.DomainNameUtils.canonicalizeHostname;
import static org.json.simple.JSONValue.toJSONString;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.flogger.FluentLogger;
import com.google.common.net.InternetDomainName;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import dagger.Module;
import dagger.Provides;
import google.registry.flows.domain.DomainFlowUtils.BadCommandForRegistryPhaseException;
Expand Down Expand Up @@ -83,6 +83,7 @@ public class CheckApiAction implements Runnable {
@Inject Response response;
@Inject CheckApiMetric.Builder metricBuilder;
@Inject CheckApiMetrics checkApiMetrics;
@Inject Gson gson;

@Inject
CheckApiAction() {}
Expand All @@ -94,7 +95,7 @@ public void run() {
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
response.setContentType(MediaType.JSON_UTF_8);
response.setPayload(toJSONString(doCheck()));
response.setPayload(gson.toJson(doCheck()));
} finally {
CheckApiMetric metric = metricBuilder.build();
checkApiMetrics.incrementCheckApiRequest(metric);
Expand Down
6 changes: 4 additions & 2 deletions core/src/main/java/google/registry/flows/EppController.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.flogger.FluentLogger;
import com.google.gson.Gson;
import google.registry.flows.FlowModule.EppExceptionInProviderException;
import google.registry.model.eppcommon.Trid;
import google.registry.model.eppinput.EppInput;
Expand All @@ -34,7 +35,6 @@
import google.registry.monitoring.whitebox.EppMetric;
import jakarta.inject.Inject;
import java.util.Optional;
import org.json.simple.JSONValue;

/**
* An implementation of the EPP command/response protocol.
Expand All @@ -50,6 +50,8 @@ public final class EppController {
@Inject EppMetric.Builder eppMetricBuilder;
@Inject EppMetrics eppMetrics;
@Inject ServerTridProvider serverTridProvider;
@Inject Gson gson;

@Inject EppController() {}

/** Reads EPP XML, executes the matching flow, and returns an {@link EppOutput}. */
Expand All @@ -72,7 +74,7 @@ public EppOutput handleEppCommand(
e.getMessage(),
lazy(
() ->
JSONValue.toJSONString(
gson.toJson(
ImmutableMap.<String, Object>of(
"clientId",
nullToEmpty(sessionMetadata.getRegistrarId()),
Expand Down
6 changes: 4 additions & 2 deletions core/src/main/java/google/registry/flows/FlowReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.gson.Gson;
import google.registry.flows.FlowModule.InputXml;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.model.eppcommon.Trid;
import google.registry.model.eppinput.EppInput;
import jakarta.inject.Inject;
import java.util.Optional;
import org.json.simple.JSONValue;

/** Reporter used by {@link FlowRunner} to record flow execution data for reporting. */
public class FlowReporter {
Expand All @@ -49,6 +49,8 @@ public class FlowReporter {
@Inject @InputXml byte[] inputXmlBytes;
@Inject EppInput eppInput;
@Inject Class<? extends Flow> flowClass;
@Inject Gson gson;

@Inject FlowReporter() {}

/** Records information about the current flow execution in the request logs. */
Expand All @@ -61,7 +63,7 @@ public void recordToLogs() {
logger.atInfo().log(
"%s: %s",
METADATA_LOG_SIGNATURE,
JSONValue.toJSONString(
gson.toJson(
new ImmutableMap.Builder<String, Object>()
.put("serverTrid", trid.getServerTransactionId())
.put("clientId", registrarId)
Expand Down
8 changes: 5 additions & 3 deletions core/src/main/java/google/registry/request/JsonResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
import static com.google.common.net.HttpHeaders.X_CONTENT_TYPE_OPTIONS;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static org.json.simple.JSONValue.toJSONString;

import com.google.gson.Gson;
import jakarta.inject.Inject;
import java.time.Instant;
import java.util.Map;
Expand All @@ -31,10 +31,12 @@ public class JsonResponse {
public static final String JSON_SAFETY_PREFIX = ")]}'\n";

protected final Response response;
protected final Gson gson;

@Inject
public JsonResponse(Response rsp) {
public JsonResponse(Response rsp, Gson gson) {
this.response = rsp;
this.gson = gson;
}

/**
Expand All @@ -55,7 +57,7 @@ public void setPayload(Map<String, ?> responseMap) {
// response, even if all else fails. It's basically another anti-sniffing mechanism in the sense
// that if you hit this url directly, it would try to download the file instead of showing it.
response.setHeader(CONTENT_DISPOSITION, "attachment");
response.setPayload(JSON_SAFETY_PREFIX + toJSONString(checkNotNull(responseMap)));
response.setPayload(JSON_SAFETY_PREFIX + gson.toJson(checkNotNull(responseMap)));
}

/**
Expand Down
16 changes: 7 additions & 9 deletions core/src/main/java/google/registry/request/RequestModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package google.registry.request;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static google.registry.dns.PublishDnsUpdatesAction.CLOUD_TASKS_RETRY_HEADER;
import static google.registry.model.tld.Tlds.assertTldExists;
Expand All @@ -28,14 +29,15 @@
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteStreams;
import com.google.common.io.CharStreams;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.google.protobuf.ByteString;
import dagger.Module;
import dagger.Provides;
Expand All @@ -50,8 +52,6 @@
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;

/** Dagger module for servlets. */
@Module
Expand Down Expand Up @@ -202,18 +202,16 @@ static LockHandler provideLockHandler(LockHandlerImpl lockHandler) {

@Provides
@JsonPayload
@SuppressWarnings("unchecked")
static Map<String, Object> provideJsonPayload(
@Header("Content-Type") MediaType contentType, @Payload String payload) {
@Header("Content-Type") MediaType contentType, @Payload String payload, Gson gson) {
if (!JSON_UTF_8.is(contentType.withCharset(UTF_8))) {
throw new UnsupportedMediaTypeException(
String.format("Expected %s Content-Type", JSON_UTF_8.withoutParameters()));
}
try {
return (Map<String, Object>) JSONValue.parseWithException(payload);
} catch (ParseException e) {
throw new BadRequestException(
"Malformed JSON", new VerifyException("Malformed JSON:\n" + payload, e));
return checkNotNull(gson.fromJson(payload, new TypeToken<>() {}));
} catch (JsonSyntaxException | NullPointerException e) {
throw new BadRequestException("Malformed JSON:\n" + payload);
}
}

Expand Down
16 changes: 9 additions & 7 deletions core/src/main/java/google/registry/security/JsonHttp.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@
import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
import static com.google.common.net.HttpHeaders.X_CONTENT_TYPE_OPTIONS;
import static com.google.common.net.MediaType.JSON_UTF_8;
import static org.json.simple.JSONValue.writeJSONString;

import com.google.common.flogger.FluentLogger;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import google.registry.tools.GsonUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.Map;
import javax.annotation.Nullable;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;

/**
* Helper class for servlets that read or write JSON.
Expand All @@ -41,6 +42,8 @@ public final class JsonHttp {

private static final FluentLogger logger = FluentLogger.forEnclosingClass();

private static final Gson GSON = GsonUtils.provideGson();

/** String prefixed to all JSON-like responses. */
public static final String JSON_SAFETY_PREFIX = ")]}'\n";

Expand All @@ -51,7 +54,6 @@ public final class JsonHttp {
* @throws IOException if we failed to read from {@code req}.
*/
@Nullable
@SuppressWarnings("unchecked")
public static Map<String, ?> read(HttpServletRequest req) throws IOException {
if (!"POST".equals(req.getMethod())
&& !"PUT".equals(req.getMethod())) {
Expand All @@ -64,8 +66,8 @@ public final class JsonHttp {
}
try (Reader jsonReader = req.getReader()) {
try {
return checkNotNull((Map<String, ?>) JSONValue.parseWithException(jsonReader));
} catch (ParseException | NullPointerException | ClassCastException e) {
return checkNotNull(GSON.fromJson(jsonReader, new TypeToken<>() {}));
} catch (JsonSyntaxException | NullPointerException | ClassCastException e) {
logger.atWarning().withCause(e).log("Malformed JSON.");
return null;
}
Expand All @@ -88,7 +90,7 @@ public static void write(HttpServletResponse rsp, Map<String, ?> jsonObject) thr
rsp.setHeader(CONTENT_DISPOSITION, "attachment");
try (Writer writer = rsp.getWriter()) {
writer.write(JSON_SAFETY_PREFIX);
writeJSONString(jsonObject, writer);
GSON.toJson(jsonObject, writer);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.beust.jcommander.Parameters;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import google.registry.model.domain.Domain;
import google.registry.model.host.Host;
import google.registry.persistence.transaction.QueryComposer.Comparator;
Expand All @@ -38,7 +39,6 @@
import java.time.Instant;
import java.util.List;
import java.util.Map;
import org.json.simple.JSONValue;

/** Command to generate a report of all DNS data. */
@Parameters(separators = " =", commandDescription = "Generate report of all DNS data in a TLD.")
Expand All @@ -57,6 +57,7 @@ final class GenerateDnsReportCommand implements Command {
private Path output = Paths.get("/dev/stdout");

@Inject Clock clock;
@Inject Gson gson;

@Override
public void run() throws Exception {
Expand Down Expand Up @@ -144,7 +145,7 @@ private void writeJson(Map<String, ?> map) {
} else {
result.append(",\n");
}
result.append(JSONValue.toJSONString(map));
result.append(gson.toJson(map));
}
}
}
2 changes: 2 additions & 0 deletions core/src/main/java/google/registry/tools/GsonUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.ToNumberPolicy;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
Expand Down Expand Up @@ -82,6 +83,7 @@ public static Gson provideGson() {
.registerTypeAdapter(Serializable.class, new SerializableJsonTypeAdapter())
.registerTypeAdapterFactory(new ClassProcessingTypeAdapterFactory())
.registerTypeAdapterFactory(new GsonPostProcessableTypeAdapterFactory())
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
.excludeFieldsWithoutExposeAnnotation()
.create();
}
Expand Down
16 changes: 10 additions & 6 deletions core/src/main/java/google/registry/tools/ListObjectsCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
import com.google.common.base.VerifyException;
import com.google.common.collect.ImmutableMap;
import com.google.common.net.MediaType;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import org.json.simple.JSONValue;

/**
* Abstract base class for commands that list objects by calling a server task.
Expand All @@ -35,6 +38,8 @@
*/
abstract class ListObjectsCommand implements CommandWithConnection {

private static final Gson GSON = GsonUtils.provideGson();

@Nullable
@Parameter(
names = {"-f", "--fields"},
Expand Down Expand Up @@ -87,14 +92,13 @@ public void run() throws Exception {
connection.sendPostRequest(
getCommandPath(), params.build(), MediaType.PLAIN_TEXT_UTF_8, new byte[0]);
// Parse the returned JSON and make sure it's a map.
Object obj = JSONValue.parse(response.substring(JSON_SAFETY_PREFIX.length()));
if (!(obj instanceof Map<?, ?>)) {
JsonElement element = JsonParser.parseString(response.substring(JSON_SAFETY_PREFIX.length()));
if (!element.isJsonObject()) {
throw new VerifyException("Server returned unexpected JSON: " + response);
}
@SuppressWarnings("unchecked")
Map<String, Object> responseMap = (Map<String, Object>) obj;
Map<String, Object> responseMap = GSON.fromJson(element, new TypeToken<>() {});
// Get the status.
obj = responseMap.get("status");
Object obj = responseMap.get("status");
if (obj == null) {
throw new VerifyException("Server returned no status");
}
Expand Down
Loading
Loading