diff --git a/pom.xml b/pom.xml
index 32e4a7a96..3523a6c81 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,11 +91,6 @@
gcm-server
1.0.2
-
- com.google.code.gson
- gson
- 2.2.2
-
net.spy
spymemcached
diff --git a/src/main/java/org/whispersystems/textsecuregcm/configuration/FederationConfiguration.java b/src/main/java/org/whispersystems/textsecuregcm/configuration/FederationConfiguration.java
index c4f3484a6..6bc5ec802 100644
--- a/src/main/java/org/whispersystems/textsecuregcm/configuration/FederationConfiguration.java
+++ b/src/main/java/org/whispersystems/textsecuregcm/configuration/FederationConfiguration.java
@@ -18,12 +18,8 @@ package org.whispersystems.textsecuregcm.configuration;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
import org.whispersystems.textsecuregcm.federation.FederatedPeer;
-import java.util.LinkedList;
import java.util.List;
public class FederationConfiguration {
@@ -34,31 +30,7 @@ public class FederationConfiguration {
@JsonProperty
private String name;
- @JsonProperty
- private String herokuPeers;
-
public List getPeers() {
- if (peers != null) {
- return peers;
- }
-
- if (herokuPeers != null) {
- List peers = new LinkedList<>();
- JsonElement root = new JsonParser().parse(herokuPeers);
- JsonArray peerElements = root.getAsJsonArray();
-
- for (JsonElement peer : peerElements) {
- String name = peer.getAsJsonObject().get("name").getAsString();
- String url = peer.getAsJsonObject().get("url").getAsString();
- String authenticationToken = peer.getAsJsonObject().get("authenticationToken").getAsString();
- String certificate = peer.getAsJsonObject().get("certificate").getAsString();
-
- peers.add(new FederatedPeer(name, url, authenticationToken, certificate));
- }
-
- return peers;
- }
-
return peers;
}
diff --git a/src/main/java/org/whispersystems/textsecuregcm/entities/ClientContact.java b/src/main/java/org/whispersystems/textsecuregcm/entities/ClientContact.java
index 99ec3235c..14b2a5912 100644
--- a/src/main/java/org/whispersystems/textsecuregcm/entities/ClientContact.java
+++ b/src/main/java/org/whispersystems/textsecuregcm/entities/ClientContact.java
@@ -18,15 +18,10 @@ package org.whispersystems.textsecuregcm.entities;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.google.gson.Gson;
-import org.whispersystems.textsecuregcm.util.Base64;
import org.whispersystems.textsecuregcm.util.ByteArrayAdapter;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Arrays;
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@@ -73,9 +68,9 @@ public class ClientContact {
this.inactive = inactive;
}
- public String toString() {
- return new Gson().toJson(this);
- }
+// public String toString() {
+// return new Gson().toJson(this);
+// }
@Override
public boolean equals(Object other) {
diff --git a/src/main/java/org/whispersystems/textsecuregcm/storage/DirectoryManager.java b/src/main/java/org/whispersystems/textsecuregcm/storage/DirectoryManager.java
index baf30fee6..1c0c2f950 100644
--- a/src/main/java/org/whispersystems/textsecuregcm/storage/DirectoryManager.java
+++ b/src/main/java/org/whispersystems/textsecuregcm/storage/DirectoryManager.java
@@ -16,14 +16,19 @@
*/
package org.whispersystems.textsecuregcm.storage;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Optional;
-import com.google.gson.Gson;
-import com.google.gson.annotations.SerializedName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.entities.ClientContact;
import org.whispersystems.textsecuregcm.util.IterablePair;
import org.whispersystems.textsecuregcm.util.Pair;
import org.whispersystems.textsecuregcm.util.Util;
+import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
@@ -34,12 +39,17 @@ import redis.clients.jedis.Response;
public class DirectoryManager {
+ private final Logger logger = LoggerFactory.getLogger(DirectoryManager.class);
+
private static final byte[] DIRECTORY_KEY = {'d', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y'};
+ private final ObjectMapper objectMapper;
private final JedisPool redisPool;
public DirectoryManager(JedisPool redisPool) {
- this.redisPool = redisPool;
+ this.redisPool = redisPool;
+ this.objectMapper = new ObjectMapper();
+ this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
public void remove(String number) {
@@ -63,45 +73,48 @@ public class DirectoryManager {
public void add(ClientContact contact) {
TokenValue tokenValue = new TokenValue(contact.getRelay(), contact.isSupportsSms());
- Jedis jedis = redisPool.getResource();
- jedis.hset(DIRECTORY_KEY, contact.getToken(), new Gson().toJson(tokenValue).getBytes());
- redisPool.returnResource(jedis);
+ try (Jedis jedis = redisPool.getResource()) {
+ jedis.hset(DIRECTORY_KEY, contact.getToken(), objectMapper.writeValueAsBytes(tokenValue));
+ } catch (JsonProcessingException e) {
+ logger.warn("JSON Serialization", e);
+ }
}
public void add(BatchOperationHandle handle, ClientContact contact) {
- Pipeline pipeline = handle.pipeline;
- TokenValue tokenValue = new TokenValue(contact.getRelay(), contact.isSupportsSms());
+ try {
+ Pipeline pipeline = handle.pipeline;
+ TokenValue tokenValue = new TokenValue(contact.getRelay(), contact.isSupportsSms());
- pipeline.hset(DIRECTORY_KEY, contact.getToken(), new Gson().toJson(tokenValue).getBytes());
+ pipeline.hset(DIRECTORY_KEY, contact.getToken(), objectMapper.writeValueAsBytes(tokenValue));
+ } catch (JsonProcessingException e) {
+ logger.warn("JSON Serialization", e);
+ }
}
public PendingClientContact get(BatchOperationHandle handle, byte[] token) {
Pipeline pipeline = handle.pipeline;
- return new PendingClientContact(token, pipeline.hget(DIRECTORY_KEY, token));
+ return new PendingClientContact(objectMapper, token, pipeline.hget(DIRECTORY_KEY, token));
}
public Optional get(byte[] token) {
- Jedis jedis = redisPool.getResource();
-
- try {
+ try (Jedis jedis = redisPool.getResource()) {
byte[] result = jedis.hget(DIRECTORY_KEY, token);
if (result == null) {
return Optional.absent();
}
- TokenValue tokenValue = new Gson().fromJson(new String(result), TokenValue.class);
+ TokenValue tokenValue = objectMapper.readValue(result, TokenValue.class);
return Optional.of(new ClientContact(token, tokenValue.relay, tokenValue.supportsSms));
- } finally {
- redisPool.returnResource(jedis);
+ } catch (IOException e) {
+ logger.warn("JSON Error", e);
+ return Optional.absent();
}
}
public List get(List tokens) {
- Jedis jedis = redisPool.getResource();
-
- try {
+ try (Jedis jedis = redisPool.getResource()) {
Pipeline pipeline = jedis.pipelined();
List> futures = new LinkedList<>();
List results = new LinkedList<>();
@@ -117,17 +130,19 @@ public class DirectoryManager {
IterablePair> lists = new IterablePair<>(tokens, futures);
for (Pair> pair : lists) {
- if (pair.second().get() != null) {
- TokenValue tokenValue = new Gson().fromJson(new String(pair.second().get()), TokenValue.class);
- ClientContact clientContact = new ClientContact(pair.first(), tokenValue.relay, tokenValue.supportsSms);
+ try {
+ if (pair.second().get() != null) {
+ TokenValue tokenValue = objectMapper.readValue(pair.second().get(), TokenValue.class);
+ ClientContact clientContact = new ClientContact(pair.first(), tokenValue.relay, tokenValue.supportsSms);
- results.add(clientContact);
+ results.add(clientContact);
+ }
+ } catch (IOException e) {
+ logger.warn("Deserialization Problem: ", e);
}
}
return results;
- } finally {
- redisPool.returnResource(jedis);
}
}
@@ -156,10 +171,10 @@ public class DirectoryManager {
}
private static class TokenValue {
- @SerializedName("r")
+ @JsonProperty(value = "r")
private String relay;
- @SerializedName("s")
+ @JsonProperty(value = "s")
private boolean supportsSms;
public TokenValue(String relay, boolean supportsSms) {
@@ -169,22 +184,24 @@ public class DirectoryManager {
}
public static class PendingClientContact {
+ private final ObjectMapper objectMapper;
private final byte[] token;
private final Response response;
- PendingClientContact(byte[] token, Response response) {
- this.token = token;
- this.response = response;
+ PendingClientContact(ObjectMapper objectMapper, byte[] token, Response response) {
+ this.objectMapper = objectMapper;
+ this.token = token;
+ this.response = response;
}
- public Optional get() {
+ public Optional get() throws IOException {
byte[] result = response.get();
if (result == null) {
return Optional.absent();
}
- TokenValue tokenValue = new Gson().fromJson(new String(result), TokenValue.class);
+ TokenValue tokenValue = objectMapper.readValue(result, TokenValue.class);
return Optional.of(new ClientContact(token, tokenValue.relay, tokenValue.supportsSms));
}
diff --git a/src/main/java/org/whispersystems/textsecuregcm/workers/DirectoryUpdater.java b/src/main/java/org/whispersystems/textsecuregcm/workers/DirectoryUpdater.java
index 45b4ecd5c..2348e0500 100644
--- a/src/main/java/org/whispersystems/textsecuregcm/workers/DirectoryUpdater.java
+++ b/src/main/java/org/whispersystems/textsecuregcm/workers/DirectoryUpdater.java
@@ -29,6 +29,7 @@ import org.whispersystems.textsecuregcm.storage.DirectoryManager.BatchOperationH
import org.whispersystems.textsecuregcm.util.Base64;
import org.whispersystems.textsecuregcm.util.Util;
+import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -53,9 +54,12 @@ public class DirectoryUpdater {
}
public void updateFromLocalDatabase() {
- BatchOperationHandle batchOperation = directory.startBatchOperation();
+ int contactsAdded = 0;
+ int contactsRemoved = 0;
+ BatchOperationHandle batchOperation = directory.startBatchOperation();
try {
+ logger.info("Updating from local DB.");
Iterator accounts = accountsManager.getAll();
if (accounts == null)
@@ -69,17 +73,17 @@ public class DirectoryUpdater {
ClientContact clientContact = new ClientContact(token, null, account.getSupportsSms());
directory.add(batchOperation, clientContact);
-
- logger.debug("Adding local token: " + Base64.encodeBytesWithoutPadding(token));
+ contactsAdded++;
} else {
directory.remove(batchOperation, account.getNumber());
+ contactsRemoved++;
}
}
} finally {
directory.stopBatchOperation(batchOperation);
}
- logger.info("Local directory is updated.");
+ logger.info(String.format("Local directory is updated (%d added, %d removed).", contactsAdded, contactsRemoved));
}
public void updateFromPeers() {
@@ -121,19 +125,23 @@ public class DirectoryUpdater {
Iterator localContactIterator = localContacts.iterator();
while (remoteContactIterator.hasNext() && localContactIterator.hasNext()) {
- ClientContact remoteContact = remoteContactIterator.next();
- Optional localContact = localContactIterator.next().get();
+ try {
+ ClientContact remoteContact = remoteContactIterator.next();
+ Optional localContact = localContactIterator.next().get();
- remoteContact.setRelay(client.getPeerName());
+ remoteContact.setRelay(client.getPeerName());
- if (!remoteContact.isInactive() && (!localContact.isPresent() || client.getPeerName().equals(localContact.get().getRelay()))) {
- contactsAdded++;
- directory.add(handle, remoteContact);
- } else {
- if (localContact.isPresent() && client.getPeerName().equals(localContact.get().getRelay())) {
- contactsRemoved++;
- directory.remove(handle, remoteContact.getToken());
+ if (!remoteContact.isInactive() && (!localContact.isPresent() || client.getPeerName().equals(localContact.get().getRelay()))) {
+ contactsAdded++;
+ directory.add(handle, remoteContact);
+ } else {
+ if (localContact.isPresent() && client.getPeerName().equals(localContact.get().getRelay())) {
+ contactsRemoved++;
+ directory.remove(handle, remoteContact.getToken());
+ }
}
+ } catch (IOException e) {
+ logger.warn("JSON Serialization Failed: ", e);
}
}