diff --git a/platform-plugins/flamingock-springboot-integration/src/main/java/io/flamingock/springboot/FlamingockAutoConfiguration.java b/platform-plugins/flamingock-springboot-integration/src/main/java/io/flamingock/springboot/FlamingockAutoConfiguration.java index cca6d3d14..cb375bb40 100644 --- a/platform-plugins/flamingock-springboot-integration/src/main/java/io/flamingock/springboot/FlamingockAutoConfiguration.java +++ b/platform-plugins/flamingock-springboot-integration/src/main/java/io/flamingock/springboot/FlamingockAutoConfiguration.java @@ -24,11 +24,13 @@ import org.springframework.boot.ApplicationRunner; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import java.util.List; @@ -37,11 +39,14 @@ * *

The configuration behavior is controlled by the {@code flamingock.management-mode} property:

* + * + *

The builder bean is always created (unless UNMANAGED) and can be overridden by providing + * your own {@link AbstractChangeRunnerBuilder} bean.

*/ @Configuration @ConditionalOnClass(name = "org.springframework.boot.SpringApplication") @@ -50,56 +55,16 @@ public class FlamingockAutoConfiguration { /** - * Creates an ApplicationRunner that builds and executes Flamingock at application startup. - * Only created when management-mode is APPLICATION_RUNNER (the default). - */ - @Bean("flamingock-runner") - @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('APPLICATION_RUNNER')") - public ApplicationRunner applicationRunner(SpringbootProperties configurationProperties, - ApplicationContext springContext, - ApplicationEventPublisher applicationEventPublisher, - @Autowired(required = false) CommunityAuditStore auditStore, - List targetSystems) { - AbstractChangeRunnerBuilder builder = createBuilder( - configurationProperties, springContext, applicationEventPublisher, auditStore, targetSystems); - return SpringbootUtil.toApplicationRunner(builder); - } - - /** - * Creates an InitializingBean that builds and executes Flamingock during bean initialization. - * Only created when management-mode is INITIALIZING_BEAN. - */ - @Bean("flamingock-runner") - @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('INITIALIZING_BEAN')") - public InitializingBean initializingBeanRunner(SpringbootProperties configurationProperties, - ApplicationContext springContext, - ApplicationEventPublisher applicationEventPublisher, - @Autowired(required = false) CommunityAuditStore auditStore, - List targetSystems) { - AbstractChangeRunnerBuilder builder = createBuilder( - configurationProperties, springContext, applicationEventPublisher, auditStore, targetSystems); - return SpringbootUtil.toInitializingBean(builder); - } - - /** - * Exposes the Flamingock builder for manual control over execution. - * Only created when management-mode is DEFERRED. + * Creates the Flamingock builder bean. + * Always created unless management-mode is UNMANAGED or user provides their own builder. */ @Bean("flamingock-builder") - @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('DEFERRED')") + @ConditionalOnMissingBean(AbstractChangeRunnerBuilder.class) public AbstractChangeRunnerBuilder flamingockBuilder(SpringbootProperties configurationProperties, ApplicationContext springContext, ApplicationEventPublisher applicationEventPublisher, @Autowired(required = false) CommunityAuditStore auditStore, List targetSystems) { - return createBuilder(configurationProperties, springContext, applicationEventPublisher, auditStore, targetSystems); - } - - private AbstractChangeRunnerBuilder createBuilder(SpringbootProperties configurationProperties, - ApplicationContext springContext, - ApplicationEventPublisher applicationEventPublisher, - CommunityAuditStore auditStore, - List targetSystems) { AbstractChangeRunnerBuilder builder = FlamingockFactory.getEditionAwareBuilder( configurationProperties.getCoreConfiguration(), configurationProperties.getCloudProperties(), @@ -116,4 +81,24 @@ public InitializingBean initializingBeanRunner(SpringbootProperties configuratio return builder; } + + /** + * Creates an ApplicationRunner that builds and executes Flamingock at application startup. + * Only created when management-mode is APPLICATION_RUNNER (the default). + */ + @Bean("flamingock-runner") + @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('APPLICATION_RUNNER')") + public ApplicationRunner applicationRunner(AbstractChangeRunnerBuilder builder) { + return SpringbootUtil.toApplicationRunner(builder); + } + + /** + * Creates an InitializingBean that builds and executes Flamingock during bean initialization. + * Only created when management-mode is INITIALIZING_BEAN. + */ + @Bean("flamingock-runner") + @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('INITIALIZING_BEAN')") + public InitializingBean initializingBeanRunner(AbstractChangeRunnerBuilder builder) { + return SpringbootUtil.toInitializingBean(builder); + } } diff --git a/platform-plugins/flamingock-springboot-integration/src/test/java/io/flamingock/springboot/FlamingockAutoConfigurationTests.java b/platform-plugins/flamingock-springboot-integration/src/test/java/io/flamingock/springboot/FlamingockAutoConfigurationTests.java index 0d0e2ca33..a4f8e7baa 100644 --- a/platform-plugins/flamingock-springboot-integration/src/test/java/io/flamingock/springboot/FlamingockAutoConfigurationTests.java +++ b/platform-plugins/flamingock-springboot-integration/src/test/java/io/flamingock/springboot/FlamingockAutoConfigurationTests.java @@ -42,29 +42,29 @@ private ApplicationContextRunner contextRunner() { } @Test - void whenModeIsDefault_thenRunnerBeanExistsAndBuilderBeanDoesNot() { - // Default is APPLICATION_RUNNER - runner bean exists, builder bean does not + void whenModeIsDefault_thenBothBuilderAndRunnerBeansExist() { + // Default is APPLICATION_RUNNER - both builder and runner beans exist contextRunner().run(ctx -> { + assertThat(ctx).hasBean("flamingock-builder"); assertThat(ctx).hasBean("flamingock-runner"); - assertThat(ctx).doesNotHaveBean("flamingock-builder"); }); } @Test - void whenModeIsApplicationRunner_thenRunnerBeanExistsAndBuilderBeanDoesNot() { + void whenModeIsApplicationRunner_thenBothBuilderAndRunnerBeansExist() { contextRunner() .withPropertyValues("flamingock.management-mode=APPLICATION_RUNNER") .run(ctx -> { + assertThat(ctx).hasBean("flamingock-builder"); assertThat(ctx).hasBean("flamingock-runner"); - assertThat(ctx).doesNotHaveBean("flamingock-builder"); }); } @Test - void whenModeIsInitializingBean_thenRunnerBeanIsCreated() { + void whenModeIsInitializingBean_thenBothBeansCreatedAndExecutionAttempted() { // InitializingBean executes immediately during bean creation. - // We verify the bean creation was attempted by checking the context fails - // with a Flamingock-related error (proving the InitializingBean bean was created and executed). + // Both builder and runner beans are created, but execution fails because + // the test context doesn't have all required Flamingock dependencies. contextRunner() .withPropertyValues("flamingock.management-mode=INITIALIZING_BEAN") .run(ctx -> {