Skip to content

Commit

Permalink
fixup! Add runtime configuration property quarkus.datasource.active
Browse files Browse the repository at this point in the history
  • Loading branch information
yrodiere committed Nov 23, 2023
1 parent b968dcf commit 9d9473b
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ public AgroalDataSource getDataSource(String dataSourceName) {
return dataSource;
}

public boolean isDataSourceActive(String dataSourceName) {
return getDataSourceIfActiveOrNull(dataSourceName) != null;
}

public Optional<AgroalDataSource> getDataSourceIfActive(String dataSourceName) {
return Optional.ofNullable(getDataSourceIfActiveOrNull(dataSourceName));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public static FlywayDataSourceRuntimeConfig defaultConfig() {
/**
* Flag to activate/deactivate Flyway for a specific datasource at runtime.
*/
@ConfigItem(defaultValue = "true")
public boolean active = true;
@ConfigItem(defaultValueDocumentation = "'true' if the datasource is active; 'false' otherwise")
public Optional<Boolean> active = Optional.empty();

/**
* The maximum number of retries when attempting to connect to the database.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ public void doStartActions(String dataSourceName) {
FlywayDataSourceRuntimeConfig flywayDataSourceRuntimeConfig = config.getValue()
.getConfigForDataSourceName(dataSourceName);

if (!config.getValue().getConfigForDataSourceName(dataSourceName).active) {
if (!flywayDataSourceRuntimeConfig.active
// If not specified explicitly, Flyway is active when the datasource itself is active.
.orElseGet(() -> Arc.container().instance(DataSources.class).get().isDataSourceActive(dataSourceName))) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,13 @@ ServiceStartBuildItem startLiquibase(LiquibaseRecorder recorder,
BuildProducer<InitTaskCompletedBuildItem> initializationCompleteBuildItem,
BuildProducer<JdbcDataSourceSchemaReadyBuildItem> schemaReadyBuildItem) {

recorder.doStartActions();
Set<String> dataSourceNames = getDataSourceNames(jdbcDataSourceBuildItems);
for (String dataSourceName : dataSourceNames) {
recorder.doStartActions(dataSourceName);
}
// once we are done running the migrations, we produce a build item indicating that the
// schema is "ready"
schemaReadyBuildItem.produce(new JdbcDataSourceSchemaReadyBuildItem(getDataSourceNames(jdbcDataSourceBuildItems)));
schemaReadyBuildItem.produce(new JdbcDataSourceSchemaReadyBuildItem(dataSourceNames));
initializationCompleteBuildItem.produce(new InitTaskCompletedBuildItem("liquibase"));

return new ServiceStartBuildItem("liquibase");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package io.quarkus.liquibase.runtime;

import java.lang.annotation.Annotation;
import java.util.Locale;
import java.util.function.Function;

import javax.sql.DataSource;

import io.quarkus.datasource.common.runtime.DataSourceUtil;
import io.quarkus.runtime.configuration.ConfigurationException;
import jakarta.enterprise.inject.Any;
import jakarta.enterprise.inject.Default;
import jakarta.enterprise.inject.UnsatisfiedResolutionException;

import io.quarkus.agroal.runtime.DataSources;
import io.quarkus.agroal.runtime.UnconfiguredDataSource;
import io.quarkus.arc.Arc;
import io.quarkus.arc.InjectableInstance;
import io.quarkus.arc.InstanceHandle;
import io.quarkus.arc.SyntheticCreationalContext;
import io.quarkus.datasource.common.runtime.DataSourceUtil;
import io.quarkus.liquibase.LiquibaseDataSource.LiquibaseDataSourceLiteral;
import io.quarkus.liquibase.LiquibaseFactory;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
Expand Down Expand Up @@ -42,7 +43,8 @@ public LiquibaseFactory apply(SyntheticCreationalContext<LiquibaseFactory> conte
throw DataSourceUtil.dataSourceNotConfigured(dataSourceName);
}
} catch (RuntimeException e) {
throw new ConfigurationException(String.format("Unable to find datasource '%s' for Liquibase: %s",
throw new UnsatisfiedResolutionException(String.format(Locale.ROOT,
"Unable to find datasource '%s' for Liquibase: %s",
dataSourceName, e.getMessage()), e);
}

Expand All @@ -52,49 +54,53 @@ public LiquibaseFactory apply(SyntheticCreationalContext<LiquibaseFactory> conte
};
}

public void doStartActions() {
public void doStartActions(String dataSourceName) {
if (!config.getValue().enabled) {
return;
}
// Liquibase is active when the datasource itself is active.
if (!Arc.container().instance(DataSources.class).get().isDataSourceActive(dataSourceName)) {
return;
}

InstanceHandle<LiquibaseFactory> liquibaseFactoryHandle = Arc.container().instance(LiquibaseFactory.class,
getLiquibaseFactoryQualifier(dataSourceName));
try {
InjectableInstance<LiquibaseFactory> liquibaseFactoryInstance = Arc.container()
.select(LiquibaseFactory.class, Any.Literal.INSTANCE);
if (liquibaseFactoryInstance.isUnsatisfied()) {
LiquibaseFactory liquibaseFactory = liquibaseFactoryHandle.get();
var config = liquibaseFactory.getConfiguration();
if (!config.cleanAtStart && !config.migrateAtStart) {
return;
}

for (InstanceHandle<LiquibaseFactory> liquibaseFactoryHandle : liquibaseFactoryInstance.handles()) {
try {
LiquibaseFactory liquibaseFactory = liquibaseFactoryHandle.get();
var config = liquibaseFactory.getConfiguration();
if (!config.cleanAtStart && !config.migrateAtStart) {
continue;
}
try (Liquibase liquibase = liquibaseFactory.createLiquibase()) {
if (config.cleanAtStart) {
liquibase.dropAll();
}
if (config.migrateAtStart) {
var lockService = LockServiceFactory.getInstance()
.getLockService(liquibase.getDatabase());
lockService.waitForLock();
try {
if (config.validateOnMigrate) {
liquibase.validate();
}
liquibase.update(liquibaseFactory.createContexts(), liquibaseFactory.createLabels());
} finally {
lockService.releaseLock();
}
try (Liquibase liquibase = liquibaseFactory.createLiquibase()) {
if (config.cleanAtStart) {
liquibase.dropAll();
}
if (config.migrateAtStart) {
var lockService = LockServiceFactory.getInstance()
.getLockService(liquibase.getDatabase());
lockService.waitForLock();
try {
if (config.validateOnMigrate) {
liquibase.validate();
}
liquibase.update(liquibaseFactory.createContexts(), liquibaseFactory.createLabels());
} finally {
lockService.releaseLock();
}
} catch (UnsatisfiedResolutionException e) {
//ignore, the DS is not configured
}
}
} catch (UnsatisfiedResolutionException e) {
//ignore, the DS is not configured
} catch (Exception e) {
throw new IllegalStateException("Error starting Liquibase", e);
}
}

private static Annotation getLiquibaseFactoryQualifier(String dataSourceName) {
if (DataSourceUtil.isDefault(dataSourceName)) {
return Default.Literal.INSTANCE;
}

return LiquibaseDataSourceLiteral.of(dataSourceName);
}
}

0 comments on commit 9d9473b

Please sign in to comment.