This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch backport/2038-to-camel-spring-boot-4.18.x in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git
commit 9a613765c4c62daaf4e99e42b2bf880fbb2b64a2 Author: Andrea Cosentino <[email protected]> AuthorDate: Thu Oct 15 15:21:53 2026 +0200 CAMEL-25590: camel-lra-starter - expose the callbackSecret and allowedCoordinatorUrls options (#2038) The LRA saga service gained the callbackSecret (CAMEL-25578) and allowedCoordinatorUrls (CAMEL-25584) options, which camel-main exposes as camel.lra.callback-secret and camel.lra.allowed-coordinator-urls. The Spring Boot starter creates the LRASagaService from its own configuration class, so neither option could be set through Spring Boot properties. Add both properties to LraServiceConfiguration, pass them to the service in LraServiceAutoConfiguration, and add an auto-configuration test. The test needs the servlet API on its classpath because the starter depends on camel-servlet-starter, so spring-boot-starter-web is added with test scope, as camel-servlet-starter does. Signed-off-by: Andrea Cosentino <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]> (cherry picked from commit de7573959421e2257f4a044f949a7d895ccb7785) Signed-off-by: Claus Ibsen <[email protected]> --- components-starter/camel-lra-starter/pom.xml | 6 +++ .../camel-lra-starter/src/main/docs/lra.json | 12 +++++ .../springboot/LraServiceAutoConfiguration.java | 2 + .../lra/springboot/LraServiceConfiguration.java | 30 +++++++++++ .../LraServiceAutoConfigurationTest.java | 58 ++++++++++++++++++++++ 5 files changed, 108 insertions(+) diff --git a/components-starter/camel-lra-starter/pom.xml b/components-starter/camel-lra-starter/pom.xml index b2a7cfcf688..0dbb5a9a989 100644 --- a/components-starter/camel-lra-starter/pom.xml +++ b/components-starter/camel-lra-starter/pom.xml @@ -43,6 +43,12 @@ <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-servlet-starter</artifactId> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + <version>${spring-boot-version}</version> + <scope>test</scope> + </dependency> <!--START OF GENERATED CODE--> <dependency> <groupId>org.apache.camel.springboot</groupId> diff --git a/components-starter/camel-lra-starter/src/main/docs/lra.json b/components-starter/camel-lra-starter/src/main/docs/lra.json index c46b5eecd45..73efa8efaa6 100644 --- a/components-starter/camel-lra-starter/src/main/docs/lra.json +++ b/components-starter/camel-lra-starter/src/main/docs/lra.json @@ -7,6 +7,18 @@ } ], "properties": [ + { + "name": "camel.lra.allowed-coordinator-urls", + "type": "java.lang.String", + "description": "Comma-separated URLs, including the context path, of further LRA coordinators whose LRAs may be joined, completed or compensated. By default, only an LRA hosted by the configured coordinator is accepted. Use it when participants reach the same coordinator under different URLs, for example with different host names.", + "sourceType": "org.apache.camel.service.lra.springboot.LraServiceConfiguration" + }, + { + "name": "camel.lra.callback-secret", + "type": "java.lang.String", + "description": "Secret used to sign the participant callback URLs that are enlisted with the LRA coordinator, and to verify them when the coordinator calls back. When set, a compensation or completion callback with a missing or invalid signature is rejected with HTTP 403. All the instances of a participant must use the same secret.", + "sourceType": "org.apache.camel.service.lra.springboot.LraServiceConfiguration" + }, { "name": "camel.lra.coordinator-context-path", "type": "java.lang.String", diff --git a/components-starter/camel-lra-starter/src/main/java/org/apache/camel/service/lra/springboot/LraServiceAutoConfiguration.java b/components-starter/camel-lra-starter/src/main/java/org/apache/camel/service/lra/springboot/LraServiceAutoConfiguration.java index 6da3be979ff..fd661d6c809 100644 --- a/components-starter/camel-lra-starter/src/main/java/org/apache/camel/service/lra/springboot/LraServiceAutoConfiguration.java +++ b/components-starter/camel-lra-starter/src/main/java/org/apache/camel/service/lra/springboot/LraServiceAutoConfiguration.java @@ -57,6 +57,8 @@ public class LraServiceAutoConfiguration { service.setCoordinatorContextPath(configuration.getCoordinatorContextPath()); service.setLocalParticipantUrl(configuration.getLocalParticipantUrl()); service.setLocalParticipantContextPath(configuration.getLocalParticipantContextPath()); + service.setAllowedCoordinatorUrls(configuration.getAllowedCoordinatorUrls()); + service.setCallbackSecret(configuration.getCallbackSecret()); camelContext.addService(service); return service; diff --git a/components-starter/camel-lra-starter/src/main/java/org/apache/camel/service/lra/springboot/LraServiceConfiguration.java b/components-starter/camel-lra-starter/src/main/java/org/apache/camel/service/lra/springboot/LraServiceConfiguration.java index ba7bbc1102a..22054718666 100644 --- a/components-starter/camel-lra-starter/src/main/java/org/apache/camel/service/lra/springboot/LraServiceConfiguration.java +++ b/components-starter/camel-lra-starter/src/main/java/org/apache/camel/service/lra/springboot/LraServiceConfiguration.java @@ -52,6 +52,20 @@ public class LraServiceConfiguration { */ private String localParticipantContextPath = DEFAULT_LOCAL_PARTICIPANT_CONTEXT_PATH; + /** + * Comma-separated URLs, including the context path, of further LRA coordinators whose LRAs may be joined, completed + * or compensated. By default, only an LRA hosted by the configured coordinator is accepted. Use it when + * participants reach the same coordinator under different URLs, for example with different host names. + */ + private String allowedCoordinatorUrls; + + /** + * Secret used to sign the participant callback URLs that are enlisted with the LRA coordinator, and to verify them + * when the coordinator calls back. When set, a compensation or completion callback with a missing or invalid + * signature is rejected with HTTP 403. All the instances of a participant must use the same secret. + */ + private String callbackSecret; + public boolean isEnabled() { return enabled; } @@ -91,4 +105,20 @@ public class LraServiceConfiguration { public void setLocalParticipantContextPath(String localParticipantContextPath) { this.localParticipantContextPath = localParticipantContextPath; } + + public String getAllowedCoordinatorUrls() { + return allowedCoordinatorUrls; + } + + public void setAllowedCoordinatorUrls(String allowedCoordinatorUrls) { + this.allowedCoordinatorUrls = allowedCoordinatorUrls; + } + + public String getCallbackSecret() { + return callbackSecret; + } + + public void setCallbackSecret(String callbackSecret) { + this.callbackSecret = callbackSecret; + } } diff --git a/components-starter/camel-lra-starter/src/test/java/org/apache/camel/service/lra/springboot/LraServiceAutoConfigurationTest.java b/components-starter/camel-lra-starter/src/test/java/org/apache/camel/service/lra/springboot/LraServiceAutoConfigurationTest.java new file mode 100644 index 00000000000..88afa472155 --- /dev/null +++ b/components-starter/camel-lra-starter/src/test/java/org/apache/camel/service/lra/springboot/LraServiceAutoConfigurationTest.java @@ -0,0 +1,58 @@ +/* + * 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.service.lra.springboot; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.apache.camel.CamelContext; +import org.apache.camel.service.lra.LRASagaService; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit6.CamelSpringBootTest; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest(classes = { CamelAutoConfiguration.class, LraServiceAutoConfiguration.class }, + properties = { + "camel.lra.enabled = true", + "camel.lra.coordinator-url = http://lra-coordinator:8080", + "camel.lra.local-participant-url = http://localhost:8080", + "camel.lra.allowed-coordinator-urls = http://lra-coordinator.lra.svc:8080/lra-coordinator", + "camel.lra.callback-secret = a-callback-secret" }) +class LraServiceAutoConfigurationTest { + + @Autowired + CamelContext context; + + @Autowired + LRASagaService sagaService; + + @Test + void optionsAreSetOnTheLraSagaService() { + assertEquals("http://lra-coordinator:8080", sagaService.getCoordinatorUrl()); + assertEquals("http://localhost:8080", sagaService.getLocalParticipantUrl()); + assertEquals("http://lra-coordinator.lra.svc:8080/lra-coordinator", sagaService.getAllowedCoordinatorUrls()); + assertEquals("a-callback-secret", sagaService.getCallbackSecret()); + assertTrue(context.hasService(sagaService), "the LRA saga service must be added to the Camel context"); + } +}
