mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-22 00:18:06 +01:00
Drop the old Postgres-based pre-key store.
This commit is contained in:
committed by
Jon Chambers
parent
6865cdfce3
commit
04728ea4bc
@@ -29,7 +29,6 @@ import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.storage.KeyRecord;
|
||||
import org.whispersystems.textsecuregcm.storage.Keys;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysDynamoDb;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
|
||||
|
||||
@@ -71,12 +70,10 @@ public class KeysControllerTest {
|
||||
private final SignedPreKey SAMPLE_SIGNED_KEY3 = new SignedPreKey( 3333, "barfoo", "sig33" );
|
||||
private final SignedPreKey VALID_DEVICE_SIGNED_KEY = new SignedPreKey(89898, "zoofarb", "sigvalid");
|
||||
|
||||
private final Keys keys = mock(Keys.class );
|
||||
private final KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class );
|
||||
private final AccountsManager accounts = mock(AccountsManager.class );
|
||||
private final DirectoryQueue directoryQueue = mock(DirectoryQueue.class );
|
||||
private final Account existsAccount = mock(Account.class );
|
||||
private final ExperimentEnrollmentManager experimentEnrollmentManager = mock(ExperimentEnrollmentManager.class);
|
||||
|
||||
private RateLimiters rateLimiters = mock(RateLimiters.class);
|
||||
private RateLimiter rateLimiter = mock(RateLimiter.class );
|
||||
@@ -86,7 +83,7 @@ public class KeysControllerTest {
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new PolymorphicAuthValueFactoryProvider.Binder<>(ImmutableSet.of(Account.class, DisabledPermittedAccount.class)))
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new KeysController(rateLimiters, keys, keysDynamoDb, accounts, directoryQueue, experimentEnrollmentManager))
|
||||
.addResource(new KeysController(rateLimiters, keysDynamoDb, accounts, directoryQueue))
|
||||
.build();
|
||||
|
||||
@Before
|
||||
@@ -145,16 +142,16 @@ public class KeysControllerTest {
|
||||
|
||||
List<KeyRecord> singleDevice = new LinkedList<>();
|
||||
singleDevice.add(SAMPLE_KEY);
|
||||
when(keys.take(eq(existsAccount), eq(1L))).thenReturn(singleDevice);
|
||||
when(keysDynamoDb.take(eq(existsAccount), eq(1L))).thenReturn(singleDevice);
|
||||
|
||||
List<KeyRecord> multiDevice = new LinkedList<>();
|
||||
multiDevice.add(SAMPLE_KEY);
|
||||
multiDevice.add(SAMPLE_KEY2);
|
||||
multiDevice.add(SAMPLE_KEY3);
|
||||
multiDevice.add(SAMPLE_KEY4);
|
||||
when(keys.take(existsAccount)).thenReturn(multiDevice);
|
||||
when(keysDynamoDb.take(existsAccount)).thenReturn(multiDevice);
|
||||
|
||||
when(keys.getCount(eq(AuthHelper.VALID_ACCOUNT), eq(1L))).thenReturn(5);
|
||||
when(keysDynamoDb.getCount(eq(AuthHelper.VALID_ACCOUNT), eq(1L))).thenReturn(5);
|
||||
|
||||
when(AuthHelper.VALID_DEVICE.getSignedPreKey()).thenReturn(VALID_DEVICE_SIGNED_KEY);
|
||||
when(AuthHelper.VALID_ACCOUNT.getIdentityKey()).thenReturn(null);
|
||||
@@ -171,7 +168,7 @@ public class KeysControllerTest {
|
||||
|
||||
assertThat(result.getCount()).isEqualTo(4);
|
||||
|
||||
verify(keys).getCount(eq(AuthHelper.VALID_ACCOUNT), eq(1L));
|
||||
verify(keysDynamoDb).getCount(eq(AuthHelper.VALID_ACCOUNT), eq(1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -185,7 +182,7 @@ public class KeysControllerTest {
|
||||
|
||||
assertThat(result.getCount()).isEqualTo(4);
|
||||
|
||||
verify(keys).getCount(eq(AuthHelper.VALID_ACCOUNT), eq(1L));
|
||||
verify(keysDynamoDb).getCount(eq(AuthHelper.VALID_ACCOUNT), eq(1L));
|
||||
}
|
||||
|
||||
|
||||
@@ -285,8 +282,8 @@ public class KeysControllerTest {
|
||||
assertThat(result.getDevice(1).getPreKey().getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey());
|
||||
assertThat(result.getDevice(1).getSignedPreKey()).isEqualTo(existsAccount.getDevice(1).get().getSignedPreKey());
|
||||
|
||||
verify(keys).take(eq(existsAccount), eq(1L));
|
||||
verifyNoMoreInteractions(keys);
|
||||
verify(keysDynamoDb).take(eq(existsAccount), eq(1L));
|
||||
verifyNoMoreInteractions(keysDynamoDb);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -303,8 +300,8 @@ public class KeysControllerTest {
|
||||
assertThat(result.getDevice(1).getPreKey().getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey());
|
||||
assertThat(result.getDevice(1).getSignedPreKey()).isEqualTo(existsAccount.getDevice(1).get().getSignedPreKey());
|
||||
|
||||
verify(keys).take(eq(existsAccount), eq(1L));
|
||||
verifyNoMoreInteractions(keys);
|
||||
verify(keysDynamoDb).take(eq(existsAccount), eq(1L));
|
||||
verifyNoMoreInteractions(keysDynamoDb);
|
||||
}
|
||||
|
||||
|
||||
@@ -322,8 +319,8 @@ public class KeysControllerTest {
|
||||
assertThat(result.getDevice(1).getPreKey().getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey());
|
||||
assertThat(result.getDevice(1).getSignedPreKey()).isEqualTo(existsAccount.getDevice(1).get().getSignedPreKey());
|
||||
|
||||
verify(keys).take(eq(existsAccount), eq(1L));
|
||||
verifyNoMoreInteractions(keys);
|
||||
verify(keysDynamoDb).take(eq(existsAccount), eq(1L));
|
||||
verifyNoMoreInteractions(keysDynamoDb);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -340,8 +337,8 @@ public class KeysControllerTest {
|
||||
assertThat(result.getDevice(1).getPreKey().getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey());
|
||||
assertThat(result.getDevice(1).getSignedPreKey()).isEqualTo(existsAccount.getDevice(1).get().getSignedPreKey());
|
||||
|
||||
verify(keys).take(eq(existsAccount), eq(1L));
|
||||
verifyNoMoreInteractions(keys);
|
||||
verify(keysDynamoDb).take(eq(existsAccount), eq(1L));
|
||||
verifyNoMoreInteractions(keysDynamoDb);
|
||||
}
|
||||
|
||||
|
||||
@@ -354,7 +351,7 @@ public class KeysControllerTest {
|
||||
.get();
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
verifyNoMoreInteractions(keys);
|
||||
verifyNoMoreInteractions(keysDynamoDb);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -366,7 +363,7 @@ public class KeysControllerTest {
|
||||
.get();
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
verifyNoMoreInteractions(keys);
|
||||
verifyNoMoreInteractions(keysDynamoDb);
|
||||
}
|
||||
|
||||
|
||||
@@ -416,8 +413,8 @@ public class KeysControllerTest {
|
||||
assertThat(signedPreKey).isNull();
|
||||
assertThat(deviceId).isEqualTo(4);
|
||||
|
||||
verify(keys).take(eq(existsAccount));
|
||||
verifyNoMoreInteractions(keys);
|
||||
verify(keysDynamoDb).take(eq(existsAccount));
|
||||
verifyNoMoreInteractions(keysDynamoDb);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -466,8 +463,8 @@ public class KeysControllerTest {
|
||||
assertThat(signedPreKey).isNull();
|
||||
assertThat(deviceId).isEqualTo(4);
|
||||
|
||||
verify(keys).take(eq(existsAccount));
|
||||
verifyNoMoreInteractions(keys);
|
||||
verify(keysDynamoDb).take(eq(existsAccount));
|
||||
verifyNoMoreInteractions(keysDynamoDb);
|
||||
}
|
||||
|
||||
|
||||
@@ -535,7 +532,7 @@ public class KeysControllerTest {
|
||||
assertThat(response.getStatus()).isEqualTo(204);
|
||||
|
||||
ArgumentCaptor<List> listCaptor = ArgumentCaptor.forClass(List.class);
|
||||
verify(keys).store(eq(AuthHelper.VALID_ACCOUNT), eq(1L), listCaptor.capture());
|
||||
verify(keysDynamoDb).store(eq(AuthHelper.VALID_ACCOUNT), eq(1L), listCaptor.capture());
|
||||
|
||||
List<PreKey> capturedList = listCaptor.getValue();
|
||||
assertThat(capturedList.size()).isEqualTo(1);
|
||||
@@ -569,7 +566,7 @@ public class KeysControllerTest {
|
||||
assertThat(response.getStatus()).isEqualTo(204);
|
||||
|
||||
ArgumentCaptor<List> listCaptor = ArgumentCaptor.forClass(List.class);
|
||||
verify(keys).store(eq(AuthHelper.DISABLED_ACCOUNT), eq(1L), listCaptor.capture());
|
||||
verify(keysDynamoDb).store(eq(AuthHelper.DISABLED_ACCOUNT), eq(1L), listCaptor.capture());
|
||||
|
||||
List<PreKey> capturedList = listCaptor.getValue();
|
||||
assertThat(capturedList.size()).isEqualTo(1);
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.Accounts;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.DirectoryManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Keys;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysDynamoDb;
|
||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
|
||||
@@ -45,7 +44,6 @@ public class AccountsManagerTest {
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
DirectoryManager directoryManager = mock(DirectoryManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
Keys keys = mock(Keys.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
@@ -56,7 +54,7 @@ public class AccountsManagerTest {
|
||||
when(commands.get(eq("AccountMap::+14152222222"))).thenReturn(uuid.toString());
|
||||
when(commands.get(eq("Account3::" + uuid.toString()))).thenReturn("{\"number\": \"+14152222222\", \"name\": \"test\"}");
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keys, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
Optional<Account> account = accountsManager.get("+14152222222");
|
||||
|
||||
assertTrue(account.isPresent());
|
||||
@@ -76,7 +74,6 @@ public class AccountsManagerTest {
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
DirectoryManager directoryManager = mock(DirectoryManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
Keys keys = mock(Keys.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
@@ -86,7 +83,7 @@ public class AccountsManagerTest {
|
||||
|
||||
when(commands.get(eq("Account3::" + uuid.toString()))).thenReturn("{\"number\": \"+14152222222\", \"name\": \"test\"}");
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keys, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
Optional<Account> account = accountsManager.get(uuid);
|
||||
|
||||
assertTrue(account.isPresent());
|
||||
@@ -107,7 +104,6 @@ public class AccountsManagerTest {
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
DirectoryManager directoryManager = mock(DirectoryManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
Keys keys = mock(Keys.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
@@ -118,7 +114,7 @@ public class AccountsManagerTest {
|
||||
when(commands.get(eq("AccountMap::+14152222222"))).thenReturn(null);
|
||||
when(accounts.get(eq("+14152222222"))).thenReturn(Optional.of(account));
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keys, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
Optional<Account> retrieved = accountsManager.get("+14152222222");
|
||||
|
||||
assertTrue(retrieved.isPresent());
|
||||
@@ -140,7 +136,6 @@ public class AccountsManagerTest {
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
DirectoryManager directoryManager = mock(DirectoryManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
Keys keys = mock(Keys.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
@@ -151,7 +146,7 @@ public class AccountsManagerTest {
|
||||
when(commands.get(eq("Account3::" + uuid))).thenReturn(null);
|
||||
when(accounts.get(eq(uuid))).thenReturn(Optional.of(account));
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keys, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
Optional<Account> retrieved = accountsManager.get(uuid);
|
||||
|
||||
assertTrue(retrieved.isPresent());
|
||||
@@ -173,7 +168,6 @@ public class AccountsManagerTest {
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
DirectoryManager directoryManager = mock(DirectoryManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
Keys keys = mock(Keys.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
@@ -184,7 +178,7 @@ public class AccountsManagerTest {
|
||||
when(commands.get(eq("AccountMap::+14152222222"))).thenThrow(new RedisException("Connection lost!"));
|
||||
when(accounts.get(eq("+14152222222"))).thenReturn(Optional.of(account));
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keys, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
Optional<Account> retrieved = accountsManager.get("+14152222222");
|
||||
|
||||
assertTrue(retrieved.isPresent());
|
||||
@@ -206,7 +200,6 @@ public class AccountsManagerTest {
|
||||
Accounts accounts = mock(Accounts.class);
|
||||
DirectoryManager directoryManager = mock(DirectoryManager.class);
|
||||
DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
Keys keys = mock(Keys.class);
|
||||
KeysDynamoDb keysDynamoDb = mock(KeysDynamoDb.class);
|
||||
MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
UsernamesManager usernamesManager = mock(UsernamesManager.class);
|
||||
@@ -217,7 +210,7 @@ public class AccountsManagerTest {
|
||||
when(commands.get(eq("Account3::" + uuid))).thenThrow(new RedisException("Connection lost!"));
|
||||
when(accounts.get(eq(uuid))).thenReturn(Optional.of(account));
|
||||
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keys, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directoryManager, cacheCluster, directoryQueue, keysDynamoDb, messagesManager, usernamesManager, profilesManager);
|
||||
Optional<Account> retrieved = accountsManager.get(uuid);
|
||||
|
||||
assertTrue(retrieved.isPresent());
|
||||
|
||||
@@ -1,462 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2020 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.tests.storage;
|
||||
|
||||
import com.opentable.db.postgres.embedded.LiquibasePreparer;
|
||||
import com.opentable.db.postgres.junit.EmbeddedPostgresRules;
|
||||
import com.opentable.db.postgres.junit.PreparedDbRule;
|
||||
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
|
||||
import org.jdbi.v3.core.HandleCallback;
|
||||
import org.jdbi.v3.core.HandleConsumer;
|
||||
import org.jdbi.v3.core.Jdbi;
|
||||
import org.jdbi.v3.core.statement.UnableToExecuteStatementException;
|
||||
import org.jdbi.v3.core.transaction.SerializableTransactionRunner;
|
||||
import org.jdbi.v3.core.transaction.TransactionException;
|
||||
import org.jdbi.v3.core.transaction.TransactionIsolationLevel;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.AccountsDatabaseConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.RetryConfiguration;
|
||||
import org.whispersystems.textsecuregcm.entities.PreKey;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.FaultTolerantDatabase;
|
||||
import org.whispersystems.textsecuregcm.storage.KeyRecord;
|
||||
import org.whispersystems.textsecuregcm.storage.Keys;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class KeysTest {
|
||||
|
||||
@Rule
|
||||
public PreparedDbRule db = EmbeddedPostgresRules.preparedDatabase(LiquibasePreparer.forClasspathLocation("accountsdb.xml"));
|
||||
|
||||
private Account firstAccount;
|
||||
private Account secondAccount;
|
||||
private Keys keys;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
FaultTolerantDatabase faultTolerantDatabase = new FaultTolerantDatabase("keysTest",
|
||||
Jdbi.create(db.getTestDatabase()),
|
||||
new CircuitBreakerConfiguration());
|
||||
|
||||
this.keys = new Keys(faultTolerantDatabase, new RetryConfiguration());
|
||||
|
||||
this.firstAccount = mock(Account.class);
|
||||
this.secondAccount = mock(Account.class);
|
||||
|
||||
when(firstAccount.getNumber()).thenReturn("+14152222222");
|
||||
when(secondAccount.getNumber()).thenReturn("+14151111111");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPopulateKeys() throws SQLException {
|
||||
List<PreKey> deviceOnePreKeys = new LinkedList<>();
|
||||
List<PreKey> deviceTwoPreKeys = new LinkedList<>();
|
||||
|
||||
List<PreKey> oldAnotherDeviceOnePrKeys = new LinkedList<>();
|
||||
List<PreKey> anotherDeviceOnePreKeys = new LinkedList<>();
|
||||
List<PreKey> anotherDeviceTwoPreKeys = new LinkedList<>();
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
deviceOnePreKeys.add(new PreKey(i, "+14152222222Device1PublicKey" + i));
|
||||
deviceTwoPreKeys.add(new PreKey(i, "+14152222222Device2PublicKey" + i));
|
||||
}
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
oldAnotherDeviceOnePrKeys.add(new PreKey(i, "OldPublicKey" + i));
|
||||
anotherDeviceOnePreKeys.add(new PreKey(i, "+14151111111Device1PublicKey" + i));
|
||||
anotherDeviceTwoPreKeys.add(new PreKey(i, "+14151111111Device2PublicKey" + i));
|
||||
}
|
||||
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
keys.store(firstAccount, 2, deviceTwoPreKeys);
|
||||
|
||||
keys.store(secondAccount, 1, oldAnotherDeviceOnePrKeys);
|
||||
keys.store(secondAccount, 1, anotherDeviceOnePreKeys);
|
||||
keys.store(secondAccount, 2, anotherDeviceTwoPreKeys);
|
||||
|
||||
PreparedStatement statement = db.getTestDatabase().getConnection().prepareStatement("SELECT * FROM keys WHERE number = ? AND device_id = ? ORDER BY key_id");
|
||||
verifyStoredState(statement, firstAccount, 1);
|
||||
verifyStoredState(statement, firstAccount, 2);
|
||||
verifyStoredState(statement, secondAccount, 1);
|
||||
verifyStoredState(statement, secondAccount, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyCount() {
|
||||
List<PreKey> deviceOnePreKeys = new LinkedList<>();
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
deviceOnePreKeys.add(new PreKey(i, "+14152222222Device1PublicKey" + i));
|
||||
}
|
||||
|
||||
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(100);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testGetForDevice() {
|
||||
List<PreKey> deviceOnePreKeys = new LinkedList<>();
|
||||
List<PreKey> deviceTwoPreKeys = new LinkedList<>();
|
||||
|
||||
List<PreKey> anotherDeviceOnePreKeys = new LinkedList<>();
|
||||
List<PreKey> anotherDeviceTwoPreKeys = new LinkedList<>();
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
deviceOnePreKeys.add(new PreKey(i, "+14152222222Device1PublicKey" + i));
|
||||
deviceTwoPreKeys.add(new PreKey(i, "+14152222222Device2PublicKey" + i));
|
||||
}
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
anotherDeviceOnePreKeys.add(new PreKey(i, "+14151111111Device1PublicKey" + i));
|
||||
anotherDeviceTwoPreKeys.add(new PreKey(i, "+14151111111Device2PublicKey" + i));
|
||||
}
|
||||
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
keys.store(firstAccount, 2, deviceTwoPreKeys);
|
||||
|
||||
keys.store(secondAccount, 1, anotherDeviceOnePreKeys);
|
||||
keys.store(secondAccount, 2, anotherDeviceTwoPreKeys);
|
||||
|
||||
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(100);
|
||||
List<KeyRecord> records = keys.take(firstAccount, 1);
|
||||
|
||||
assertThat(records.size()).isEqualTo(1);
|
||||
assertThat(records.get(0).getKeyId()).isEqualTo(1);
|
||||
assertThat(records.get(0).getPublicKey()).isEqualTo("+14152222222Device1PublicKey1");
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(99);
|
||||
assertThat(keys.getCount(firstAccount, 2)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 1)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 2)).isEqualTo(100);
|
||||
|
||||
records = keys.take(firstAccount, 1);
|
||||
|
||||
assertThat(records.size()).isEqualTo(1);
|
||||
assertThat(records.get(0).getKeyId()).isEqualTo(2);
|
||||
assertThat(records.get(0).getPublicKey()).isEqualTo("+14152222222Device1PublicKey2");
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(98);
|
||||
assertThat(keys.getCount(firstAccount, 2)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 1)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 2)).isEqualTo(100);
|
||||
|
||||
records = keys.take(firstAccount, 2);
|
||||
|
||||
assertThat(records.size()).isEqualTo(1);
|
||||
assertThat(records.get(0).getKeyId()).isEqualTo(1);
|
||||
assertThat(records.get(0).getPublicKey()).isEqualTo("+14152222222Device2PublicKey1");
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(98);
|
||||
assertThat(keys.getCount(firstAccount, 2)).isEqualTo(99);
|
||||
assertThat(keys.getCount(secondAccount, 1)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 2)).isEqualTo(100);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testGetForAllDevices() {
|
||||
List<PreKey> deviceOnePreKeys = new LinkedList<>();
|
||||
List<PreKey> deviceTwoPreKeys = new LinkedList<>();
|
||||
|
||||
List<PreKey> anotherDeviceOnePreKeys = new LinkedList<>();
|
||||
List<PreKey> anotherDeviceTwoPreKeys = new LinkedList<>();
|
||||
List<PreKey> anotherDeviceThreePreKeys = new LinkedList<>();
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
deviceOnePreKeys.add(new PreKey(i, "+14152222222Device1PublicKey" + i));
|
||||
deviceTwoPreKeys.add(new PreKey(i, "+14152222222Device2PublicKey" + i));
|
||||
}
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
anotherDeviceOnePreKeys.add(new PreKey(i, "+14151111111Device1PublicKey" + i));
|
||||
anotherDeviceTwoPreKeys.add(new PreKey(i, "+14151111111Device2PublicKey" + i));
|
||||
anotherDeviceThreePreKeys.add(new PreKey(i, "+14151111111Device3PublicKey" + i));
|
||||
}
|
||||
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
keys.store(firstAccount, 2, deviceTwoPreKeys);
|
||||
|
||||
keys.store(secondAccount, 1, anotherDeviceOnePreKeys);
|
||||
keys.store(secondAccount, 2, anotherDeviceTwoPreKeys);
|
||||
keys.store(secondAccount, 3, anotherDeviceThreePreKeys);
|
||||
|
||||
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(100);
|
||||
assertThat(keys.getCount(firstAccount, 2)).isEqualTo(100);
|
||||
|
||||
List<KeyRecord> records = keys.take(firstAccount);
|
||||
|
||||
assertThat(records.size()).isEqualTo(2);
|
||||
assertThat(records.get(0).getKeyId()).isEqualTo(1);
|
||||
assertThat(records.get(1).getKeyId()).isEqualTo(1);
|
||||
|
||||
assertThat(records.stream().anyMatch(record -> record.getPublicKey().equals("+14152222222Device1PublicKey1"))).isTrue();
|
||||
assertThat(records.stream().anyMatch(record -> record.getPublicKey().equals("+14152222222Device2PublicKey1"))).isTrue();
|
||||
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(99);
|
||||
assertThat(keys.getCount(firstAccount, 2)).isEqualTo(99);
|
||||
|
||||
records = keys.take(firstAccount);
|
||||
|
||||
assertThat(records.size()).isEqualTo(2);
|
||||
assertThat(records.get(0).getKeyId()).isEqualTo(2);
|
||||
assertThat(records.get(1).getKeyId()).isEqualTo(2);
|
||||
|
||||
assertThat(records.stream().anyMatch(record -> record.getPublicKey().equals("+14152222222Device1PublicKey2"))).isTrue();
|
||||
assertThat(records.stream().anyMatch(record -> record.getPublicKey().equals("+14152222222Device2PublicKey2"))).isTrue();
|
||||
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(98);
|
||||
assertThat(keys.getCount(firstAccount, 2)).isEqualTo(98);
|
||||
|
||||
|
||||
records = keys.take(secondAccount);
|
||||
|
||||
assertThat(records.size()).isEqualTo(3);
|
||||
assertThat(records.get(0).getKeyId()).isEqualTo(1);
|
||||
assertThat(records.get(1).getKeyId()).isEqualTo(1);
|
||||
assertThat(records.get(2).getKeyId()).isEqualTo(1);
|
||||
|
||||
assertThat(records.stream().anyMatch(record -> record.getPublicKey().equals("+14151111111Device1PublicKey1"))).isTrue();
|
||||
assertThat(records.stream().anyMatch(record -> record.getPublicKey().equals("+14151111111Device2PublicKey1"))).isTrue();
|
||||
assertThat(records.stream().anyMatch(record -> record.getPublicKey().equals("+14151111111Device3PublicKey1"))).isTrue();
|
||||
|
||||
assertThat(keys.getCount(secondAccount, 1)).isEqualTo(99);
|
||||
assertThat(keys.getCount(secondAccount, 2)).isEqualTo(99);
|
||||
assertThat(keys.getCount(secondAccount, 3)).isEqualTo(99);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testGetForAllDevicesParallel() throws InterruptedException {
|
||||
List<PreKey> deviceOnePreKeys = new LinkedList<>();
|
||||
List<PreKey> deviceTwoPreKeys = new LinkedList<>();
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
deviceOnePreKeys.add(new PreKey(i, "+14152222222Device1PublicKey" + i));
|
||||
deviceTwoPreKeys.add(new PreKey(i, "+14152222222Device2PublicKey" + i));
|
||||
}
|
||||
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
keys.store(firstAccount, 2, deviceTwoPreKeys);
|
||||
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(100);
|
||||
assertThat(keys.getCount(firstAccount, 2)).isEqualTo(100);
|
||||
|
||||
List<Thread> threads = new LinkedList<>();
|
||||
|
||||
for (int i=0;i<20;i++) {
|
||||
Thread thread = new Thread(() -> {
|
||||
List<KeyRecord> results = null;
|
||||
final int MAX_RETRIES = 5;
|
||||
for (int retryAttempt = 0; results == null && retryAttempt < MAX_RETRIES; ++retryAttempt) {
|
||||
try {
|
||||
results = keys.take(firstAccount);
|
||||
} catch (UnableToExecuteStatementException e) {
|
||||
if (retryAttempt == MAX_RETRIES - 1) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
assertThat(results).isNotNull();
|
||||
assertThat(results.size()).isEqualTo(2);
|
||||
});
|
||||
thread.start();
|
||||
threads.add(thread);
|
||||
}
|
||||
|
||||
for (Thread thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(80);
|
||||
assertThat(keys.getCount(firstAccount,2)).isEqualTo(80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() {
|
||||
List<PreKey> deviceOnePreKeys = new LinkedList<>();
|
||||
List<PreKey> deviceTwoPreKeys = new LinkedList<>();
|
||||
|
||||
List<PreKey> anotherDeviceOnePreKeys = new LinkedList<>();
|
||||
List<PreKey> anotherDeviceTwoPreKeys = new LinkedList<>();
|
||||
List<PreKey> anotherDeviceThreePreKeys = new LinkedList<>();
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
deviceOnePreKeys.add(new PreKey(i, "+14152222222Device1PublicKey" + i));
|
||||
deviceTwoPreKeys.add(new PreKey(i, "+14152222222Device2PublicKey" + i));
|
||||
}
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
anotherDeviceOnePreKeys.add(new PreKey(i, "+14151111111Device1PublicKey" + i));
|
||||
anotherDeviceTwoPreKeys.add(new PreKey(i, "+14151111111Device2PublicKey" + i));
|
||||
anotherDeviceThreePreKeys.add(new PreKey(i, "+14151111111Device3PublicKey" + i));
|
||||
}
|
||||
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
keys.store(firstAccount, 2, deviceTwoPreKeys);
|
||||
|
||||
keys.store(secondAccount, 1, anotherDeviceOnePreKeys);
|
||||
keys.store(secondAccount, 2, anotherDeviceTwoPreKeys);
|
||||
keys.store(secondAccount, 3, anotherDeviceThreePreKeys);
|
||||
|
||||
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(100);
|
||||
assertThat(keys.getCount(firstAccount, 2)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 1)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 2)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 3)).isEqualTo(100);
|
||||
|
||||
keys.delete(firstAccount);
|
||||
|
||||
assertThat(keys.getCount(firstAccount, 1)).isEqualTo(0);
|
||||
assertThat(keys.getCount(firstAccount, 2)).isEqualTo(0);
|
||||
assertThat(keys.getCount(secondAccount, 1)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 2)).isEqualTo(100);
|
||||
assertThat(keys.getCount(secondAccount, 3)).isEqualTo(100);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyKeyGet() {
|
||||
List<KeyRecord> records = keys.take(firstAccount);
|
||||
|
||||
assertThat(records.isEmpty()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVacuum() {
|
||||
keys.vacuum();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBreaker() throws InterruptedException {
|
||||
Jdbi jdbi = mock(Jdbi.class);
|
||||
doThrow(new TransactionException("Database error!")).when(jdbi).useTransaction(any(TransactionIsolationLevel.class), any(HandleConsumer.class));
|
||||
when(jdbi.getConfig(any())).thenReturn(mock(SerializableTransactionRunner.Configuration.class));
|
||||
|
||||
CircuitBreakerConfiguration configuration = new CircuitBreakerConfiguration();
|
||||
configuration.setWaitDurationInOpenStateInSeconds(1);
|
||||
configuration.setRingBufferSizeInHalfOpenState(1);
|
||||
configuration.setRingBufferSizeInClosedState(2);
|
||||
configuration.setFailureRateThreshold(50);
|
||||
|
||||
RetryConfiguration retryConfiguration = new RetryConfiguration();
|
||||
retryConfiguration.setMaxAttempts(1);
|
||||
|
||||
Keys keys = new Keys(new FaultTolerantDatabase("testBreaker", jdbi, configuration), retryConfiguration);
|
||||
|
||||
List<PreKey> deviceOnePreKeys = new LinkedList<>();
|
||||
|
||||
for (int i=1;i<=100;i++) {
|
||||
deviceOnePreKeys.add(new PreKey(i, "+14152222222Device1PublicKey" + i));
|
||||
}
|
||||
|
||||
try {
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
throw new AssertionError();
|
||||
} catch (TransactionException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
try {
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
throw new AssertionError();
|
||||
} catch (TransactionException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
try {
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
throw new AssertionError();
|
||||
} catch (CallNotPermittedException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
Thread.sleep(1100);
|
||||
|
||||
try {
|
||||
keys.store(firstAccount, 1, deviceOnePreKeys);
|
||||
throw new AssertionError();
|
||||
} catch (TransactionException e) {
|
||||
// good
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetry() {
|
||||
Jdbi jdbi = mock(Jdbi.class);
|
||||
doThrow(new TransactionException("Database error!")).doNothing().when(jdbi).useTransaction(any(TransactionIsolationLevel.class), any(HandleConsumer.class));
|
||||
when(jdbi.getConfig(any())).thenReturn(mock(SerializableTransactionRunner.Configuration.class));
|
||||
|
||||
Keys keys = new Keys(new FaultTolerantDatabase("testBreaker", jdbi, new CircuitBreakerConfiguration()), new RetryConfiguration());
|
||||
|
||||
// We're happy as long as nothing throws an exception
|
||||
Account account = mock(Account.class);
|
||||
when(account.getNumber()).thenReturn("+18005551234");
|
||||
|
||||
keys.store(account, 1, Collections.emptyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetKeysWithException() {
|
||||
Jdbi jdbi = mock(Jdbi.class);
|
||||
when(jdbi.getConfig(any())).thenReturn(mock(SerializableTransactionRunner.Configuration.class));
|
||||
|
||||
when(jdbi.inTransaction(any(TransactionIsolationLevel.class), any(HandleCallback.class)))
|
||||
.thenThrow(new TransactionException("Database error!"));
|
||||
|
||||
Keys keys = new Keys(new FaultTolerantDatabase("testBreaker", jdbi, new CircuitBreakerConfiguration()), new RetryConfiguration());
|
||||
|
||||
Account account = mock(Account.class);
|
||||
when(account.getNumber()).thenReturn("+18005551234");
|
||||
|
||||
assertThat(keys.take(account)).isEqualTo(Collections.emptyList());
|
||||
assertThat(keys.take(account, 1)).isEqualTo(Collections.emptyList());
|
||||
}
|
||||
|
||||
private void verifyStoredState(PreparedStatement statement, Account account, int deviceId) throws SQLException {
|
||||
statement.setString(1, account.getNumber());
|
||||
statement.setInt(2, deviceId);
|
||||
|
||||
ResultSet resultSet = statement.executeQuery();
|
||||
int rowCount = 1;
|
||||
|
||||
while (resultSet.next()) {
|
||||
long keyId = resultSet.getLong("key_id");
|
||||
String publicKey = resultSet.getString("public_key");
|
||||
|
||||
|
||||
assertThat(keyId).isEqualTo(rowCount);
|
||||
assertThat(publicKey).isEqualTo(account.getNumber() + "Device" + deviceId + "PublicKey" + rowCount);
|
||||
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
resultSet.close();
|
||||
|
||||
assertThat(rowCount).isEqualTo(101);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user