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

Replace Gson with Jackson.

Implements #26163.
parent 84b07361
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
# Changes in version 2.0.3 - 2018-0?-??

 * Medium changes
   - Replace Gson with Jackson.

 * Minor changes
   - Remove duplicate [] surrounding suggested IPv6 addresses.

+4 −2
Original line number Diff line number Diff line
@@ -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"/>
+20 −27
Original line number Diff line number Diff line
@@ -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;
}
+3 −2
Original line number Diff line number Diff line
@@ -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;
    }