Commit e15c3a64 authored by Karsten Loesing's avatar Karsten Loesing
Browse files

Replace Gson with Jackson.

Implements #26163.
parent 84b07361
# Changes in version 2.0.3 - 2018-0?-??
* Medium changes
- Replace Gson with Jackson.
* Minor changes
- Remove duplicate [] surrounding suggested IPv6 addresses.
......
......@@ -9,7 +9,7 @@
<property name="javadoc-title" value="ExoneraTor API Documentation"/>
<property name="implementation-title" value="ExoneraTor" />
<property name="release.version" value="2.0.2-dev" />
<property name="metricslibversion" value="2.1.1" />
<property name="metricslibversion" value="2.4.0" />
<property name="jetty.version" value="-9.2.21.v20170120" />
<property name="warfile"
value="exonerator-${release.version}.war"/>
......@@ -34,7 +34,9 @@
<patternset id="common" >
<include name="commons-codec-1.10.jar"/>
<include name="commons-lang3-3.5.jar"/>
<include name="gson-2.4.jar" />
<include name="jackson-annotations-2.8.6.jar"/>
<include name="jackson-core-2.8.6.jar"/>
<include name="jackson-databind-2.8.6.jar"/>
<include name="logback-core-1.1.9.jar" />
<include name="logback-classic-1.1.9.jar" />
<include name="postgresql-9.4.1212.jar"/>
......
......@@ -3,68 +3,60 @@
package org.torproject.metrics.exonerator;
import com.google.gson.Gson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.Reader;
/** Query response from the ExoneraTor database. */
public class QueryResponse {
@Expose(serialize = false, deserialize = false)
private static Logger logger = LoggerFactory.getLogger(QueryResponse.class);
/* Actual version implemented by this class. */
@Expose(serialize = false, deserialize = false)
private static final String VERSION = "1.0";
/* Don't accept query responses with versions lower than this. */
@Expose(serialize = false, deserialize = false)
private static final String FIRSTRECOGNIZEDVERSION = "1.0";
/* Don't accept query responses with this version or higher. */
@Expose(serialize = false, deserialize = false)
private static final String FIRSTUNRECOGNIZEDVERSION = "2.0";
private static ObjectMapper objectMapper = new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
.setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
/** Version of this response format. */
@Expose
String version = VERSION;
/** Query IP address passed in the request; never <code>null</code>. */
@Expose
@SerializedName("query_address")
String queryAddress;
/** Query date passed in the request; never <code>null</code>. */
@Expose
@SerializedName("query_date")
String queryDate;
/** ISO-formatted valid-after time of the first status contained in the
* database; only <code>null</code> if the database is empty. */
@Expose
@SerializedName("first_date_in_database")
String firstDateInDatabase;
/** ISO-formatted valid-after time of the last status contained in the
* database; only <code>null</code> if the database is empty. */
@Expose
@SerializedName("last_date_in_database")
String lastDateInDatabase;
/** Whether there is at least one relevant status in the database on or within
* a day of the requested date; <code>null</code> if the database is empty. */
@Expose
@SerializedName("relevant_statuses")
Boolean relevantStatuses;
/** All matches for the given IP address and date; <code>null</code> if there
* were no matches at all. */
@Expose
Match[] matches;
/** Constructor for Gson. */
......@@ -85,16 +77,16 @@ public class QueryResponse {
}
/** Return JSON string for given QueryResponse. */
public static String toJson(QueryResponse response) {
return new Gson().toJson(response);
public static String toJson(QueryResponse response) throws IOException {
return objectMapper.writeValueAsString(response);
}
/** Return QueryResponse parsed from the given input stream, or
* {@code null} if something fails or an unrecognized version is found. */
public static QueryResponse fromJson(Reader reader) {
Gson gson = new Gson();
try {
QueryResponse response = gson.fromJson(reader, QueryResponse.class);
QueryResponse response = objectMapper.readValue(reader,
QueryResponse.class);
if (null == response || null == response.version) {
logger.warn("Response is either empty or does not contain "
+ "version information.");
......@@ -107,7 +99,10 @@ public class QueryResponse {
return null;
}
return response;
} catch (RuntimeException e) {
} catch (IOException | RuntimeException e) {
/* We're catching RuntimeException here, rather than IOException, so that
* we return null if anything goes wrong, including cases that we did not
* anticipate. */
logger.error("JSON decoding failed.", e);
}
return null;
......@@ -148,8 +143,6 @@ public class QueryResponse {
/** All known IP addresses in the same /24 or /48 network; <code>null</code>
* if there were direct matches for the given IP address. */
@Expose
@SerializedName("nearby_addresses")
String[] nearbyAddresses;
}
......@@ -11,6 +11,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.io.IOException;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Collection;
......@@ -103,7 +104,7 @@ public class QueryResponseTest {
}
@Test
public void testJsonReading() {
public void testJsonReading() throws IOException {
if (null == this.queryResponse) {
assertNull(QueryResponse.fromJson(new StringReader(this.json)));
} else {
......@@ -113,7 +114,7 @@ public class QueryResponseTest {
}
@Test
public void testJsonWriting() {
public void testJsonWriting() throws IOException {
if (null == this.queryResponse) {
return;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment