Skip to content

Commit

Permalink
WIP Fail on startup when Flyway/Liquibase for inactive datasources ar…
Browse files Browse the repository at this point in the history
…e injected 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 Jul 30, 2024
1 parent 8f8ecf4 commit 41fe36b
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,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 @@ -247,6 +249,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 41fe36b

Please sign in to comment.