mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 05:28:03 +01:00
Break out into a multi-module project
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package org.whispersystems.textsecuregcm.liquibase;
|
||||
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import io.dropwizard.Configuration;
|
||||
import io.dropwizard.cli.ConfiguredCommand;
|
||||
import io.dropwizard.db.DatabaseConfiguration;
|
||||
import io.dropwizard.db.ManagedDataSource;
|
||||
import io.dropwizard.db.PooledDataSourceFactory;
|
||||
import io.dropwizard.setup.Bootstrap;
|
||||
import liquibase.Liquibase;
|
||||
import liquibase.exception.LiquibaseException;
|
||||
import liquibase.exception.ValidationFailedException;
|
||||
|
||||
public abstract class AbstractLiquibaseCommand<T extends Configuration> extends ConfiguredCommand<T> {
|
||||
|
||||
private final DatabaseConfiguration<T> strategy;
|
||||
private final Class<T> configurationClass;
|
||||
private final String migrations;
|
||||
|
||||
protected AbstractLiquibaseCommand(String name,
|
||||
String description,
|
||||
String migrations,
|
||||
DatabaseConfiguration<T> strategy,
|
||||
Class<T> configurationClass) {
|
||||
super(name, description);
|
||||
this.migrations = migrations;
|
||||
this.strategy = strategy;
|
||||
this.configurationClass = configurationClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<T> getConfigurationClass() {
|
||||
return configurationClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
protected void run(Bootstrap<T> bootstrap, Namespace namespace, T configuration) throws Exception {
|
||||
final PooledDataSourceFactory dbConfig = strategy.getDataSourceFactory(configuration);
|
||||
dbConfig.asSingleConnectionPool();
|
||||
|
||||
try (final CloseableLiquibase liquibase = openLiquibase(dbConfig, namespace)) {
|
||||
run(namespace, liquibase);
|
||||
} catch (ValidationFailedException e) {
|
||||
e.printDescriptiveError(System.err);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private CloseableLiquibase openLiquibase(final PooledDataSourceFactory dataSourceFactory, final Namespace namespace)
|
||||
throws ClassNotFoundException, SQLException, LiquibaseException
|
||||
{
|
||||
final ManagedDataSource dataSource = dataSourceFactory.build(new MetricRegistry(), "liquibase");
|
||||
return new CloseableLiquibase(dataSource, migrations);
|
||||
}
|
||||
|
||||
protected abstract void run(Namespace namespace, Liquibase liquibase) throws Exception;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.whispersystems.textsecuregcm.liquibase;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import io.dropwizard.db.ManagedDataSource;
|
||||
import liquibase.Liquibase;
|
||||
import liquibase.database.jvm.JdbcConnection;
|
||||
import liquibase.exception.LiquibaseException;
|
||||
import liquibase.resource.ClassLoaderResourceAccessor;
|
||||
|
||||
|
||||
public class CloseableLiquibase extends Liquibase implements AutoCloseable {
|
||||
private final ManagedDataSource dataSource;
|
||||
|
||||
public CloseableLiquibase(ManagedDataSource dataSource, String migrations)
|
||||
throws LiquibaseException, ClassNotFoundException, SQLException
|
||||
{
|
||||
super(migrations,
|
||||
new ClassLoaderResourceAccessor(),
|
||||
new JdbcConnection(dataSource.getConnection()));
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
dataSource.stop();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.whispersystems.textsecuregcm.liquibase;
|
||||
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Joiner;
|
||||
import net.sourceforge.argparse4j.impl.Arguments;
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.List;
|
||||
|
||||
import io.dropwizard.Configuration;
|
||||
import io.dropwizard.db.DatabaseConfiguration;
|
||||
import liquibase.Liquibase;
|
||||
|
||||
public class DbMigrateCommand<T extends Configuration> extends AbstractLiquibaseCommand<T> {
|
||||
|
||||
public DbMigrateCommand(String migration, DatabaseConfiguration<T> strategy, Class<T> configurationClass) {
|
||||
super("migrate", "Apply all pending change sets.", migration, strategy, configurationClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Subparser subparser) {
|
||||
super.configure(subparser);
|
||||
|
||||
subparser.addArgument("-n", "--dry-run")
|
||||
.action(Arguments.storeTrue())
|
||||
.dest("dry-run")
|
||||
.setDefault(Boolean.FALSE)
|
||||
.help("output the DDL to stdout, don't run it");
|
||||
|
||||
subparser.addArgument("-c", "--count")
|
||||
.type(Integer.class)
|
||||
.dest("count")
|
||||
.help("only apply the next N change sets");
|
||||
|
||||
subparser.addArgument("-i", "--include")
|
||||
.action(Arguments.append())
|
||||
.dest("contexts")
|
||||
.help("include change sets from the given context");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
public void run(Namespace namespace, Liquibase liquibase) throws Exception {
|
||||
final String context = getContext(namespace);
|
||||
final Integer count = namespace.getInt("count");
|
||||
final Boolean dryRun = namespace.getBoolean("dry-run");
|
||||
if (count != null) {
|
||||
if (dryRun) {
|
||||
liquibase.update(count, context, new OutputStreamWriter(System.out, Charsets.UTF_8));
|
||||
} else {
|
||||
liquibase.update(count, context);
|
||||
}
|
||||
} else {
|
||||
if (dryRun) {
|
||||
liquibase.update(context, new OutputStreamWriter(System.out, Charsets.UTF_8));
|
||||
} else {
|
||||
liquibase.update(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getContext(Namespace namespace) {
|
||||
final List<Object> contexts = namespace.getList("contexts");
|
||||
if (contexts == null) {
|
||||
return "";
|
||||
}
|
||||
return Joiner.on(',').join(contexts);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.whispersystems.textsecuregcm.liquibase;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Joiner;
|
||||
import net.sourceforge.argparse4j.impl.Arguments;
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.List;
|
||||
|
||||
import io.dropwizard.Configuration;
|
||||
import io.dropwizard.db.DatabaseConfiguration;
|
||||
import liquibase.Liquibase;
|
||||
|
||||
public class DbStatusCommand <T extends Configuration> extends AbstractLiquibaseCommand<T> {
|
||||
|
||||
public DbStatusCommand(String migrations, DatabaseConfiguration<T> strategy, Class<T> configurationClass) {
|
||||
super("status", "Check for pending change sets.", migrations, strategy, configurationClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Subparser subparser) {
|
||||
super.configure(subparser);
|
||||
|
||||
subparser.addArgument("-v", "--verbose")
|
||||
.action(Arguments.storeTrue())
|
||||
.dest("verbose")
|
||||
.help("Output verbose information");
|
||||
subparser.addArgument("-i", "--include")
|
||||
.action(Arguments.append())
|
||||
.dest("contexts")
|
||||
.help("include change sets from the given context");
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
public void run(Namespace namespace, Liquibase liquibase) throws Exception {
|
||||
liquibase.reportStatus(namespace.getBoolean("verbose"),
|
||||
getContext(namespace),
|
||||
new OutputStreamWriter(System.out, Charsets.UTF_8));
|
||||
}
|
||||
|
||||
private String getContext(Namespace namespace) {
|
||||
final List<Object> contexts = namespace.getList("contexts");
|
||||
if (contexts == null) {
|
||||
return "";
|
||||
}
|
||||
return Joiner.on(',').join(contexts);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.whispersystems.textsecuregcm.liquibase;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.sourceforge.argparse4j.inf.Namespace;
|
||||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import java.util.SortedMap;
|
||||
|
||||
import io.dropwizard.Configuration;
|
||||
import io.dropwizard.db.DatabaseConfiguration;
|
||||
import liquibase.Liquibase;
|
||||
|
||||
public class NameableDbCommand<T extends Configuration> extends AbstractLiquibaseCommand<T> {
|
||||
private static final String COMMAND_NAME_ATTR = "subcommand";
|
||||
private final SortedMap<String, AbstractLiquibaseCommand<T>> subcommands;
|
||||
|
||||
public NameableDbCommand(String name, String migrations, DatabaseConfiguration<T> strategy, Class<T> configurationClass) {
|
||||
super(name, "Run database migrations tasks", migrations, strategy, configurationClass);
|
||||
this.subcommands = Maps.newTreeMap();
|
||||
addSubcommand(new DbMigrateCommand<>(migrations, strategy, configurationClass));
|
||||
addSubcommand(new DbStatusCommand<>(migrations, strategy, configurationClass));
|
||||
}
|
||||
|
||||
private void addSubcommand(AbstractLiquibaseCommand<T> subcommand) {
|
||||
subcommands.put(subcommand.getName(), subcommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Subparser subparser) {
|
||||
for (AbstractLiquibaseCommand<T> subcommand : subcommands.values()) {
|
||||
final Subparser cmdParser = subparser.addSubparsers()
|
||||
.addParser(subcommand.getName())
|
||||
.setDefault(COMMAND_NAME_ATTR, subcommand.getName())
|
||||
.description(subcommand.getDescription());
|
||||
subcommand.configure(cmdParser);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Namespace namespace, Liquibase liquibase) throws Exception {
|
||||
final AbstractLiquibaseCommand<T> subcommand = subcommands.get(namespace.getString(COMMAND_NAME_ATTR));
|
||||
subcommand.run(namespace, liquibase);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.whispersystems.textsecuregcm.liquibase;
|
||||
|
||||
import io.dropwizard.Bundle;
|
||||
import io.dropwizard.Configuration;
|
||||
import io.dropwizard.db.DatabaseConfiguration;
|
||||
import io.dropwizard.setup.Bootstrap;
|
||||
import io.dropwizard.setup.Environment;
|
||||
import io.dropwizard.util.Generics;
|
||||
|
||||
public abstract class NameableMigrationsBundle<T extends Configuration> implements Bundle, DatabaseConfiguration<T> {
|
||||
|
||||
private final String name;
|
||||
private final String migrations;
|
||||
|
||||
public NameableMigrationsBundle(String name, String migrations) {
|
||||
this.name = name;
|
||||
this.migrations = migrations;
|
||||
}
|
||||
|
||||
public final void initialize(Bootstrap<?> bootstrap) {
|
||||
Class klass = Generics.getTypeParameter(this.getClass(), Configuration.class);
|
||||
bootstrap.addCommand(new NameableDbCommand(name, migrations, this, klass));
|
||||
}
|
||||
|
||||
public final void run(Environment environment) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user