2014-05-10 21 views
5

Tôi có ứng dụng dropwizard (0.7.0) mà tôi muốn chạy thử nghiệm tích hợp.Chạy di chuyển theo chương trình trong Dropwizard

tôi đã thiết lập một thử nghiệm tích hợp sử dụng DropwizardAppRule, như thế này:

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

Khi tôi cố gắng để chạy thử nghiệm dưới đây sử dụng nó, nó không hoạt động bởi vì tôi đã không chạy di cư của tôi. Cách tốt nhất để chạy di chuyển là gì?

Test:

@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")); 
} 

Cấu hình:

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

}

Trả lời

8

Nhờ Kimble và andersem để đưa tôi đi đúng hướng. Dưới đây là những gì tôi đã đưa ra trong phương pháp @BeforeClass tôi:

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

tôi đã làm nó theo cách này sử dụng API Liquibase của:

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

Và sau đó tôi đặt điều này trong một beforeclass:

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

Nó có lẽ không phải là giải pháp tối thượng, và nó phụ thuộc rất nhiều vào cơ sở dữ liệu bạn đang sử dụng, nhưng nó hoạt động.

3

Tôi đã gặp phải một số sự cố đồng thời khi cố thực hiện di chuyển cơ sở dữ liệu như một phần của trường hợp thử nghiệm và kết thúc tự nướng vào ứng dụng (được bảo vệ bằng tùy chọn cấu hình).

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

Điều tôi làm để đạt được mục tiêu tương tự là chạy di chuyển từ bên trong maven.

Thêm phần này vào phần trong sction của pom.xml của bạn:

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

này sẽ làm việc với maven từ dòng lệnh. Với thiết lập này, maven sẽ sử dụng thả lỏng liquAll để thả tất cả các đối tượng cơ sở dữ liệu, và sau đó chạy một di chuyển, vì vậy với mọi thử nghiệm bạn có một cơ sở dữ liệu mới sạch.

Khi sử dụng điều đó, tôi chạy các lỗi với nhật thực, nó phàn nàn về ánh xạ vòng đời không hoạt động khi thẻ thực thi của plugin. Trong trường hợp này, bạn cần phải thêm dòng sau vào phần xây dựng là tốt, nên che khuất đúng cách có thể lập bản đồ chu kỳ cuộc sống:

<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

Một cách tiếp cận mà không dựa vào nhập khẩu các lớp Liquibase của trực tiếp là để chạy các lệnh db di cư trong cùng một cách mà bạn có thể từ dòng lệnh, sử dụng RULE:

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

Phương pháp này cũng hoạt động cho bất kỳ lệnh nào khác mà bạn có thể muốn chạy trước khi bắt đầu kiểm tra.

Lấp lánh nhỏ: Thực hiện việc này với bất kỳ lệnh nào mở rộng Dropwizards ConfiguredCommand (tất cả các di chuyển dropwizard làm) sẽ vô hiệu hóa việc vô hiệu hóa đăng nhập khi lệnh kết thúc. Để khôi phục, bạn có thể gọi:

 RULE.getConfiguration().getLoggingFactory().configure(RULE.getEnvironment().metrics(), 
      RULE.getApplication().getName()); 
Các vấn đề liên quan