Skip to content

Commit

Permalink
Merge pull request #40603 from geoand/#40493
Browse files Browse the repository at this point in the history
Add configuration option for liquibase.allowDuplicatedChangesetIdentifiers
  • Loading branch information
geoand authored May 14, 2024
2 parents 7f8a039 + f52e66b commit 6c34ace
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.quarkus.runtime;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
* Utility that allows for setting system properties when it's created and resetting them when it's closed.
* This is meant to be used in try-with-resources statements
*/
public class ResettableSystemProperties implements AutoCloseable {

private final Map<String, String> toRestore;

public ResettableSystemProperties(Map<String, String> toSet) {
Objects.requireNonNull(toSet);
if (toSet.isEmpty()) {
toRestore = Collections.emptyMap();
return;
}
toRestore = new HashMap<>();
for (var entry : toSet.entrySet()) {
String oldValue = System.setProperty(entry.getKey(), entry.getValue());
toRestore.put(entry.getKey(), oldValue);
}
}

public static ResettableSystemProperties of(String name, String value) {
return new ResettableSystemProperties(Map.of(name, value));
}

public static ResettableSystemProperties empty() {
return new ResettableSystemProperties(Collections.emptyMap());
}

@Override
public void close() {
for (var entry : toRestore.entrySet()) {
if (entry.getValue() != null) {
System.setProperty(entry.getKey(), entry.getValue());
} else {
System.clearProperty(entry.getKey());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.quarkus.runtime;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Map;

import org.junit.jupiter.api.Test;

class ResettableSystemPropertiesTest {

@Test
public void happyPath() {
System.setProperty("prop1", "val1");
assertThat(System.getProperty("prop1")).isEqualTo("val1");
try (var ignored = new ResettableSystemProperties(
Map.of("prop1", "val11", "prop2", "val2"))) {
assertThat(System.getProperty("prop1")).isEqualTo("val11");
assertThat(System.getProperty("prop2")).isEqualTo("val2");
}
assertThat(System.getProperty("prop1")).isEqualTo("val1");
assertThat(System.getProperties()).doesNotContainKey("prop2");
}

@Test
public void exceptionThrown() {
System.setProperty("prop1", "val1");
int initCount = System.getProperties().size();
assertThat(System.getProperty("prop1")).isEqualTo("val1");
try (var ignored = new ResettableSystemProperties(
Map.of("prop1", "val11", "prop2", "val2"))) {
assertThat(System.getProperty("prop1")).isEqualTo("val11");
assertThat(System.getProperty("prop2")).isEqualTo("val2");

throw new RuntimeException("dummy");
} catch (Exception ignored) {

}
assertThat(System.getProperty("prop1")).isEqualTo("val1");
assertThat(System.getProperties()).doesNotContainKey("prop2");
assertThat(System.getProperties().size()).isEqualTo(initCount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import io.agroal.api.AgroalDataSource;
import io.quarkus.liquibase.runtime.LiquibaseConfig;
import io.quarkus.runtime.ResettableSystemProperties;
import io.quarkus.runtime.util.StringUtil;
import liquibase.Contexts;
import liquibase.LabelExpression;
Expand Down Expand Up @@ -150,4 +151,12 @@ public Contexts createContexts() {
public String getDataSourceName() {
return dataSourceName;
}

public ResettableSystemProperties createResettableSystemProperties() {
if (config.allowDuplicatedChangesetIdentifiers.isEmpty()) {
return ResettableSystemProperties.empty();
}
return ResettableSystemProperties.of("liquibase.allowDuplicatedChangesetIdentifiers",
config.allowDuplicatedChangesetIdentifiers.get().toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,9 @@ public class LiquibaseConfig {
*/
public Optional<String> password = Optional.empty();

/**
* Allows duplicated changeset identifiers without failing Liquibase execution.
*/
public Optional<Boolean> allowDuplicatedChangesetIdentifiers;

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public LiquibaseFactory createLiquibaseFactory(DataSource dataSource, String dat
config.migrateAtStart = liquibaseRuntimeConfig.migrateAtStart;
config.cleanAtStart = liquibaseRuntimeConfig.cleanAtStart;
config.validateOnMigrate = liquibaseRuntimeConfig.validateOnMigrate;
config.allowDuplicatedChangesetIdentifiers = liquibaseRuntimeConfig.allowDuplicatedChangesetIdentifiers;
return new LiquibaseFactory(config, dataSource, dataSourceName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,10 @@ public static final LiquibaseDataSourceRuntimeConfig defaultConfig() {
@ConfigItem
public Optional<String> liquibaseTablespaceName = Optional.empty();

/**
* Allows duplicated changeset identifiers without failing Liquibase execution.
*/
@ConfigItem
public Optional<Boolean> allowDuplicatedChangesetIdentifiers = Optional.empty();

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.quarkus.arc.SyntheticCreationalContext;
import io.quarkus.datasource.common.runtime.DataSourceUtil;
import io.quarkus.liquibase.LiquibaseFactory;
import io.quarkus.runtime.ResettableSystemProperties;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import liquibase.Liquibase;
Expand Down Expand Up @@ -66,7 +67,9 @@ public void doStartActions(String dataSourceName) {
if (!config.cleanAtStart && !config.migrateAtStart) {
return;
}
try (Liquibase liquibase = liquibaseFactory.createLiquibase()) {
try (Liquibase liquibase = liquibaseFactory.createLiquibase();
ResettableSystemProperties resettableSystemProperties = liquibaseFactory
.createResettableSystemProperties()) {
if (config.cleanAtStart) {
liquibase.dropAll();
}
Expand Down

0 comments on commit 6c34ace

Please sign in to comment.