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); }