Remove all vestiges of the relational account database
This commit is contained in:
parent
4d2403d619
commit
401953313a
|
@ -221,12 +221,6 @@ abuseDatabase: # Postgresql database configuration
|
||||||
password: password
|
password: password
|
||||||
url: jdbc:postgresql://example.com:5432/abusedb
|
url: jdbc:postgresql://example.com:5432/abusedb
|
||||||
|
|
||||||
accountsDatabase: # Postgresql database configuration
|
|
||||||
driverClass: org.postgresql.Driver
|
|
||||||
user: example
|
|
||||||
password: password
|
|
||||||
url: jdbc:postgresql://example.com:5432/accountsdb
|
|
||||||
|
|
||||||
accountDatabaseCrawler:
|
accountDatabaseCrawler:
|
||||||
chunkSize: 10 # accounts per run
|
chunkSize: 10 # accounts per run
|
||||||
chunkIntervalMs: 60000 # time per run
|
chunkIntervalMs: 60000 # time per run
|
||||||
|
|
|
@ -15,7 +15,6 @@ import javax.validation.Valid;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import org.whispersystems.textsecuregcm.configuration.AbusiveMessageFilterConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.AbusiveMessageFilterConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.AccountDatabaseCrawlerConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.AccountDatabaseCrawlerConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.AccountsDatabaseConfiguration;
|
|
||||||
import org.whispersystems.textsecuregcm.configuration.AccountsDynamoDbConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.AccountsDynamoDbConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.ApnConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.ApnConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.AppConfigConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.AppConfigConfiguration;
|
||||||
|
@ -226,11 +225,6 @@ public class WhisperServerConfiguration extends Configuration {
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private List<MaxDeviceConfiguration> maxDevices = new LinkedList<>();
|
private List<MaxDeviceConfiguration> maxDevices = new LinkedList<>();
|
||||||
|
|
||||||
@Valid
|
|
||||||
@NotNull
|
|
||||||
@JsonProperty
|
|
||||||
private AccountsDatabaseConfiguration accountsDatabase;
|
|
||||||
|
|
||||||
@Valid
|
@Valid
|
||||||
@NotNull
|
@NotNull
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
|
@ -462,10 +456,6 @@ public class WhisperServerConfiguration extends Configuration {
|
||||||
return abuseDatabase;
|
return abuseDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountsDatabaseConfiguration getAccountsDatabaseConfiguration() {
|
|
||||||
return accountsDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RateLimitsConfiguration getLimitsConfiguration() {
|
public RateLimitsConfiguration getLimitsConfiguration() {
|
||||||
return limits;
|
return limits;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ import io.dropwizard.auth.PolymorphicAuthDynamicFeature;
|
||||||
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
|
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
|
||||||
import io.dropwizard.auth.basic.BasicCredentialAuthFilter;
|
import io.dropwizard.auth.basic.BasicCredentialAuthFilter;
|
||||||
import io.dropwizard.auth.basic.BasicCredentials;
|
import io.dropwizard.auth.basic.BasicCredentials;
|
||||||
import io.dropwizard.db.DataSourceFactory;
|
|
||||||
import io.dropwizard.db.PooledDataSourceFactory;
|
import io.dropwizard.db.PooledDataSourceFactory;
|
||||||
import io.dropwizard.jdbi3.JdbiFactory;
|
import io.dropwizard.jdbi3.JdbiFactory;
|
||||||
import io.dropwizard.setup.Bootstrap;
|
import io.dropwizard.setup.Bootstrap;
|
||||||
|
@ -244,13 +243,6 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
bootstrap.addCommand(new SetUserDiscoverabilityCommand());
|
bootstrap.addCommand(new SetUserDiscoverabilityCommand());
|
||||||
bootstrap.addCommand(new ReserveUsernameCommand());
|
bootstrap.addCommand(new ReserveUsernameCommand());
|
||||||
|
|
||||||
bootstrap.addBundle(new NameableMigrationsBundle<WhisperServerConfiguration>("accountdb", "accountsdb.xml") {
|
|
||||||
@Override
|
|
||||||
public DataSourceFactory getDataSourceFactory(WhisperServerConfiguration configuration) {
|
|
||||||
return configuration.getAccountsDatabaseConfiguration();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
bootstrap.addBundle(new NameableMigrationsBundle<WhisperServerConfiguration>("abusedb", "abusedb.xml") {
|
bootstrap.addBundle(new NameableMigrationsBundle<WhisperServerConfiguration>("abusedb", "abusedb.xml") {
|
||||||
@Override
|
@Override
|
||||||
public PooledDataSourceFactory getDataSourceFactory(WhisperServerConfiguration configuration) {
|
public PooledDataSourceFactory getDataSourceFactory(WhisperServerConfiguration configuration) {
|
||||||
|
@ -313,10 +305,8 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
headerControlledResourceBundleLookup);
|
headerControlledResourceBundleLookup);
|
||||||
|
|
||||||
JdbiFactory jdbiFactory = new JdbiFactory(DefaultNameStrategy.CHECK_EMPTY);
|
JdbiFactory jdbiFactory = new JdbiFactory(DefaultNameStrategy.CHECK_EMPTY);
|
||||||
Jdbi accountJdbi = jdbiFactory.build(environment, config.getAccountsDatabaseConfiguration(), "accountdb");
|
|
||||||
Jdbi abuseJdbi = jdbiFactory.build(environment, config.getAbuseDatabaseConfiguration(), "abusedb" );
|
Jdbi abuseJdbi = jdbiFactory.build(environment, config.getAbuseDatabaseConfiguration(), "abusedb" );
|
||||||
|
|
||||||
FaultTolerantDatabase accountDatabase = new FaultTolerantDatabase("accounts_database", accountJdbi, config.getAccountsDatabaseConfiguration().getCircuitBreakerConfiguration());
|
|
||||||
FaultTolerantDatabase abuseDatabase = new FaultTolerantDatabase("abuse_database", abuseJdbi, config.getAbuseDatabaseConfiguration().getCircuitBreakerConfiguration());
|
FaultTolerantDatabase abuseDatabase = new FaultTolerantDatabase("abuse_database", abuseJdbi, config.getAbuseDatabaseConfiguration().getCircuitBreakerConfiguration());
|
||||||
|
|
||||||
DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbFromConfig.asyncClient(
|
DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbFromConfig.asyncClient(
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2021 Signal Messenger, LLC
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.configuration;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
public class AccountsDatabaseConfiguration extends DatabaseConfiguration {
|
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
@NotNull
|
|
||||||
@Valid
|
|
||||||
private RetryConfiguration keyOperationRetry = new RetryConfiguration();
|
|
||||||
|
|
||||||
public RetryConfiguration getKeyOperationRetryConfiguration() {
|
|
||||||
return keyOperationRetry;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,6 @@ import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import io.dropwizard.Application;
|
import io.dropwizard.Application;
|
||||||
import io.dropwizard.cli.EnvironmentCommand;
|
import io.dropwizard.cli.EnvironmentCommand;
|
||||||
import io.dropwizard.jdbi3.JdbiFactory;
|
|
||||||
import io.dropwizard.setup.Environment;
|
import io.dropwizard.setup.Environment;
|
||||||
import io.lettuce.core.resource.ClientResources;
|
import io.lettuce.core.resource.ClientResources;
|
||||||
import io.micrometer.core.instrument.Metrics;
|
import io.micrometer.core.instrument.Metrics;
|
||||||
|
@ -24,7 +23,6 @@ import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import net.sourceforge.argparse4j.inf.Namespace;
|
import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
import net.sourceforge.argparse4j.inf.Subparser;
|
import net.sourceforge.argparse4j.inf.Subparser;
|
||||||
import org.jdbi.v3.core.Jdbi;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.whispersystems.textsecuregcm.WhisperServerConfiguration;
|
import org.whispersystems.textsecuregcm.WhisperServerConfiguration;
|
||||||
|
@ -43,7 +41,6 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager.DeletionReason;
|
||||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||||
import org.whispersystems.textsecuregcm.storage.DeletedAccountsManager;
|
import org.whispersystems.textsecuregcm.storage.DeletedAccountsManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.FaultTolerantDatabase;
|
|
||||||
import org.whispersystems.textsecuregcm.storage.Keys;
|
import org.whispersystems.textsecuregcm.storage.Keys;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.MessagesDynamoDb;
|
||||||
|
@ -94,9 +91,6 @@ public class DeleteUserCommand extends EnvironmentCommand<WhisperServerConfigura
|
||||||
|
|
||||||
environment.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
environment.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
|
||||||
JdbiFactory jdbiFactory = new JdbiFactory();
|
|
||||||
Jdbi accountJdbi = jdbiFactory.build(environment, configuration.getAccountsDatabaseConfiguration(), "accountdb");
|
|
||||||
FaultTolerantDatabase accountDatabase = new FaultTolerantDatabase("account_database_delete_user", accountJdbi, configuration.getAccountsDatabaseConfiguration().getCircuitBreakerConfiguration());
|
|
||||||
ClientResources redisClusterClientResources = ClientResources.builder().build();
|
ClientResources redisClusterClientResources = ClientResources.builder().build();
|
||||||
|
|
||||||
DynamoDbClient reportMessagesDynamoDb = DynamoDbFromConfig.client(
|
DynamoDbClient reportMessagesDynamoDb = DynamoDbFromConfig.client(
|
||||||
|
|
|
@ -14,7 +14,6 @@ import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import io.dropwizard.Application;
|
import io.dropwizard.Application;
|
||||||
import io.dropwizard.cli.EnvironmentCommand;
|
import io.dropwizard.cli.EnvironmentCommand;
|
||||||
import io.dropwizard.jdbi3.JdbiFactory;
|
|
||||||
import io.dropwizard.setup.Environment;
|
import io.dropwizard.setup.Environment;
|
||||||
import io.lettuce.core.resource.ClientResources;
|
import io.lettuce.core.resource.ClientResources;
|
||||||
import io.micrometer.core.instrument.Metrics;
|
import io.micrometer.core.instrument.Metrics;
|
||||||
|
@ -25,7 +24,6 @@ import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import net.sourceforge.argparse4j.inf.Namespace;
|
import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
import net.sourceforge.argparse4j.inf.Subparser;
|
import net.sourceforge.argparse4j.inf.Subparser;
|
||||||
import org.jdbi.v3.core.Jdbi;
|
|
||||||
import org.whispersystems.textsecuregcm.WhisperServerConfiguration;
|
import org.whispersystems.textsecuregcm.WhisperServerConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
|
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
|
||||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||||
|
@ -41,7 +39,6 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||||
import org.whispersystems.textsecuregcm.storage.DeletedAccountsManager;
|
import org.whispersystems.textsecuregcm.storage.DeletedAccountsManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||||
import org.whispersystems.textsecuregcm.storage.FaultTolerantDatabase;
|
|
||||||
import org.whispersystems.textsecuregcm.storage.Keys;
|
import org.whispersystems.textsecuregcm.storage.Keys;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
||||||
import org.whispersystems.textsecuregcm.storage.MessagesDynamoDb;
|
import org.whispersystems.textsecuregcm.storage.MessagesDynamoDb;
|
||||||
|
@ -95,10 +92,6 @@ public class SetUserDiscoverabilityCommand extends EnvironmentCommand<WhisperSer
|
||||||
Clock clock = Clock.systemUTC();
|
Clock clock = Clock.systemUTC();
|
||||||
environment.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
environment.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
|
||||||
JdbiFactory jdbiFactory = new JdbiFactory();
|
|
||||||
Jdbi accountJdbi = jdbiFactory.build(environment, configuration.getAccountsDatabaseConfiguration(), "accountdb");
|
|
||||||
FaultTolerantDatabase accountDatabase = new FaultTolerantDatabase("account_database_delete_user", accountJdbi,
|
|
||||||
configuration.getAccountsDatabaseConfiguration().getCircuitBreakerConfiguration());
|
|
||||||
ClientResources redisClusterClientResources = ClientResources.builder().build();
|
ClientResources redisClusterClientResources = ClientResources.builder().build();
|
||||||
|
|
||||||
DynamoDbClient reportMessagesDynamoDb = DynamoDbFromConfig
|
DynamoDbClient reportMessagesDynamoDb = DynamoDbFromConfig
|
||||||
|
|
|
@ -1,398 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
~ Copyright 2013-2021 Signal Messenger, LLC
|
|
||||||
~ SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
-->
|
|
||||||
|
|
||||||
<databaseChangeLog
|
|
||||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
|
||||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"
|
|
||||||
logicalFilePath="migrations.xml">
|
|
||||||
|
|
||||||
<changeSet id="1" author="moxie">
|
|
||||||
<createTable tableName="accounts">
|
|
||||||
<column name="id" type="bigint" autoIncrement="true">
|
|
||||||
<constraints primaryKey="true" nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="number" type="varchar(255)">
|
|
||||||
<constraints unique="true" nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="auth_token" type="varchar(255)">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="salt" type="varchar(255)">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="signaling_key" type="varchar(255)"/>
|
|
||||||
|
|
||||||
<column name="gcm_id" type="text"/>
|
|
||||||
|
|
||||||
<column name="apn_id" type="text"/>
|
|
||||||
|
|
||||||
<column name="supports_sms" type="smallint" defaultValue="0"/>
|
|
||||||
</createTable>
|
|
||||||
|
|
||||||
<createTable tableName="pending_accounts">
|
|
||||||
<column name="id" type="bigint" autoIncrement="true">
|
|
||||||
<constraints primaryKey="true" nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="number" type="varchar(255)">
|
|
||||||
<constraints unique="true" nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="verification_code" type="varchar(255)">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
</createTable>
|
|
||||||
|
|
||||||
<createTable tableName="keys">
|
|
||||||
<column name="id" type="bigint" autoIncrement="true">
|
|
||||||
<constraints primaryKey="true" nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="number" type="varchar(255)">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="key_id" type="bigint">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="public_key" type="text">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="identity_key" type="text">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="last_resort" type="smallint" defaultValue="0"/>
|
|
||||||
</createTable>
|
|
||||||
|
|
||||||
<createIndex tableName="keys" indexName="keys_number_index">
|
|
||||||
<column name="number"/>
|
|
||||||
</createIndex>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="2" author="matt">
|
|
||||||
|
|
||||||
<addColumn tableName="accounts">
|
|
||||||
<column name="data" type="json" />
|
|
||||||
</addColumn>
|
|
||||||
|
|
||||||
<sql>CREATE type device_t AS (id integer, "authToken" varchar(255), salt varchar(255), "signalingKey" varchar(255), "gcmId" text, "apnId" text);</sql>
|
|
||||||
<sql>CREATE type account_t AS (number varchar(255), "supportsSms" smallint, devices device_t array);</sql>
|
|
||||||
<sql>UPDATE accounts SET data = row_to_json(row(number, supports_sms, array[row(1, auth_token, salt, signaling_key, gcm_id, apn_id)::device_t])::account_t)</sql>
|
|
||||||
|
|
||||||
<addNotNullConstraint tableName="accounts" columnName="data"/>
|
|
||||||
|
|
||||||
<dropColumn tableName="accounts" columnName="auth_token"/>
|
|
||||||
<dropColumn tableName="accounts" columnName="salt"/>
|
|
||||||
<dropColumn tableName="accounts" columnName="signaling_key"/>
|
|
||||||
<dropColumn tableName="accounts" columnName="gcm_id"/>
|
|
||||||
<dropColumn tableName="accounts" columnName="apn_id"/>
|
|
||||||
<dropColumn tableName="accounts" columnName="supports_sms"/>
|
|
||||||
|
|
||||||
<sql>DROP type account_t;</sql>
|
|
||||||
<sql>DROP type device_t;</sql>
|
|
||||||
|
|
||||||
<addColumn tableName="keys">
|
|
||||||
<column name="device_id" type="bigint" defaultValue="1">
|
|
||||||
<constraints nullable="false" />
|
|
||||||
</column>
|
|
||||||
</addColumn>
|
|
||||||
|
|
||||||
<createTable tableName="pending_devices">
|
|
||||||
<column name="id" type="bigint" autoIncrement="true">
|
|
||||||
<constraints primaryKey="true" nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="number" type="text">
|
|
||||||
<constraints unique="true" nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="verification_code" type="text">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
</createTable>
|
|
||||||
|
|
||||||
<createTable tableName="messages">
|
|
||||||
<column name="id" type="bigint" autoIncrement="true">
|
|
||||||
<constraints primaryKey="true" nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="account_id" type="bigint">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="device_id" type="bigint">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="encrypted_message" type="text">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
</createTable>
|
|
||||||
|
|
||||||
<createIndex tableName="messages" indexName="messages_account_and_device">
|
|
||||||
<column name="account_id"/>
|
|
||||||
<column name="device_id"/>
|
|
||||||
</createIndex>
|
|
||||||
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="3" author="moxie">
|
|
||||||
<sql>CREATE OR REPLACE FUNCTION "custom_json_object_set_key"(
|
|
||||||
"json" json,
|
|
||||||
"key_to_set" TEXT,
|
|
||||||
"value_to_set" anyelement
|
|
||||||
)
|
|
||||||
RETURNS json
|
|
||||||
LANGUAGE sql
|
|
||||||
IMMUTABLE
|
|
||||||
STRICT
|
|
||||||
AS $function$
|
|
||||||
SELECT COALESCE(
|
|
||||||
(SELECT ('{' || string_agg(to_json("key") || ':' || "value", ',') || '}')
|
|
||||||
FROM (SELECT *
|
|
||||||
FROM json_each("json")
|
|
||||||
WHERE "key" <> "key_to_set"
|
|
||||||
UNION ALL
|
|
||||||
SELECT "key_to_set", to_json("value_to_set")) AS "fields"),
|
|
||||||
'{}'
|
|
||||||
)::json
|
|
||||||
$function$;</sql>
|
|
||||||
<sql>UPDATE accounts SET data = custom_json_object_set_key(data, 'identityKey', k.identity_key) FROM keys k WHERE (data->>'identityKey')::text is null AND k.number = data->>'number' AND k.last_resort = 1;</sql>
|
|
||||||
<sql>UPDATE accounts SET data = custom_json_object_set_key(data, 'identityKey', k.identity_key) FROM keys k WHERE (data->>'identityKey')::text is null AND k.number = data->>'number';</sql>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="4" author="moxie">
|
|
||||||
<dropColumn tableName="keys" columnName="identity_key"/>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="5" author="moxie">
|
|
||||||
<addColumn tableName="pending_accounts">
|
|
||||||
<column name="timestamp" type="bigint" defaultValueComputed="extract(epoch from now()) * 1000">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
</addColumn>
|
|
||||||
|
|
||||||
<addColumn tableName="pending_devices">
|
|
||||||
<column name="timestamp" type="bigint" defaultValueComputed="extract(epoch from now()) * 1000">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="6" author="moxie">
|
|
||||||
<addColumn tableName="pending_accounts">
|
|
||||||
<column name="push_code" type="text">
|
|
||||||
<constraints nullable="true"/>
|
|
||||||
</column>
|
|
||||||
</addColumn>
|
|
||||||
|
|
||||||
<dropNotNullConstraint tableName="pending_accounts" columnName="verification_code"/>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="7" author="moxie">
|
|
||||||
<addColumn tableName="accounts">
|
|
||||||
<column name="uuid" type="uuid"/>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="8" author="moxie" runInTransaction="false">
|
|
||||||
<sql>CREATE UNIQUE INDEX CONCURRENTLY uuid_index ON accounts (uuid);</sql>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="9" author="moxie">
|
|
||||||
<createTable tableName="usernames">
|
|
||||||
<column name="id" type="bigint" autoIncrement="true">
|
|
||||||
<constraints nullable="false" primaryKey="true"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="uuid" type="uuid">
|
|
||||||
<constraints nullable="false" unique="true"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="username" type="text">
|
|
||||||
<constraints nullable="false" unique="true"/>
|
|
||||||
</column>
|
|
||||||
</createTable>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="10" author="moxie">
|
|
||||||
<createTable tableName="reserved_usernames">
|
|
||||||
<column name="id" type="bigint" autoIncrement="true">
|
|
||||||
<constraints nullable="false" primaryKey="true"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="username" type="text">
|
|
||||||
<constraints nullable="false" unique="true"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="uuid" type="uuid">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
</createTable>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="11" author="moxie">
|
|
||||||
<createTable tableName="profiles">
|
|
||||||
<column name="id" type="bigint" autoIncrement="true">
|
|
||||||
<constraints nullable="false" primaryKey="true"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="uuid" type="uuid">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="version" type="text">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="name" type="text">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="avatar" type="text">
|
|
||||||
<constraints nullable="true"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="commitment" type="bytea">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
</createTable>
|
|
||||||
|
|
||||||
<addUniqueConstraint tableName="profiles" columnNames="uuid, version" constraintName="uuid_and_version"/>
|
|
||||||
|
|
||||||
<createIndex tableName="profiles" indexName="profiles_uuid">
|
|
||||||
<column name="uuid"/>
|
|
||||||
</createIndex>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="12" author="moxie">
|
|
||||||
<createTable tableName="remote_config">
|
|
||||||
<column name="id" type="bigint" autoIncrement="true">
|
|
||||||
<constraints nullable="false" primaryKey="true"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="name" type="text">
|
|
||||||
<constraints nullable="false" unique="true"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="percentage" type="int">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="uuids" type="uuid[]">
|
|
||||||
<constraints nullable="false"/>
|
|
||||||
</column>
|
|
||||||
</createTable>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="13" author="moxie">
|
|
||||||
<addColumn tableName="keys">
|
|
||||||
<column name="deleted" type="boolean"/>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="14" author="moxie" runInTransaction="false">
|
|
||||||
<sql>CREATE INDEX CONCURRENTLY deleted_key_index ON keys (deleted);</sql>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="15" author="moxie" runInTransaction="false">
|
|
||||||
<sql>DROP INDEX CONCURRENTLY deleted_key_index;</sql>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="16" author="moxie">
|
|
||||||
<dropColumn tableName="keys" columnName="deleted"/>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="17" author="ehren">
|
|
||||||
<addColumn tableName="remote_config">
|
|
||||||
<column name="default_value" type="text"/>
|
|
||||||
<column name="value" type="text"/>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="18" author="ehren">
|
|
||||||
<addColumn tableName="remote_config">
|
|
||||||
<column name="hash_key" type="text"/>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="19" author="jon">
|
|
||||||
<createTable tableName="feature_flags">
|
|
||||||
<column name="flag" type="text">
|
|
||||||
<constraints primaryKey="true" nullable="false"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="active" type="boolean"/>
|
|
||||||
</createTable>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="20" author="jon">
|
|
||||||
<addColumn tableName="profiles">
|
|
||||||
<column name="about" type="text">
|
|
||||||
<constraints nullable="true"/>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="about_emoji" type="text">
|
|
||||||
<constraints nullable="true"/>
|
|
||||||
</column>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="21" author="ehren">
|
|
||||||
<dropTable tableName="messages"/>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="22" author="jon">
|
|
||||||
<dropTable tableName="feature_flags" />
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="23" author="ehren">
|
|
||||||
<addColumn tableName="profiles">
|
|
||||||
<column name="payment_address" type="text">
|
|
||||||
<constraints nullable="true"/>
|
|
||||||
</column>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="24" author="chris">
|
|
||||||
<addColumn tableName="pending_accounts">
|
|
||||||
<column name="twilio_verification_sid" type="text">
|
|
||||||
<constraints nullable="true" />
|
|
||||||
</column>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="25" author="chris">
|
|
||||||
<addColumn tableName="accounts">
|
|
||||||
<column name="version" type="int" defaultValue="0"/>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="26" author="chris">
|
|
||||||
<dropTable tableName="accounts"/>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="27" author="jon">
|
|
||||||
<addColumn tableName="profiles">
|
|
||||||
<column name="deleted" type="boolean" defaultValue="false"/>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
<changeSet id="28" author="jon" runInTransaction="false">
|
|
||||||
<sql>CREATE INDEX CONCURRENTLY deleted_profile_index ON profiles (deleted);</sql>
|
|
||||||
</changeSet>
|
|
||||||
|
|
||||||
</databaseChangeLog>
|
|
|
@ -13,9 +13,6 @@ import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.opentable.db.postgres.embedded.LiquibasePreparer;
|
|
||||||
import com.opentable.db.postgres.junit5.EmbeddedPostgresExtension;
|
|
||||||
import com.opentable.db.postgres.junit5.PreparedDbExtension;
|
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -44,10 +41,6 @@ import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
|
||||||
|
|
||||||
class AccountsManagerChangeNumberIntegrationTest {
|
class AccountsManagerChangeNumberIntegrationTest {
|
||||||
|
|
||||||
@RegisterExtension
|
|
||||||
static PreparedDbExtension ACCOUNTS_POSTGRES_EXTENSION =
|
|
||||||
EmbeddedPostgresExtension.preparedDatabase(LiquibasePreparer.forClasspathLocation("accountsdb.xml"));
|
|
||||||
|
|
||||||
private static final String ACCOUNTS_TABLE_NAME = "accounts_test";
|
private static final String ACCOUNTS_TABLE_NAME = "accounts_test";
|
||||||
private static final String NUMBERS_TABLE_NAME = "numbers_test";
|
private static final String NUMBERS_TABLE_NAME = "numbers_test";
|
||||||
private static final String PNI_ASSIGNMENT_TABLE_NAME = "pni_assignment_test";
|
private static final String PNI_ASSIGNMENT_TABLE_NAME = "pni_assignment_test";
|
||||||
|
|
Loading…
Reference in New Issue