Rework messages API to fail if you miss some deviceIds per number

This commit is contained in:
Matt Corallo
2014-01-09 15:20:06 -10:00
parent 918ef4a7ca
commit 8c74ad073b
6 changed files with 183 additions and 66 deletions

View File

@@ -27,6 +27,7 @@ import org.whispersystems.textsecuregcm.entities.AttachmentUri;
import org.whispersystems.textsecuregcm.entities.ClientContact;
import org.whispersystems.textsecuregcm.entities.ClientContacts;
import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal;
import org.whispersystems.textsecuregcm.entities.MessageResponse;
import org.whispersystems.textsecuregcm.entities.RelayMessage;
import org.whispersystems.textsecuregcm.entities.UnstructuredPreKeyList;
import org.whispersystems.textsecuregcm.federation.FederatedPeer;
@@ -34,9 +35,11 @@ import org.whispersystems.textsecuregcm.push.PushSender;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Keys;
import org.whispersystems.textsecuregcm.util.Pair;
import org.whispersystems.textsecuregcm.util.UrlSigner;
import org.whispersystems.textsecuregcm.util.Util;
import javax.print.attribute.standard.Media;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -49,8 +52,12 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Path("/v1/federation")
public class FederationController {
@@ -102,22 +109,49 @@ public class FederationController {
@PUT
@Path("/message")
@Consumes(MediaType.APPLICATION_JSON)
public void relayMessage(@Auth FederatedPeer peer, @Valid RelayMessage message)
@Produces(MediaType.APPLICATION_JSON)
public MessageResponse relayMessage(@Auth FederatedPeer peer, @Valid List<RelayMessage> messages)
throws IOException
{
try {
OutgoingMessageSignal signal = OutgoingMessageSignal.parseFrom(message.getOutgoingMessageSignal())
.toBuilder()
.setRelay(peer.getName())
.build();
Map<String, Pair<Boolean, Set<Long>>> destinations = new HashMap<>();
pushSender.sendMessage(message.getDestination(), message.getDestinationDeviceId(), signal);
for (RelayMessage message : messages) {
Pair<Boolean, Set<Long>> deviceIds = destinations.get(message.getDestination());
if (deviceIds == null) {
deviceIds = new Pair<Boolean, Set<Long>>(true, new HashSet<Long>());
destinations.put(message.getDestination(), deviceIds);
}
deviceIds.second().add(message.getDestinationDeviceId());
}
Map<Pair<String, Long>, Account> accountCache = new HashMap<>();
List<String> numbersMissingDevices = new LinkedList<>();
pushSender.fillLocalAccountsCache(destinations, accountCache, numbersMissingDevices);
List<String> success = new LinkedList<>();
List<String> failure = new LinkedList<>(numbersMissingDevices);
for (RelayMessage message : messages) {
Account account = accountCache.get(new Pair<>(message.getDestination(), message.getDestinationDeviceId()));
if (account == null)
continue;
OutgoingMessageSignal signal = OutgoingMessageSignal.parseFrom(message.getOutgoingMessageSignal())
.toBuilder()
.setRelay(peer.getName())
.build();
try {
pushSender.sendMessage(account, signal);
} catch (NoSuchUserException e) {
logger.info("No such user", e);
failure.add(message.getDestination());
}
}
return new MessageResponse(success, failure, numbersMissingDevices);
} catch (InvalidProtocolBufferException ipe) {
logger.warn("ProtoBuf", ipe);
throw new WebApplicationException(Response.status(400).build());
} catch (NoSuchUserException e) {
logger.debug("No User", e);
throw new WebApplicationException(Response.status(404).build());
}
}