- * Imports {@link org.fireflyframework.transactional.config.TransactionalEngineConfiguration} that wires: + * This annotation imports {@link TransactionalEngineConfiguration} directly so it works + * in both Spring Boot (auto-configuration) and plain Spring contexts + * (e.g. {@code AnnotationConfigApplicationContext}). + *
+ * Additional conditional configurations (persistence, Redis, composition) are registered via + * {@code META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports} + * and activated automatically in Spring Boot applications. + *
+ * Components wired by this annotation: * - {@code SagaRegistry}: scans for @Saga beans and indexes steps * - {@code SagaEngine}: the in-memory orchestrator - * - {@code SagaEvents}: default implementation {@code SagaLoggerEvents} (override by declaring your own bean) + * - {@code TccEngine}: the TCC coordinator + * - {@code SagaEvents}: default implementation (override by declaring your own bean) * - {@code StepLoggingAspect}: AOP aspect for additional logging * - {@code WebClient.Builder}: convenience bean for HTTP clients */ @@ -38,6 +45,6 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@Import({TransactionalEngineConfiguration.class, SagaPersistenceAutoConfiguration.class, SagaRedisAutoConfiguration.class}) +@Import(TransactionalEngineConfiguration.class) public @interface EnableTransactionalEngine { } diff --git a/src/main/java/org/fireflyframework/transactional/shared/config/TransactionalEngineConfiguration.java b/src/main/java/org/fireflyframework/transactional/shared/config/TransactionalEngineConfiguration.java index 7bad0fb..a6f923c 100644 --- a/src/main/java/org/fireflyframework/transactional/shared/config/TransactionalEngineConfiguration.java +++ b/src/main/java/org/fireflyframework/transactional/shared/config/TransactionalEngineConfiguration.java @@ -156,6 +156,12 @@ public TccEventPublisher tccEventPublisher() { return new NoOpTccEventPublisher(); } + @Bean + @ConditionalOnMissingBean + public SagaPersistenceProvider sagaPersistenceProvider() { + return new org.fireflyframework.transactional.saga.persistence.impl.InMemorySagaPersistenceProvider(); + } + @Bean @ConditionalOnMissingBean public TccPersistenceProvider tccPersistenceProvider() { diff --git a/src/main/java/org/fireflyframework/transactional/shared/engine/backpressure/CircuitBreakerBackpressureStrategy.java b/src/main/java/org/fireflyframework/transactional/shared/engine/backpressure/CircuitBreakerBackpressureStrategy.java index 2d336dc..7be95f4 100644 --- a/src/main/java/org/fireflyframework/transactional/shared/engine/backpressure/CircuitBreakerBackpressureStrategy.java +++ b/src/main/java/org/fireflyframework/transactional/shared/engine/backpressure/CircuitBreakerBackpressureStrategy.java @@ -16,6 +16,7 @@ package org.fireflyframework.transactional.shared.engine.backpressure; +import org.fireflyframework.kernel.exception.FireflyException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; @@ -254,7 +255,7 @@ public record CircuitBreakerMetrics( /** * Exception thrown when circuit breaker is open. */ - public static class CircuitBreakerException extends RuntimeException { + public static class CircuitBreakerException extends FireflyException { public CircuitBreakerException(String message) { super(message); } diff --git a/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 544b9ff..08f0ec2 100644 --- a/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,3 +1,4 @@ +org.fireflyframework.transactional.shared.config.TransactionalEngineConfiguration org.fireflyframework.transactional.saga.config.SagaPersistenceAutoConfiguration org.fireflyframework.transactional.saga.config.SagaRedisAutoConfiguration org.fireflyframework.transactional.saga.config.SagaCompositionAutoConfiguration diff --git a/src/test/java/org/fireflyframework/transactional/persistence/integration/RedisPersistenceIntegrationTest.java b/src/test/java/org/fireflyframework/transactional/persistence/integration/RedisPersistenceIntegrationTest.java index 6c89b27..a98682f 100644 --- a/src/test/java/org/fireflyframework/transactional/persistence/integration/RedisPersistenceIntegrationTest.java +++ b/src/test/java/org/fireflyframework/transactional/persistence/integration/RedisPersistenceIntegrationTest.java @@ -22,6 +22,8 @@ import org.fireflyframework.transactional.saga.core.SagaContext; import org.fireflyframework.transactional.saga.engine.SagaEngine; import org.fireflyframework.transactional.saga.engine.StepInputs; +import org.fireflyframework.transactional.saga.config.SagaPersistenceAutoConfiguration; +import org.fireflyframework.transactional.saga.config.SagaRedisAutoConfiguration; import org.fireflyframework.transactional.shared.annotations.EnableTransactionalEngine; import org.fireflyframework.transactional.shared.core.StepStatus; import org.fireflyframework.transactional.saga.persistence.SagaExecutionState; @@ -34,6 +36,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Primary; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; @@ -101,6 +104,7 @@ static void configureProperties(DynamicPropertyRegistry registry) { @Configuration @EnableTransactionalEngine + @Import({SagaPersistenceAutoConfiguration.class, SagaRedisAutoConfiguration.class}) static class TestConfig { @Bean