From 5e462030d17a5aae14a2cec39e3ee646ff289c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Bo=C3=9Fle?= Date: Mon, 26 Jun 2023 16:32:54 +0200 Subject: [PATCH] Add possibility to override LRAClient & LRARoutes --- .../apache/camel/service/lra/LRAClient.java | 11 +- .../camel/service/lra/LRASagaService.java | 24 +++- .../camel/service/lra/LRAClientTest.java | 66 ++++++++++ .../camel/service/lra/LRASagaServiceTest.java | 113 ++++++++++++++++++ 4 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAClientTest.java create mode 100644 components/camel-lra/src/test/java/org/apache/camel/service/lra/LRASagaServiceTest.java diff --git a/components/camel-lra/src/main/java/org/apache/camel/service/lra/LRAClient.java b/components/camel-lra/src/main/java/org/apache/camel/service/lra/LRAClient.java index 0c91d514a3b38..cbeba11895c6f 100644 --- a/components/camel-lra/src/main/java/org/apache/camel/service/lra/LRAClient.java +++ b/components/camel-lra/src/main/java/org/apache/camel/service/lra/LRAClient.java @@ -47,9 +47,16 @@ public class LRAClient implements Closeable { private final String lraUrl; public LRAClient(LRASagaService sagaService) { - this.sagaService = sagaService; + this(sagaService, HttpClient.newHttpClient()); + } - client = HttpClient.newHttpClient(); + public LRAClient(LRASagaService sagaService, HttpClient client) { + if (client == null) { + throw new IllegalArgumentException("HttpClient must not be null"); + } + + this.sagaService = sagaService; + this.client = client; lraUrl = new LRAUrlBuilder() .host(sagaService.getCoordinatorUrl()) diff --git a/components/camel-lra/src/main/java/org/apache/camel/service/lra/LRASagaService.java b/components/camel-lra/src/main/java/org/apache/camel/service/lra/LRASagaService.java index de6870fbc3041..beb187da68849 100644 --- a/components/camel-lra/src/main/java/org/apache/camel/service/lra/LRASagaService.java +++ b/components/camel-lra/src/main/java/org/apache/camel/service/lra/LRASagaService.java @@ -94,10 +94,20 @@ protected void doStart() throws Exception { .newDefaultScheduledThreadPool(this, "saga-lra"); } if (this.client == null) { - this.client = new LRAClient(this); + this.client = createLRAClient(); } } + /** + * Use this method to override some behavior within the LRAClient + * + * @return the LRAClient to be used within the LRASagaService + * + */ + protected LRAClient createLRAClient() { + return new LRAClient(this); + } + @Override protected void doStop() throws Exception { if (this.executorService != null) { @@ -114,7 +124,7 @@ protected void doStop() throws Exception { public void setCamelContext(CamelContext camelContext) { this.camelContext = camelContext; if (this.routes == null) { - this.routes = new LRASagaRoutes(this); + this.routes = createLRASagaRoutes(camelContext); try { this.camelContext.addRoutes(this.routes); } catch (Exception ex) { @@ -123,6 +133,16 @@ public void setCamelContext(CamelContext camelContext) { } } + /** + * Use this method to override the creation of LRASagaRoutes + * + * @param camelContext + * @return the LRASagaRoutes instance to use in this service + */ + protected LRASagaRoutes createLRASagaRoutes(CamelContext camelContext) { + return new LRASagaRoutes(this); + } + @Override public CamelContext getCamelContext() { return this.camelContext; diff --git a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAClientTest.java b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAClientTest.java new file mode 100644 index 0000000000000..647c1e91fe4d9 --- /dev/null +++ b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAClientTest.java @@ -0,0 +1,66 @@ +/* + * 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; + +import java.net.http.HttpClient; + +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class LRAClientTest extends CamelTestSupport { + + public LRAClientTest() { + setUseRouteBuilder(false); + } + + @DisplayName("Tests whether LRAClient is using a default HttpClient") + @Test + void testCanCreateLRAClient() throws Exception { + LRASagaService sagaService = new LRASagaService(); + applyMockProperties(sagaService); + LRAClient client = new LRAClient(sagaService); + Assertions.assertNotNull(client, "client must not be null after initializing"); + } + + @DisplayName("Tests whether LRAClient is using a custom set HttpClient") + @Test + void testCanCreateLRAClientWithCustomHttpClient() throws Exception { + LRASagaService sagaService = new LRASagaService(); + applyMockProperties(sagaService); + LRAClient client = new LRAClient(sagaService, HttpClient.newBuilder().build()); + Assertions.assertNotNull(client, "client must not be null after initializing"); + } + + @DisplayName("Tests whether LRAClient is throwing an exception if httpclient is null") + @Test + void testCannotCreateLRAClientWithoutHttpClient() throws Exception { + LRASagaService sagaService = new LRASagaService(); + applyMockProperties(sagaService); + Assertions.assertThrows(IllegalArgumentException.class, () -> new LRAClient(sagaService, null), + "no client should result in IllegalArgumentException"); + } + + private void applyMockProperties(LRASagaService sagaService) { + sagaService.setCoordinatorUrl("mockCoordinatorUrl"); + sagaService.setLocalParticipantUrl("mockLocalParticipantUrl"); + sagaService.setLocalParticipantContextPath("mockLocalParticipantContextPath"); + sagaService.setCoordinatorContextPath("mockCoordinatorContextPath"); + } + +} diff --git a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRASagaServiceTest.java b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRASagaServiceTest.java new file mode 100644 index 0000000000000..bb37081de6865 --- /dev/null +++ b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRASagaServiceTest.java @@ -0,0 +1,113 @@ +/* + * 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; + +import org.apache.camel.CamelContext; +import org.apache.camel.model.Model; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class LRASagaServiceTest extends CamelTestSupport { + + public LRASagaServiceTest() { + setUseRouteBuilder(false); + } + + @DisplayName("Tests whether doStart() is creating a LRAClient") + @Test + void testCanCreateLRAClient() throws Exception { + LRASagaService sagaService = new LRASagaService(); + applyMockProperties(sagaService); + sagaService.setCamelContext(this.context()); + sagaService.doStart(); + + LRAClient client = sagaService.getClient(); + Assertions.assertNotNull(client, "lraClient must not be null"); + } + + @DisplayName("Tests whether doStart() is creating an alternative LRAClient") + @Test + void testCanCreateAlternativeLRAClient() throws Exception { + LRASagaService sagaService = new AlternativeLRASagaService(); + applyMockProperties(sagaService); + sagaService.setCamelContext(this.context()); + sagaService.doStart(); + + LRAClient client = sagaService.getClient(); + Assertions.assertNotNull(client, "lraClient must not be null"); + + Assertions.assertInstanceOf(AlternativeLRAClient.class, client, "client must be an instance of AlternativeLRAClient"); + } + + @DisplayName("Tests whether setCamelContext() is creating a LRARoutes in the context") + @Test + void testCanCreateLRARoutes() throws Exception { + LRASagaService sagaService = new LRASagaService(); + sagaService.setCamelContext(this.context()); + + Assertions.assertNotNull(this.context().getRoutes(), "routes of the context must not be null"); + Assertions.assertEquals(4, + context().getExtension(Model.class).getRouteDefinitions().size()); + } + + @DisplayName("Tests whether setCamelContext() is creating AlternativeLRARoutes in the context") + @Test + void testCanCreateAlternativeLRARoutes() throws Exception { + AlternativeLRASagaService sagaService = new AlternativeLRASagaService(); + sagaService.setCamelContext(this.context()); + + Assertions.assertNotNull(this.context().getRoutes(), "routes of the context must not be null"); + Assertions.assertEquals(5, + context().getExtension(Model.class).getRouteDefinitions().size()); + } + + private void applyMockProperties(LRASagaService sagaService) { + sagaService.setCoordinatorUrl("mockCoordinatorUrl"); + sagaService.setLocalParticipantUrl("mockLocalParticipantUrl"); + sagaService.setLocalParticipantContextPath("mockLocalParticipantContextPath"); + sagaService.setCoordinatorContextPath("mockCoordinatorContextPath"); + } + + private class AlternativeLRASagaService extends LRASagaService { + protected LRAClient createLRAClient() { + return new AlternativeLRAClient(this); + } + + protected LRASagaRoutes createLRASagaRoutes(CamelContext camelContext) { + return new AlternativeLRASagaRoutes(this); + } + } + + private class AlternativeLRAClient extends LRAClient { + public AlternativeLRAClient(LRASagaService sagaService) { + super(sagaService); + } + } + + private class AlternativeLRASagaRoutes extends LRASagaRoutes { + public AlternativeLRASagaRoutes(LRASagaService sagaService) { + super(sagaService); + } + + public void configure() throws Exception { + super.configure(); + from("direct:test").log("another route"); + } + } +}