Fix Liquibase endpoint's output with multiple datasources

Previously, the endpoint used the same change log history service for
for each SpringLiquibase bean that it processed. This resulted in
pollution of the reported changes as the history of each bean was not
isolated.

This commit updates the endpoint to use a new history service for each
SpringLiquibase bean that is processed.

See gh-19171
This commit is contained in:
Leo Li 2019-11-28 11:58:58 +08:00 committed by Andy Wilkinson
parent 2be3057904
commit 5302d91930
3 changed files with 81 additions and 3 deletions

View File

@ -63,9 +63,10 @@ public class LiquibaseEndpoint {
while (target != null) {
Map<String, LiquibaseBean> liquibaseBeans = new HashMap<>();
DatabaseFactory factory = DatabaseFactory.getInstance();
StandardChangeLogHistoryService service = new StandardChangeLogHistoryService();
this.context.getBeansOfType(SpringLiquibase.class)
.forEach((name, liquibase) -> liquibaseBeans.put(name, createReport(liquibase, service, factory)));
this.context.getBeansOfType(SpringLiquibase.class).forEach((name, liquibase) -> {
StandardChangeLogHistoryService service = new StandardChangeLogHistoryService();
liquibaseBeans.put(name, createReport(liquibase, service, factory));
});
ApplicationContext parent = target.getParent();
contextBeans.put(target.getId(),
new ContextLiquibaseBeans(liquibaseBeans, (parent != null) ? parent.getId() : null));

View File

@ -22,6 +22,9 @@ import java.util.Map;
import javax.sql.DataSource;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import liquibase.integration.spring.SpringLiquibase;
import org.junit.Test;
import org.springframework.boot.actuate.liquibase.LiquibaseEndpoint.LiquibaseBean;
@ -41,6 +44,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Eddú Meléndez
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Leo Li
*/
public class LiquibaseEndpointTests {
@ -92,6 +96,20 @@ public class LiquibaseEndpointTests {
});
}
@Test
public void multipleLiquibaseReportIsReturned() {
this.contextRunner.withUserConfiguration(Config.class, LiquibaseConfiguration.class).run((context) -> {
Map<String, LiquibaseBean> liquibaseBeans = context.getBean(LiquibaseEndpoint.class).liquibaseBeans()
.getContexts().get(context.getId()).getLiquibaseBeans();
assertThat(liquibaseBeans.get("liquibase").getChangeSets()).hasSize(1);
assertThat(liquibaseBeans.get("liquibase").getChangeSets().get(0).getChangeLog())
.isEqualTo("classpath:/db/changelog/db.changelog-master.yaml");
assertThat(liquibaseBeans.get("liquibaseBackup").getChangeSets()).hasSize(1);
assertThat(liquibaseBeans.get("liquibaseBackup").getChangeSets().get(0).getChangeLog())
.isEqualTo("classpath:/db/changelog/db.changelog-master-backup.yaml");
});
}
private boolean getAutoCommit(DataSource dataSource) throws SQLException {
try (Connection connection = dataSource.getConnection()) {
return connection.getAutoCommit();
@ -108,4 +126,43 @@ public class LiquibaseEndpointTests {
}
@Configuration
static class LiquibaseConfiguration {
@Bean
DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:hsqldb:mem:test");
config.setUsername("sa");
return new HikariDataSource(config);
}
@Bean
DataSource dataSourceBackup() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:hsqldb:mem:testBackup");
config.setUsername("sa");
return new HikariDataSource(config);
}
@Bean
SpringLiquibase liquibase(DataSource dataSource) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setChangeLog("classpath:/db/changelog/db.changelog-master.yaml");
liquibase.setShouldRun(true);
liquibase.setDataSource(dataSource);
return liquibase;
}
@Bean
SpringLiquibase liquibaseBackup(DataSource dataSourceBackup) {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setChangeLog("classpath:/db/changelog/db.changelog-master-backup.yaml");
liquibase.setShouldRun(true);
liquibase.setDataSource(dataSourceBackup);
return liquibase;
}
}
}

View File

@ -0,0 +1,20 @@
databaseChangeLog:
- changeSet:
id: 1
author: leoli
changes:
- createTable:
tableName: customerbackup
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: name
type: varchar(50)
constraints:
nullable: false