Java 在Dropwizard中以编程方式运行迁移

Java 在Dropwizard中以编程方式运行迁移,java,liquibase,dropwizard,Java,Liquibase,Dropwizard,我有dropwizard应用程序(0.7.0),我想为其运行集成测试 我使用DropwizardAppRule设置了一个集成测试,如下所示: @ClassRule public static final DropwizardAppRule<MyAppConfiguration> RULE = new DropwizardAppRule<MyAppConfiguration>( MyApplication.class, Res

我有dropwizard应用程序(0.7.0),我想为其运行集成测试

我使用DropwizardAppRule设置了一个集成测试,如下所示:

@ClassRule
public static final DropwizardAppRule<MyAppConfiguration> RULE =
        new DropwizardAppRule<MyAppConfiguration>(
                MyApplication.class, Resources.getResource("testconfiguration.yml").getPath());
配置:

 public class MyAppConfiguration extends Configuration {
@Valid
@NotNull
private DataSourceFactory database = new DataSourceFactory();

@JsonProperty("database")
public DataSourceFactory getDataSourceFactory() {
    return database;
}

@JsonProperty("database")
public void setDataSourceFactory(DataSourceFactory dataSourceFactory) {
    this.database = dataSourceFactory;
}

}

我使用Liquibase的API这样做:

private void migrate(){
    DataSourceFactory dataSourceFactory = RULE.getConfiguration().dataSourceFactory;
    Properties info = new Properties();
    info.setProperty("user", dataSourceFactory.getUser());
    info.setProperty("password", dataSourceFactory.getPassword());
    org.h2.jdbc.JdbcConnection h2Conn = new org.h2.jdbc.JdbcConnection(dataSourceFactory.getUrl(), info);
    JdbcConnection conn = new JdbcConnection(h2Conn);
    Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(conn);
    Liquibase liquibase = new Liquibase("migrations.xml", new ClassLoaderResourceAccessor(), database);
    String ctx = null;
    liquibase.update(ctx);
}
然后我把这个放在课前:

@BeforeClass
public void setup(){
    migrate();
}

这可能不是最终的解决方案,它在很大程度上取决于您正在使用的数据库,但它是有效的。

我在尝试将数据库迁移作为测试用例的一部分时遇到了一些并发问题,并最终将其烘焙到应用程序本身中(受配置选项保护)


为了实现同样的目标,我所做的是从maven内部运行迁移

将此内容添加到pom.xml的选项中:

<plugin>
  <groupId>org.liquibase</groupId>
  <artifactId>liquibase-maven-plugin</artifactId>
  <version>3.0.5</version>
  <executions>
      <execution>
          <phase>process-test-resources</phase>  
          <configuration>
            <changeLogFile>PATH TO YOUR MIGRATIONS FILE</changeLogFile>
            <driver>org.h2.Driver</driver>
            <url>JDBC URL LIKE IN YOUR APP.YML</url>
            <username>USERNAME</username>
            <password>PASSWORD</password>
            <dropFirst>false</dropFirst>
            <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
            <logging>info</logging>
          </configuration>
          <goals>
            <goal>dropAll</goal>
            <goal>update</goal>
          </goals>
      </execution>
  </executions>               
</plugin>

org.liquibase
liquibase maven插件
3.0.5
过程测试资源
迁移文件的路径
org.h2.Driver
类似于APP.YML中的JDBC URL
用户名
密码
假的
假的
信息
滴落球
更新
这将从命令行使用maven。使用此设置,maven将使用liquibase dropAll删除所有数据库对象,然后运行迁移,因此每次测试都会有一个干净的新数据库

在使用它时,我遇到了eclipse的问题,它抱怨生命周期映射不能在插件的执行标签上工作。在这种情况下,您还需要将以下内容添加到构建部分,以便eclipse能够正确地映射生命周期:

<pluginManagement>
  <plugins>
    <plugin>
      <groupId>org.eclipse.m2e</groupId>
      <artifactId>lifecycle-mapping</artifactId>
      <version>1.0.0</version>
      <configuration>
        <lifecycleMappingMetadata>
        <pluginExecutions>
          <pluginExecution>
            <pluginExecutionFilter>
              <groupId>org.liquibase</groupId>
              <artifactId>liquibase-maven-plugin</artifactId>
              <versionRange>[1.0,)</versionRange>
              <goals>
                <goal>dropAll</goal>
                <goal>update</goal>
              </goals>
            </pluginExecutionFilter>
            <action>
              <execute />
            </action>
          </pluginExecution>
        </pluginExecutions>
        </lifecycleMappingMetadata>
      </configuration>
    </plugin>
  </plugins>
  </pluginManagement>  

org.eclipse.m2e
生命周期映射
1.0.0
org.liquibase
liquibase maven插件
[1.0,)
滴落球
更新

感谢Kimble和andersem让我走上正轨。以下是我在@BeforeClass方法中的想法:

// Create the test database with the LiquiBase migrations.
@BeforeClass
public static void up() throws Exception
{
    ManagedDataSource ds = RULE.getConfiguration().getMainDataSource().build(
        RULE.getEnvironment().metrics(), "migrations");
    try (Connection connection = ds.getConnection())
    {
        Liquibase migrator = new Liquibase("migrations.xml", new ClassLoaderResourceAccessor(), new JdbcConnection(connection));
        migrator.update("");
    }
}

另一种不依赖于直接导入Liquibase类的方法是使用以下规则,以与从命令行相同的方式运行db migrate命令:

@Before
public void migrateDatabase() throws Exception {
    RULE.getApplication().run("db", "migrate", ResourceHelpers.resourceFilePath("testconfiguration.yml"));
}
这种方法也适用于您可能希望在启动测试之前运行的任何其他捆绑包中的任何其他命令

一个小问题:如果使用任何扩展dropwizard ConfiguredCommand的命令(所有dropwizard迁移都会这样做)执行此操作,则在命令完成时将不必要地禁用logback。 要还原它,您可以调用:

        RULE.getConfiguration().getLoggingFactory().configure(RULE.getEnvironment().metrics(),
            RULE.getApplication().getName());
@Before
public void migrateDatabase() throws Exception {
    RULE.getApplication().run("db", "migrate", ResourceHelpers.resourceFilePath("testconfiguration.yml"));
}
        RULE.getConfiguration().getLoggingFactory().configure(RULE.getEnvironment().metrics(),
            RULE.getApplication().getName());