Use `ClientReleasesManager` when deciding whether to add client version tags
This commit is contained in:
parent
6f4801fd6f
commit
4ead8527c8
|
@ -88,6 +88,8 @@ dynamoDbTables:
|
||||||
phoneNumberIdentifierTableName: Example_Accounts_PhoneNumberIdentifiers
|
phoneNumberIdentifierTableName: Example_Accounts_PhoneNumberIdentifiers
|
||||||
usernamesTableName: Example_Accounts_Usernames
|
usernamesTableName: Example_Accounts_Usernames
|
||||||
scanPageSize: 100
|
scanPageSize: 100
|
||||||
|
clientReleases:
|
||||||
|
tableName: Example_ClientReleases
|
||||||
deletedAccounts:
|
deletedAccounts:
|
||||||
tableName: Example_DeletedAccounts
|
tableName: Example_DeletedAccounts
|
||||||
deletedAccountsLock:
|
deletedAccountsLock:
|
||||||
|
|
|
@ -6,6 +6,7 @@ package org.whispersystems.textsecuregcm;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import io.dropwizard.Configuration;
|
import io.dropwizard.Configuration;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -24,6 +25,7 @@ import org.whispersystems.textsecuregcm.configuration.AwsAttachmentsConfiguratio
|
||||||
import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.BraintreeConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.BraintreeConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.CdnConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.CdnConfiguration;
|
||||||
|
import org.whispersystems.textsecuregcm.configuration.ClientReleaseConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.DatadogConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.DatadogConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.DirectoryV2Configuration;
|
import org.whispersystems.textsecuregcm.configuration.DirectoryV2Configuration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.DynamoDbClientConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.DynamoDbClientConfiguration;
|
||||||
|
@ -281,6 +283,11 @@ public class WhisperServerConfiguration extends Configuration {
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private int grpcPort;
|
private int grpcPort;
|
||||||
|
|
||||||
|
@Valid
|
||||||
|
@NotNull
|
||||||
|
@JsonProperty
|
||||||
|
private ClientReleaseConfiguration clientRelease = new ClientReleaseConfiguration(Duration.ofHours(4));
|
||||||
|
|
||||||
public AdminEventLoggingConfiguration getAdminEventLoggingConfiguration() {
|
public AdminEventLoggingConfiguration getAdminEventLoggingConfiguration() {
|
||||||
return adminEventLoggingConfiguration;
|
return adminEventLoggingConfiguration;
|
||||||
}
|
}
|
||||||
|
@ -468,4 +475,7 @@ public class WhisperServerConfiguration extends Configuration {
|
||||||
return grpcPort;
|
return grpcPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClientReleaseConfiguration getClientReleaseConfiguration() {
|
||||||
|
return clientRelease;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,6 +168,8 @@ import org.whispersystems.textsecuregcm.storage.AccountLockManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.Accounts;
|
import org.whispersystems.textsecuregcm.storage.Accounts;
|
||||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.ChangeNumberManager;
|
import org.whispersystems.textsecuregcm.storage.ChangeNumberManager;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleases;
|
||||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.IssuedReceiptsManager;
|
import org.whispersystems.textsecuregcm.storage.IssuedReceiptsManager;
|
||||||
|
@ -320,6 +322,8 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
config.getDynamoDbTables().getAccounts().getPhoneNumberIdentifierTableName(),
|
config.getDynamoDbTables().getAccounts().getPhoneNumberIdentifierTableName(),
|
||||||
config.getDynamoDbTables().getAccounts().getUsernamesTableName(),
|
config.getDynamoDbTables().getAccounts().getUsernamesTableName(),
|
||||||
config.getDynamoDbTables().getAccounts().getScanPageSize());
|
config.getDynamoDbTables().getAccounts().getScanPageSize());
|
||||||
|
ClientReleases clientReleases = new ClientReleases(dynamoDbAsyncClient,
|
||||||
|
config.getDynamoDbTables().getClientReleases().getTableName());
|
||||||
PhoneNumberIdentifiers phoneNumberIdentifiers = new PhoneNumberIdentifiers(dynamoDbClient,
|
PhoneNumberIdentifiers phoneNumberIdentifiers = new PhoneNumberIdentifiers(dynamoDbClient,
|
||||||
config.getDynamoDbTables().getPhoneNumberIdentifiers().getTableName());
|
config.getDynamoDbTables().getPhoneNumberIdentifiers().getTableName());
|
||||||
Profiles profiles = new Profiles(dynamoDbClient, dynamoDbAsyncClient,
|
Profiles profiles = new Profiles(dynamoDbClient, dynamoDbAsyncClient,
|
||||||
|
@ -499,7 +503,11 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
ProfilesManager profilesManager = new ProfilesManager(profiles, cacheCluster);
|
ProfilesManager profilesManager = new ProfilesManager(profiles, cacheCluster);
|
||||||
MessagesCache messagesCache = new MessagesCache(messagesCluster, messagesCluster,
|
MessagesCache messagesCache = new MessagesCache(messagesCluster, messagesCluster,
|
||||||
keyspaceNotificationDispatchExecutor, messageDeliveryScheduler, messageDeletionAsyncExecutor, clock);
|
keyspaceNotificationDispatchExecutor, messageDeliveryScheduler, messageDeletionAsyncExecutor, clock);
|
||||||
PushLatencyManager pushLatencyManager = new PushLatencyManager(metricsCluster, dynamicConfigurationManager);
|
ClientReleaseManager clientReleaseManager = new ClientReleaseManager(clientReleases,
|
||||||
|
recurringJobExecutor,
|
||||||
|
config.getClientReleaseConfiguration().refreshInterval(),
|
||||||
|
Clock.systemUTC());
|
||||||
|
PushLatencyManager pushLatencyManager = new PushLatencyManager(metricsCluster, clientReleaseManager);
|
||||||
ReportMessageManager reportMessageManager = new ReportMessageManager(reportMessageDynamoDb, rateLimitersCluster,
|
ReportMessageManager reportMessageManager = new ReportMessageManager(reportMessageDynamoDb, rateLimitersCluster,
|
||||||
config.getReportMessageConfiguration().getCounterTtl());
|
config.getReportMessageConfiguration().getCounterTtl());
|
||||||
MessagesManager messagesManager = new MessagesManager(messagesDynamoDb, messagesCache, reportMessageManager,
|
MessagesManager messagesManager = new MessagesManager(messagesDynamoDb, messagesCache, reportMessageManager,
|
||||||
|
@ -587,6 +595,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
environment.lifecycle().manage(clientPresenceManager);
|
environment.lifecycle().manage(clientPresenceManager);
|
||||||
environment.lifecycle().manage(currencyManager);
|
environment.lifecycle().manage(currencyManager);
|
||||||
environment.lifecycle().manage(registrationServiceClient);
|
environment.lifecycle().manage(registrationServiceClient);
|
||||||
|
environment.lifecycle().manage(clientReleaseManager);
|
||||||
|
|
||||||
final RegistrationCaptchaManager registrationCaptchaManager = new RegistrationCaptchaManager(captchaChecker,
|
final RegistrationCaptchaManager registrationCaptchaManager = new RegistrationCaptchaManager(captchaChecker,
|
||||||
rateLimiters, config.getTestDevices(), dynamicConfigurationManager);
|
rateLimiters, config.getTestDevices(), dynamicConfigurationManager);
|
||||||
|
@ -662,7 +671,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
webSocketEnvironment.setAuthenticator(new WebSocketAccountAuthenticator(accountAuthenticator));
|
webSocketEnvironment.setAuthenticator(new WebSocketAccountAuthenticator(accountAuthenticator));
|
||||||
webSocketEnvironment.setConnectListener(
|
webSocketEnvironment.setConnectListener(
|
||||||
new AuthenticatedConnectListener(receiptSender, messagesManager, pushNotificationManager,
|
new AuthenticatedConnectListener(receiptSender, messagesManager, pushNotificationManager,
|
||||||
clientPresenceManager, websocketScheduledExecutor, messageDeliveryScheduler, dynamicConfigurationManager));
|
clientPresenceManager, websocketScheduledExecutor, messageDeliveryScheduler, clientReleaseManager));
|
||||||
webSocketEnvironment.jersey()
|
webSocketEnvironment.jersey()
|
||||||
.register(new WebsocketRefreshApplicationEventListener(accountsManager, clientPresenceManager));
|
.register(new WebsocketRefreshApplicationEventListener(accountsManager, clientPresenceManager));
|
||||||
webSocketEnvironment.jersey().register(new RequestStatisticsFilter(TrafficSource.WEBSOCKET));
|
webSocketEnvironment.jersey().register(new RequestStatisticsFilter(TrafficSource.WEBSOCKET));
|
||||||
|
@ -740,7 +749,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
ReceiptCredentialPresentation::new),
|
ReceiptCredentialPresentation::new),
|
||||||
new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, deletedAccounts,
|
new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, deletedAccounts,
|
||||||
messagesManager, pushNotificationManager, reportMessageManager, multiRecipientMessageExecutor,
|
messagesManager, pushNotificationManager, reportMessageManager, multiRecipientMessageExecutor,
|
||||||
messageDeliveryScheduler, reportSpamTokenProvider, dynamicConfigurationManager),
|
messageDeliveryScheduler, reportSpamTokenProvider, clientReleaseManager, dynamicConfigurationManager),
|
||||||
new PaymentsController(currencyManager, paymentsCredentialsGenerator),
|
new PaymentsController(currencyManager, paymentsCredentialsGenerator),
|
||||||
new ProfileController(clock, rateLimiters, accountsManager, profilesManager, dynamicConfigurationManager,
|
new ProfileController(clock, rateLimiters, accountsManager, profilesManager, dynamicConfigurationManager,
|
||||||
profileBadgeConverter, config.getBadges(), cdnS3Client, profileCdnPolicyGenerator, profileCdnPolicySigner,
|
profileBadgeConverter, config.getBadges(), cdnS3Client, profileCdnPolicyGenerator, profileCdnPolicySigner,
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.whispersystems.textsecuregcm.configuration;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
public record ClientReleaseConfiguration(@NotNull Duration refreshInterval) {
|
||||||
|
}
|
|
@ -47,6 +47,7 @@ public class DynamoDbTables {
|
||||||
}
|
}
|
||||||
|
|
||||||
private final AccountsTableConfiguration accounts;
|
private final AccountsTableConfiguration accounts;
|
||||||
|
private final Table clientReleases;
|
||||||
private final Table deletedAccounts;
|
private final Table deletedAccounts;
|
||||||
private final Table deletedAccountsLock;
|
private final Table deletedAccountsLock;
|
||||||
private final IssuedReceiptsTableConfiguration issuedReceipts;
|
private final IssuedReceiptsTableConfiguration issuedReceipts;
|
||||||
|
@ -69,6 +70,7 @@ public class DynamoDbTables {
|
||||||
|
|
||||||
public DynamoDbTables(
|
public DynamoDbTables(
|
||||||
@JsonProperty("accounts") final AccountsTableConfiguration accounts,
|
@JsonProperty("accounts") final AccountsTableConfiguration accounts,
|
||||||
|
@JsonProperty("clientReleases") final Table clientReleases,
|
||||||
@JsonProperty("deletedAccounts") final Table deletedAccounts,
|
@JsonProperty("deletedAccounts") final Table deletedAccounts,
|
||||||
@JsonProperty("deletedAccountsLock") final Table deletedAccountsLock,
|
@JsonProperty("deletedAccountsLock") final Table deletedAccountsLock,
|
||||||
@JsonProperty("issuedReceipts") final IssuedReceiptsTableConfiguration issuedReceipts,
|
@JsonProperty("issuedReceipts") final IssuedReceiptsTableConfiguration issuedReceipts,
|
||||||
|
@ -90,6 +92,7 @@ public class DynamoDbTables {
|
||||||
@JsonProperty("verificationSessions") final Table verificationSessions) {
|
@JsonProperty("verificationSessions") final Table verificationSessions) {
|
||||||
|
|
||||||
this.accounts = accounts;
|
this.accounts = accounts;
|
||||||
|
this.clientReleases = clientReleases;
|
||||||
this.deletedAccounts = deletedAccounts;
|
this.deletedAccounts = deletedAccounts;
|
||||||
this.deletedAccountsLock = deletedAccountsLock;
|
this.deletedAccountsLock = deletedAccountsLock;
|
||||||
this.issuedReceipts = issuedReceipts;
|
this.issuedReceipts = issuedReceipts;
|
||||||
|
@ -117,6 +120,12 @@ public class DynamoDbTables {
|
||||||
return accounts;
|
return accounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Valid
|
||||||
|
public Table getClientReleases() {
|
||||||
|
return clientReleases;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Valid
|
@Valid
|
||||||
public Table getDeletedAccounts() {
|
public Table getDeletedAccounts() {
|
||||||
|
|
|
@ -39,10 +39,6 @@ public class DynamicConfiguration {
|
||||||
@Valid
|
@Valid
|
||||||
private DynamicCaptchaConfiguration captcha = new DynamicCaptchaConfiguration();
|
private DynamicCaptchaConfiguration captcha = new DynamicCaptchaConfiguration();
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
@Valid
|
|
||||||
private DynamicPushLatencyConfiguration pushLatency = new DynamicPushLatencyConfiguration(Collections.emptyMap());
|
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@Valid
|
@Valid
|
||||||
private DynamicTurnConfiguration turn = new DynamicTurnConfiguration();
|
private DynamicTurnConfiguration turn = new DynamicTurnConfiguration();
|
||||||
|
@ -59,10 +55,6 @@ public class DynamicConfiguration {
|
||||||
@Valid
|
@Valid
|
||||||
DynamicECPreKeyMigrationConfiguration ecPreKeyMigration = new DynamicECPreKeyMigrationConfiguration(true, false);
|
DynamicECPreKeyMigrationConfiguration ecPreKeyMigration = new DynamicECPreKeyMigrationConfiguration(true, false);
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
@Valid
|
|
||||||
DynamicDeliveryLatencyConfiguration deliveryLatency = new DynamicDeliveryLatencyConfiguration(Collections.emptyMap());
|
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@Valid
|
@Valid
|
||||||
DynamicInboundMessageByteLimitConfiguration inboundMessageByteLimit = new DynamicInboundMessageByteLimitConfiguration(true);
|
DynamicInboundMessageByteLimitConfiguration inboundMessageByteLimit = new DynamicInboundMessageByteLimitConfiguration(true);
|
||||||
|
@ -93,10 +85,6 @@ public class DynamicConfiguration {
|
||||||
return captcha;
|
return captcha;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicPushLatencyConfiguration getPushLatencyConfiguration() {
|
|
||||||
return pushLatency;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynamicTurnConfiguration getTurnConfiguration() {
|
public DynamicTurnConfiguration getTurnConfiguration() {
|
||||||
return turn;
|
return turn;
|
||||||
}
|
}
|
||||||
|
@ -113,10 +101,6 @@ public class DynamicConfiguration {
|
||||||
return ecPreKeyMigration;
|
return ecPreKeyMigration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicDeliveryLatencyConfiguration getDeliveryLatencyConfiguration() {
|
|
||||||
return deliveryLatency;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynamicInboundMessageByteLimitConfiguration getInboundMessageByteLimitConfiguration() {
|
public DynamicInboundMessageByteLimitConfiguration getInboundMessageByteLimitConfiguration() {
|
||||||
return inboundMessageByteLimit;
|
return inboundMessageByteLimit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2023 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.configuration.dynamic;
|
|
||||||
|
|
||||||
import com.vdurmont.semver4j.Semver;
|
|
||||||
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public record DynamicDeliveryLatencyConfiguration(Map<ClientPlatform, Set<Semver>> instrumentedVersions) {
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2013-2021 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.configuration.dynamic;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.vdurmont.semver4j.Semver;
|
|
||||||
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public record DynamicPushLatencyConfiguration(Map<ClientPlatform, Set<Semver>> instrumentedVersions) {
|
|
||||||
}
|
|
|
@ -97,6 +97,7 @@ import org.whispersystems.textsecuregcm.spam.FilterSpam;
|
||||||
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenProvider;
|
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenProvider;
|
||||||
import org.whispersystems.textsecuregcm.storage.Account;
|
import org.whispersystems.textsecuregcm.storage.Account;
|
||||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||||
import org.whispersystems.textsecuregcm.storage.Device;
|
import org.whispersystems.textsecuregcm.storage.Device;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||||
|
@ -127,6 +128,7 @@ public class MessageController {
|
||||||
private final ExecutorService multiRecipientMessageExecutor;
|
private final ExecutorService multiRecipientMessageExecutor;
|
||||||
private final Scheduler messageDeliveryScheduler;
|
private final Scheduler messageDeliveryScheduler;
|
||||||
private final ReportSpamTokenProvider reportSpamTokenProvider;
|
private final ReportSpamTokenProvider reportSpamTokenProvider;
|
||||||
|
private final ClientReleaseManager clientReleaseManager;
|
||||||
private final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
|
private final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
|
||||||
|
|
||||||
private static final String REJECT_OVERSIZE_MESSAGE_COUNTER = name(MessageController.class, "rejectOversizeMessage");
|
private static final String REJECT_OVERSIZE_MESSAGE_COUNTER = name(MessageController.class, "rejectOversizeMessage");
|
||||||
|
@ -161,6 +163,7 @@ public class MessageController {
|
||||||
@Nonnull ExecutorService multiRecipientMessageExecutor,
|
@Nonnull ExecutorService multiRecipientMessageExecutor,
|
||||||
Scheduler messageDeliveryScheduler,
|
Scheduler messageDeliveryScheduler,
|
||||||
@Nonnull ReportSpamTokenProvider reportSpamTokenProvider,
|
@Nonnull ReportSpamTokenProvider reportSpamTokenProvider,
|
||||||
|
final ClientReleaseManager clientReleaseManager,
|
||||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager) {
|
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager) {
|
||||||
this.rateLimiters = rateLimiters;
|
this.rateLimiters = rateLimiters;
|
||||||
this.messageSender = messageSender;
|
this.messageSender = messageSender;
|
||||||
|
@ -173,6 +176,7 @@ public class MessageController {
|
||||||
this.multiRecipientMessageExecutor = Objects.requireNonNull(multiRecipientMessageExecutor);
|
this.multiRecipientMessageExecutor = Objects.requireNonNull(multiRecipientMessageExecutor);
|
||||||
this.messageDeliveryScheduler = messageDeliveryScheduler;
|
this.messageDeliveryScheduler = messageDeliveryScheduler;
|
||||||
this.reportSpamTokenProvider = reportSpamTokenProvider;
|
this.reportSpamTokenProvider = reportSpamTokenProvider;
|
||||||
|
this.clientReleaseManager = clientReleaseManager;
|
||||||
this.dynamicConfigurationManager = dynamicConfigurationManager;
|
this.dynamicConfigurationManager = dynamicConfigurationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,8 +547,7 @@ public class MessageController {
|
||||||
.map(OutgoingMessageEntity::fromEnvelope)
|
.map(OutgoingMessageEntity::fromEnvelope)
|
||||||
.peek(outgoingMessageEntity -> {
|
.peek(outgoingMessageEntity -> {
|
||||||
MessageMetrics.measureAccountOutgoingMessageUuidMismatches(auth.getAccount(), outgoingMessageEntity);
|
MessageMetrics.measureAccountOutgoingMessageUuidMismatches(auth.getAccount(), outgoingMessageEntity);
|
||||||
MessageMetrics.measureOutgoingMessageLatency(outgoingMessageEntity.serverTimestamp(), "rest", userAgent,
|
MessageMetrics.measureOutgoingMessageLatency(outgoingMessageEntity.serverTimestamp(), "rest", userAgent, clientReleaseManager);
|
||||||
dynamicConfigurationManager.getConfiguration().getDeliveryLatencyConfiguration().instrumentedVersions());
|
|
||||||
})
|
})
|
||||||
.collect(Collectors.toList()),
|
.collect(Collectors.toList()),
|
||||||
messagesAndHasMore.second());
|
messagesAndHasMore.second());
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.whispersystems.textsecuregcm.entities.MessageProtos;
|
||||||
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity;
|
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity;
|
||||||
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||||
import org.whispersystems.textsecuregcm.storage.Account;
|
import org.whispersystems.textsecuregcm.storage.Account;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
||||||
|
|
||||||
public final class MessageMetrics {
|
public final class MessageMetrics {
|
||||||
|
@ -61,13 +62,13 @@ public final class MessageMetrics {
|
||||||
public static void measureOutgoingMessageLatency(final long serverTimestamp,
|
public static void measureOutgoingMessageLatency(final long serverTimestamp,
|
||||||
final String channel,
|
final String channel,
|
||||||
final String userAgent,
|
final String userAgent,
|
||||||
final Map<ClientPlatform, Set<Semver>> taggedVersions) {
|
final ClientReleaseManager clientReleaseManager) {
|
||||||
|
|
||||||
final List<Tag> tags = new ArrayList<>(3);
|
final List<Tag> tags = new ArrayList<>(3);
|
||||||
tags.add(UserAgentTagUtil.getPlatformTag(userAgent));
|
tags.add(UserAgentTagUtil.getPlatformTag(userAgent));
|
||||||
tags.add(Tag.of("channel", channel));
|
tags.add(Tag.of("channel", channel));
|
||||||
|
|
||||||
UserAgentTagUtil.getClientVersionTag(userAgent, taggedVersions).ifPresent(tags::add);
|
UserAgentTagUtil.getClientVersionTag(userAgent, clientReleaseManager).ifPresent(tags::add);
|
||||||
|
|
||||||
Metrics.timer(DELIVERY_LATENCY_TIMER_NAME, tags)
|
Metrics.timer(DELIVERY_LATENCY_TIMER_NAME, tags)
|
||||||
.record(Duration.between(Instant.ofEpochMilli(serverTimestamp), Instant.now()));
|
.record(Duration.between(Instant.ofEpochMilli(serverTimestamp), Instant.now()));
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
||||||
import org.whispersystems.textsecuregcm.util.ua.UnrecognizedUserAgentException;
|
import org.whispersystems.textsecuregcm.util.ua.UnrecognizedUserAgentException;
|
||||||
import org.whispersystems.textsecuregcm.util.ua.UserAgent;
|
import org.whispersystems.textsecuregcm.util.ua.UserAgent;
|
||||||
|
@ -39,11 +40,11 @@ public class UserAgentTagUtil {
|
||||||
return Tag.of(PLATFORM_TAG, platform);
|
return Tag.of(PLATFORM_TAG, platform);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<Tag> getClientVersionTag(final String userAgentString, final Map<ClientPlatform, Set<Semver>> taggedVersions) {
|
public static Optional<Tag> getClientVersionTag(final String userAgentString, final ClientReleaseManager clientReleaseManager) {
|
||||||
try {
|
try {
|
||||||
final UserAgent userAgent = UserAgentUtil.parseUserAgentString(userAgentString);
|
final UserAgent userAgent = UserAgentUtil.parseUserAgentString(userAgentString);
|
||||||
|
|
||||||
if (taggedVersions.getOrDefault(userAgent.getPlatform(), Collections.emptySet()).contains(userAgent.getVersion())) {
|
if (clientReleaseManager.isVersionActive(userAgent.getPlatform(), userAgent.getVersion())) {
|
||||||
return Optional.of(Tag.of(VERSION_TAG, userAgent.getVersion().toString()));
|
return Optional.of(Tag.of(VERSION_TAG, userAgent.getVersion().toString()));
|
||||||
}
|
}
|
||||||
} catch (final UnrecognizedUserAgentException ignored) {
|
} catch (final UnrecognizedUserAgentException ignored) {
|
||||||
|
|
|
@ -22,10 +22,9 @@ import java.util.concurrent.CompletableFuture;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
||||||
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
|
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.util.SystemMapper;
|
import org.whispersystems.textsecuregcm.util.SystemMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,7 +39,7 @@ import org.whispersystems.textsecuregcm.util.SystemMapper;
|
||||||
public class PushLatencyManager {
|
public class PushLatencyManager {
|
||||||
|
|
||||||
private final FaultTolerantRedisCluster redisCluster;
|
private final FaultTolerantRedisCluster redisCluster;
|
||||||
private final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
|
private final ClientReleaseManager clientReleaseManager;
|
||||||
|
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|
||||||
|
@ -59,18 +58,18 @@ public class PushLatencyManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PushLatencyManager(final FaultTolerantRedisCluster redisCluster,
|
public PushLatencyManager(final FaultTolerantRedisCluster redisCluster,
|
||||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager) {
|
final ClientReleaseManager clientReleaseManager) {
|
||||||
|
|
||||||
this(redisCluster, dynamicConfigurationManager, Clock.systemUTC());
|
this(redisCluster, clientReleaseManager, Clock.systemUTC());
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
PushLatencyManager(final FaultTolerantRedisCluster redisCluster,
|
PushLatencyManager(final FaultTolerantRedisCluster redisCluster,
|
||||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager,
|
final ClientReleaseManager clientReleaseManager,
|
||||||
final Clock clock) {
|
final Clock clock) {
|
||||||
|
|
||||||
this.redisCluster = redisCluster;
|
this.redisCluster = redisCluster;
|
||||||
this.dynamicConfigurationManager = dynamicConfigurationManager;
|
this.clientReleaseManager = clientReleaseManager;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +98,7 @@ public class PushLatencyManager {
|
||||||
tags.add(UserAgentTagUtil.getPlatformTag(userAgentString));
|
tags.add(UserAgentTagUtil.getPlatformTag(userAgentString));
|
||||||
tags.add(Tag.of("pushType", pushRecord.pushType().name().toLowerCase()));
|
tags.add(Tag.of("pushType", pushRecord.pushType().name().toLowerCase()));
|
||||||
|
|
||||||
UserAgentTagUtil.getClientVersionTag(userAgentString,
|
UserAgentTagUtil.getClientVersionTag(userAgentString, clientReleaseManager)
|
||||||
dynamicConfigurationManager.getConfiguration().getPushLatencyConfiguration().instrumentedVersions())
|
|
||||||
.ifPresent(tags::add);
|
.ifPresent(tags::add);
|
||||||
|
|
||||||
pushRecord.urgent().ifPresent(urgent -> tags.add(Tag.of("urgent", String.valueOf(urgent))));
|
pushRecord.urgent().ifPresent(urgent -> tags.add(Tag.of("urgent", String.valueOf(urgent))));
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
|
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
|
||||||
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
||||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||||
|
@ -31,8 +30,8 @@ import org.whispersystems.textsecuregcm.push.NotPushRegisteredException;
|
||||||
import org.whispersystems.textsecuregcm.push.PushNotificationManager;
|
import org.whispersystems.textsecuregcm.push.PushNotificationManager;
|
||||||
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
||||||
import org.whispersystems.textsecuregcm.redis.RedisOperation;
|
import org.whispersystems.textsecuregcm.redis.RedisOperation;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.Device;
|
import org.whispersystems.textsecuregcm.storage.Device;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||||
import org.whispersystems.textsecuregcm.util.Constants;
|
import org.whispersystems.textsecuregcm.util.Constants;
|
||||||
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
||||||
|
@ -69,7 +68,7 @@ public class AuthenticatedConnectListener implements WebSocketConnectListener {
|
||||||
private final ClientPresenceManager clientPresenceManager;
|
private final ClientPresenceManager clientPresenceManager;
|
||||||
private final ScheduledExecutorService scheduledExecutorService;
|
private final ScheduledExecutorService scheduledExecutorService;
|
||||||
private final Scheduler messageDeliveryScheduler;
|
private final Scheduler messageDeliveryScheduler;
|
||||||
private final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
|
private final ClientReleaseManager clientReleaseManager;
|
||||||
|
|
||||||
private final Map<ClientPlatform, AtomicInteger> openAuthenticatedWebsocketsByClientPlatform;
|
private final Map<ClientPlatform, AtomicInteger> openAuthenticatedWebsocketsByClientPlatform;
|
||||||
private final Map<ClientPlatform, AtomicInteger> openUnauthenticatedWebsocketsByClientPlatform;
|
private final Map<ClientPlatform, AtomicInteger> openUnauthenticatedWebsocketsByClientPlatform;
|
||||||
|
@ -87,14 +86,14 @@ public class AuthenticatedConnectListener implements WebSocketConnectListener {
|
||||||
ClientPresenceManager clientPresenceManager,
|
ClientPresenceManager clientPresenceManager,
|
||||||
ScheduledExecutorService scheduledExecutorService,
|
ScheduledExecutorService scheduledExecutorService,
|
||||||
Scheduler messageDeliveryScheduler,
|
Scheduler messageDeliveryScheduler,
|
||||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager) {
|
ClientReleaseManager clientReleaseManager) {
|
||||||
this.receiptSender = receiptSender;
|
this.receiptSender = receiptSender;
|
||||||
this.messagesManager = messagesManager;
|
this.messagesManager = messagesManager;
|
||||||
this.pushNotificationManager = pushNotificationManager;
|
this.pushNotificationManager = pushNotificationManager;
|
||||||
this.clientPresenceManager = clientPresenceManager;
|
this.clientPresenceManager = clientPresenceManager;
|
||||||
this.scheduledExecutorService = scheduledExecutorService;
|
this.scheduledExecutorService = scheduledExecutorService;
|
||||||
this.messageDeliveryScheduler = messageDeliveryScheduler;
|
this.messageDeliveryScheduler = messageDeliveryScheduler;
|
||||||
this.dynamicConfigurationManager = dynamicConfigurationManager;
|
this.clientReleaseManager = clientReleaseManager;
|
||||||
|
|
||||||
openAuthenticatedWebsocketsByClientPlatform = new EnumMap<>(ClientPlatform.class);
|
openAuthenticatedWebsocketsByClientPlatform = new EnumMap<>(ClientPlatform.class);
|
||||||
openUnauthenticatedWebsocketsByClientPlatform = new EnumMap<>(ClientPlatform.class);
|
openUnauthenticatedWebsocketsByClientPlatform = new EnumMap<>(ClientPlatform.class);
|
||||||
|
@ -157,7 +156,7 @@ public class AuthenticatedConnectListener implements WebSocketConnectListener {
|
||||||
context.getClient(),
|
context.getClient(),
|
||||||
scheduledExecutorService,
|
scheduledExecutorService,
|
||||||
messageDeliveryScheduler,
|
messageDeliveryScheduler,
|
||||||
dynamicConfigurationManager);
|
clientReleaseManager);
|
||||||
|
|
||||||
openWebsocketAtomicInteger.incrementAndGet();
|
openWebsocketAtomicInteger.incrementAndGet();
|
||||||
openWebsocketCounter.inc();
|
openWebsocketCounter.inc();
|
||||||
|
|
|
@ -37,7 +37,6 @@ import org.reactivestreams.Publisher;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.controllers.MessageController;
|
import org.whispersystems.textsecuregcm.controllers.MessageController;
|
||||||
import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
|
import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
|
||||||
import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
||||||
|
@ -47,8 +46,8 @@ import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
|
||||||
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
||||||
import org.whispersystems.textsecuregcm.push.DisplacedPresenceListener;
|
import org.whispersystems.textsecuregcm.push.DisplacedPresenceListener;
|
||||||
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.Device;
|
import org.whispersystems.textsecuregcm.storage.Device;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
|
||||||
import org.whispersystems.textsecuregcm.storage.MessageAvailabilityListener;
|
import org.whispersystems.textsecuregcm.storage.MessageAvailabilityListener;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||||
import org.whispersystems.textsecuregcm.util.Constants;
|
import org.whispersystems.textsecuregcm.util.Constants;
|
||||||
|
@ -132,7 +131,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac
|
||||||
private final Random random = new Random();
|
private final Random random = new Random();
|
||||||
private final Scheduler messageDeliveryScheduler;
|
private final Scheduler messageDeliveryScheduler;
|
||||||
|
|
||||||
private final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
|
private final ClientReleaseManager clientReleaseManager;
|
||||||
|
|
||||||
private enum StoredMessageState {
|
private enum StoredMessageState {
|
||||||
EMPTY,
|
EMPTY,
|
||||||
|
@ -147,7 +146,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac
|
||||||
WebSocketClient client,
|
WebSocketClient client,
|
||||||
ScheduledExecutorService scheduledExecutorService,
|
ScheduledExecutorService scheduledExecutorService,
|
||||||
Scheduler messageDeliveryScheduler,
|
Scheduler messageDeliveryScheduler,
|
||||||
DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager) {
|
ClientReleaseManager clientReleaseManager) {
|
||||||
|
|
||||||
this(receiptSender,
|
this(receiptSender,
|
||||||
messagesManager,
|
messagesManager,
|
||||||
|
@ -156,7 +155,8 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac
|
||||||
client,
|
client,
|
||||||
DEFAULT_SEND_FUTURES_TIMEOUT_MILLIS,
|
DEFAULT_SEND_FUTURES_TIMEOUT_MILLIS,
|
||||||
scheduledExecutorService,
|
scheduledExecutorService,
|
||||||
messageDeliveryScheduler, dynamicConfigurationManager);
|
messageDeliveryScheduler,
|
||||||
|
clientReleaseManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -168,7 +168,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac
|
||||||
int sendFuturesTimeoutMillis,
|
int sendFuturesTimeoutMillis,
|
||||||
ScheduledExecutorService scheduledExecutorService,
|
ScheduledExecutorService scheduledExecutorService,
|
||||||
Scheduler messageDeliveryScheduler,
|
Scheduler messageDeliveryScheduler,
|
||||||
DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager) {
|
ClientReleaseManager clientReleaseManager) {
|
||||||
|
|
||||||
this.receiptSender = receiptSender;
|
this.receiptSender = receiptSender;
|
||||||
this.messagesManager = messagesManager;
|
this.messagesManager = messagesManager;
|
||||||
|
@ -178,7 +178,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac
|
||||||
this.sendFuturesTimeoutMillis = sendFuturesTimeoutMillis;
|
this.sendFuturesTimeoutMillis = sendFuturesTimeoutMillis;
|
||||||
this.scheduledExecutorService = scheduledExecutorService;
|
this.scheduledExecutorService = scheduledExecutorService;
|
||||||
this.messageDeliveryScheduler = messageDeliveryScheduler;
|
this.messageDeliveryScheduler = messageDeliveryScheduler;
|
||||||
this.dynamicConfigurationManager = dynamicConfigurationManager;
|
this.clientReleaseManager = clientReleaseManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
|
@ -217,8 +217,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
sendFailuresMeter.mark();
|
sendFailuresMeter.mark();
|
||||||
} else {
|
} else {
|
||||||
MessageMetrics.measureOutgoingMessageLatency(message.getServerTimestamp(), "websocket", client.getUserAgent(),
|
MessageMetrics.measureOutgoingMessageLatency(message.getServerTimestamp(), "websocket", client.getUserAgent(), clientReleaseManager);
|
||||||
dynamicConfigurationManager.getConfiguration().getDeliveryLatencyConfiguration().instrumentedVersions());
|
|
||||||
}
|
}
|
||||||
}).thenCompose(response -> {
|
}).thenCompose(response -> {
|
||||||
final CompletableFuture<Void> result;
|
final CompletableFuture<Void> result;
|
||||||
|
|
|
@ -81,7 +81,6 @@ import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
|
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
|
||||||
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
|
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicDeliveryLatencyConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicInboundMessageByteLimitConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicInboundMessageByteLimitConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.entities.AccountMismatchedDevices;
|
import org.whispersystems.textsecuregcm.entities.AccountMismatchedDevices;
|
||||||
import org.whispersystems.textsecuregcm.entities.AccountStaleDevices;
|
import org.whispersystems.textsecuregcm.entities.AccountStaleDevices;
|
||||||
|
@ -112,6 +111,7 @@ import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
||||||
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenProvider;
|
import org.whispersystems.textsecuregcm.spam.ReportSpamTokenProvider;
|
||||||
import org.whispersystems.textsecuregcm.storage.Account;
|
import org.whispersystems.textsecuregcm.storage.Account;
|
||||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||||
import org.whispersystems.textsecuregcm.storage.Device;
|
import org.whispersystems.textsecuregcm.storage.Device;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||||
|
@ -179,7 +179,7 @@ class MessageControllerTest {
|
||||||
.addResource(
|
.addResource(
|
||||||
new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, deletedAccounts,
|
new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, deletedAccounts,
|
||||||
messagesManager, pushNotificationManager, reportMessageManager, multiRecipientMessageExecutor,
|
messagesManager, pushNotificationManager, reportMessageManager, multiRecipientMessageExecutor,
|
||||||
messageDeliveryScheduler, ReportSpamTokenProvider.noop(), dynamicConfigurationManager))
|
messageDeliveryScheduler, ReportSpamTokenProvider.noop(), mock(ClientReleaseManager.class), dynamicConfigurationManager))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -209,16 +209,12 @@ class MessageControllerTest {
|
||||||
when(accountsManager.getByServiceIdentifier(new PniServiceIdentifier(MULTI_DEVICE_PNI))).thenReturn(Optional.of(multiDeviceAccount));
|
when(accountsManager.getByServiceIdentifier(new PniServiceIdentifier(MULTI_DEVICE_PNI))).thenReturn(Optional.of(multiDeviceAccount));
|
||||||
when(accountsManager.getByServiceIdentifier(new AciServiceIdentifier(INTERNATIONAL_UUID))).thenReturn(Optional.of(internationalAccount));
|
when(accountsManager.getByServiceIdentifier(new AciServiceIdentifier(INTERNATIONAL_UUID))).thenReturn(Optional.of(internationalAccount));
|
||||||
|
|
||||||
final DynamicDeliveryLatencyConfiguration deliveryLatencyConfiguration = mock(DynamicDeliveryLatencyConfiguration.class);
|
|
||||||
when(deliveryLatencyConfiguration.instrumentedVersions()).thenReturn(Collections.emptyMap());
|
|
||||||
|
|
||||||
final DynamicInboundMessageByteLimitConfiguration inboundMessageByteLimitConfiguration =
|
final DynamicInboundMessageByteLimitConfiguration inboundMessageByteLimitConfiguration =
|
||||||
mock(DynamicInboundMessageByteLimitConfiguration.class);
|
mock(DynamicInboundMessageByteLimitConfiguration.class);
|
||||||
|
|
||||||
when(inboundMessageByteLimitConfiguration.enforceInboundLimit()).thenReturn(false);
|
when(inboundMessageByteLimitConfiguration.enforceInboundLimit()).thenReturn(false);
|
||||||
|
|
||||||
final DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
|
final DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
|
||||||
when(dynamicConfiguration.getDeliveryLatencyConfiguration()).thenReturn(deliveryLatencyConfiguration);
|
|
||||||
when(dynamicConfiguration.getInboundMessageByteLimitConfiguration()).thenReturn(inboundMessageByteLimitConfiguration);
|
when(dynamicConfiguration.getInboundMessageByteLimitConfiguration()).thenReturn(inboundMessageByteLimitConfiguration);
|
||||||
|
|
||||||
when(dynamicConfigurationManager.getConfiguration()).thenReturn(dynamicConfiguration);
|
when(dynamicConfigurationManager.getConfiguration()).thenReturn(dynamicConfiguration);
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
package org.whispersystems.textsecuregcm.metrics;
|
package org.whispersystems.textsecuregcm.metrics;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.vdurmont.semver4j.Semver;
|
import com.vdurmont.semver4j.Semver;
|
||||||
import io.micrometer.core.instrument.Tag;
|
import io.micrometer.core.instrument.Tag;
|
||||||
|
@ -17,6 +20,7 @@ import java.util.stream.Stream;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
||||||
|
|
||||||
class UserAgentTagUtilTest {
|
class UserAgentTagUtilTest {
|
||||||
|
@ -49,26 +53,21 @@ class UserAgentTagUtilTest {
|
||||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource
|
@MethodSource
|
||||||
void getClientVersionTag(final String userAgent, final Map<ClientPlatform, Set<Semver>> taggedVersions, final Optional<Tag> expectedTag) {
|
void getClientVersionTag(final String userAgent, final boolean isVersionLive, final Optional<Tag> expectedTag) {
|
||||||
assertEquals(expectedTag, UserAgentTagUtil.getClientVersionTag(userAgent, taggedVersions));
|
final ClientReleaseManager clientReleaseManager = mock(ClientReleaseManager.class);
|
||||||
|
when(clientReleaseManager.isVersionActive(any(), any())).thenReturn(isVersionLive);
|
||||||
|
|
||||||
|
assertEquals(expectedTag, UserAgentTagUtil.getClientVersionTag(userAgent, clientReleaseManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream<Arguments> getClientVersionTag() {
|
private static Stream<Arguments> getClientVersionTag() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
Arguments.of("Signal-Android/1.2.3 (Android 9)",
|
Arguments.of("Signal-Android/1.2.3 (Android 9)",
|
||||||
Map.of(ClientPlatform.ANDROID, Set.of(new Semver("1.2.3"))),
|
true,
|
||||||
Optional.of(Tag.of(UserAgentTagUtil.VERSION_TAG, "1.2.3"))),
|
Optional.of(Tag.of(UserAgentTagUtil.VERSION_TAG, "1.2.3"))),
|
||||||
|
|
||||||
Arguments.of("Signal-Android/1.2.3 (Android 9)",
|
Arguments.of("Signal-Android/1.2.3 (Android 9)",
|
||||||
Collections.emptyMap(),
|
false,
|
||||||
Optional.empty()),
|
|
||||||
|
|
||||||
Arguments.of("Signal-Android/1.2.3.0-bobsbootlegclient",
|
|
||||||
Map.of(ClientPlatform.ANDROID, Set.of(new Semver("1.2.3"))),
|
|
||||||
Optional.empty()),
|
|
||||||
|
|
||||||
Arguments.of("Signal-Desktop/1.2.3",
|
|
||||||
Map.of(ClientPlatform.ANDROID, Set.of(new Semver("1.2.3"))),
|
|
||||||
Optional.empty())
|
Optional.empty())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,47 +9,28 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicPushLatencyConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.push.PushLatencyManager.PushRecord;
|
import org.whispersystems.textsecuregcm.push.PushLatencyManager.PushRecord;
|
||||||
import org.whispersystems.textsecuregcm.push.PushLatencyManager.PushType;
|
import org.whispersystems.textsecuregcm.push.PushLatencyManager.PushType;
|
||||||
import org.whispersystems.textsecuregcm.redis.RedisClusterExtension;
|
import org.whispersystems.textsecuregcm.redis.RedisClusterExtension;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
|
|
||||||
class PushLatencyManagerTest {
|
class PushLatencyManagerTest {
|
||||||
|
|
||||||
@RegisterExtension
|
@RegisterExtension
|
||||||
static final RedisClusterExtension REDIS_CLUSTER_EXTENSION = RedisClusterExtension.builder().build();
|
static final RedisClusterExtension REDIS_CLUSTER_EXTENSION = RedisClusterExtension.builder().build();
|
||||||
|
|
||||||
private DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setUp() {
|
|
||||||
//noinspection unchecked
|
|
||||||
dynamicConfigurationManager = mock(DynamicConfigurationManager.class);
|
|
||||||
final DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
|
|
||||||
final DynamicPushLatencyConfiguration dynamicPushLatencyConfiguration = mock(DynamicPushLatencyConfiguration.class);
|
|
||||||
|
|
||||||
when(dynamicConfigurationManager.getConfiguration()).thenReturn(dynamicConfiguration);
|
|
||||||
when(dynamicConfiguration.getPushLatencyConfiguration()).thenReturn(dynamicPushLatencyConfiguration);
|
|
||||||
when(dynamicPushLatencyConfiguration.instrumentedVersions()).thenReturn(Collections.emptyMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource
|
@MethodSource
|
||||||
void testTakeRecord(final boolean isVoip, final boolean isUrgent) throws ExecutionException, InterruptedException {
|
void testTakeRecord(final boolean isVoip, final boolean isUrgent) throws ExecutionException, InterruptedException {
|
||||||
|
@ -59,7 +40,7 @@ class PushLatencyManagerTest {
|
||||||
final Instant pushTimestamp = Instant.now();
|
final Instant pushTimestamp = Instant.now();
|
||||||
|
|
||||||
final PushLatencyManager pushLatencyManager = new PushLatencyManager(REDIS_CLUSTER_EXTENSION.getRedisCluster(),
|
final PushLatencyManager pushLatencyManager = new PushLatencyManager(REDIS_CLUSTER_EXTENSION.getRedisCluster(),
|
||||||
dynamicConfigurationManager, Clock.fixed(pushTimestamp, ZoneId.systemDefault()));
|
mock(ClientReleaseManager.class), Clock.fixed(pushTimestamp, ZoneId.systemDefault()));
|
||||||
|
|
||||||
assertNull(pushLatencyManager.takePushRecord(accountUuid, deviceId).get());
|
assertNull(pushLatencyManager.takePushRecord(accountUuid, deviceId).get());
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ import java.io.IOException;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -45,15 +44,13 @@ import org.junit.jupiter.params.provider.CsvSource;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicDeliveryLatencyConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.entities.MessageProtos;
|
import org.whispersystems.textsecuregcm.entities.MessageProtos;
|
||||||
import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
|
import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
|
||||||
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
||||||
import org.whispersystems.textsecuregcm.redis.RedisClusterExtension;
|
import org.whispersystems.textsecuregcm.redis.RedisClusterExtension;
|
||||||
import org.whispersystems.textsecuregcm.storage.Account;
|
import org.whispersystems.textsecuregcm.storage.Account;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.Device;
|
import org.whispersystems.textsecuregcm.storage.Device;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamoDbExtension;
|
import org.whispersystems.textsecuregcm.storage.DynamoDbExtension;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamoDbExtensionSchema.Tables;
|
import org.whispersystems.textsecuregcm.storage.DynamoDbExtensionSchema.Tables;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
||||||
|
@ -83,7 +80,7 @@ class WebSocketConnectionIntegrationTest {
|
||||||
private Device device;
|
private Device device;
|
||||||
private WebSocketClient webSocketClient;
|
private WebSocketClient webSocketClient;
|
||||||
private Scheduler messageDeliveryScheduler;
|
private Scheduler messageDeliveryScheduler;
|
||||||
private DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
|
private ClientReleaseManager clientReleaseManager;
|
||||||
|
|
||||||
private long serialTimestamp = System.currentTimeMillis();
|
private long serialTimestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
@ -102,15 +99,7 @@ class WebSocketConnectionIntegrationTest {
|
||||||
account = mock(Account.class);
|
account = mock(Account.class);
|
||||||
device = mock(Device.class);
|
device = mock(Device.class);
|
||||||
webSocketClient = mock(WebSocketClient.class);
|
webSocketClient = mock(WebSocketClient.class);
|
||||||
|
clientReleaseManager = mock(ClientReleaseManager.class);
|
||||||
final DynamicDeliveryLatencyConfiguration deliveryLatencyConfiguration = mock(DynamicDeliveryLatencyConfiguration.class);
|
|
||||||
when(deliveryLatencyConfiguration.instrumentedVersions()).thenReturn(Collections.emptyMap());
|
|
||||||
|
|
||||||
final DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
|
|
||||||
when(dynamicConfiguration.getDeliveryLatencyConfiguration()).thenReturn(deliveryLatencyConfiguration);
|
|
||||||
|
|
||||||
dynamicConfigurationManager = mock(DynamicConfigurationManager.class);
|
|
||||||
when(dynamicConfigurationManager.getConfiguration()).thenReturn(dynamicConfiguration);
|
|
||||||
|
|
||||||
when(account.getNumber()).thenReturn("+18005551234");
|
when(account.getNumber()).thenReturn("+18005551234");
|
||||||
when(account.getUuid()).thenReturn(UUID.randomUUID());
|
when(account.getUuid()).thenReturn(UUID.randomUUID());
|
||||||
|
@ -140,7 +129,8 @@ class WebSocketConnectionIntegrationTest {
|
||||||
device,
|
device,
|
||||||
webSocketClient,
|
webSocketClient,
|
||||||
scheduledExecutorService,
|
scheduledExecutorService,
|
||||||
messageDeliveryScheduler, dynamicConfigurationManager);
|
messageDeliveryScheduler,
|
||||||
|
clientReleaseManager);
|
||||||
|
|
||||||
final List<MessageProtos.Envelope> expectedMessages = new ArrayList<>(persistedMessageCount + cachedMessageCount);
|
final List<MessageProtos.Envelope> expectedMessages = new ArrayList<>(persistedMessageCount + cachedMessageCount);
|
||||||
|
|
||||||
|
@ -224,7 +214,8 @@ class WebSocketConnectionIntegrationTest {
|
||||||
device,
|
device,
|
||||||
webSocketClient,
|
webSocketClient,
|
||||||
scheduledExecutorService,
|
scheduledExecutorService,
|
||||||
messageDeliveryScheduler, dynamicConfigurationManager);
|
messageDeliveryScheduler,
|
||||||
|
clientReleaseManager);
|
||||||
|
|
||||||
final int persistedMessageCount = 207;
|
final int persistedMessageCount = 207;
|
||||||
final int cachedMessageCount = 173;
|
final int cachedMessageCount = 173;
|
||||||
|
@ -291,7 +282,7 @@ class WebSocketConnectionIntegrationTest {
|
||||||
100, // use a very short timeout, so that this test completes quickly
|
100, // use a very short timeout, so that this test completes quickly
|
||||||
scheduledExecutorService,
|
scheduledExecutorService,
|
||||||
messageDeliveryScheduler,
|
messageDeliveryScheduler,
|
||||||
dynamicConfigurationManager);
|
clientReleaseManager);
|
||||||
|
|
||||||
final int persistedMessageCount = 207;
|
final int persistedMessageCount = 207;
|
||||||
final int cachedMessageCount = 173;
|
final int cachedMessageCount = 173;
|
||||||
|
|
|
@ -33,7 +33,6 @@ import io.lettuce.core.RedisException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -53,16 +52,14 @@ import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
|
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
|
||||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicDeliveryLatencyConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
||||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||||
import org.whispersystems.textsecuregcm.push.PushNotificationManager;
|
import org.whispersystems.textsecuregcm.push.PushNotificationManager;
|
||||||
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
||||||
import org.whispersystems.textsecuregcm.storage.Account;
|
import org.whispersystems.textsecuregcm.storage.Account;
|
||||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||||
|
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.Device;
|
import org.whispersystems.textsecuregcm.storage.Device;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||||
import org.whispersystems.textsecuregcm.util.Pair;
|
import org.whispersystems.textsecuregcm.util.Pair;
|
||||||
import org.whispersystems.websocket.WebSocketClient;
|
import org.whispersystems.websocket.WebSocketClient;
|
||||||
|
@ -93,7 +90,7 @@ class WebSocketConnectionTest {
|
||||||
private ReceiptSender receiptSender;
|
private ReceiptSender receiptSender;
|
||||||
private ScheduledExecutorService retrySchedulingExecutor;
|
private ScheduledExecutorService retrySchedulingExecutor;
|
||||||
private Scheduler messageDeliveryScheduler;
|
private Scheduler messageDeliveryScheduler;
|
||||||
private DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
|
private ClientReleaseManager clientReleaseManager;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup() {
|
void setup() {
|
||||||
|
@ -107,15 +104,7 @@ class WebSocketConnectionTest {
|
||||||
receiptSender = mock(ReceiptSender.class);
|
receiptSender = mock(ReceiptSender.class);
|
||||||
retrySchedulingExecutor = mock(ScheduledExecutorService.class);
|
retrySchedulingExecutor = mock(ScheduledExecutorService.class);
|
||||||
messageDeliveryScheduler = Schedulers.newBoundedElastic(10, 10_000, "messageDelivery");
|
messageDeliveryScheduler = Schedulers.newBoundedElastic(10, 10_000, "messageDelivery");
|
||||||
|
clientReleaseManager = mock(ClientReleaseManager.class);
|
||||||
final DynamicDeliveryLatencyConfiguration deliveryLatencyConfiguration = mock(DynamicDeliveryLatencyConfiguration.class);
|
|
||||||
when(deliveryLatencyConfiguration.instrumentedVersions()).thenReturn(Collections.emptyMap());
|
|
||||||
|
|
||||||
final DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
|
|
||||||
when(dynamicConfiguration.getDeliveryLatencyConfiguration()).thenReturn(deliveryLatencyConfiguration);
|
|
||||||
|
|
||||||
dynamicConfigurationManager = mock(DynamicConfigurationManager.class);
|
|
||||||
when(dynamicConfigurationManager.getConfiguration()).thenReturn(dynamicConfiguration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
|
@ -129,7 +118,7 @@ class WebSocketConnectionTest {
|
||||||
WebSocketAccountAuthenticator webSocketAuthenticator = new WebSocketAccountAuthenticator(accountAuthenticator);
|
WebSocketAccountAuthenticator webSocketAuthenticator = new WebSocketAccountAuthenticator(accountAuthenticator);
|
||||||
AuthenticatedConnectListener connectListener = new AuthenticatedConnectListener(receiptSender, messagesManager,
|
AuthenticatedConnectListener connectListener = new AuthenticatedConnectListener(receiptSender, messagesManager,
|
||||||
mock(PushNotificationManager.class), mock(ClientPresenceManager.class),
|
mock(PushNotificationManager.class), mock(ClientPresenceManager.class),
|
||||||
retrySchedulingExecutor, messageDeliveryScheduler, dynamicConfigurationManager);
|
retrySchedulingExecutor, messageDeliveryScheduler, clientReleaseManager);
|
||||||
WebSocketSessionContext sessionContext = mock(WebSocketSessionContext.class);
|
WebSocketSessionContext sessionContext = mock(WebSocketSessionContext.class);
|
||||||
|
|
||||||
when(accountAuthenticator.authenticate(eq(new BasicCredentials(VALID_USER, VALID_PASSWORD))))
|
when(accountAuthenticator.authenticate(eq(new BasicCredentials(VALID_USER, VALID_PASSWORD))))
|
||||||
|
@ -209,7 +198,7 @@ class WebSocketConnectionTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager,
|
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager,
|
||||||
auth, device, client, retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
auth, device, client, retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
connection.start();
|
connection.start();
|
||||||
verify(client, times(3)).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class),
|
verify(client, times(3)).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class),
|
||||||
|
@ -237,7 +226,7 @@ class WebSocketConnectionTest {
|
||||||
public void testOnlineSend() {
|
public void testOnlineSend() {
|
||||||
final WebSocketClient client = mock(WebSocketClient.class);
|
final WebSocketClient client = mock(WebSocketClient.class);
|
||||||
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
final UUID accountUuid = UUID.randomUUID();
|
final UUID accountUuid = UUID.randomUUID();
|
||||||
|
|
||||||
|
@ -357,7 +346,7 @@ class WebSocketConnectionTest {
|
||||||
});
|
});
|
||||||
|
|
||||||
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager,
|
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager,
|
||||||
auth, device, client, retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
auth, device, client, retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
connection.start();
|
connection.start();
|
||||||
|
|
||||||
|
@ -381,7 +370,7 @@ class WebSocketConnectionTest {
|
||||||
void testProcessStoredMessageConcurrency() {
|
void testProcessStoredMessageConcurrency() {
|
||||||
final WebSocketClient client = mock(WebSocketClient.class);
|
final WebSocketClient client = mock(WebSocketClient.class);
|
||||||
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
when(account.getNumber()).thenReturn("+18005551234");
|
when(account.getNumber()).thenReturn("+18005551234");
|
||||||
when(account.getUuid()).thenReturn(UUID.randomUUID());
|
when(account.getUuid()).thenReturn(UUID.randomUUID());
|
||||||
|
@ -446,7 +435,7 @@ class WebSocketConnectionTest {
|
||||||
void testProcessStoredMessagesMultiplePages() {
|
void testProcessStoredMessagesMultiplePages() {
|
||||||
final WebSocketClient client = mock(WebSocketClient.class);
|
final WebSocketClient client = mock(WebSocketClient.class);
|
||||||
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
when(account.getNumber()).thenReturn("+18005551234");
|
when(account.getNumber()).thenReturn("+18005551234");
|
||||||
final UUID accountUuid = UUID.randomUUID();
|
final UUID accountUuid = UUID.randomUUID();
|
||||||
|
@ -498,7 +487,7 @@ class WebSocketConnectionTest {
|
||||||
void testProcessStoredMessagesContainsSenderUuid() {
|
void testProcessStoredMessagesContainsSenderUuid() {
|
||||||
final WebSocketClient client = mock(WebSocketClient.class);
|
final WebSocketClient client = mock(WebSocketClient.class);
|
||||||
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
when(account.getNumber()).thenReturn("+18005551234");
|
when(account.getNumber()).thenReturn("+18005551234");
|
||||||
final UUID accountUuid = UUID.randomUUID();
|
final UUID accountUuid = UUID.randomUUID();
|
||||||
|
@ -560,7 +549,7 @@ class WebSocketConnectionTest {
|
||||||
void testProcessStoredMessagesSingleEmptyCall() {
|
void testProcessStoredMessagesSingleEmptyCall() {
|
||||||
final WebSocketClient client = mock(WebSocketClient.class);
|
final WebSocketClient client = mock(WebSocketClient.class);
|
||||||
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
final UUID accountUuid = UUID.randomUUID();
|
final UUID accountUuid = UUID.randomUUID();
|
||||||
|
|
||||||
|
@ -589,7 +578,7 @@ class WebSocketConnectionTest {
|
||||||
public void testRequeryOnStateMismatch() {
|
public void testRequeryOnStateMismatch() {
|
||||||
final WebSocketClient client = mock(WebSocketClient.class);
|
final WebSocketClient client = mock(WebSocketClient.class);
|
||||||
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
final UUID accountUuid = UUID.randomUUID();
|
final UUID accountUuid = UUID.randomUUID();
|
||||||
|
|
||||||
when(account.getNumber()).thenReturn("+18005551234");
|
when(account.getNumber()).thenReturn("+18005551234");
|
||||||
|
@ -645,7 +634,7 @@ class WebSocketConnectionTest {
|
||||||
void testProcessCachedMessagesOnly() {
|
void testProcessCachedMessagesOnly() {
|
||||||
final WebSocketClient client = mock(WebSocketClient.class);
|
final WebSocketClient client = mock(WebSocketClient.class);
|
||||||
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
final UUID accountUuid = UUID.randomUUID();
|
final UUID accountUuid = UUID.randomUUID();
|
||||||
|
|
||||||
|
@ -677,7 +666,7 @@ class WebSocketConnectionTest {
|
||||||
void testProcessDatabaseMessagesAfterPersist() {
|
void testProcessDatabaseMessagesAfterPersist() {
|
||||||
final WebSocketClient client = mock(WebSocketClient.class);
|
final WebSocketClient client = mock(WebSocketClient.class);
|
||||||
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
final UUID accountUuid = UUID.randomUUID();
|
final UUID accountUuid = UUID.randomUUID();
|
||||||
|
|
||||||
|
@ -724,7 +713,7 @@ class WebSocketConnectionTest {
|
||||||
when(client.isOpen()).thenReturn(true);
|
when(client.isOpen()).thenReturn(true);
|
||||||
|
|
||||||
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
connection.start();
|
connection.start();
|
||||||
|
|
||||||
verify(retrySchedulingExecutor, times(WebSocketConnection.MAX_CONSECUTIVE_RETRIES)).schedule(any(Runnable.class),
|
verify(retrySchedulingExecutor, times(WebSocketConnection.MAX_CONSECUTIVE_RETRIES)).schedule(any(Runnable.class),
|
||||||
|
@ -748,7 +737,7 @@ class WebSocketConnectionTest {
|
||||||
when(client.isOpen()).thenReturn(false);
|
when(client.isOpen()).thenReturn(false);
|
||||||
|
|
||||||
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
connection.start();
|
connection.start();
|
||||||
|
|
||||||
verify(retrySchedulingExecutor, never()).schedule(any(Runnable.class), anyLong(), any());
|
verify(retrySchedulingExecutor, never()).schedule(any(Runnable.class), anyLong(), any());
|
||||||
|
@ -782,7 +771,7 @@ class WebSocketConnectionTest {
|
||||||
CompletableFuture.completedFuture(Optional.empty()));
|
CompletableFuture.completedFuture(Optional.empty()));
|
||||||
|
|
||||||
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, messageDeliveryScheduler, dynamicConfigurationManager);
|
retrySchedulingExecutor, messageDeliveryScheduler, clientReleaseManager);
|
||||||
|
|
||||||
connection.start();
|
connection.start();
|
||||||
|
|
||||||
|
@ -839,7 +828,7 @@ class WebSocketConnectionTest {
|
||||||
CompletableFuture.completedFuture(Optional.empty()));
|
CompletableFuture.completedFuture(Optional.empty()));
|
||||||
|
|
||||||
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
|
||||||
retrySchedulingExecutor, Schedulers.immediate(), dynamicConfigurationManager);
|
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||||
|
|
||||||
connection.start();
|
connection.start();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue