From 6c667daace907d21dc1b4e95c51de3ca88cf663f Mon Sep 17 00:00:00 2001 From: croway Date: Sun, 12 Jul 2026 14:10:29 +0200 Subject: [PATCH] CAMEL-24025: ship observability-services defaults via EnvironmentPostProcessor Replace the packaged config/application.properties in camel-observability-services-starter with an EnvironmentPostProcessor that registers the same defaults as the lowest precedence property source. The packaged file was loaded from classpath:/config/ which silently overrode the user's own application.properties; with this change the defaults follow the standard Spring Boot precedence rules and can be overridden by any user-provided configuration. Co-Authored-By: Claude Fable 5 --- .../pom.xml | 7 ++ ...ilityServicesEnvironmentPostProcessor.java | 70 +++++++++++++++++++ .../main/resources/META-INF/spring.factories | 19 +++++ ...yServicesEnvironmentPostProcessorTest.java | 65 +++++++++++++++++ .../ObservabilityServicesTestApplication.java | 23 ++++++ .../resources}/application.properties | 28 ++------ 6 files changed, 190 insertions(+), 22 deletions(-) create mode 100644 components-starter/camel-observability-services-starter/src/main/java/org/apache/camel/observability/services/springboot/ObservabilityServicesEnvironmentPostProcessor.java create mode 100644 components-starter/camel-observability-services-starter/src/main/resources/META-INF/spring.factories create mode 100644 components-starter/camel-observability-services-starter/src/test/java/org/apache/camel/observability/services/springboot/ObservabilityServicesEnvironmentPostProcessorTest.java create mode 100644 components-starter/camel-observability-services-starter/src/test/java/org/apache/camel/observability/services/springboot/ObservabilityServicesTestApplication.java rename components-starter/camel-observability-services-starter/src/{main/resources/config => test/resources}/application.properties (50%) diff --git a/components-starter/camel-observability-services-starter/pom.xml b/components-starter/camel-observability-services-starter/pom.xml index bab40878d5f1..6ee236256cc3 100644 --- a/components-starter/camel-observability-services-starter/pom.xml +++ b/components-starter/camel-observability-services-starter/pom.xml @@ -60,6 +60,13 @@ + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot-version} + test + org.apache.camel.springboot diff --git a/components-starter/camel-observability-services-starter/src/main/java/org/apache/camel/observability/services/springboot/ObservabilityServicesEnvironmentPostProcessor.java b/components-starter/camel-observability-services-starter/src/main/java/org/apache/camel/observability/services/springboot/ObservabilityServicesEnvironmentPostProcessor.java new file mode 100644 index 000000000000..498bf024b234 --- /dev/null +++ b/components-starter/camel-observability-services-starter/src/main/java/org/apache/camel/observability/services/springboot/ObservabilityServicesEnvironmentPostProcessor.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.observability.services.springboot; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.springframework.boot.EnvironmentPostProcessor; +import org.springframework.boot.SpringApplication; +import org.springframework.core.Ordered; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; + +/** + * Contributes the opinionated observability defaults as the lowest precedence property source so that any + * user-provided configuration (application.properties, environment variables, system properties, ...) overrides them + * following the standard Spring Boot precedence rules. + */ +public class ObservabilityServicesEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { + + public static final String PROPERTY_SOURCE_NAME = "camel-observability-services"; + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + Map defaults = new LinkedHashMap<>(); + defaults.put("management.server.port", "9876"); + defaults.put("management.endpoints.web.exposure.include", "health,prometheus"); + defaults.put("management.endpoints.web.base-path", "/observe"); + defaults.put("management.endpoints.web.path-mapping.prometheus", "metrics"); + // Metrics + defaults.put("camel.metrics.log-metrics-on-shutdown", "true"); + defaults.put("camel.metrics.log-metrics-on-shutdown-filters", "app.info,camel.exchanges.*"); + // Opentelemetry + defaults.put("camel.opentelemetry2.enabled", "true"); + // Health + defaults.put("camel.health.exposure-level", "full"); + defaults.put("management.endpoint.health.probes.enabled", "true"); + defaults.put("management.health.readinessState.enabled", "true"); + defaults.put("management.health.livenessState.enabled", "true"); + defaults.put("management.endpoint.health.show-details", "always"); + // /observe/health/live remap + defaults.put("management.endpoint.health.group.live.include", "livenessState,camelLivenessState"); + defaults.put("management.endpoint.health.group.live.show-details", "always"); + // /observe/health/ready remap + defaults.put("management.endpoint.health.group.ready.include", "readinessState,camelReadinessState"); + defaults.put("management.endpoint.health.group.ready.show-details", "always"); + + environment.getPropertySources().addLast(new MapPropertySource(PROPERTY_SOURCE_NAME, defaults)); + } + + @Override + public int getOrder() { + // run after ConfigDataEnvironmentPostProcessor so user configuration is already present + return Ordered.LOWEST_PRECEDENCE; + } +} diff --git a/components-starter/camel-observability-services-starter/src/main/resources/META-INF/spring.factories b/components-starter/camel-observability-services-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000000..a089815481f9 --- /dev/null +++ b/components-starter/camel-observability-services-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,19 @@ +## --------------------------------------------------------------------------- +## Licensed to the Apache Software Foundation (ASF) under one or more +## contributor license agreements. See the NOTICE file distributed with +## this work for additional information regarding copyright ownership. +## The ASF licenses this file to You 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. +## --------------------------------------------------------------------------- + +org.springframework.boot.EnvironmentPostProcessor=\ +org.apache.camel.observability.services.springboot.ObservabilityServicesEnvironmentPostProcessor diff --git a/components-starter/camel-observability-services-starter/src/test/java/org/apache/camel/observability/services/springboot/ObservabilityServicesEnvironmentPostProcessorTest.java b/components-starter/camel-observability-services-starter/src/test/java/org/apache/camel/observability/services/springboot/ObservabilityServicesEnvironmentPostProcessorTest.java new file mode 100644 index 000000000000..5b41c9a510c8 --- /dev/null +++ b/components-starter/camel-observability-services-starter/src/test/java/org/apache/camel/observability/services/springboot/ObservabilityServicesEnvironmentPostProcessorTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.observability.services.springboot; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.env.ConfigurableEnvironment; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringBootTest(classes = ObservabilityServicesTestApplication.class) +public class ObservabilityServicesEnvironmentPostProcessorTest { + + @Autowired + private ConfigurableEnvironment environment; + + @Test + public void defaultsAreApplied() { + assertTrue(environment.getPropertySources() + .contains(ObservabilityServicesEnvironmentPostProcessor.PROPERTY_SOURCE_NAME)); + + assertEquals("health,prometheus", environment.getProperty("management.endpoints.web.exposure.include")); + assertEquals("metrics", environment.getProperty("management.endpoints.web.path-mapping.prometheus")); + assertEquals("true", environment.getProperty("camel.metrics.log-metrics-on-shutdown")); + assertEquals("app.info,camel.exchanges.*", + environment.getProperty("camel.metrics.log-metrics-on-shutdown-filters")); + assertEquals("full", environment.getProperty("camel.health.exposure-level")); + assertEquals("true", environment.getProperty("management.endpoint.health.probes.enabled")); + assertEquals("true", environment.getProperty("management.health.readinessState.enabled")); + assertEquals("true", environment.getProperty("management.health.livenessState.enabled")); + assertEquals("always", environment.getProperty("management.endpoint.health.show-details")); + assertEquals("livenessState,camelLivenessState", + environment.getProperty("management.endpoint.health.group.live.include")); + assertEquals("always", environment.getProperty("management.endpoint.health.group.live.show-details")); + assertEquals("readinessState,camelReadinessState", + environment.getProperty("management.endpoint.health.group.ready.include")); + assertEquals("always", environment.getProperty("management.endpoint.health.group.ready.show-details")); + } + + @Test + public void userApplicationPropertiesOverrideDefaults() { + // these values are set in src/test/resources/application.properties and must win + // over the starter defaults, which was not possible when the defaults were + // packaged as config/application.properties inside the starter jar + assertEquals("9999", environment.getProperty("management.server.port")); + assertEquals("/custom-observe", environment.getProperty("management.endpoints.web.base-path")); + assertEquals("false", environment.getProperty("camel.opentelemetry2.enabled")); + } +} diff --git a/components-starter/camel-observability-services-starter/src/test/java/org/apache/camel/observability/services/springboot/ObservabilityServicesTestApplication.java b/components-starter/camel-observability-services-starter/src/test/java/org/apache/camel/observability/services/springboot/ObservabilityServicesTestApplication.java new file mode 100644 index 000000000000..6bf332443eb9 --- /dev/null +++ b/components-starter/camel-observability-services-starter/src/test/java/org/apache/camel/observability/services/springboot/ObservabilityServicesTestApplication.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.observability.services.springboot; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ObservabilityServicesTestApplication { +} diff --git a/components-starter/camel-observability-services-starter/src/main/resources/config/application.properties b/components-starter/camel-observability-services-starter/src/test/resources/application.properties similarity index 50% rename from components-starter/camel-observability-services-starter/src/main/resources/config/application.properties rename to components-starter/camel-observability-services-starter/src/test/resources/application.properties index f77ad7c8433d..a3b22bcdba16 100644 --- a/components-starter/camel-observability-services-starter/src/main/resources/config/application.properties +++ b/components-starter/camel-observability-services-starter/src/test/resources/application.properties @@ -1,4 +1,3 @@ - ## --------------------------------------------------------------------------- ## Licensed to the Apache Software Foundation (ASF) under one or more ## contributor license agreements. See the NOTICE file distributed with @@ -16,24 +15,9 @@ ## limitations under the License. ## --------------------------------------------------------------------------- -management.server.port=9876 -management.endpoints.web.exposure.include=health,prometheus -management.endpoints.web.base-path=/observe -management.endpoints.web.path-mapping.prometheus=metrics -# Metrics -camel.metrics.log-metrics-on-shutdown=true -camel.metrics.log-metrics-on-shutdown-filters=app.info,camel.exchanges.* -# Opentelemetry -camel.opentelemetry2.enabled=true -# Health -camel.health.exposure-level=full -management.endpoint.health.probes.enabled=true -management.health.readinessState.enabled=true -management.health.livenessState.enabled=true -management.endpoint.health.show-details=always -# /observe/health/live remap -management.endpoint.health.group.live.include=livenessState,camelLivenessState -management.endpoint.health.group.live.show-details=always -# /observe/health/ready remap -management.endpoint.health.group.ready.include=readinessState,camelReadinessState -management.endpoint.health.group.ready.show-details=always +# User-level overrides of the starter defaults, used by +# ObservabilityServicesEnvironmentPostProcessorTest to verify that regular +# application.properties take precedence over the starter defaults +management.server.port=9999 +management.endpoints.web.base-path=/custom-observe +camel.opentelemetry2.enabled=false