Consolidate profiles store tests and discard `ProfilesStore` interface
This commit is contained in:
parent
afa910bbd7
commit
064861b930
|
@ -188,7 +188,7 @@ import org.whispersystems.textsecuregcm.storage.MessagesDynamoDb;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.NonNormalizedAccountCrawlerListener;
|
import org.whispersystems.textsecuregcm.storage.NonNormalizedAccountCrawlerListener;
|
||||||
import org.whispersystems.textsecuregcm.storage.PhoneNumberIdentifiers;
|
import org.whispersystems.textsecuregcm.storage.PhoneNumberIdentifiers;
|
||||||
import org.whispersystems.textsecuregcm.storage.ProfilesDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.Profiles;
|
||||||
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.PubSubManager;
|
import org.whispersystems.textsecuregcm.storage.PubSubManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.PushChallengeDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.PushChallengeDynamoDb;
|
||||||
|
@ -385,7 +385,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
config.getPhoneNumberIdentifiersDynamoDbConfiguration().getTableName());
|
config.getPhoneNumberIdentifiersDynamoDbConfiguration().getTableName());
|
||||||
ReservedUsernames reservedUsernames = new ReservedUsernames(reservedUsernamesDynamoDbClient,
|
ReservedUsernames reservedUsernames = new ReservedUsernames(reservedUsernamesDynamoDbClient,
|
||||||
config.getReservedUsernamesDynamoDbConfiguration().getTableName());
|
config.getReservedUsernamesDynamoDbConfiguration().getTableName());
|
||||||
ProfilesDynamoDb profilesDynamoDb = new ProfilesDynamoDb(dynamoDbClient, dynamoDbAsyncClient,
|
Profiles profiles = new Profiles(dynamoDbClient, dynamoDbAsyncClient,
|
||||||
config.getDynamoDbTables().getProfiles().getTableName());
|
config.getDynamoDbTables().getProfiles().getTableName());
|
||||||
Keys keys = new Keys(preKeyDynamoDb, config.getKeysDynamoDbConfiguration().getTableName());
|
Keys keys = new Keys(preKeyDynamoDb, config.getKeysDynamoDbConfiguration().getTableName());
|
||||||
MessagesDynamoDb messagesDynamoDb = new MessagesDynamoDb(messageDynamoDb,
|
MessagesDynamoDb messagesDynamoDb = new MessagesDynamoDb(messageDynamoDb,
|
||||||
|
@ -466,7 +466,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
DirectoryQueue directoryQueue = new DirectoryQueue(config.getDirectoryConfiguration().getSqsConfiguration());
|
DirectoryQueue directoryQueue = new DirectoryQueue(config.getDirectoryConfiguration().getSqsConfiguration());
|
||||||
StoredVerificationCodeManager pendingAccountsManager = new StoredVerificationCodeManager(pendingAccounts);
|
StoredVerificationCodeManager pendingAccountsManager = new StoredVerificationCodeManager(pendingAccounts);
|
||||||
StoredVerificationCodeManager pendingDevicesManager = new StoredVerificationCodeManager(pendingDevices);
|
StoredVerificationCodeManager pendingDevicesManager = new StoredVerificationCodeManager(pendingDevices);
|
||||||
ProfilesManager profilesManager = new ProfilesManager(profilesDynamoDb, cacheCluster);
|
ProfilesManager profilesManager = new ProfilesManager(profiles, cacheCluster);
|
||||||
MessagesCache messagesCache = new MessagesCache(messagesCluster, messagesCluster, keyspaceNotificationDispatchExecutor);
|
MessagesCache messagesCache = new MessagesCache(messagesCluster, messagesCluster, keyspaceNotificationDispatchExecutor);
|
||||||
PushLatencyManager pushLatencyManager = new PushLatencyManager(metricsCluster, dynamicConfigurationManager);
|
PushLatencyManager pushLatencyManager = new PushLatencyManager(metricsCluster, dynamicConfigurationManager);
|
||||||
ReportMessageManager reportMessageManager = new ReportMessageManager(reportMessageDynamoDb, rateLimitersCluster, Metrics.globalRegistry, config.getReportMessageConfiguration().getCounterTtl());
|
ReportMessageManager reportMessageManager = new ReportMessageManager(reportMessageDynamoDb, rateLimitersCluster, Metrics.globalRegistry, config.getReportMessageConfiguration().getCounterTtl());
|
||||||
|
|
|
@ -30,7 +30,7 @@ import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
|
||||||
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
|
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
|
||||||
import software.amazon.awssdk.services.dynamodb.paginators.QueryIterable;
|
import software.amazon.awssdk.services.dynamodb.paginators.QueryIterable;
|
||||||
|
|
||||||
public class ProfilesDynamoDb implements ProfilesStore {
|
public class Profiles {
|
||||||
|
|
||||||
private final DynamoDbClient dynamoDbClient;
|
private final DynamoDbClient dynamoDbClient;
|
||||||
private final DynamoDbAsyncClient dynamoDbAsyncClient;
|
private final DynamoDbAsyncClient dynamoDbAsyncClient;
|
||||||
|
@ -70,11 +70,11 @@ public class ProfilesDynamoDb implements ProfilesStore {
|
||||||
"#aboutEmoji", ATTR_EMOJI,
|
"#aboutEmoji", ATTR_EMOJI,
|
||||||
"#paymentAddress", ATTR_PAYMENT_ADDRESS);
|
"#paymentAddress", ATTR_PAYMENT_ADDRESS);
|
||||||
|
|
||||||
private static final Timer SET_PROFILES_TIMER = Metrics.timer(name(ProfilesDynamoDb.class, "set"));
|
private static final Timer SET_PROFILES_TIMER = Metrics.timer(name(Profiles.class, "set"));
|
||||||
private static final Timer GET_PROFILE_TIMER = Metrics.timer(name(ProfilesDynamoDb.class, "get"));
|
private static final Timer GET_PROFILE_TIMER = Metrics.timer(name(Profiles.class, "get"));
|
||||||
private static final Timer DELETE_PROFILES_TIMER = Metrics.timer(name(ProfilesDynamoDb.class, "delete"));
|
private static final Timer DELETE_PROFILES_TIMER = Metrics.timer(name(Profiles.class, "delete"));
|
||||||
|
|
||||||
public ProfilesDynamoDb(final DynamoDbClient dynamoDbClient,
|
public Profiles(final DynamoDbClient dynamoDbClient,
|
||||||
final DynamoDbAsyncClient dynamoDbAsyncClient,
|
final DynamoDbAsyncClient dynamoDbAsyncClient,
|
||||||
final String tableName) {
|
final String tableName) {
|
||||||
|
|
||||||
|
@ -83,7 +83,6 @@ public class ProfilesDynamoDb implements ProfilesStore {
|
||||||
this.tableName = tableName;
|
this.tableName = tableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(final UUID uuid, final VersionedProfile profile) {
|
public void set(final UUID uuid, final VersionedProfile profile) {
|
||||||
SET_PROFILES_TIMER.record(() -> {
|
SET_PROFILES_TIMER.record(() -> {
|
||||||
dynamoDbClient.updateItem(UpdateItemRequest.builder()
|
dynamoDbClient.updateItem(UpdateItemRequest.builder()
|
||||||
|
@ -187,7 +186,6 @@ public class ProfilesDynamoDb implements ProfilesStore {
|
||||||
return expressionValues;
|
return expressionValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<VersionedProfile> get(final UUID uuid, final String version) {
|
public Optional<VersionedProfile> get(final UUID uuid, final String version) {
|
||||||
return GET_PROFILE_TIMER.record(() -> {
|
return GET_PROFILE_TIMER.record(() -> {
|
||||||
final GetItemResponse response = dynamoDbClient.getItem(GetItemRequest.builder()
|
final GetItemResponse response = dynamoDbClient.getItem(GetItemRequest.builder()
|
||||||
|
@ -211,7 +209,6 @@ public class ProfilesDynamoDb implements ProfilesStore {
|
||||||
AttributeValues.getByteArray(item, ATTR_COMMITMENT, null));
|
AttributeValues.getByteArray(item, ATTR_COMMITMENT, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteAll(final UUID uuid) {
|
public void deleteAll(final UUID uuid) {
|
||||||
DELETE_PROFILES_TIMER.record(() -> {
|
DELETE_PROFILES_TIMER.record(() -> {
|
||||||
final AttributeValue uuidAttributeValue = AttributeValues.fromUUID(uuid);
|
final AttributeValue uuidAttributeValue = AttributeValues.fromUUID(uuid);
|
|
@ -22,31 +22,32 @@ public class ProfilesManager {
|
||||||
|
|
||||||
private static final String CACHE_PREFIX = "profiles::";
|
private static final String CACHE_PREFIX = "profiles::";
|
||||||
|
|
||||||
private final ProfilesDynamoDb profilesDynamoDb;
|
private final Profiles profiles;
|
||||||
private final FaultTolerantRedisCluster cacheCluster;
|
private final FaultTolerantRedisCluster cacheCluster;
|
||||||
private final ObjectMapper mapper;
|
private final ObjectMapper mapper;
|
||||||
|
|
||||||
public ProfilesManager(final ProfilesDynamoDb profilesDynamoDb, final FaultTolerantRedisCluster cacheCluster) {
|
public ProfilesManager(final Profiles profiles,
|
||||||
this.profilesDynamoDb = profilesDynamoDb;
|
final FaultTolerantRedisCluster cacheCluster) {
|
||||||
|
this.profiles = profiles;
|
||||||
this.cacheCluster = cacheCluster;
|
this.cacheCluster = cacheCluster;
|
||||||
this.mapper = SystemMapper.getMapper();
|
this.mapper = SystemMapper.getMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(UUID uuid, VersionedProfile versionedProfile) {
|
public void set(UUID uuid, VersionedProfile versionedProfile) {
|
||||||
memcacheSet(uuid, versionedProfile);
|
memcacheSet(uuid, versionedProfile);
|
||||||
profilesDynamoDb.set(uuid, versionedProfile);
|
profiles.set(uuid, versionedProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAll(UUID uuid) {
|
public void deleteAll(UUID uuid) {
|
||||||
memcacheDelete(uuid);
|
memcacheDelete(uuid);
|
||||||
profilesDynamoDb.deleteAll(uuid);
|
profiles.deleteAll(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<VersionedProfile> get(UUID uuid, String version) {
|
public Optional<VersionedProfile> get(UUID uuid, String version) {
|
||||||
Optional<VersionedProfile> profile = memcacheGet(uuid, version);
|
Optional<VersionedProfile> profile = memcacheGet(uuid, version);
|
||||||
|
|
||||||
if (profile.isEmpty()) {
|
if (profile.isEmpty()) {
|
||||||
profile = profilesDynamoDb.get(uuid, version);
|
profile = profiles.get(uuid, version);
|
||||||
profile.ifPresent(versionedProfile -> memcacheSet(uuid, versionedProfile));
|
profile.ifPresent(versionedProfile -> memcacheSet(uuid, versionedProfile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2013-2021 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.storage;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public interface ProfilesStore {
|
|
||||||
|
|
||||||
void set(UUID uuid, VersionedProfile profile);
|
|
||||||
|
|
||||||
Optional<VersionedProfile> get(UUID uuid, String version);
|
|
||||||
|
|
||||||
void deleteAll(UUID uuid);
|
|
||||||
}
|
|
|
@ -49,7 +49,7 @@ import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.MessagesDynamoDb;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.PhoneNumberIdentifiers;
|
import org.whispersystems.textsecuregcm.storage.PhoneNumberIdentifiers;
|
||||||
import org.whispersystems.textsecuregcm.storage.ProfilesDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.Profiles;
|
||||||
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.ReportMessageDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.ReportMessageDynamoDb;
|
||||||
import org.whispersystems.textsecuregcm.storage.ReportMessageManager;
|
import org.whispersystems.textsecuregcm.storage.ReportMessageManager;
|
||||||
|
@ -176,7 +176,7 @@ public class DeleteUserCommand extends EnvironmentCommand<WhisperServerConfigura
|
||||||
configuration.getAccountsDynamoDbConfiguration().getScanPageSize());
|
configuration.getAccountsDynamoDbConfiguration().getScanPageSize());
|
||||||
PhoneNumberIdentifiers phoneNumberIdentifiers = new PhoneNumberIdentifiers(phoneNumberIdentifiersDynamoDbClient,
|
PhoneNumberIdentifiers phoneNumberIdentifiers = new PhoneNumberIdentifiers(phoneNumberIdentifiersDynamoDbClient,
|
||||||
configuration.getPhoneNumberIdentifiersDynamoDbConfiguration().getTableName());
|
configuration.getPhoneNumberIdentifiersDynamoDbConfiguration().getTableName());
|
||||||
ProfilesDynamoDb profilesDynamoDb = new ProfilesDynamoDb(dynamoDbClient, dynamoDbAsyncClient,
|
Profiles profiles = new Profiles(dynamoDbClient, dynamoDbAsyncClient,
|
||||||
configuration.getDynamoDbTables().getProfiles().getTableName());
|
configuration.getDynamoDbTables().getProfiles().getTableName());
|
||||||
ReservedUsernames reservedUsernames = new ReservedUsernames(reservedUsernamesDynamoDbClient,
|
ReservedUsernames reservedUsernames = new ReservedUsernames(reservedUsernamesDynamoDbClient,
|
||||||
configuration.getReservedUsernamesDynamoDbConfiguration().getTableName());
|
configuration.getReservedUsernamesDynamoDbConfiguration().getTableName());
|
||||||
|
@ -206,7 +206,7 @@ public class DeleteUserCommand extends EnvironmentCommand<WhisperServerConfigura
|
||||||
PushLatencyManager pushLatencyManager = new PushLatencyManager(metricsCluster, dynamicConfigurationManager);
|
PushLatencyManager pushLatencyManager = new PushLatencyManager(metricsCluster, dynamicConfigurationManager);
|
||||||
DirectoryQueue directoryQueue = new DirectoryQueue(
|
DirectoryQueue directoryQueue = new DirectoryQueue(
|
||||||
configuration.getDirectoryConfiguration().getSqsConfiguration());
|
configuration.getDirectoryConfiguration().getSqsConfiguration());
|
||||||
ProfilesManager profilesManager = new ProfilesManager(profilesDynamoDb, cacheCluster);
|
ProfilesManager profilesManager = new ProfilesManager(profiles, cacheCluster);
|
||||||
ReportMessageDynamoDb reportMessageDynamoDb = new ReportMessageDynamoDb(reportMessagesDynamoDb,
|
ReportMessageDynamoDb reportMessageDynamoDb = new ReportMessageDynamoDb(reportMessagesDynamoDb,
|
||||||
configuration.getReportMessageDynamoDbConfiguration().getTableName(),
|
configuration.getReportMessageDynamoDbConfiguration().getTableName(),
|
||||||
configuration.getReportMessageConfiguration().getReportTtl());
|
configuration.getReportMessageConfiguration().getReportTtl());
|
||||||
|
|
|
@ -47,7 +47,7 @@ import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.MessagesDynamoDb;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.PhoneNumberIdentifiers;
|
import org.whispersystems.textsecuregcm.storage.PhoneNumberIdentifiers;
|
||||||
import org.whispersystems.textsecuregcm.storage.ProfilesDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.Profiles;
|
||||||
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.ReportMessageDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.ReportMessageDynamoDb;
|
||||||
import org.whispersystems.textsecuregcm.storage.ReportMessageManager;
|
import org.whispersystems.textsecuregcm.storage.ReportMessageManager;
|
||||||
|
@ -180,7 +180,7 @@ public class SetUserDiscoverabilityCommand extends EnvironmentCommand<WhisperSer
|
||||||
configuration.getAccountsDynamoDbConfiguration().getScanPageSize());
|
configuration.getAccountsDynamoDbConfiguration().getScanPageSize());
|
||||||
PhoneNumberIdentifiers phoneNumberIdentifiers = new PhoneNumberIdentifiers(phoneNumberIdentifiersDynamoDbClient,
|
PhoneNumberIdentifiers phoneNumberIdentifiers = new PhoneNumberIdentifiers(phoneNumberIdentifiersDynamoDbClient,
|
||||||
configuration.getPhoneNumberIdentifiersDynamoDbConfiguration().getTableName());
|
configuration.getPhoneNumberIdentifiersDynamoDbConfiguration().getTableName());
|
||||||
ProfilesDynamoDb profilesDynamoDb = new ProfilesDynamoDb(dynamoDbClient, dynamoDbAsyncClient,
|
Profiles profiles = new Profiles(dynamoDbClient, dynamoDbAsyncClient,
|
||||||
configuration.getDynamoDbTables().getProfiles().getTableName());
|
configuration.getDynamoDbTables().getProfiles().getTableName());
|
||||||
ReservedUsernames reservedUsernames = new ReservedUsernames(reservedUsernamesDynamoDbClient,
|
ReservedUsernames reservedUsernames = new ReservedUsernames(reservedUsernamesDynamoDbClient,
|
||||||
configuration.getReservedUsernamesDynamoDbConfiguration().getTableName());
|
configuration.getReservedUsernamesDynamoDbConfiguration().getTableName());
|
||||||
|
@ -208,7 +208,7 @@ public class SetUserDiscoverabilityCommand extends EnvironmentCommand<WhisperSer
|
||||||
PushLatencyManager pushLatencyManager = new PushLatencyManager(metricsCluster, dynamicConfigurationManager);
|
PushLatencyManager pushLatencyManager = new PushLatencyManager(metricsCluster, dynamicConfigurationManager);
|
||||||
DirectoryQueue directoryQueue = new DirectoryQueue(
|
DirectoryQueue directoryQueue = new DirectoryQueue(
|
||||||
configuration.getDirectoryConfiguration().getSqsConfiguration());
|
configuration.getDirectoryConfiguration().getSqsConfiguration());
|
||||||
ProfilesManager profilesManager = new ProfilesManager(profilesDynamoDb, cacheCluster);
|
ProfilesManager profilesManager = new ProfilesManager(profiles, cacheCluster);
|
||||||
ReportMessageDynamoDb reportMessageDynamoDb = new ReportMessageDynamoDb(reportMessagesDynamoDb,
|
ReportMessageDynamoDb reportMessageDynamoDb = new ReportMessageDynamoDb(reportMessagesDynamoDb,
|
||||||
configuration.getReportMessageDynamoDbConfiguration().getTableName(),
|
configuration.getReportMessageDynamoDbConfiguration().getTableName(),
|
||||||
configuration.getReportMessageConfiguration().getReportTtl());
|
configuration.getReportMessageConfiguration().getReportTtl());
|
||||||
|
|
|
@ -1,147 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2013-2021 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.storage;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
|
||||||
import org.whispersystems.textsecuregcm.util.AttributeValues;
|
|
||||||
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
|
|
||||||
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
|
|
||||||
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
|
|
||||||
|
|
||||||
class ProfilesDynamoDbTest extends ProfilesTest {
|
|
||||||
|
|
||||||
private static final String PROFILES_TABLE_NAME = "profiles_test";
|
|
||||||
|
|
||||||
@RegisterExtension
|
|
||||||
static DynamoDbExtension dynamoDbExtension = DynamoDbExtension.builder()
|
|
||||||
.tableName(PROFILES_TABLE_NAME)
|
|
||||||
.hashKey(ProfilesDynamoDb.KEY_ACCOUNT_UUID)
|
|
||||||
.rangeKey(ProfilesDynamoDb.ATTR_VERSION)
|
|
||||||
.attributeDefinition(AttributeDefinition.builder()
|
|
||||||
.attributeName(ProfilesDynamoDb.KEY_ACCOUNT_UUID)
|
|
||||||
.attributeType(ScalarAttributeType.B)
|
|
||||||
.build())
|
|
||||||
.attributeDefinition(AttributeDefinition.builder()
|
|
||||||
.attributeName(ProfilesDynamoDb.ATTR_VERSION)
|
|
||||||
.attributeType(ScalarAttributeType.S)
|
|
||||||
.build())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private ProfilesDynamoDb profiles;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setUp() {
|
|
||||||
profiles = new ProfilesDynamoDb(dynamoDbExtension.getDynamoDbClient(),
|
|
||||||
dynamoDbExtension.getDynamoDbAsyncClient(),
|
|
||||||
PROFILES_TABLE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ProfilesStore getProfilesStore() {
|
|
||||||
return profiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource
|
|
||||||
void buildUpdateExpression(final VersionedProfile profile, final String expectedUpdateExpression) {
|
|
||||||
assertEquals(expectedUpdateExpression, ProfilesDynamoDb.buildUpdateExpression(profile));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Stream<Arguments> buildUpdateExpression() {
|
|
||||||
final byte[] commitment = "commitment".getBytes(StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
return Stream.of(
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", "avatar", "emoji", "about", "paymentAddress", commitment),
|
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji, #paymentAddress = :paymentAddress"),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", "avatar", "emoji", "about", null, commitment),
|
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji REMOVE #paymentAddress"),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", "avatar", "emoji", null, null, commitment),
|
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #aboutEmoji = :aboutEmoji REMOVE #about, #paymentAddress"),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", "avatar", null, null, null, commitment),
|
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar REMOVE #about, #aboutEmoji, #paymentAddress"),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", null, null, null, null, commitment),
|
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name REMOVE #avatar, #about, #aboutEmoji, #paymentAddress"),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", null, null, null, null, null, commitment),
|
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment) REMOVE #name, #avatar, #about, #aboutEmoji, #paymentAddress")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@MethodSource
|
|
||||||
void buildUpdateExpressionAttributeValues(final VersionedProfile profile, final Map<String, AttributeValue> expectedAttributeValues) {
|
|
||||||
assertEquals(expectedAttributeValues, ProfilesDynamoDb.buildUpdateExpressionAttributeValues(profile));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Stream<Arguments> buildUpdateExpressionAttributeValues() {
|
|
||||||
final byte[] commitment = "commitment".getBytes(StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
return Stream.of(
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", "avatar", "emoji", "about", "paymentAddress", commitment),
|
|
||||||
Map.of(
|
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
|
||||||
":name", AttributeValues.fromString("name"),
|
|
||||||
":avatar", AttributeValues.fromString("avatar"),
|
|
||||||
":aboutEmoji", AttributeValues.fromString("emoji"),
|
|
||||||
":about", AttributeValues.fromString("about"),
|
|
||||||
":paymentAddress", AttributeValues.fromString("paymentAddress"))),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", "avatar", "emoji", "about", null, commitment),
|
|
||||||
Map.of(
|
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
|
||||||
":name", AttributeValues.fromString("name"),
|
|
||||||
":avatar", AttributeValues.fromString("avatar"),
|
|
||||||
":aboutEmoji", AttributeValues.fromString("emoji"),
|
|
||||||
":about", AttributeValues.fromString("about"))),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", "avatar", "emoji", null, null, commitment),
|
|
||||||
Map.of(
|
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
|
||||||
":name", AttributeValues.fromString("name"),
|
|
||||||
":avatar", AttributeValues.fromString("avatar"),
|
|
||||||
":aboutEmoji", AttributeValues.fromString("emoji"))),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", "avatar", null, null, null, commitment),
|
|
||||||
Map.of(
|
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
|
||||||
":name", AttributeValues.fromString("name"),
|
|
||||||
":avatar", AttributeValues.fromString("avatar"))),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", "name", null, null, null, null, commitment),
|
|
||||||
Map.of(
|
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
|
||||||
":name", AttributeValues.fromString("name"))),
|
|
||||||
|
|
||||||
Arguments.of(
|
|
||||||
new VersionedProfile("version", null, null, null, null, null, commitment),
|
|
||||||
Map.of(":commitment", AttributeValues.fromByteArray(commitment)))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,20 +5,56 @@
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.storage;
|
package org.whispersystems.textsecuregcm.storage;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.whispersystems.textsecuregcm.util.AttributeValues;
|
||||||
|
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
|
||||||
|
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
|
||||||
|
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
|
||||||
|
|
||||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import org.junit.jupiter.api.Test;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public abstract class ProfilesTest {
|
public abstract class ProfilesTest {
|
||||||
|
|
||||||
protected abstract ProfilesStore getProfilesStore();
|
private static final String PROFILES_TABLE_NAME = "profiles_test";
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static DynamoDbExtension dynamoDbExtension = DynamoDbExtension.builder()
|
||||||
|
.tableName(PROFILES_TABLE_NAME)
|
||||||
|
.hashKey(Profiles.KEY_ACCOUNT_UUID)
|
||||||
|
.rangeKey(Profiles.ATTR_VERSION)
|
||||||
|
.attributeDefinition(AttributeDefinition.builder()
|
||||||
|
.attributeName(Profiles.KEY_ACCOUNT_UUID)
|
||||||
|
.attributeType(ScalarAttributeType.B)
|
||||||
|
.build())
|
||||||
|
.attributeDefinition(AttributeDefinition.builder()
|
||||||
|
.attributeName(Profiles.ATTR_VERSION)
|
||||||
|
.attributeType(ScalarAttributeType.S)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
private Profiles profiles;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
profiles = new Profiles(dynamoDbExtension.getDynamoDbClient(),
|
||||||
|
dynamoDbExtension.getDynamoDbAsyncClient(),
|
||||||
|
PROFILES_TABLE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSetGet() {
|
void testSetGet() {
|
||||||
ProfilesStore profiles = getProfilesStore();
|
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", "emoji",
|
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", "emoji",
|
||||||
"the very model of a modern major general",
|
"the very model of a modern major general",
|
||||||
|
@ -37,7 +73,6 @@ public abstract class ProfilesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDeleteReset() {
|
void testDeleteReset() {
|
||||||
ProfilesStore profiles = getProfilesStore();
|
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
profiles.set(uuid, new VersionedProfile("123", "foo", "avatarLocation", "emoji",
|
profiles.set(uuid, new VersionedProfile("123", "foo", "avatarLocation", "emoji",
|
||||||
"the very model of a modern major general",
|
"the very model of a modern major general",
|
||||||
|
@ -62,7 +97,6 @@ public abstract class ProfilesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSetGetNullOptionalFields() {
|
void testSetGetNullOptionalFields() {
|
||||||
ProfilesStore profiles = getProfilesStore();
|
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
VersionedProfile profile = new VersionedProfile("123", "foo", null, null, null, null,
|
VersionedProfile profile = new VersionedProfile("123", "foo", null, null, null, null,
|
||||||
"acommitment".getBytes());
|
"acommitment".getBytes());
|
||||||
|
@ -80,7 +114,6 @@ public abstract class ProfilesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSetReplace() {
|
void testSetReplace() {
|
||||||
ProfilesStore profiles = getProfilesStore();
|
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
||||||
"paymentAddress", "acommitment".getBytes());
|
"paymentAddress", "acommitment".getBytes());
|
||||||
|
@ -113,7 +146,6 @@ public abstract class ProfilesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMultipleVersions() {
|
void testMultipleVersions() {
|
||||||
ProfilesStore profiles = getProfilesStore();
|
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
VersionedProfile profileOne = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
VersionedProfile profileOne = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
||||||
null, "acommitmnet".getBytes());
|
null, "acommitmnet".getBytes());
|
||||||
|
@ -145,7 +177,6 @@ public abstract class ProfilesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMissing() {
|
void testMissing() {
|
||||||
ProfilesStore profiles = getProfilesStore();
|
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
VersionedProfile profile = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
||||||
null, "aDigest".getBytes());
|
null, "aDigest".getBytes());
|
||||||
|
@ -158,7 +189,6 @@ public abstract class ProfilesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDelete() {
|
void testDelete() {
|
||||||
ProfilesStore profiles = getProfilesStore();
|
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
VersionedProfile profileOne = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
VersionedProfile profileOne = new VersionedProfile("123", "foo", "avatarLocation", null, null,
|
||||||
null, "aDigest".getBytes());
|
null, "aDigest".getBytes());
|
||||||
|
@ -177,4 +207,96 @@ public abstract class ProfilesTest {
|
||||||
|
|
||||||
assertThat(retrieved.isPresent()).isFalse();
|
assertThat(retrieved.isPresent()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource
|
||||||
|
void buildUpdateExpression(final VersionedProfile profile, final String expectedUpdateExpression) {
|
||||||
|
assertEquals(expectedUpdateExpression, Profiles.buildUpdateExpression(profile));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> buildUpdateExpression() {
|
||||||
|
final byte[] commitment = "commitment".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", "avatar", "emoji", "about", "paymentAddress", commitment),
|
||||||
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji, #paymentAddress = :paymentAddress"),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", "avatar", "emoji", "about", null, commitment),
|
||||||
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji REMOVE #paymentAddress"),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", "avatar", "emoji", null, null, commitment),
|
||||||
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #aboutEmoji = :aboutEmoji REMOVE #about, #paymentAddress"),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", "avatar", null, null, null, commitment),
|
||||||
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar REMOVE #about, #aboutEmoji, #paymentAddress"),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", null, null, null, null, commitment),
|
||||||
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name REMOVE #avatar, #about, #aboutEmoji, #paymentAddress"),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", null, null, null, null, null, commitment),
|
||||||
|
"SET #commitment = if_not_exists(#commitment, :commitment) REMOVE #name, #avatar, #about, #aboutEmoji, #paymentAddress")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource
|
||||||
|
void buildUpdateExpressionAttributeValues(final VersionedProfile profile, final Map<String, AttributeValue> expectedAttributeValues) {
|
||||||
|
assertEquals(expectedAttributeValues, Profiles.buildUpdateExpressionAttributeValues(profile));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> buildUpdateExpressionAttributeValues() {
|
||||||
|
final byte[] commitment = "commitment".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", "avatar", "emoji", "about", "paymentAddress", commitment),
|
||||||
|
Map.of(
|
||||||
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
|
":name", AttributeValues.fromString("name"),
|
||||||
|
":avatar", AttributeValues.fromString("avatar"),
|
||||||
|
":aboutEmoji", AttributeValues.fromString("emoji"),
|
||||||
|
":about", AttributeValues.fromString("about"),
|
||||||
|
":paymentAddress", AttributeValues.fromString("paymentAddress"))),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", "avatar", "emoji", "about", null, commitment),
|
||||||
|
Map.of(
|
||||||
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
|
":name", AttributeValues.fromString("name"),
|
||||||
|
":avatar", AttributeValues.fromString("avatar"),
|
||||||
|
":aboutEmoji", AttributeValues.fromString("emoji"),
|
||||||
|
":about", AttributeValues.fromString("about"))),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", "avatar", "emoji", null, null, commitment),
|
||||||
|
Map.of(
|
||||||
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
|
":name", AttributeValues.fromString("name"),
|
||||||
|
":avatar", AttributeValues.fromString("avatar"),
|
||||||
|
":aboutEmoji", AttributeValues.fromString("emoji"))),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", "avatar", null, null, null, commitment),
|
||||||
|
Map.of(
|
||||||
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
|
":name", AttributeValues.fromString("name"),
|
||||||
|
":avatar", AttributeValues.fromString("avatar"))),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", "name", null, null, null, null, commitment),
|
||||||
|
Map.of(
|
||||||
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
|
":name", AttributeValues.fromString("name"))),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile("version", null, null, null, null, null, commitment),
|
||||||
|
Map.of(":commitment", AttributeValues.fromByteArray(commitment)))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,14 +25,14 @@ import java.util.UUID;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
|
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
|
||||||
import org.whispersystems.textsecuregcm.storage.ProfilesDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.Profiles;
|
||||||
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.VersionedProfile;
|
import org.whispersystems.textsecuregcm.storage.VersionedProfile;
|
||||||
import org.whispersystems.textsecuregcm.tests.util.RedisClusterHelper;
|
import org.whispersystems.textsecuregcm.tests.util.RedisClusterHelper;
|
||||||
|
|
||||||
public class ProfilesManagerTest {
|
public class ProfilesManagerTest {
|
||||||
|
|
||||||
private ProfilesDynamoDb profiles;
|
private Profiles profiles;
|
||||||
private RedisAdvancedClusterCommands<String, String> commands;
|
private RedisAdvancedClusterCommands<String, String> commands;
|
||||||
|
|
||||||
private ProfilesManager profilesManager;
|
private ProfilesManager profilesManager;
|
||||||
|
@ -43,7 +43,7 @@ public class ProfilesManagerTest {
|
||||||
commands = mock(RedisAdvancedClusterCommands.class);
|
commands = mock(RedisAdvancedClusterCommands.class);
|
||||||
final FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
final FaultTolerantRedisCluster cacheCluster = RedisClusterHelper.buildMockRedisCluster(commands);
|
||||||
|
|
||||||
profiles = mock(ProfilesDynamoDb.class);
|
profiles = mock(Profiles.class);
|
||||||
|
|
||||||
profilesManager = new ProfilesManager(profiles, cacheCluster);
|
profilesManager = new ProfilesManager(profiles, cacheCluster);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue