Skip to content

Commit

Permalink
Fail on startup when Flyway/Liquibase for inactive datasources are in…
Browse files Browse the repository at this point in the history
…jected into user beans

By reimplementing Flyway's/Liquibase's inactive/active handling and eager
startup through Arc's native features, which is better integrated and gives
us this behavior.
  • Loading branch information
yrodiere committed Sep 25, 2024
1 parent e4c18b3 commit 71212ae
Show file tree
Hide file tree
Showing 16 changed files with 231 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ void createBeans(FlywayRecorder recorder,
.addInjectionPoint(ClassType.create(DotName.createSimple(FlywayContainerProducer.class)))
.addInjectionPoint(ClassType.create(DotName.createSimple(DataSource.class)),
AgroalDataSourceBuildUtil.qualifier(dataSourceName))
.startup()
.isActive(recorder.flywayContainerActiveSupplier(dataSourceName))
.createWith(recorder.flywayContainerFunction(dataSourceName, hasMigrations, createPossible));

AnnotationInstance flywayContainerQualifier;
Expand Down Expand Up @@ -249,6 +251,11 @@ void createBeans(FlywayRecorder recorder,
.setRuntimeInit()
.unremovable()
.addInjectionPoint(ClassType.create(DotName.createSimple(FlywayContainer.class)), flywayContainerQualifier)
// TODO uncomment this once we remove UnconfiguredDataSourceFlywayContainer
// Right now we can't, because UnconfiguredDataSourceFlywayContainer#getFlyway would throw an exception on startup,
// and unfortunately this also means we won't detect user beans being injected with Flyway for deactivated datasources...
//.startup()
.isActive(recorder.flywayActiveSupplier(dataSourceName))
.createWith(recorder.flywayFunction(dataSourceName));

if (DataSourceUtil.isDefault(dataSourceName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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

import jakarta.enterprise.inject.CreationException;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;

Expand All @@ -11,6 +10,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.InactiveBeanException;
import io.quarkus.test.QuarkusUnitTest;

public class FlywayExtensionConfigActiveFalseDefaultDatasourceTest {
Expand All @@ -26,10 +26,9 @@ public class FlywayExtensionConfigActiveFalseDefaultDatasourceTest {
@DisplayName("If the default datasource is deactivated, the application should boot, but Flyway should be deactivated for that datasource")
public void testBootSucceedsButFlywayDeactivated() {
assertThatThrownBy(flywayForDefaultDatasource::get)
.isInstanceOf(CreationException.class)
.cause()
.hasMessageContainingAll("Unable to find datasource '<default>' for Flyway",
"Datasource '<default>' was deactivated through configuration properties.",
.isInstanceOf(InactiveBeanException.class)
.hasMessageContainingAll(
"Flyway for datasource '<default>' was deactivated automatically because this datasource was deactivated.",
"To avoid this exception while keeping the bean inactive", // Message from Arc with generic hints
"To activate the datasource, set configuration property 'quarkus.datasource.active'"
+ " to 'true' and configure datasource '<default>'",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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

import jakarta.enterprise.inject.CreationException;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;

Expand All @@ -11,6 +10,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.InactiveBeanException;
import io.quarkus.flyway.FlywayDataSource;
import io.quarkus.test.QuarkusUnitTest;

Expand All @@ -37,10 +37,9 @@ public class FlywayExtensionConfigActiveFalseNamedDataSourceTest {
@DisplayName("If a named datasource is deactivated, the application should boot, but Flyway should be deactivated for that datasource")
public void testBootSucceedsButFlywayDeactivated() {
assertThatThrownBy(flywayForNamedDatasource::get)
.isInstanceOf(CreationException.class)
.cause()
.hasMessageContainingAll("Unable to find datasource 'users' for Flyway",
"Datasource 'users' was deactivated through configuration properties.",
.isInstanceOf(InactiveBeanException.class)
.hasMessageContainingAll(
"Flyway for datasource 'users' was deactivated automatically because this datasource was deactivated.",
"To avoid this exception while keeping the bean inactive", // Message from Arc with generic hints
"To activate the datasource, set configuration property 'quarkus.datasource.\"users\".active'"
+ " to 'true' and configure datasource 'users'",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.CreationException;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;

Expand All @@ -12,6 +11,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.InactiveBeanException;
import io.quarkus.test.QuarkusUnitTest;

public class FlywayExtensionConfigEmptyDefaultDatasourceTest {
Expand All @@ -31,9 +31,9 @@ public class FlywayExtensionConfigEmptyDefaultDatasourceTest {
@DisplayName("If there is no config for the default datasource, the application should boot, but Flyway should be deactivated for that datasource")
public void testBootSucceedsButFlywayDeactivated() {
assertThatThrownBy(flywayForDefaultDatasource::get)
.isInstanceOf(CreationException.class)
.cause()
.hasMessageContainingAll("Unable to find datasource '<default>' for Flyway",
.isInstanceOf(InactiveBeanException.class)
.hasMessageContainingAll(
"Flyway for datasource '<default>' was deactivated automatically because this datasource was not configured",
"Datasource '<default>' is not configured.",
"To solve this, configure datasource '<default>'.",
"Refer to https://quarkus.io/guides/datasource for guidance.");
Expand All @@ -44,7 +44,8 @@ public void testBootSucceedsButFlywayDeactivated() {
public void testBootSucceedsWithInjectedBeanDependingOnFlywayButFlywayDeactivated() {
assertThatThrownBy(() -> myBean.useFlyway())
.cause()
.hasMessageContainingAll("Unable to find datasource '<default>' for Flyway",
.hasMessageContainingAll(
"Flyway for datasource '<default>' was deactivated automatically because this datasource was not configured",
"Datasource '<default>' is not configured.",
"To solve this, configure datasource '<default>'.",
"Refer to https://quarkus.io/guides/datasource for guidance.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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

import jakarta.enterprise.inject.CreationException;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;

Expand All @@ -11,6 +10,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.InactiveBeanException;
import io.quarkus.test.QuarkusUnitTest;

public class FlywayExtensionMigrateAtStartDefaultDatasourceConfigActiveFalseTest {
Expand All @@ -29,10 +29,9 @@ public class FlywayExtensionMigrateAtStartDefaultDatasourceConfigActiveFalseTest
@DisplayName("If the default datasource is deactivated, even if migrate-at-start is enabled, the application should boot, but Flyway should be deactivated for that datasource")
public void testBootSucceedsButFlywayDeactivated() {
assertThatThrownBy(flywayForDefaultDatasource::get)
.isInstanceOf(CreationException.class)
.cause()
.hasMessageContainingAll("Unable to find datasource '<default>' for Flyway",
"Datasource '<default>' was deactivated through configuration properties.",
.isInstanceOf(InactiveBeanException.class)
.hasMessageContainingAll(
"Flyway for datasource '<default>' was deactivated automatically because this datasource was deactivated",
"To avoid this exception while keeping the bean inactive", // Message from Arc with generic hints
"To activate the datasource, set configuration property 'quarkus.datasource.active'"
+ " to 'true' and configure datasource '<default>'",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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

import jakarta.enterprise.inject.CreationException;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;

Expand All @@ -11,6 +10,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.InactiveBeanException;
import io.quarkus.test.QuarkusUnitTest;

public class FlywayExtensionMigrateAtStartDefaultDatasourceConfigEmptyTest {
Expand All @@ -30,10 +30,9 @@ public class FlywayExtensionMigrateAtStartDefaultDatasourceConfigEmptyTest {
@DisplayName("If there is no config for the default datasource, even if migrate-at-start is enabled, the application should boot, but Flyway should be deactivated for that datasource")
public void testBootSucceedsButFlywayDeactivated() {
assertThatThrownBy(flywayForDefaultDatasource::get)
.isInstanceOf(CreationException.class)
.cause()
.hasMessageContainingAll("Unable to find datasource '<default>' for Flyway",
"Datasource '<default>' is not configured.",
.isInstanceOf(InactiveBeanException.class)
.hasMessageContainingAll(
"Flyway for datasource '<default>' was deactivated automatically because this datasource was not configured",
"To solve this, configure datasource '<default>'.",
"Refer to https://quarkus.io/guides/datasource for guidance.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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

import jakarta.enterprise.inject.CreationException;
import jakarta.enterprise.inject.Instance;
import jakarta.inject.Inject;

Expand All @@ -11,6 +10,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.InactiveBeanException;
import io.quarkus.flyway.FlywayDataSource;
import io.quarkus.test.QuarkusUnitTest;

Expand Down Expand Up @@ -40,10 +40,9 @@ public class FlywayExtensionMigrateAtStartNamedDatasourceConfigActiveFalseTest {
@DisplayName("If a named datasource is deactivated, even if migrate-at-start is enabled, the application should boot, but Flyway should be deactivated for that datasource")
public void testBootSucceedsButFlywayDeactivated() {
assertThatThrownBy(flywayForNamedDatasource::get)
.isInstanceOf(CreationException.class)
.cause()
.hasMessageContainingAll("Unable to find datasource 'users' for Flyway",
"Datasource 'users' was deactivated through configuration properties.",
.isInstanceOf(InactiveBeanException.class)
.hasMessageContainingAll(
"Flyway for datasource 'users' was deactivated automatically because this datasource was deactivated",
"To avoid this exception while keeping the bean inactive", // Message from Arc with generic hints
"To activate the datasource, set configuration property 'quarkus.datasource.\"users\".active'"
+ " to 'true' and configure datasource 'users'",
Expand Down
Loading

0 comments on commit 71212ae

Please sign in to comment.