2014-05-10 3 views
5

통합 테스트를 실행하려는 dropwizard-application (0.7.0)이 있습니다.Dropwizard에서 프로그래밍 방식으로 마이그레이션 실행

나는이 같은 DropwizardAppRule를 사용하여 통합 테스트를 설정 한 : 나는 그것을 사용하여 아래의 테스트를 실행하려고하면 내 마이그레이션을 실행하지 않았기 때문에

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

, 그것은 작동하지 않습니다. 마이그레이션을 실행하는 가장 좋은 방법은 무엇입니까?

테스트 :

@Test 
public void fooTest() { 
    Client client = new Client(); 
    String root = String.format("http://localhost:%d/", RULE.getLocalPort()); 
    URI uri = UriBuilder.fromUri(root).path("/users").build(); 
    client.resource(uri).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).post(User.class, new LoginUserDTO("[email protected]", "password")); 
} 

구성 :

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; 
} 

}

답변

8

감사하고 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(""); 
    } 
} 
1

나는 그것을 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 :

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

아마도 궁극적 인 해결책은 아니며 사용중인 데이터베이스에 많이 달려 있지만 작동합니다.

3

테스트 사례의 일부로 데이터베이스 마이그레이션을 시도 할 때 일부 동시성 문제가 발생하여 응용 프로그램 자체에 베이킹되어 종료되었습니다 (구성 옵션으로 보호 됨).

private void migrate(MyAppConfiguration configuration, Environment environment) { 
    if (configuration.isMigrateSchemaOnStartup()) { 
     log.info("Running schema migration"); 
     ManagedDataSource dataSource = createMigrationDataSource(configuration, environment); 

     try (Connection connection = dataSource.getConnection()) { 
      JdbcConnection conn = new JdbcConnection(connection); 

      Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(conn); 
      Liquibase liquibase = new Liquibase("migrations.xml", new ClassLoaderResourceAccessor(), database); 
      liquibase.update(""); 

      log.info("Migration completed!"); 
     } 
     catch (Exception ex) { 
      throw new IllegalStateException("Unable to migrate database", ex); 
     } 
     finally { 
      try { 
       dataSource.stop(); 
      } 
      catch (Exception ex) { 
       log.error("Unable to stop data source used to execute schema migration", ex); 
      } 
     } 
    } 
    else { 
     log.info("Skipping schema migration"); 
    } 
} 

private ManagedDataSource createMigrationDataSource(MyAppConfiguration configuration, Environment environment) { 
    DataSourceFactory dataSourceFactory = configuration.getDataSourceFactory(); 

    try { 
     return dataSourceFactory.build(environment.metrics(), "migration-ds"); 
    } 
    catch (ClassNotFoundException ex) { 
     throw new IllegalStateException("Unable to initialize data source for schema migration", ex); 
    } 
} 
1

동일한 목표를 달성하기 위해 수행하는 작업은 maven 내에서 마이그레이션을 실행하는 것입니다.

당신의 pom.xml의 sction의 섹션이 추가 :이 명령 줄에서 받는다는와 함께 작동합니다

<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> 

. 이 설정을 사용하면 maven은 liquibase dropAll을 사용하여 모든 데이터베이스 객체를 삭제 한 다음 마이그레이션을 실행하므로 모든 테스트마다 깨끗한 새 데이터베이스가 생성됩니다.

일식을 사용하여 발목을 만났을 때 플러그인의 실행 태그에서 작동하지 않는 라이프 사이클 매핑에 대해 불평했습니다. 킴블에

<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> 
2

직접 같은 방법으로 DB를 마이그레이션 명령을 실행하는 것입니다 Liquibase의 클래스를 수입에 의존하지 않는 또 다른 방법은 명령 줄에서 수도, 규칙을 사용 :

이 방법은 테스트를 시작하기 전에 실행할 다른 번들의 다른 명령에서도 작동합니다.

작은 윙클 : Dropwizards ConfiguredCommand (모든 dropwizard-migrations에서 수행)를 확장하는 명령에 대해 수행하면 명령이 완료 될 때 logback을 불필요하게 비활성화 할 수 있습니다. 복원하려면 다음 번호로 전화하십시오.

 RULE.getConfiguration().getLoggingFactory().configure(RULE.getEnvironment().metrics(), 
      RULE.getApplication().getName()); 
관련 문제