diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java
index 956193706..aeb44d866 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java
@@ -104,7 +104,7 @@ import org.whispersystems.textsecuregcm.push.ApnFallbackManager;
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
import org.whispersystems.textsecuregcm.push.GCMSender;
import org.whispersystems.textsecuregcm.push.ProvisioningManager;
-import org.whispersystems.textsecuregcm.push.PushSender;
+import org.whispersystems.textsecuregcm.push.MessageSender;
import org.whispersystems.textsecuregcm.push.ReceiptSender;
import org.whispersystems.textsecuregcm.recaptcha.RecaptchaClient;
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
@@ -329,8 +329,8 @@ public class WhisperServerService extends Application
+ * If a client is not actively connected to a Signal server to receive a message as soon as it is sent, the
+ * MessageSender will send a push notification to the destination device if possible. Some messages may be designated
+ * for "online" delivery only and will not be delivered (and clients will not be notified) if the destination device
+ * isn't actively connected to a Signal server.
+ *
+ * @see ClientPresenceManager
+ * @see org.whispersystems.textsecuregcm.storage.MessageAvailabilityListener
+ * @see ReceiptSender
+ */
+public class MessageSender implements Managed {
private final ApnFallbackManager apnFallbackManager;
private final ClientPresenceManager clientPresenceManager;
@@ -50,18 +63,18 @@ public class PushSender implements Managed {
private final int queueSize;
private final PushLatencyManager pushLatencyManager;
- private static final String SEND_COUNTER_NAME = name(PushSender.class, "sendMessage");
+ private static final String SEND_COUNTER_NAME = name(MessageSender.class, "sendMessage");
private static final String CHANNEL_TAG_NAME = "channel";
private static final String EPHEMERAL_TAG_NAME = "ephemeral";
private static final String CLIENT_ONLINE_TAG_NAME = "clientOnline";
- public PushSender(ApnFallbackManager apnFallbackManager,
- ClientPresenceManager clientPresenceManager,
- MessagesManager messagesManager,
- GCMSender gcmSender,
- APNSender apnSender,
- int queueSize,
- PushLatencyManager pushLatencyManager)
+ public MessageSender(ApnFallbackManager apnFallbackManager,
+ ClientPresenceManager clientPresenceManager,
+ MessagesManager messagesManager,
+ GCMSender gcmSender,
+ APNSender apnSender,
+ int queueSize,
+ PushLatencyManager pushLatencyManager)
{
this(apnFallbackManager,
clientPresenceManager,
@@ -73,19 +86,19 @@ public class PushSender implements Managed {
pushLatencyManager);
SharedMetricRegistries.getOrCreate(Constants.METRICS_NAME)
- .register(name(PushSender.class, "send_queue_depth"),
+ .register(name(MessageSender.class, "send_queue_depth"),
(Gauge) ((BlockingThreadPoolExecutor)executor)::getSize);
}
@VisibleForTesting
- PushSender(ApnFallbackManager apnFallbackManager,
- ClientPresenceManager clientPresenceManager,
- MessagesManager messagesManager,
- GCMSender gcmSender,
- APNSender apnSender,
- int queueSize,
- ExecutorService executor,
- PushLatencyManager pushLatencyManager) {
+ MessageSender(ApnFallbackManager apnFallbackManager,
+ ClientPresenceManager clientPresenceManager,
+ MessagesManager messagesManager,
+ GCMSender gcmSender,
+ APNSender apnSender,
+ int queueSize,
+ ExecutorService executor,
+ PushLatencyManager pushLatencyManager) {
this.apnFallbackManager = apnFallbackManager;
this.clientPresenceManager = clientPresenceManager;
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java b/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java
index 5c43cc3ce..3e7d6d8c5 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java
@@ -12,16 +12,16 @@ import java.util.Optional;
public class ReceiptSender {
- private final PushSender pushSender;
- private final AccountsManager accountManager;
+ private final MessageSender messageSender;
+ private final AccountsManager accountManager;
- private static final Logger logger = LoggerFactory.getLogger(ReceiptSender.class);
+ private static final Logger logger = LoggerFactory.getLogger(ReceiptSender.class);
public ReceiptSender(AccountsManager accountManager,
- PushSender pushSender)
+ MessageSender messageSender)
{
this.accountManager = accountManager;
- this.pushSender = pushSender;
+ this.messageSender = messageSender;
}
public void sendReceipt(Account source, String destination, long messageId)
@@ -45,7 +45,7 @@ public class ReceiptSender {
for (final Device destinationDevice : destinationAccount.getDevices()) {
try {
- pushSender.sendMessage(destinationAccount, destinationDevice, message.build(), false);
+ messageSender.sendMessage(destinationAccount, destinationDevice, message.build(), false);
} catch (NotPushRegisteredException e) {
logger.info("User no longer push registered for delivery receipt: " + e.getMessage());
}
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/redis/RedisOperation.java b/service/src/main/java/org/whispersystems/textsecuregcm/redis/RedisOperation.java
index 47f6255a8..def49dc5d 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/redis/RedisOperation.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/redis/RedisOperation.java
@@ -2,7 +2,6 @@ package org.whispersystems.textsecuregcm.redis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.whispersystems.textsecuregcm.push.PushSender;
public class RedisOperation {
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java b/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java
index e8bef3947..7d5d021bc 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java
@@ -6,10 +6,8 @@ import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.SharedMetricRegistries;
import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.ByteString;
-import com.google.protobuf.InvalidProtocolBufferException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.whispersystems.dispatch.DispatchChannel;
import org.whispersystems.textsecuregcm.controllers.MessageController;
import org.whispersystems.textsecuregcm.controllers.NoSuchUserException;
import org.whispersystems.textsecuregcm.entities.CryptoEncodingException;
@@ -17,8 +15,6 @@ import org.whispersystems.textsecuregcm.entities.EncryptedOutgoingMessage;
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity;
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntityList;
import org.whispersystems.textsecuregcm.push.DisplacedPresenceListener;
-import org.whispersystems.textsecuregcm.push.NotPushRegisteredException;
-import org.whispersystems.textsecuregcm.push.PushSender;
import org.whispersystems.textsecuregcm.push.ReceiptSender;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.Device;
@@ -41,7 +37,6 @@ import java.util.concurrent.atomic.AtomicReference;
import static com.codahale.metrics.MetricRegistry.name;
import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
-import static org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public class WebSocketConnection implements MessageAvailabilityListener, DisplacedPresenceListener {
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/push/PushSenderTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/push/MessageSenderTest.java
similarity index 82%
rename from service/src/test/java/org/whispersystems/textsecuregcm/push/PushSenderTest.java
rename to service/src/test/java/org/whispersystems/textsecuregcm/push/MessageSenderTest.java
index 1a8d4f58e..be452172d 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/push/PushSenderTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/push/MessageSenderTest.java
@@ -21,7 +21,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
-public class PushSenderTest {
+public class MessageSenderTest {
private Account account;
private Device device;
@@ -31,7 +31,7 @@ public class PushSenderTest {
private MessagesManager messagesManager;
private GCMSender gcmSender;
private APNSender apnSender;
- private PushSender pushSender;
+ private MessageSender messageSender;
private static final UUID ACCOUNT_UUID = UUID.randomUUID();
private static final long DEVICE_ID = 1L;
@@ -47,14 +47,14 @@ public class PushSenderTest {
messagesManager = mock(MessagesManager.class);
gcmSender = mock(GCMSender.class);
apnSender = mock(APNSender.class);
- pushSender = new PushSender(mock(ApnFallbackManager.class),
- clientPresenceManager,
- messagesManager,
- gcmSender,
- apnSender,
- 0,
- mock(ExecutorService.class),
- mock(PushLatencyManager.class));
+ messageSender = new MessageSender(mock(ApnFallbackManager.class),
+ clientPresenceManager,
+ messagesManager,
+ gcmSender,
+ apnSender,
+ 0,
+ mock(ExecutorService.class),
+ mock(PushLatencyManager.class));
when(account.getUuid()).thenReturn(ACCOUNT_UUID);
when(device.getId()).thenReturn(DEVICE_ID);
@@ -65,7 +65,7 @@ public class PushSenderTest {
when(clientPresenceManager.isPresent(ACCOUNT_UUID, DEVICE_ID)).thenReturn(true);
when(device.getGcmId()).thenReturn("gcm-id");
- pushSender.sendSynchronousMessage(account, device, message, true);
+ messageSender.sendSynchronousMessage(account, device, message, true);
verify(messagesManager).insertEphemeral(ACCOUNT_UUID, DEVICE_ID, message);
verify(messagesManager, never()).insert(any(), anyLong(), any());
@@ -78,7 +78,7 @@ public class PushSenderTest {
when(clientPresenceManager.isPresent(ACCOUNT_UUID, DEVICE_ID)).thenReturn(false);
when(device.getGcmId()).thenReturn("gcm-id");
- pushSender.sendSynchronousMessage(account, device, message, true);
+ messageSender.sendSynchronousMessage(account, device, message, true);
verify(messagesManager, never()).insertEphemeral(any(), anyLong(), any());
verify(messagesManager, never()).insert(any(), anyLong(), any());
@@ -91,7 +91,7 @@ public class PushSenderTest {
when(clientPresenceManager.isPresent(ACCOUNT_UUID, DEVICE_ID)).thenReturn(true);
when(device.getGcmId()).thenReturn("gcm-id");
- pushSender.sendSynchronousMessage(account, device, message, false);
+ messageSender.sendSynchronousMessage(account, device, message, false);
verify(messagesManager, never()).insertEphemeral(any(), anyLong(), any());
verify(messagesManager).insert(ACCOUNT_UUID, DEVICE_ID, message);
@@ -104,7 +104,7 @@ public class PushSenderTest {
when(clientPresenceManager.isPresent(ACCOUNT_UUID, DEVICE_ID)).thenReturn(false);
when(device.getGcmId()).thenReturn("gcm-id");
- pushSender.sendSynchronousMessage(account, device, message, false);
+ messageSender.sendSynchronousMessage(account, device, message, false);
verify(messagesManager, never()).insertEphemeral(any(), anyLong(), any());
verify(messagesManager).insert(ACCOUNT_UUID, DEVICE_ID, message);
@@ -117,7 +117,7 @@ public class PushSenderTest {
when(clientPresenceManager.isPresent(ACCOUNT_UUID, DEVICE_ID)).thenReturn(false);
when(device.getApnId()).thenReturn("apn-id");
- pushSender.sendSynchronousMessage(account, device, message, false);
+ messageSender.sendSynchronousMessage(account, device, message, false);
verify(messagesManager, never()).insertEphemeral(any(), anyLong(), any());
verify(messagesManager).insert(ACCOUNT_UUID, DEVICE_ID, message);
@@ -130,7 +130,7 @@ public class PushSenderTest {
when(clientPresenceManager.isPresent(ACCOUNT_UUID, DEVICE_ID)).thenReturn(false);
when(device.getFetchesMessages()).thenReturn(true);
- pushSender.sendSynchronousMessage(account, device, message, false);
+ messageSender.sendSynchronousMessage(account, device, message, false);
verify(messagesManager, never()).insertEphemeral(any(), anyLong(), any());
verify(messagesManager).insert(ACCOUNT_UUID, DEVICE_ID, message);
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java
index 6ee696532..cd9f5f2e0 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java
@@ -22,7 +22,7 @@ import org.whispersystems.textsecuregcm.entities.StaleDevices;
import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.push.ApnFallbackManager;
-import org.whispersystems.textsecuregcm.push.PushSender;
+import org.whispersystems.textsecuregcm.push.MessageSender;
import org.whispersystems.textsecuregcm.push.ReceiptSender;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
@@ -62,12 +62,12 @@ public class MessageControllerTest {
private static final String MULTI_DEVICE_RECIPIENT = "+14152222222";
private static final UUID MULTI_DEVICE_UUID = UUID.randomUUID();
- private final PushSender pushSender = mock(PushSender.class );
+ private final MessageSender messageSender = mock(MessageSender.class);
private final ReceiptSender receiptSender = mock(ReceiptSender.class);
- private final AccountsManager accountsManager = mock(AccountsManager.class );
+ private final AccountsManager accountsManager = mock(AccountsManager.class);
private final MessagesManager messagesManager = mock(MessagesManager.class);
- private final RateLimiters rateLimiters = mock(RateLimiters.class );
- private final RateLimiter rateLimiter = mock(RateLimiter.class );
+ private final RateLimiters rateLimiters = mock(RateLimiters.class);
+ private final RateLimiter rateLimiter = mock(RateLimiter.class);
private final ApnFallbackManager apnFallbackManager = mock(ApnFallbackManager.class);
private final ObjectMapper mapper = new ObjectMapper();
@@ -77,7 +77,7 @@ public class MessageControllerTest {
.addProvider(AuthHelper.getAuthFilter())
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
- .addResource(new MessageController(rateLimiters, pushSender, receiptSender, accountsManager,
+ .addResource(new MessageController(rateLimiters, messageSender, receiptSender, accountsManager,
messagesManager, apnFallbackManager))
.build();
@@ -131,7 +131,7 @@ public class MessageControllerTest {
assertThat("Good Response", response.getStatus(), is(equalTo(200)));
ArgumentCaptor captor = ArgumentCaptor.forClass(Envelope.class);
- verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture(), eq(false));
+ verify(messageSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture(), eq(false));
assertTrue(captor.getValue().hasSource());
assertTrue(captor.getValue().hasSourceDevice());
@@ -150,7 +150,7 @@ public class MessageControllerTest {
assertThat("Good Response", response.getStatus(), is(equalTo(200)));
ArgumentCaptor captor = ArgumentCaptor.forClass(Envelope.class);
- verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture(), eq(false));
+ verify(messageSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture(), eq(false));
assertFalse(captor.getValue().hasSource());
assertFalse(captor.getValue().hasSourceDevice());
@@ -185,7 +185,7 @@ public class MessageControllerTest {
asJson(response.readEntity(MismatchedDevices.class)),
is(equalTo(jsonFixture("fixtures/missing_device_response.json"))));
- verifyNoMoreInteractions(pushSender);
+ verifyNoMoreInteractions(messageSender);
}
@Test
@@ -204,7 +204,7 @@ public class MessageControllerTest {
asJson(response.readEntity(MismatchedDevices.class)),
is(equalTo(jsonFixture("fixtures/missing_device_response2.json"))));
- verifyNoMoreInteractions(pushSender);
+ verifyNoMoreInteractions(messageSender);
}
@Test
@@ -219,7 +219,7 @@ public class MessageControllerTest {
assertThat("Good Response Code", response.getStatus(), is(equalTo(200)));
- verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class), eq(false));
+ verify(messageSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class), eq(false));
}
@Test
@@ -237,7 +237,7 @@ public class MessageControllerTest {
asJson(response.readEntity(StaleDevices.class)),
is(equalTo(jsonFixture("fixtures/mismatched_registration_id.json"))));
- verifyNoMoreInteractions(pushSender);
+ verifyNoMoreInteractions(messageSender);
}