You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by or...@apache.org on 2022/10/07 15:45:18 UTC

[camel] branch main updated: CAMEL-18595: microprofile-lra test-infra

This is an automated email from the ASF dual-hosted git repository.

orpiske pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new e2a08bf5387 CAMEL-18595: microprofile-lra test-infra
e2a08bf5387 is described below

commit e2a08bf53870cdda2f580bf77e02311394366a80
Author: Croway <fe...@gmail.com>
AuthorDate: Thu Oct 6 17:10:04 2022 +0200

    CAMEL-18595: microprofile-lra test-infra
---
 components/camel-lra/pom.xml                       |   7 ++
 .../camel/service/lra/AbstractLRATestSupport.java  |  15 +--
 .../org/apache/camel/service/lra/LRACreditIT.java  |   3 -
 .../apache/camel/service/lra/LRAFailuresIT.java    |   3 -
 .../org/apache/camel/service/lra/LRAManualIT.java  |   3 -
 .../org/apache/camel/service/lra/LRAOptionsIT.java |   3 -
 .../org/apache/camel/service/lra/LRATimeoutIT.java |   3 -
 .../camel-test-infra-microprofile-lra/pom.xml      |  59 +++++++++++
 .../src/main/resources/META-INF/MANIFEST.MF        |   0
 .../lra/common/MicroprofileLRAProperties.java      |  31 ++++++
 .../MicroprofileLRALocalContainerService.java      | 109 +++++++++++++++++++++
 .../lra/services/MicroprofileLRARemoteService.java |  58 +++++++++++
 .../lra/services/MicroprofileLRAService.java       |  48 +++++++++
 .../services/MicroprofileLRAServiceFactory.java    |  36 +++++++
 test-infra/pom.xml                                 |   1 +
 15 files changed, 358 insertions(+), 21 deletions(-)

diff --git a/components/camel-lra/pom.xml b/components/camel-lra/pom.xml
index b1b5d4c4840..f88f9eaaaa2 100644
--- a/components/camel-lra/pom.xml
+++ b/components/camel-lra/pom.xml
@@ -81,6 +81,13 @@
             <artifactId>log4j-slf4j-impl</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-microprofile-lra</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/components/camel-lra/src/test/java/org/apache/camel/service/lra/AbstractLRATestSupport.java b/components/camel-lra/src/test/java/org/apache/camel/service/lra/AbstractLRATestSupport.java
index 7be4bc38b6b..127ff3b4bcd 100644
--- a/components/camel-lra/src/test/java/org/apache/camel/service/lra/AbstractLRATestSupport.java
+++ b/components/camel-lra/src/test/java/org/apache/camel/service/lra/AbstractLRATestSupport.java
@@ -27,9 +27,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.test.AvailablePortFinder;
+import org.apache.camel.test.infra.microprofile.lra.services.MicroprofileLRAService;
+import org.apache.camel.test.infra.microprofile.lra.services.MicroprofileLRAServiceFactory;
 import org.apache.camel.test.junit5.CamelTestSupport;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.RegisterExtension;
 
 import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.awaitility.Awaitility.await;
@@ -41,6 +44,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
  */
 public abstract class AbstractLRATestSupport extends CamelTestSupport {
 
+    @RegisterExtension
+    static MicroprofileLRAService service = MicroprofileLRAServiceFactory.createService();
+
     private Integer serverPort;
 
     private int activeLRAs;
@@ -76,7 +82,8 @@ public abstract class AbstractLRATestSupport extends CamelTestSupport {
     protected LRASagaService createLRASagaService() {
         LRASagaService sagaService = new LRASagaService();
         sagaService.setCoordinatorUrl(getCoordinatorURL());
-        sagaService.setLocalParticipantUrl("http://localhost:" + getServerPort());
+        sagaService.setLocalParticipantUrl(
+                String.format("http://%s:%d", service.callbackHost(), getServerPort()));
         return sagaService;
     }
 
@@ -95,11 +102,7 @@ public abstract class AbstractLRATestSupport extends CamelTestSupport {
     }
 
     private String getCoordinatorURL() {
-        String url = System.getenv("LRA_COORDINATOR_URL");
-        if (url == null) {
-            throw new IllegalStateException("Cannot run test: environment variable LRA_COORDINATOR_URL is missing");
-        }
-        return url;
+        return service.getServiceAddress();
     }
 
     protected int getServerPort() {
diff --git a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRACreditIT.java b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRACreditIT.java
index dccbdc15d49..8cf84e7185b 100644
--- a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRACreditIT.java
+++ b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRACreditIT.java
@@ -28,14 +28,11 @@ import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.model.SagaPropagation;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
 
 import static org.awaitility.Awaitility.await;
 import static org.hamcrest.Matchers.equalTo;
 import static org.junit.jupiter.api.Assertions.fail;
 
-@EnabledIfEnvironmentVariable(named = "LRA_COORDINATOR_URL", matches = ".*",
-                              disabledReason = "Coordinator URL not provided")
 public class LRACreditIT extends AbstractLRATestSupport {
 
     private OrderManagerService orderManagerService;
diff --git a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAFailuresIT.java b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAFailuresIT.java
index a010a2650d0..69b792aa917 100644
--- a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAFailuresIT.java
+++ b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAFailuresIT.java
@@ -22,10 +22,7 @@ import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
 
-@EnabledIfEnvironmentVariable(named = "LRA_COORDINATOR_URL", matches = ".*",
-                              disabledReason = "Coordinator URL not provided")
 public class LRAFailuresIT extends AbstractLRATestSupport {
 
     private AtomicInteger maxFailures;
diff --git a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAManualIT.java b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAManualIT.java
index 5d82cfa294a..1b3453e4bbe 100644
--- a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAManualIT.java
+++ b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAManualIT.java
@@ -24,10 +24,7 @@ import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.model.SagaCompletionMode;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
 
-@EnabledIfEnvironmentVariable(named = "LRA_COORDINATOR_URL", matches = ".*",
-                              disabledReason = "Coordinator URL not provided")
 public class LRAManualIT extends AbstractLRATestSupport {
 
     @Test
diff --git a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAOptionsIT.java b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAOptionsIT.java
index a1794f18b60..813f0bea480 100644
--- a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAOptionsIT.java
+++ b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRAOptionsIT.java
@@ -21,12 +21,9 @@ import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
 
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
-@EnabledIfEnvironmentVariable(named = "LRA_COORDINATOR_URL", matches = ".*",
-                              disabledReason = "Coordinator URL not provided")
 public class LRAOptionsIT extends AbstractLRATestSupport {
 
     @Test
diff --git a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRATimeoutIT.java b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRATimeoutIT.java
index ab9d1d85cb1..92e689e67ba 100644
--- a/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRATimeoutIT.java
+++ b/components/camel-lra/src/test/java/org/apache/camel/service/lra/LRATimeoutIT.java
@@ -22,10 +22,7 @@ import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.model.SagaCompletionMode;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
 
-@EnabledIfEnvironmentVariable(named = "LRA_COORDINATOR_URL", matches = ".*",
-                              disabledReason = "Coordinator URL not provided")
 public class LRATimeoutIT extends AbstractLRATestSupport {
 
     @Test
diff --git a/test-infra/camel-test-infra-microprofile-lra/pom.xml b/test-infra/camel-test-infra-microprofile-lra/pom.xml
new file mode 100644
index 00000000000..c562c7060ce
--- /dev/null
+++ b/test-infra/camel-test-infra-microprofile-lra/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>camel-test-infra-parent</artifactId>
+        <groupId>org.apache.camel</groupId>
+        <relativePath>../camel-test-infra-parent/pom.xml</relativePath>
+        <version>3.20.0-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>camel-test-infra-microprofile-lra</artifactId>
+    <name>Camel :: Test Infra :: Microprofile LRA</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>testcontainers</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
diff --git a/test-infra/camel-test-infra-microprofile-lra/src/main/resources/META-INF/MANIFEST.MF b/test-infra/camel-test-infra-microprofile-lra/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/common/MicroprofileLRAProperties.java b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/common/MicroprofileLRAProperties.java
new file mode 100644
index 00000000000..83f8e017bbb
--- /dev/null
+++ b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/common/MicroprofileLRAProperties.java
@@ -0,0 +1,31 @@
+/*
+ * 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.test.infra.microprofile.lra.common;
+
+public final class MicroprofileLRAProperties {
+    public static final String MICROPROFILE_LRA_CONTAINER = "microprofile.lra.container";
+    public static final String SERVICE_ADDRESS = "microprofile.lra.service.address";
+    public static final String HOST = "microprofile.lra.host";
+    public static final String PORT = "microprofile.lra.port";
+    public static final String CALLBACK_HOST = "microprofile.lra.callback.host";
+    public static final int DEFAULT_PORT = 8080;
+
+    private MicroprofileLRAProperties() {
+
+    }
+}
diff --git a/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRALocalContainerService.java b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRALocalContainerService.java
new file mode 100644
index 00000000000..3bc47dc2f4e
--- /dev/null
+++ b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRALocalContainerService.java
@@ -0,0 +1,109 @@
+/*
+ * 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.test.infra.microprofile.lra.services;
+
+import com.github.dockerjava.api.model.Network;
+import org.apache.camel.test.infra.common.services.ContainerService;
+import org.apache.camel.test.infra.microprofile.lra.common.MicroprofileLRAProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.utility.DockerImageName;
+
+public class MicroprofileLRALocalContainerService implements MicroprofileLRAService, ContainerService<GenericContainer> {
+    public static final String CONTAINER_IMAGE = "quay.io/jbosstm/lra-coordinator:5.13.0.Final-2.12.3.Final";
+    public static final String CONTAINER_NAME = "microprofile-lra";
+
+    private static final Logger LOG = LoggerFactory.getLogger(MicroprofileLRALocalContainerService.class);
+
+    private final GenericContainer container;
+
+    public MicroprofileLRALocalContainerService() {
+        this(System.getProperty(MicroprofileLRAProperties.MICROPROFILE_LRA_CONTAINER, CONTAINER_IMAGE));
+    }
+
+    public MicroprofileLRALocalContainerService(String imageName) {
+        container = initContainer(imageName, CONTAINER_NAME);
+    }
+
+    public MicroprofileLRALocalContainerService(GenericContainer container) {
+        this.container = container;
+    }
+
+    public GenericContainer initContainer(String imageName, String networkAlias) {
+        return new GenericContainer<>(DockerImageName.parse(imageName))
+                .withNetworkAliases(networkAlias)
+                .withExposedPorts(MicroprofileLRAProperties.DEFAULT_PORT)
+                .waitingFor(Wait.forListeningPort())
+                .waitingFor(Wait.forLogMessage(".*lra-coordinator-quarkus.*Listening on.*", 1));
+    }
+
+    @Override
+    public void registerProperties() {
+        System.setProperty(MicroprofileLRAProperties.SERVICE_ADDRESS, getServiceAddress());
+        System.setProperty(MicroprofileLRAProperties.PORT, String.valueOf(port()));
+        System.setProperty(MicroprofileLRAProperties.HOST, host());
+    }
+
+    @Override
+    public void initialize() {
+        LOG.info("Trying to start the Microprofile LRA container");
+        container.start();
+
+        registerProperties();
+        LOG.info("Microprofile LRA instance running at {}", getServiceAddress());
+    }
+
+    @Override
+    public void shutdown() {
+        LOG.info("Stopping the Microprofile LRA container");
+        container.stop();
+    }
+
+    @Override
+    public GenericContainer getContainer() {
+        return container;
+    }
+
+    @Override
+    public String host() {
+        return container.getHost();
+    }
+
+    @Override
+    public int port() {
+        return container.getMappedPort(MicroprofileLRAProperties.DEFAULT_PORT);
+    }
+
+    @Override
+    public String callbackHost() {
+        // Get host ip address from container
+        Network bridgeNetwork = this.container.getDockerClient()
+                .inspectNetworkCmd()
+                .withNetworkId("bridge")
+                .exec();
+
+        String networkGateway = bridgeNetwork.getIpam().getConfig().stream()
+                .filter(config -> config.getGateway() != null)
+                .findAny()
+                .map(Network.Ipam.Config::getGateway)
+                .orElseThrow(() -> new IllegalStateException("Gateway cannot be found in the bridge network"));
+
+        return networkGateway;
+    }
+}
diff --git a/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRARemoteService.java b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRARemoteService.java
new file mode 100644
index 00000000000..2a6966911f8
--- /dev/null
+++ b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRARemoteService.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.test.infra.microprofile.lra.services;
+
+import org.apache.camel.test.infra.microprofile.lra.common.MicroprofileLRAProperties;
+
+public class MicroprofileLRARemoteService implements MicroprofileLRAService {
+
+    @Override
+    public void registerProperties() {
+        // NO-OP
+    }
+
+    @Override
+    public void initialize() {
+        registerProperties();
+    }
+
+    @Override
+    public void shutdown() {
+        // NO-OP
+    }
+
+    @Override
+    public String host() {
+        return System.getProperty(MicroprofileLRAProperties.HOST);
+    }
+
+    @Override
+    public int port() {
+        String port = System.getProperty(MicroprofileLRAProperties.PORT);
+
+        if (port == null) {
+            return MicroprofileLRAProperties.DEFAULT_PORT;
+        }
+
+        return Integer.valueOf(port);
+    }
+
+    @Override
+    public String callbackHost() {
+        return System.getProperty(MicroprofileLRAProperties.CALLBACK_HOST, "localhost");
+    }
+}
diff --git a/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAService.java b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAService.java
new file mode 100644
index 00000000000..eacfb4edef5
--- /dev/null
+++ b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAService.java
@@ -0,0 +1,48 @@
+/*
+ * 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.test.infra.microprofile.lra.services;
+
+import org.apache.camel.test.infra.common.services.TestService;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+/**
+ * Test infra service for Microprofile LRA
+ */
+public interface MicroprofileLRAService extends BeforeAllCallback, AfterAllCallback, TestService {
+
+    String host();
+
+    int port();
+
+    String callbackHost();
+
+    default String getServiceAddress() {
+        return String.format("http://%s:%d", host(), port());
+    }
+
+    @Override
+    default void beforeAll(ExtensionContext extensionContext) {
+        initialize();
+    }
+
+    @Override
+    default void afterAll(ExtensionContext extensionContext) {
+        shutdown();
+    }
+}
diff --git a/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAServiceFactory.java b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAServiceFactory.java
new file mode 100644
index 00000000000..9ed0eaad471
--- /dev/null
+++ b/test-infra/camel-test-infra-microprofile-lra/src/test/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAServiceFactory.java
@@ -0,0 +1,36 @@
+/*
+ * 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.test.infra.microprofile.lra.services;
+
+import org.apache.camel.test.infra.common.services.SimpleTestServiceBuilder;
+
+public final class MicroprofileLRAServiceFactory {
+    private MicroprofileLRAServiceFactory() {
+
+    }
+
+    public static SimpleTestServiceBuilder<MicroprofileLRAService> builder() {
+        return new SimpleTestServiceBuilder<>("microprofile-lra");
+    }
+
+    public static MicroprofileLRAService createService() {
+        return builder()
+                .addLocalMapping(MicroprofileLRALocalContainerService::new)
+                .addRemoteMapping(MicroprofileLRARemoteService::new)
+                .build();
+    }
+}
diff --git a/test-infra/pom.xml b/test-infra/pom.xml
index 1b90299b5ee..d09d3beda47 100644
--- a/test-infra/pom.xml
+++ b/test-infra/pom.xml
@@ -57,6 +57,7 @@
         <module>camel-test-infra-google-pubsub</module>
         <module>camel-test-infra-hbase</module>
         <module>camel-test-infra-infinispan</module>
+        <module>camel-test-infra-microprofile-lra</module>
         <module>camel-test-infra-minio</module>
         <module>camel-test-infra-nats</module>
         <module>camel-test-infra-pulsar</module>