From 21b9e19e652ccbb0707e459c257d660b7862bb0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez?= Date: Fri, 13 Feb 2026 17:00:03 +0100 Subject: [PATCH] Add EnvironmentPostProcessor to conditionally exclude RabbitMQ and Kafka auto-configurations When neither firefly.eda.rabbit nor firefly.eda.kafka publisher/consumer properties are enabled, the corresponding Spring Boot auto-configurations are excluded at startup, preventing health check errors for unconfigured messaging infrastructure. --- pom.xml | 4 +- .../FireflyEdaEnvironmentPostProcessor.java | 131 ++++++++++++++++++ src/main/resources/META-INF/spring.factories | 2 + 3 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/fireflyframework/eda/config/FireflyEdaEnvironmentPostProcessor.java create mode 100644 src/main/resources/META-INF/spring.factories diff --git a/pom.xml b/pom.xml index 8f78231..69748c9 100644 --- a/pom.xml +++ b/pom.xml @@ -91,13 +91,13 @@ provided - + org.springframework.kafka spring-kafka - + org.springframework.boot spring-boot-starter-amqp diff --git a/src/main/java/org/fireflyframework/eda/config/FireflyEdaEnvironmentPostProcessor.java b/src/main/java/org/fireflyframework/eda/config/FireflyEdaEnvironmentPostProcessor.java new file mode 100644 index 0000000..2aaa187 --- /dev/null +++ b/src/main/java/org/fireflyframework/eda/config/FireflyEdaEnvironmentPostProcessor.java @@ -0,0 +1,131 @@ +/* + * Copyright 2024-2026 Firefly Software Solutions Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.fireflyframework.eda.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Environment post-processor that conditionally excludes Spring Boot's + * RabbitMQ and Kafka auto-configurations when the corresponding Firefly EDA + * transports are not enabled. + * + *

This prevents Spring Boot from auto-creating connection factories and + * health indicators for messaging systems that the application does not use, + * avoiding startup errors like "Rabbit health check failed - Connection refused". + * + *

Behavior: + *

+ * + *

Any existing {@code spring.autoconfigure.exclude} entries are preserved. + */ +public class FireflyEdaEnvironmentPostProcessor implements EnvironmentPostProcessor { + + private static final String EXCLUDE_PROPERTY = "spring.autoconfigure.exclude"; + private static final String RABBIT_AUTO_CONFIG = "org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration"; + private static final String KAFKA_AUTO_CONFIG = "org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration"; + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + List excludes = new ArrayList<>(); + + if (shouldExcludeRabbit(environment)) { + excludes.add(RABBIT_AUTO_CONFIG); + } + + if (shouldExcludeKafka(environment)) { + excludes.add(KAFKA_AUTO_CONFIG); + } + + if (!excludes.isEmpty()) { + applyExcludes(environment, excludes); + } + } + + private boolean shouldExcludeRabbit(ConfigurableEnvironment env) { + // Respect explicit Spring Boot native configuration + if (env.containsProperty("spring.rabbitmq.host")) { + return false; + } + + boolean publisherEnabled = env.getProperty( + "firefly.eda.publishers.rabbitmq.default.enabled", Boolean.class, false); + boolean consumerEnabled = env.getProperty( + "firefly.eda.consumer.rabbitmq.default.enabled", Boolean.class, false); + + return !publisherEnabled && !consumerEnabled; + } + + private boolean shouldExcludeKafka(ConfigurableEnvironment env) { + // Respect explicit Spring Boot native configuration + if (env.containsProperty("spring.kafka.bootstrap-servers")) { + return false; + } + + boolean publisherEnabled = env.getProperty( + "firefly.eda.publishers.kafka.default.enabled", Boolean.class, false); + boolean consumerEnabled = env.getProperty( + "firefly.eda.consumer.kafka.default.enabled", Boolean.class, false); + + return !publisherEnabled && !consumerEnabled; + } + + private void applyExcludes(ConfigurableEnvironment environment, List newExcludes) { + // Read existing excludes to preserve them + String existing = environment.getProperty(EXCLUDE_PROPERTY, ""); + List allExcludes = new ArrayList<>(); + + if (!existing.isEmpty()) { + allExcludes.addAll( + Arrays.stream(existing.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toList())); + } + + // Add new excludes (avoiding duplicates) + for (String exclude : newExcludes) { + if (!allExcludes.contains(exclude)) { + allExcludes.add(exclude); + } + } + + Map props = new HashMap<>(); + props.put(EXCLUDE_PROPERTY, String.join(",", allExcludes)); + + environment.getPropertySources().addFirst( + new MapPropertySource("fireflyEdaAutoConfigExcludes", props)); + } +} diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..a8642fb --- /dev/null +++ b/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.env.EnvironmentPostProcessor=\ + org.fireflyframework.eda.config.FireflyEdaEnvironmentPostProcessor