schema migrator validation skips skippable tasks (#6050)
This commit is contained in:
parent
39396b136f
commit
315a05eeb8
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 6049
|
||||||
|
title: "Rolled back org.apache.derby dependency to one that
|
||||||
|
supports JREs 11 - 17.
|
||||||
|
"
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 6049
|
||||||
|
title: "Fixed a bug in SchemaMigrator that would considered
|
||||||
|
skippable migration tasks as 'failed' migrations.
|
||||||
|
"
|
|
@ -152,7 +152,6 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,12 @@ public class MigrationTaskList implements Iterable<BaseTask> {
|
||||||
return new MigrationTaskList(unappliedTasks);
|
return new MigrationTaskList(unappliedTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MigrationTaskList getUnskippableTasks() {
|
||||||
|
List<BaseTask> tasks =
|
||||||
|
myTasks.stream().filter(t -> !t.isHeavyweightSkippableTask()).collect(Collectors.toList());
|
||||||
|
return new MigrationTaskList(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
public void append(Iterable<BaseTask> theMigrationTasks) {
|
public void append(Iterable<BaseTask> theMigrationTasks) {
|
||||||
for (BaseTask next : theMigrationTasks) {
|
for (BaseTask next : theMigrationTasks) {
|
||||||
myTasks.add(next);
|
myTasks.add(next);
|
||||||
|
|
|
@ -72,8 +72,10 @@ public class SchemaMigrator {
|
||||||
try (Connection connection = myDataSource.getConnection()) {
|
try (Connection connection = myDataSource.getConnection()) {
|
||||||
MigrationTaskList unappliedMigrations = myHapiMigrationStorageSvc.diff(myMigrationTasks);
|
MigrationTaskList unappliedMigrations = myHapiMigrationStorageSvc.diff(myMigrationTasks);
|
||||||
|
|
||||||
if (unappliedMigrations.size() > 0) {
|
// remove skippable tasks
|
||||||
|
MigrationTaskList unappliedUnskippable = unappliedMigrations.getUnskippableTasks();
|
||||||
|
|
||||||
|
if (unappliedUnskippable.size() > 0) {
|
||||||
String url = connection.getMetaData().getURL();
|
String url = connection.getMetaData().getURL();
|
||||||
throw new ConfigurationException(Msg.code(27) + "The database schema for " + url + " is out of date. "
|
throw new ConfigurationException(Msg.code(27) + "The database schema for " + url + " is out of date. "
|
||||||
+ "Current database schema version is "
|
+ "Current database schema version is "
|
||||||
|
|
|
@ -6,12 +6,16 @@ import ca.uhn.fhir.jpa.migrate.entity.HapiMigrationEntity;
|
||||||
import ca.uhn.fhir.jpa.migrate.taskdef.AddTableRawSqlTask;
|
import ca.uhn.fhir.jpa.migrate.taskdef.AddTableRawSqlTask;
|
||||||
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask;
|
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTask;
|
||||||
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTest;
|
import ca.uhn.fhir.jpa.migrate.taskdef.BaseTest;
|
||||||
|
import ca.uhn.fhir.jpa.migrate.tasks.api.TaskFlagEnum;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import jakarta.annotation.Nonnull;
|
import jakarta.annotation.Nonnull;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -19,13 +23,61 @@ import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
|
||||||
public class SchemaMigratorTest extends BaseTest {
|
public class SchemaMigratorTest extends BaseTest {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SchemaMigratorTest.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SchemaMigratorTest.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validate_withSkippableTasks_returnsSuccessful() throws SQLException {
|
||||||
|
// setup
|
||||||
|
Connection connection = mock(Connection.class);
|
||||||
|
DataSource dataSource = mock(DataSource.class);
|
||||||
|
DriverTypeEnum driverTypeEnum = DriverTypeEnum.POSTGRES_9_4; // does not matter
|
||||||
|
HapiMigrationStorageSvc migrationStorageSvc = mock(HapiMigrationStorageSvc.class);
|
||||||
|
|
||||||
|
// create some tasks
|
||||||
|
AddTableRawSqlTask taskA = new AddTableRawSqlTask("V4_1_0", "20191214.1");
|
||||||
|
taskA.setTableName("SOMETABLE_A");
|
||||||
|
taskA.addSql(driverTypeEnum, "create table SOMETABLE_A (PID bigint not null, TEXTCOL varchar(255))");
|
||||||
|
|
||||||
|
AddTableRawSqlTask taskB = new AddTableRawSqlTask("V4_1_0", "20191214.2");
|
||||||
|
taskB.setTableName("SOMETABLE_B");
|
||||||
|
taskB.addSql(driverTypeEnum, "create table SOMETABLE_B (PID bigint not null, TEXTCOL varchar(255))");
|
||||||
|
|
||||||
|
AddTableRawSqlTask taskC = new AddTableRawSqlTask("V4_1_0", "20191214.3");
|
||||||
|
taskC.setTableName("SOMETABLE_C");
|
||||||
|
taskC.addSql(driverTypeEnum, "create table SOMETABLE_C (PID bigint not null, TEXTCOL varchar(255))");
|
||||||
|
|
||||||
|
AddTableRawSqlTask taskD = new AddTableRawSqlTask("V4_1_0", "20191214.4");
|
||||||
|
taskD.setTableName("SOMETABLE_D");
|
||||||
|
taskD.addSql(driverTypeEnum, "create table SOMETABLE_D (PID bigint not null, TEXTCOL varchar(255))");
|
||||||
|
|
||||||
|
List<BaseTask> tasks = ImmutableList.of(taskA, taskB, taskC, taskD);
|
||||||
|
for (BaseTask t : tasks) {
|
||||||
|
t.addFlag(TaskFlagEnum.HEAVYWEIGHT_SKIP_BY_DEFAULT);
|
||||||
|
}
|
||||||
|
MigrationTaskList taskList = new MigrationTaskList(tasks);
|
||||||
|
|
||||||
|
// when
|
||||||
|
when(migrationStorageSvc.diff(any(MigrationTaskList.class)))
|
||||||
|
.thenReturn(taskList);
|
||||||
|
when(dataSource.getConnection())
|
||||||
|
.thenReturn(connection);
|
||||||
|
|
||||||
|
// create a migrator (with empty task list)
|
||||||
|
SchemaMigrator schemaMigrator = new SchemaMigrator(getUrl(), SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME, dataSource, new Properties(), new MigrationTaskList(), migrationStorageSvc);
|
||||||
|
schemaMigrator.setDriverType(driverTypeEnum);
|
||||||
|
|
||||||
|
// test
|
||||||
|
assertDoesNotThrow(schemaMigrator::validate);
|
||||||
|
}
|
||||||
|
|
||||||
@ParameterizedTest(name = "{index}: {0}")
|
@ParameterizedTest(name = "{index}: {0}")
|
||||||
@MethodSource("data")
|
@MethodSource("data")
|
||||||
|
@ -47,7 +99,6 @@ public class SchemaMigratorTest extends BaseTest {
|
||||||
schemaMigrator.validate();
|
schemaMigrator.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ParameterizedTest(name = "{index}: {0}")
|
@ParameterizedTest(name = "{index}: {0}")
|
||||||
@MethodSource("data")
|
@MethodSource("data")
|
||||||
public void testRepairFailedMigration(Supplier<TestDatabaseDetails> theTestDatabaseDetails) {
|
public void testRepairFailedMigration(Supplier<TestDatabaseDetails> theTestDatabaseDetails) {
|
||||||
|
|
3
pom.xml
3
pom.xml
|
@ -969,7 +969,8 @@
|
||||||
<commons_io_version>2.11.0</commons_io_version>
|
<commons_io_version>2.11.0</commons_io_version>
|
||||||
<commons_lang3_version>3.14.0</commons_lang3_version>
|
<commons_lang3_version>3.14.0</commons_lang3_version>
|
||||||
<com_jamesmurty_utils_version>1.2</com_jamesmurty_utils_version>
|
<com_jamesmurty_utils_version>1.2</com_jamesmurty_utils_version>
|
||||||
<derby_version>10.17.1.0</derby_version>
|
<!-- Note: Derby is held to 10.15.x deliberately, as the 10.17+ version requires Java 21 to build -->
|
||||||
|
<derby_version>10.15.2.0</derby_version>
|
||||||
<error_prone_core_version>2.23.0</error_prone_core_version>
|
<error_prone_core_version>2.23.0</error_prone_core_version>
|
||||||
<mockito_version>5.8.0</mockito_version>
|
<mockito_version>5.8.0</mockito_version>
|
||||||
<nullaway_version>0.7.9</nullaway_version>
|
<nullaway_version>0.7.9</nullaway_version>
|
||||||
|
|
Loading…
Reference in New Issue