consumerRoute() {
- return null;
- }
-
- protected void configureProducer(RouteBuilder builder, RouteDefinition producerRoute) {
- // Do nothing by default
- }
-
- protected void configureConsumer(RouteDefinition consumerRoute) {
- if (consumerRoute.hasCustomIdAssigned()) {
- return;
- }
- consumerRoute.routeId("consumer-%s".formatted(getTestComponentName()));
- }
-}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelComponentResultFileBased.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelComponentResultFileBased.java
deleted file mode 100644
index bc102b5e0..000000000
--- a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelComponentResultFileBased.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.apache.karaf.camel.itests;
-
-import org.apache.camel.model.RouteDefinition;
-
-public abstract class AbstractCamelComponentResultFileBased extends AbstractCamelComponent {
-
- protected String getResultFileName() {
- return getTestComponentName();
- }
-
- @Override
- protected void configureConsumer(RouteDefinition consumerRoute) {
- consumerRoute.toF("file:%s?fileName=%s", getBaseDir(), getResultFileName());
- }
-}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelKarafITest.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelKarafITest.java
deleted file mode 100644
index 8d4c6025d..000000000
--- a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelKarafITest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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.apache.karaf.camel.itests;
-
-
-import java.io.File;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.ProducerTemplate;
-import org.junit.After;
-import org.junit.Before;
-import org.osgi.framework.Bundle;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.util.stream.Stream;
-
-import org.apache.karaf.itests.KarafTestSupport;
-import org.junit.Assert;
-import org.ops4j.pax.exam.Configuration;
-
-import org.ops4j.pax.exam.CoreOptions;
-import org.ops4j.pax.exam.Option;
-
-import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
-import org.osgi.framework.BundleException;
-
-import static org.apache.karaf.camel.itests.Utils.toKebabCase;
-
-public abstract class AbstractCamelKarafITest extends KarafTestSupport {
-
- protected CamelContext context;
- protected ProducerTemplate template;
-
- public String getVersion() {
- return System.getProperty("project.version");
- }
-
- public String getBaseDir() {
- return System.getProperty("project.target");
- }
-
- public File getUsersFile() {
- // retrieve the users.properties file from the resources folder to avoid file duplication
- return new File(System.getProperty("integration.test.project.resources"), "etc/users.properties");
- }
-
- public String getTestComponentName() {
- return toKebabCase(this.getClass().getSimpleName()).replace("-itest", "-test");
- }
-
- @Override
- public File getConfigFile(String path) {
- if (path.equals("/etc/users.properties")) {
- return getUsersFile();
- }
- return super.getConfigFile(path);
- }
-
- @Configuration
- @Override
- public Option[] config() {
- // Workaround to fix the issue with the port already in use
- String httpPort = Integer.toString(getAvailablePort(Integer.parseInt(MIN_HTTP_PORT), Integer.parseInt(MAX_HTTP_PORT)));
- String rmiRegistryPort = Integer.toString(getAvailablePort(Integer.parseInt(MIN_RMI_REG_PORT), Integer.parseInt(MAX_RMI_REG_PORT)));
- String rmiServerPort = Integer.toString(getAvailablePort(Integer.parseInt(MIN_RMI_SERVER_PORT), Integer.parseInt(MAX_RMI_SERVER_PORT)));
- String sshPort = Integer.toString(getAvailablePort(Integer.parseInt(MIN_SSH_PORT), Integer.parseInt(MAX_SSH_PORT)));
-
- Option[] options = new Option[]{
- KarafDistributionOption.editConfigurationFilePut("etc/system.properties", "project.version", getVersion()),
- KarafDistributionOption.editConfigurationFileExtend("etc/system.properties", "project.target", getBaseDir()),
- KarafDistributionOption.features("mvn:org.apache.camel.karaf/apache-camel/"+ getVersion() + "/xml/features", "scr","camel-core"),
- CoreOptions.mavenBundle().groupId("org.apache.camel.karaf").artifactId("camel-integration-test").versionAsInProject(),
- KarafDistributionOption.editConfigurationFilePut("etc/org.ops4j.pax.web.cfg", "org.osgi.service.http.port", httpPort),
- KarafDistributionOption.editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiRegistryPort", rmiRegistryPort),
- KarafDistributionOption.editConfigurationFilePut("etc/org.apache.karaf.management.cfg", "rmiServerPort", rmiServerPort),
- KarafDistributionOption.editConfigurationFilePut("etc/org.apache.karaf.shell.cfg", "sshPort", sshPort),
- };
- return Stream.of(super.config(), options).flatMap(Stream::of).toArray(Option[]::new);
- }
-
- @Before
- public void init() throws Exception {
- String testComponentName = getTestComponentName();
- installBundle("file://%s/%s-%s.jar".formatted(getBaseDir(), testComponentName, getVersion()),true);
- assertBundleInstalled(testComponentName);
- assertBundleInstalledAndRunning(testComponentName);
- initCamelContext();
- initProducerTemplate();
- }
-
- private void initCamelContext() {
- this.context = bundleContext.getService(bundleContext.getServiceReference(CamelContext.class));
- }
-
- private void initProducerTemplate() {
- template = context.createProducerTemplate();
- template.start();
- }
-
- @After
- public void destroy() {
- destroyProducerTemplate();
- uninstallBundle();
- }
-
- private void destroyProducerTemplate() {
- if (template != null) {
- template.stop();
- }
- }
-
- private void uninstallBundle() {
- Bundle bundle = findBundleByName(getTestComponentName());
- if (bundle == null) {
- return;
- }
- try {
- bundle.uninstall();
- } catch (BundleException e) {
- // Ignore me
- }
- }
-
- public static int getAvailablePort(int min, int max) {
- for (int port = min; port <= max; port++) {
- try (ServerSocket socket = new ServerSocket()) {
- socket.setReuseAddress(true);
- socket.bind(new InetSocketAddress(InetAddress.getByName("localhost"), port), 1);
- return socket.getLocalPort();
- } catch (Exception e) {
- System.err.println("Port " + port + " not available, trying next one");
- }
- }
- throw new IllegalStateException("Can't find available network ports");
- }
-
- protected void assertBundleInstalledAndRunning(String name) {
- Bundle bundle = findBundleByName(name);
- Assert.assertNotNull("Bundle %s should be installed".formatted(name), bundle);
- Assert.assertEquals(Bundle.ACTIVE, bundle.getState());
- //need to check with the command because the status may be Active while it's displayed as Waiting in the console
- //because of an exception for instance
- String bundles = executeCommand("bundle:list -s -t 0 | grep %s".formatted(name));
- Assert.assertTrue("bundle%s is in state %d /%s".formatted(bundle.getSymbolicName(), bundle.getState(), bundles),
- bundles.contains("Active"));
- }
-}
\ No newline at end of file
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelKarafResultFileBasedITest.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelKarafResultFileBasedITest.java
deleted file mode 100644
index 3aa388a72..000000000
--- a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelKarafResultFileBasedITest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * 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.karaf.camel.itests;
-
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.concurrent.TimeUnit;
-
-import org.awaitility.Awaitility;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-public abstract class AbstractCamelKarafResultFileBasedITest extends AbstractCamelKarafITest {
-
- protected String getResultFileName() {
- return getTestComponentName();
- }
-
- protected Charset getResultFileCharset() {
- return StandardCharsets.UTF_8;
- }
-
- protected int getTimeoutInSeconds() {
- return 5;
- }
-
- protected Path assertResultFileExists() {
- Path filePath = Path.of(getBaseDir(), getResultFileName());
- Awaitility.await().atMost(getTimeoutInSeconds(), TimeUnit.SECONDS)
- .until(() -> Files.exists(filePath));
- assertTrue(Files.exists(filePath));
- return filePath;
- }
-
- protected void assertResultFileContains(String expectedFileContent) throws Exception {
- assertEquals(
- "The content of the result file is not correct",
- expectedFileContent, Files.readString(assertResultFileExists(), getResultFileCharset())
- );
- }
-
- protected void assertResultFileIsSameAs(String expectedResultFileName) throws Exception {
- assertResultFileContains(
- Files.readString(createExpectedResultPath(expectedResultFileName))
- );
- }
-
- protected void assertResultFileIsSameAs(String expectedResultFileName, Charset encoding) throws Exception {
- assertResultFileContains(
- Files.readString(createExpectedResultPath(expectedResultFileName), encoding)
- );
- }
-
- protected Path createExpectedResultPath(String expectedResultFileName) {
- return Path.of(getBaseDir(), "test-classes", expectedResultFileName);
- }
-}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelRouteITest.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelRouteITest.java
new file mode 100644
index 000000000..b821dd244
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelRouteITest.java
@@ -0,0 +1,466 @@
+/*
+ * 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.apache.karaf.camel.itests;
+
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.blueprint.BlueprintCamelContext;
+import org.apache.camel.karaf.core.OsgiDefaultCamelContext;
+import org.apache.karaf.itests.KarafTestSupport;
+import org.jetbrains.annotations.NotNull;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.CoreOptions;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.karaf.options.KarafDistributionConfigurationFilePutOption;
+import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.ops4j.pax.exam.OptionUtils.combine;
+
+public abstract class AbstractCamelRouteITest extends KarafTestSupport implements CamelContextProvider {
+
+ public static final int CAMEL_KARAF_INTEGRATION_TEST_DEBUG_DEFAULT_PORT = 8889;
+ public static final String CAMEL_KARAF_INTEGRATION_TEST_DEBUG_PROPERTY = "camel.karaf.itest.debug";
+ static final String CAMEL_KARAF_INTEGRATION_TEST_ROUTE_SUPPLIERS_PROPERTY = "camel.karaf.itest.route.suppliers";
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractCamelRouteITest.class);
+ private final Map contexts = new ConcurrentHashMap<>();
+ private final Map templates = new ConcurrentHashMap<>();
+ private List requiredBundles;
+
+ public String getCamelKarafVersion() {
+ String version = System.getProperty("camel.karaf.version");
+ if (version == null) {
+ version = Utils.loadCamelKarafVersion();
+ }
+ return version;
+ }
+
+ public String getBaseDir() {
+ String location = System.getProperty("project.target");
+ if (location == null) {
+ throw new IllegalStateException("The system property 'project.target' must be set to the target directory of" +
+ " the project or the method getBaseDir must be overridden to provide the base directory");
+ }
+ return location;
+ }
+
+ public File getUsersFile() {
+ // retrieve the users.properties file from the resources folder to avoid file duplication
+ String location = System.getProperty("users.file.location");
+ if (location == null) {
+ location = Utils.loadUsersFileIfAbsent(getBaseDir());
+ }
+ return new File(location);
+ }
+
+ @Override
+ public File getConfigFile(String path) {
+ if (path.equals("/etc/users.properties")) {
+ return getUsersFile();
+ }
+ return super.getConfigFile(path);
+ }
+
+ @Configuration
+ @Override
+ public Option[] config() {
+ String camelKarafVersion = getCamelKarafVersion();
+ if (camelKarafVersion == null) {
+ throw new IllegalArgumentException("The system property 'camel.karaf.version' must be set or the method " +
+ "getCamelKarafVersion must be overridden to provide the version of Camel Karaf to use");
+ }
+ Option[] options = new Option[]{
+ CoreOptions.systemProperty("project.target").value(getBaseDir()),
+ KarafDistributionOption.features("mvn:org.apache.camel.karaf/apache-camel/%s/xml/features".formatted(camelKarafVersion), "scr", getMode().getFeatureName()),
+ CoreOptions.mavenBundle().groupId("org.apache.camel.karaf").artifactId("camel-integration-test").version(camelKarafVersion)
+ };
+ Option[] combine = combine(updatePorts(super.config()), options);
+ if (isDebugModeEnabled()) {
+ combine = combine(combine, KarafDistributionOption.debugConfiguration(Integer.toString(getDebugPort()), true));
+ }
+ if (hasExternalResources()) {
+ combine = combine(combine, getExternalResourceOptions());
+ }
+ if (hasCamelRouteSupplierFilter()) {
+ combine = combine(combine, getCamelRouteSupplierFilter());
+ }
+ return combine(combine, getAdditionalOptions());
+ }
+
+ /**
+ * Indicates whether the debug mode is enabled or not. The debug mode is enabled when the system property
+ * {@link #CAMEL_KARAF_INTEGRATION_TEST_DEBUG_PROPERTY} is set.
+ * @return {@code true} if the debug mode is enabled, {@code false} otherwise
+ */
+ private boolean isDebugModeEnabled() {
+ return System.getProperty(CAMEL_KARAF_INTEGRATION_TEST_DEBUG_PROPERTY) != null;
+ }
+
+ /**
+ * Returns the debug port to use when the debug mode is enabled, corresponding to the value of the system property
+ * {@link #CAMEL_KARAF_INTEGRATION_TEST_DEBUG_PROPERTY}. The default value is {@link #CAMEL_KARAF_INTEGRATION_TEST_DEBUG_DEFAULT_PORT}.
+ * @return the debug port
+ */
+ private int getDebugPort() {
+ return Integer.getInteger(CAMEL_KARAF_INTEGRATION_TEST_DEBUG_PROPERTY, CAMEL_KARAF_INTEGRATION_TEST_DEBUG_DEFAULT_PORT);
+ }
+
+ /**
+ * Update the ports in the given options to work around the issue with the default method {@code getAvailablePort}
+ * that doesn't seem to work properly on macOS because the ports are not modified when a Karaf instance is already
+ * started locally.
+ */
+ private static Option[] updatePorts(Option[] options) {
+ for (int i = 0; i < options.length; i++) {
+ Option option = options[i];
+ if (option instanceof KarafDistributionConfigurationFilePutOption putOption) {
+ if (putOption.getConfigurationFilePath().equals("etc/org.ops4j.pax.web.cfg") && putOption.getKey().equals("org.osgi.service.http.port")) {
+ String httpPort = Integer.toString(Utils.getAvailablePort(Integer.parseInt(MIN_HTTP_PORT), Integer.parseInt(MAX_HTTP_PORT)));
+ options[i] = KarafDistributionOption.editConfigurationFilePut(putOption.getConfigurationFilePath(), putOption.getKey(), httpPort);
+ } else if (putOption.getConfigurationFilePath().equals("etc/org.apache.karaf.management.cfg")) {
+ if (putOption.getKey().equals("rmiRegistryPort")) {
+ String rmiRegistryPort = Integer.toString(Utils.getAvailablePort(Integer.parseInt(MIN_RMI_REG_PORT), Integer.parseInt(MAX_RMI_REG_PORT)));
+ options[i] = KarafDistributionOption.editConfigurationFilePut(putOption.getConfigurationFilePath(), putOption.getKey(), rmiRegistryPort);
+ } else if (putOption.getKey().equals("rmiServerPort")) {
+ String rmiServerPort = Integer.toString(Utils.getAvailablePort(Integer.parseInt(MIN_RMI_SERVER_PORT), Integer.parseInt(MAX_RMI_SERVER_PORT)));
+ options[i] = KarafDistributionOption.editConfigurationFilePut(putOption.getConfigurationFilePath(), putOption.getKey(), rmiServerPort);
+ }
+ } else if (putOption.getConfigurationFilePath().equals("etc/org.apache.karaf.shell.cfg") && putOption.getKey().equals("sshPort")) {
+ String sshPort = Integer.toString(Utils.getAvailablePort(Integer.parseInt(MIN_SSH_PORT), Integer.parseInt(MAX_SSH_PORT)));
+ options[i] = KarafDistributionOption.editConfigurationFilePut(putOption.getConfigurationFilePath(), putOption.getKey(), sshPort);
+ }
+ }
+ }
+ return options;
+ }
+
+ @NotNull
+ private static Option[] getExternalResourceOptions() {
+ return PaxExamWithExternalResource.systemProperties().entrySet().stream()
+ .map(e -> CoreOptions.systemProperty(e.getKey()).value(e.getValue()))
+ .toArray(Option[]::new);
+ }
+
+ private boolean hasExternalResources() {
+ CamelKarafTestHint hint = getClass().getAnnotation(CamelKarafTestHint.class);
+ return hint != null && hint.externalResourceProvider() != Object.class;
+ }
+
+
+ private Option getCamelRouteSupplierFilter() {
+ return CoreOptions.systemProperty(CAMEL_KARAF_INTEGRATION_TEST_ROUTE_SUPPLIERS_PROPERTY)
+ .value(String.join(",", getClass().getAnnotation(CamelKarafTestHint.class).camelRouteSuppliers()));
+ }
+
+ private boolean hasCamelRouteSupplierFilter() {
+ CamelKarafTestHint hint = getClass().getAnnotation(CamelKarafTestHint.class);
+ return hint != null && hint.camelRouteSuppliers().length > 0;
+ }
+
+ /**
+ * Returns the list of additional options to add to the configuration.
+ */
+ protected Option[] getAdditionalOptions() {
+ return new Option[0];
+ }
+
+ @Before
+ public final void init() throws Exception {
+ installRequiredFeaturesRepositories();
+ installRequiredFeatures();
+ this.requiredBundles = installRequiredBundles();
+ }
+
+ /**
+ * Gives the list of features repositories' URI to install that are required for the test.
+ */
+ protected List getRequiredFeaturesRepositories() {
+ return List.of();
+ }
+
+ private void installRequiredFeaturesRepositories() throws Exception {
+ for (String featuresRepository : getRequiredFeaturesRepositories()) {
+ addFeaturesRepository(featuresRepository);
+ }
+ }
+
+ /**
+ * Gives the list of features to install that are required for the test.
+ */
+ protected abstract List getRequiredFeatures();
+
+ /**
+ * Gives the list of all required features including the additional features specified in
+ * the {@link CamelKarafTestHint#additionalRequiredFeatures()}.
+ */
+ private List getAllRequiredFeatures() {
+ CamelKarafTestHint hint = getClass().getAnnotation(CamelKarafTestHint.class);
+ if (hint == null || hint.additionalRequiredFeatures().length == 0) {
+ return getRequiredFeatures();
+ }
+ List requiredFeatures = new ArrayList<>(getRequiredFeatures());
+ requiredFeatures.addAll(List.of(hint.additionalRequiredFeatures()));
+ return requiredFeatures;
+ }
+
+ private void installRequiredFeatures() throws Exception {
+ for (String featureName : getAllRequiredFeatures()) {
+ if (featureService.getFeature(featureName) == null) {
+ throw new IllegalArgumentException("Feature %s is not available".formatted(featureName));
+ }
+ installAndAssertFeature(featureName);
+ }
+ }
+
+ /**
+ * Installs the required bundles for the test.
+ *
+ * @return the list of the name of the installed bundles
+ * @throws Exception if an error occurs while installing a bundle
+ */
+ protected List installRequiredBundles() throws Exception {
+ return List.of();
+ }
+
+ /**
+ * Indicates whether the test is a blueprint test or not. By default, it's not a blueprint test.
+ * @return {@code true} if the test is a blueprint test, {@code false} otherwise
+ */
+ private static boolean isBlueprintTest(Class> clazz) {
+ CamelKarafTestHint hint = clazz.getAnnotation(CamelKarafTestHint.class);
+ return hint != null && hint.isBlueprintTest();
+ }
+
+ private static Mode getMode(Class> clazz) {
+ return getMode(isBlueprintTest(clazz));
+ }
+
+ private static Mode getMode(boolean blueprint) {
+ return blueprint ? Mode.BLUEPRINT : Mode.CORE;
+ }
+
+ private Mode getMode() {
+ return getMode(getClass());
+ }
+
+ @After
+ public final void destroy() {
+ destroyProducerTemplates();
+ uninstallRequiredBundles();
+ uninstallRequiredFeatures();
+ removeRequiredFeaturesRepositories();
+ }
+
+ private void uninstallRequiredBundles() {
+ if (requiredBundles == null) {
+ return;
+ }
+ for (String bundleName : requiredBundles) {
+ try {
+ uninstallBundle(bundleName);
+ } catch (Exception e) {
+ LOG.warn("Error while uninstalling bundle {}", bundleName, e);
+ }
+ }
+ }
+
+ private void uninstallBundle(String bundleName) {
+ Bundle bundle = findBundleByName(bundleName);
+ if (bundle == null) {
+ return;
+ }
+ try {
+ bundle.uninstall();
+ } catch (BundleException e) {
+ LOG.warn("Error while uninstalling bundle {}", bundleName, e);
+ }
+ }
+
+ private void uninstallRequiredFeatures() {
+ for (String featureName : getAllRequiredFeatures()) {
+ try {
+ featureService.uninstallFeature(featureName);
+ } catch (Exception e) {
+ LOG.warn("Error while uninstalling feature {}", featureName, e);
+ }
+ }
+ }
+
+ private void removeRequiredFeaturesRepositories() {
+ for (String featuresRepository : getRequiredFeaturesRepositories()) {
+ try {
+ featureService.removeRepository(new URI(featuresRepository));
+ } catch (Exception e) {
+ LOG.warn("Error while removing features repository {}", featuresRepository, e);
+ }
+ }
+ }
+
+ private void destroyProducerTemplates() {
+ templates.values().forEach(ProducerTemplate::stop);
+ templates.clear();
+ }
+
+ protected void assertBundleInstalledAndRunning(String name) {
+ Bundle bundle = findBundleByName(name);
+ Assert.assertNotNull("Bundle %s should be installed".formatted(name), bundle);
+ Assert.assertEquals(Bundle.ACTIVE, bundle.getState());
+ //need to check with the command because the status may be Active while it's displayed as Waiting in the console
+ //because of an exception for instance
+ String bundles = executeCommand("bundle:list -s -t 0 | grep %s".formatted(name));
+ Assert.assertTrue("bundle %s is in state %d /%s".formatted(bundle.getSymbolicName(), bundle.getState(), bundles),
+ bundles.contains("Active"));
+ }
+
+ @Override
+ public CamelContext getContext(Class> clazz) {
+ return contexts.computeIfAbsent(new CamelContextKey(clazz), key -> {
+ try {
+ return getMode(clazz).getCamelContextClass(bundleContext, key.getCamelContextName());
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalStateException("No CamelContext could be found matching the criteria", e);
+ }
+ });
+ }
+
+ @Override
+ public ProducerTemplate getTemplate(Class> clazz) {
+ return templates.computeIfAbsent(new CamelContextKey(clazz),
+ key -> {
+ ProducerTemplate template = getContext(clazz).createProducerTemplate();
+ template.start();
+ return template;
+ });
+ }
+
+ @Override
+ public CamelContext getContext(String name, boolean isBlueprintTest) {
+ return contexts.computeIfAbsent(new CamelContextKey(name, isBlueprintTest), key -> {
+ try {
+ return getMode(isBlueprintTest).getCamelContextClass(bundleContext, key.getCamelContextName());
+ } catch (InvalidSyntaxException e) {
+ throw new IllegalStateException("No CamelContext could be found matching the criteria", e);
+ }
+ });
+ }
+
+ @Override
+ public ProducerTemplate getTemplate(String name, boolean isBlueprintTest) {
+ return templates.computeIfAbsent(new CamelContextKey(name, isBlueprintTest),
+ key -> {
+ ProducerTemplate template = getContext(name, isBlueprintTest).createProducerTemplate();
+ template.start();
+ return template;
+ });
+ }
+
+ private enum Mode {
+ BLUEPRINT {
+ @Override
+ String getFeatureName() {
+ return "camel-blueprint";
+ }
+
+ @Override
+ Class extends CamelContext> getCamelContextClass() {
+ return BlueprintCamelContext.class;
+ }
+ },
+ CORE {
+ @Override
+ String getFeatureName() {
+ return "camel-core";
+ }
+
+ @Override
+ Class extends CamelContext> getCamelContextClass() {
+ return OsgiDefaultCamelContext.class;
+ }
+ };
+
+ abstract String getFeatureName();
+
+ abstract Class extends CamelContext> getCamelContextClass();
+
+ CamelContext getCamelContextClass(BundleContext bundleContext, String name) throws InvalidSyntaxException {
+ ServiceReference>[] references = bundleContext.getServiceReferences(CamelContext.class.getName(), null);
+ if (references == null) {
+ throw new IllegalStateException("No CamelContext available");
+ }
+ for (ServiceReference> reference : references) {
+ if (reference == null) {
+ continue;
+ }
+ CamelContext camelContext = (CamelContext) bundleContext.getService(reference);
+ if (camelContext.getClass().equals(getCamelContextClass())
+ && (name == null || name.equals(camelContext.getName()))) {
+ return camelContext;
+ }
+ }
+ throw new IllegalStateException("No CamelContext could be found matching the criteria (mode = " + this + ", name = " + name + ")");
+ }
+ }
+
+ private static class CamelContextKey {
+ private final String name;
+ private final boolean blueprint;
+
+ CamelContextKey(String name, boolean blueprint) {
+ this.name = name;
+ this.blueprint = blueprint;
+ }
+
+ CamelContextKey(Class> clazz) {
+ this(Utils.getCamelContextName(clazz), isBlueprintTest(clazz));
+ }
+
+ public String getCamelContextName() {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ CamelContextKey that = (CamelContextKey) o;
+ return blueprint == that.blueprint && Objects.equals(name, that.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, blueprint);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelRouteLauncher.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelRouteLauncher.java
new file mode 100644
index 000000000..f478a94cf
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelRouteLauncher.java
@@ -0,0 +1,65 @@
+/*
+ * 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.apache.karaf.camel.itests;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.karaf.core.OsgiCamelContextPublisher;
+import org.apache.camel.karaf.core.OsgiDefaultCamelContext;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Deactivate;
+
+/**
+ * The parent class of the Camel Karaf integration test for a specific Camel component/wrapper/feature.
+ */
+public abstract class AbstractCamelRouteLauncher {
+
+ protected OsgiDefaultCamelContext camelContext;
+ protected ServiceRegistration> serviceRegistration;
+
+ @Activate
+ public void activate(ComponentContext componentContext) throws Exception {
+ BundleContext bundleContext = componentContext.getBundleContext();
+ camelContext = new OsgiDefaultCamelContext(bundleContext);
+ String contextName = Utils.getCamelContextName(getClass());
+ if (contextName == null) {
+ throw new IllegalStateException("Camel context name not set for " + getClass().getName() + " using @CamelKarafTestHint annotation");
+ }
+ camelContext.getCamelContextExtension().setName(contextName);
+ serviceRegistration = new OsgiCamelContextPublisher(bundleContext).registerCamelContext(camelContext);
+ if (serviceRegistration == null) {
+ throw new IllegalStateException("Camel context registration failed for " + contextName + " most likely because the context name is already in use");
+ }
+ camelContext.start();
+ camelContext.addRoutes(createRouteBuilder());
+ }
+
+ @Deactivate
+ public void deactivate() {
+ if (camelContext == null) {
+ return;
+ }
+ camelContext.stop();
+ if (serviceRegistration != null) {
+ serviceRegistration.unregister();
+ }
+ }
+
+ /**
+ * Create the RouteBuilder that will be used to create the Camel routes to test.
+ */
+ protected abstract RouteBuilder createRouteBuilder();
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelRouteWithBundleITest.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelRouteWithBundleITest.java
new file mode 100644
index 000000000..96da477ce
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelRouteWithBundleITest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.karaf.camel.itests;
+
+import java.util.List;
+
+import org.ops4j.pax.exam.CoreOptions;
+import org.ops4j.pax.exam.Option;
+
+import static org.ops4j.pax.exam.OptionUtils.combine;
+
+public abstract class AbstractCamelRouteWithBundleITest extends AbstractCamelRouteITest {
+
+
+ protected abstract String getTestBundleName();
+
+ public String getTestBundleVersion() {
+ return System.getProperty("project.version");
+ }
+
+ @Override
+ protected List installRequiredBundles() throws Exception {
+ String testBundleName = getTestBundleName();
+ String testBundleVersion = getTestBundleVersion();
+ if (testBundleVersion == null) {
+ throw new IllegalArgumentException("The system property project.version must be set to the version of the " +
+ "test bundle to install or the method getTestBundleVersion must be overridden to provide the version");
+ }
+ installBundle("file://%s/%s-%s.jar".formatted(getBaseDir(), testBundleName, testBundleVersion), true);
+ assertBundleInstalledAndRunning(testBundleName);
+ return List.of(testBundleName);
+ }
+
+ @Override
+ protected Option[] getAdditionalOptions() {
+ return combine(
+ super.getAdditionalOptions(), CoreOptions.systemProperty("project.version").value(getTestBundleVersion())
+ );
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultFileBasedRoute.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultFileBasedRoute.java
new file mode 100644
index 000000000..5be4e71c4
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultFileBasedRoute.java
@@ -0,0 +1,54 @@
+/**
+ * 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.karaf.camel.itests;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+
+public abstract class AbstractCamelSingleFeatureResultFileBasedRoute implements CamelSingleFeatureResultFileBasedRoute {
+
+ private final CamelContextProvider provider;
+ private final String baseDir;
+
+ protected AbstractCamelSingleFeatureResultFileBasedRoute(CamelContextProvider provider, String baseDir) {
+ this.provider = provider;
+ this.baseDir = baseDir;
+ }
+
+ @Override
+ public String getBaseDir() {
+ return baseDir;
+ }
+
+ @Override
+ public CamelContext getContext() {
+ return provider.getContext();
+ }
+
+ @Override
+ public ProducerTemplate getTemplate() {
+ return provider.getTemplate();
+ }
+
+ public void testRoutes() throws Exception {
+ triggerProducerRoute();
+ executeTest();
+ }
+
+ protected abstract void executeTest() throws Exception;
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultFileBasedRouteITest.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultFileBasedRouteITest.java
new file mode 100644
index 000000000..ff02b3134
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultFileBasedRouteITest.java
@@ -0,0 +1,29 @@
+/**
+ * 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.karaf.camel.itests;
+
+import org.junit.Before;
+
+public abstract class AbstractCamelSingleFeatureResultFileBasedRouteITest extends AbstractCamelSingleFeatureRouteITest
+ implements CamelSingleFeatureResultFileBasedRoute {
+
+ @Override
+ @Before
+ public void triggerProducerRoute() {
+ super.triggerProducerRoute();
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultFileBasedRouteSupplier.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultFileBasedRouteSupplier.java
new file mode 100644
index 000000000..8a9ab9438
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultFileBasedRouteSupplier.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.karaf.camel.itests;
+
+import org.apache.camel.model.RouteDefinition;
+
+public abstract class AbstractCamelSingleFeatureResultFileBasedRouteSupplier extends AbstractCamelSingleFeatureRouteSupplier {
+
+ public String getBaseDir() {
+ return System.getProperty("project.target");
+ }
+
+ protected String getResultFileName() {
+ return getTestComponentName();
+ }
+
+ @Override
+ protected void configureConsumer(RouteDefinition consumerRoute) {
+ consumerRoute.toF("file:%s?fileName=%s", getBaseDir(), getResultFileName());
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultMockBasedRoute.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultMockBasedRoute.java
new file mode 100644
index 000000000..2e6118b66
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultMockBasedRoute.java
@@ -0,0 +1,54 @@
+/**
+ * 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.karaf.camel.itests;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+
+public abstract class AbstractCamelSingleFeatureResultMockBasedRoute implements CamelSingleFeatureResultMockBasedRoute {
+
+ private final CamelContextProvider provider;
+
+ protected AbstractCamelSingleFeatureResultMockBasedRoute(CamelContextProvider provider) {
+ this.provider = provider;
+ }
+
+ @Override
+ public CamelContext getContext() {
+ return provider.getContext();
+ }
+
+ @Override
+ public ProducerTemplate getTemplate() {
+ return provider.getTemplate();
+ }
+
+ public void testRoutes() throws Exception {
+ setupMock();
+ try {
+ triggerProducerRoute();
+ executeTest();
+ } finally {
+ cleanMock();
+ }
+ }
+
+ protected void executeTest() throws Exception {
+ assertMockEndpointsSatisfied();
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelKarafResultMockBasedITest.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultMockBasedRouteITest.java
similarity index 61%
rename from tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelKarafResultMockBasedITest.java
rename to tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultMockBasedRouteITest.java
index 0c9e8149c..2b93ac55c 100644
--- a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelKarafResultMockBasedITest.java
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultMockBasedRouteITest.java
@@ -16,29 +16,22 @@
*/
package org.apache.karaf.camel.itests;
-import org.apache.camel.component.mock.MockEndpoint;
import org.junit.After;
import org.junit.Before;
-public abstract class AbstractCamelKarafResultMockBasedITest extends AbstractCamelKarafITest {
+public abstract class AbstractCamelSingleFeatureResultMockBasedRouteITest extends AbstractCamelSingleFeatureRouteITest
+ implements CamelSingleFeatureResultMockBasedRoute {
+ @Override
@Before
public void setupMock() {
- MockEndpoint endpoint = context.getEndpoint("mock:%s".formatted(getTestComponentName()), MockEndpoint.class);
- endpoint.expectedMinimumMessageCount(1);
- configureMock(endpoint);
+ CamelSingleFeatureResultMockBasedRoute.super.setupMock();
+ triggerProducerRoute();
}
+ @Override
@After
public void cleanMock() {
- MockEndpoint.resetMocks(context);
- }
-
- protected void configureMock(MockEndpoint mock) {
- // Do nothing by default
- }
-
- protected void assertMockEndpointsSatisfied() throws InterruptedException {
- MockEndpoint.assertIsSatisfied(context);
+ CamelSingleFeatureResultMockBasedRoute.super.cleanMock();
}
}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelComponentResultMockBased.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultMockBasedRouteSupplier.java
similarity index 90%
rename from tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelComponentResultMockBased.java
rename to tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultMockBasedRouteSupplier.java
index 4f3048614..21419fb25 100644
--- a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelComponentResultMockBased.java
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureResultMockBasedRouteSupplier.java
@@ -14,12 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.karaf.camel.itests;
import org.apache.camel.model.RouteDefinition;
-public abstract class AbstractCamelComponentResultMockBased extends AbstractCamelComponent {
-
+public class AbstractCamelSingleFeatureResultMockBasedRouteSupplier extends AbstractCamelSingleFeatureRouteSupplier {
protected String getResultMockName() {
return getTestComponentName();
}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureRouteITest.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureRouteITest.java
new file mode 100644
index 000000000..522a5c16b
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureRouteITest.java
@@ -0,0 +1,51 @@
+/**
+ * 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.karaf.camel.itests;
+
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+
+public abstract class AbstractCamelSingleFeatureRouteITest extends AbstractCamelRouteWithBundleITest
+ implements CamelSingleFeatureRoute {
+
+ @Override
+ public String getTestBundleName() {
+ return CamelSingleFeatureRoute.super.getTestBundleName();
+ }
+
+ /**
+ * Get the required features for this test. If more are needed,
+ * use {@link CamelKarafTestHint#externalResourceProvider()}.
+ */
+ @Override
+ public final List getRequiredFeatures() {
+ return CamelSingleFeatureRoute.super.getRequiredFeatures();
+ }
+
+ @Override
+ public CamelContext getContext() {
+ return super.getContext();
+ }
+
+ @Override
+ public ProducerTemplate getTemplate() {
+ return super.getTemplate();
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureRouteSupplier.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureRouteSupplier.java
new file mode 100644
index 000000000..cbd115517
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AbstractCamelSingleFeatureRouteSupplier.java
@@ -0,0 +1,93 @@
+/**
+ * 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.karaf.camel.itests;
+
+import java.util.function.Function;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.RouteDefinition;
+
+import static org.apache.karaf.camel.itests.Utils.toKebabCase;
+
+/**
+ * The parent class of the camel route suppliers that test a specific Camel component/wrapper/feature.
+ *
+ * It creates and starts two simple Camel routes, the first one if {@link #producerEnabled()} returns {@code true}
+ * calls the producer of the tested Camel component and the second one if {@link #consumerEnabled()} returns {@code true}
+ * consumes what has been produced by the first route thanks to the consumer corresponding to the tested Camel component.
+ */
+public abstract class AbstractCamelSingleFeatureRouteSupplier implements CamelRouteSupplier {
+
+ public String getTestComponentName() {
+ String name = toKebabCase(this.getClass().getSimpleName());
+ if (!name.endsWith("-route-supplier")) {
+ throw new IllegalArgumentException("The route supplier class name doesn't match with the expected format: RouteSupplier");
+ }
+ return name.replace("-route-supplier", "-test");
+ }
+
+ @Override
+ public void createRoutes(RouteBuilder builder) {
+ if (producerEnabled()) {
+ configureProducer(
+ builder, builder.fromF("direct:%s", getTestComponentName()).routeId("producer-%s".formatted(getTestComponentName()))
+ );
+ }
+ if (consumerEnabled()) {
+ configureConsumer(consumerRoute().apply(builder));
+ }
+ }
+
+ /**
+ * Indicates whether the Camel component that is tested has a producer. Default is {@code true}.
+ */
+ protected boolean producerEnabled() {
+ return true;
+ }
+
+ /**
+ * Indicates whether the Camel component that is tested has a consumer. Default is {@code true}.
+ */
+ protected boolean consumerEnabled() {
+ return true;
+ }
+
+ /**
+ * Returns the function used to build the Camel route to test the consumer. Default is {@code null}.
+ */
+ protected Function consumerRoute() {
+ return null;
+ }
+
+ /**
+ * Executes the code needed to configure the Camel route to test the producer.
+ */
+ protected void configureProducer(RouteBuilder builder, RouteDefinition producerRoute) {
+ // Do nothing by default
+ }
+
+ /**
+ * Executes the code needed to configure the Camel route to test the consumer.
+ */
+ protected void configureConsumer(RouteDefinition consumerRoute) {
+ if (consumerRoute.hasCustomIdAssigned()) {
+ return;
+ }
+ consumerRoute.routeId("consumer-%s".formatted(getTestComponentName()));
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AvailablePortProvider.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AvailablePortProvider.java
new file mode 100644
index 000000000..34763a940
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/AvailablePortProvider.java
@@ -0,0 +1,68 @@
+/**
+ * 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.karaf.camel.itests;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+/**
+ * A class that provides available ports for the test.
+ */
+public class AvailablePortProvider implements ExternalResource {
+
+ private static final Set USED_PORTS = ConcurrentHashMap.newKeySet();
+
+ private final Map ports = new ConcurrentHashMap<>();
+
+ private final List neededPortPropertyNames;
+
+ /**
+ * Create an AvailablePortProvider with the given name of property that will have the needed ports for the test as
+ * value.
+ * @param neededPortPropertyNames the name of the property that will have the needed ports as value
+ */
+ public AvailablePortProvider(List neededPortPropertyNames) {
+ this.neededPortPropertyNames = neededPortPropertyNames;
+ }
+
+ @Override
+ public void before() {
+ for (String name : neededPortPropertyNames) {
+ Utils.getNextAvailablePort(port -> {
+ if (USED_PORTS.add(port)) {
+ ports.put(name, port);
+ return true;
+ }
+ return false;
+ });
+ }
+ }
+
+ @Override
+ public void after() {
+ ports.values().forEach(USED_PORTS::remove);
+ }
+
+ @Override
+ public Map properties() {
+ return ports.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toString()));
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelContextProvider.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelContextProvider.java
new file mode 100644
index 000000000..eb6e62aa7
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelContextProvider.java
@@ -0,0 +1,59 @@
+package org.apache.karaf.camel.itests;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+
+public interface CamelContextProvider {
+
+ /**
+ * Returns the {@link CamelContext} associated with the given class according to the annotation
+ * {@link CamelKarafTestHint}.
+ */
+ CamelContext getContext(Class> clazz);
+
+ /**
+ * Returns the {@link CamelContext} associated with the current class according to the annotation
+ * {@link CamelKarafTestHint}.
+ */
+ default CamelContext getContext() {
+ return getContext(getClass());
+ }
+
+ /**
+ * Returns the {@link CamelContext} associated with the given name and type of test
+ */
+ CamelContext getContext(String name, boolean isBlueprintTest);
+
+ /**
+ * Returns the {@link CamelContext} associated with the given name for a blueprint test
+ */
+ default CamelContext getContext(String name) {
+ return getContext(name, true);
+ }
+
+ /**
+ * Returns the {@link ProducerTemplate} associated with the given class according to the annotation
+ * {@link CamelKarafTestHint}.
+ */
+ ProducerTemplate getTemplate(Class> clazz);
+
+ /**
+ * Returns the {@link ProducerTemplate} associated with the current class according to the annotation
+ * {@link CamelKarafTestHint}.
+ */
+ default ProducerTemplate getTemplate() {
+ return getTemplate(getClass());
+ }
+
+ /**
+ * Returns the {@link ProducerTemplate} associated with the given name and type of test
+ */
+ ProducerTemplate getTemplate(String name, boolean isBlueprintTest);
+
+ /**
+ * Returns the {@link ProducerTemplate} associated with the given name for a blueprint test
+ */
+ default ProducerTemplate getTemplate(String name) {
+ return getTemplate(name, true);
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelKarafTestHint.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelKarafTestHint.java
new file mode 100644
index 000000000..8e9139e5b
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelKarafTestHint.java
@@ -0,0 +1,50 @@
+package org.apache.karaf.camel.itests;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+
+/**
+ * The annotation uses to provide hints to the Camel Karaf test framework.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+public @interface CamelKarafTestHint {
+
+ /**
+ * Specify the class that provides the methods to create all the external resources required by the test.
+ * In the provider class, each public static method that returns an instance of a subtype of {@link ExternalResource}
+ * with no parameters is considered as an {@link ExternalResource} supplier, so it will be invoked before executing
+ * the test and {@code PaxExamWithExternalResource} will take care of its lifecycle making sure that it is created and
+ * destroyed outside Karaf.
+ *
+ * @see PaxExamWithExternalResource
+ */
+ Class> externalResourceProvider() default Object.class;
+
+ /**
+ * Indicates whether the test is a blueprint test or not. By default, it's not a blueprint test.
+ * @return {@code true} if the test is a blueprint test, {@code false} otherwise
+ */
+ boolean isBlueprintTest() default false;
+
+ /**
+ * Specify the list of additional features required by the test.
+ */
+ String[] additionalRequiredFeatures() default {};
+
+ /**
+ * Specify the name of the Camel context to use in the test.
+ */
+ String camelContextName() default "";
+
+ /**
+ * Specify the list of Camel route suppliers to use within the context of the test. By default, all detected
+ * Camel route suppliers are used.
+ */
+ String[] camelRouteSuppliers() default {};
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelRouteSupplier.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelRouteSupplier.java
new file mode 100644
index 000000000..ec844954a
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelRouteSupplier.java
@@ -0,0 +1,26 @@
+package org.apache.karaf.camel.itests;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * The interface that provides the ability to supply Camel routes to create and start in the Camel context.
+ */
+public interface CamelRouteSupplier {
+
+ /**
+ * Configures the Camel context before creating the routes.
+ *
+ * @param camelContext the Camel context
+ */
+ default void configure(CamelContext camelContext) {
+ // Do nothing by default
+ }
+
+ /**
+ * Creates the Camel routes in the Camel context.
+ *
+ * @param builder the Camel route builder
+ */
+ void createRoutes(RouteBuilder builder);
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSingleFeatureResultFileBasedRoute.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSingleFeatureResultFileBasedRoute.java
new file mode 100644
index 000000000..a5a49faa3
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSingleFeatureResultFileBasedRoute.java
@@ -0,0 +1,56 @@
+package org.apache.karaf.camel.itests;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.concurrent.TimeUnit;
+
+import org.awaitility.Awaitility;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public interface CamelSingleFeatureResultFileBasedRoute extends CamelSingleFeatureRoute {
+
+ default String getResultFileName() {
+ return getTestComponentName();
+ }
+
+ default Charset getResultFileCharset() {
+ return StandardCharsets.UTF_8;
+ }
+
+ default Path assertResultFileExists() {
+ Path filePath = Path.of(getBaseDir(), getResultFileName());
+ Awaitility.await().atMost(getTimeoutInSeconds(), TimeUnit.SECONDS)
+ .until(() -> Files.exists(filePath));
+ assertTrue(Files.exists(filePath));
+ return filePath;
+ }
+
+ default void assertResultFileContains(String expectedFileContent) throws Exception {
+ assertEquals(
+ "The content of the result file is not correct",
+ expectedFileContent, Files.readString(assertResultFileExists(), getResultFileCharset())
+ );
+ }
+
+ default void assertResultFileIsSameAs(String expectedResultFileName) throws Exception {
+ assertResultFileContains(
+ Files.readString(createExpectedResultPath(expectedResultFileName))
+ );
+ }
+
+ default void assertResultFileIsSameAs(String expectedResultFileName, Charset encoding) throws Exception {
+ assertResultFileContains(
+ Files.readString(createExpectedResultPath(expectedResultFileName), encoding)
+ );
+ }
+
+ default Path createExpectedResultPath(String expectedResultFileName) {
+ return Path.of(getBaseDir(), "test-classes", expectedResultFileName);
+ }
+
+ String getBaseDir();
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSingleFeatureResultMockBasedRoute.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSingleFeatureResultMockBasedRoute.java
new file mode 100644
index 000000000..c36e4b9b4
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSingleFeatureResultMockBasedRoute.java
@@ -0,0 +1,28 @@
+package org.apache.karaf.camel.itests;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.mock.MockEndpoint;
+
+public interface CamelSingleFeatureResultMockBasedRoute extends CamelSingleFeatureRoute {
+
+ default void setupMock() {
+ MockEndpoint endpoint = getContext().getEndpoint("mock:%s".formatted(getTestComponentName()), MockEndpoint.class);
+ endpoint.setFailFast(false);
+ configureMock(endpoint);
+ }
+
+ default void cleanMock() {
+ CamelContext context = getContext();
+ if (context != null) {
+ MockEndpoint.resetMocks(context);
+ }
+ }
+
+ default void configureMock(MockEndpoint mock) {
+ mock.expectedMinimumMessageCount(1);
+ }
+
+ default void assertMockEndpointsSatisfied() throws InterruptedException {
+ MockEndpoint.assertIsSatisfied(getContext());
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSingleFeatureRoute.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSingleFeatureRoute.java
new file mode 100644
index 000000000..5ac3758c1
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSingleFeatureRoute.java
@@ -0,0 +1,62 @@
+package org.apache.karaf.camel.itests;
+
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Processor;
+import org.apache.camel.ProducerTemplate;
+import org.jetbrains.annotations.NotNull;
+
+import static org.apache.karaf.camel.itests.Utils.toKebabCase;
+
+public interface CamelSingleFeatureRoute {
+
+ default int getTimeoutInSeconds() {
+ return 5;
+ }
+
+ default String getTestComponentName() {
+ return getTestClassSimpleNameInKebabCase().replace("-itest", "-test");
+ }
+
+ default String getCamelFeatureName() {
+ return getTestClassSimpleNameInKebabCase().replace("-itest", "");
+ }
+
+ @NotNull
+ private String getTestClassSimpleNameInKebabCase() {
+ String name = toKebabCase(this.getClass().getSimpleName());
+ if (!name.endsWith("-itest")) {
+ throw new IllegalArgumentException("The integration test class name doesn't match with the expected format: ITest");
+ }
+ return name;
+ }
+
+ default String getTestBundleName() {
+ return getTestComponentName();
+ }
+
+ default List getRequiredFeatures() {
+ return List.of(getCamelFeatureName());
+ }
+
+ default Processor getProcessorToCallOnSend() {
+ return exchange -> exchange.getMessage().setBody(getBodyToSend());
+ }
+
+ default String getBodyToSend() {
+ return getClass().getSimpleName();
+ }
+
+ CamelContext getContext();
+
+ ProducerTemplate getTemplate();
+
+ default void triggerProducerRoute() {
+ Endpoint endpoint = getContext().hasEndpoint("direct:%s".formatted(getTestComponentName()));
+ if (endpoint != null) {
+ getTemplate().send(endpoint, getProcessorToCallOnSend());
+ }
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSuppliedRouteLauncher.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSuppliedRouteLauncher.java
new file mode 100644
index 000000000..e2de01603
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/CamelSuppliedRouteLauncher.java
@@ -0,0 +1,140 @@
+/**
+ * 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.karaf.camel.itests;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.RouteDefinition;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.karaf.camel.itests.AbstractCamelRouteITest.CAMEL_KARAF_INTEGRATION_TEST_ROUTE_SUPPLIERS_PROPERTY;
+
+@CamelKarafTestHint(camelContextName = CamelSuppliedRouteLauncher.CAMEL_CONTEXT_NAME)
+@Component(
+ name = "camel-supplied-route-launcher",
+ immediate = true
+)
+public class CamelSuppliedRouteLauncher extends AbstractCamelRouteLauncher implements ServiceListener {
+
+ public static final String CAMEL_CONTEXT_NAME = "supplied-route-launcher";
+ private static final Logger LOG = LoggerFactory.getLogger(CamelSuppliedRouteLauncher.class);
+ private final Map> routes = new ConcurrentHashMap<>();
+ private final Set suppliers = ConcurrentHashMap.newKeySet();
+
+ @Override
+ public void activate(ComponentContext componentContext) throws Exception {
+ super.activate(componentContext);
+ camelContext.getBundleContext().addServiceListener(this);
+ loadSuppliers();
+ }
+
+ @Override
+ public void deactivate() {
+ suppliers.clear();
+ super.deactivate();
+ }
+
+ private void loadSuppliers() {
+ String property = System.getProperty(CAMEL_KARAF_INTEGRATION_TEST_ROUTE_SUPPLIERS_PROPERTY);
+ if (property == null) {
+ return;
+ }
+ suppliers.addAll(List.of(property.split(",")));
+ }
+
+ @SuppressWarnings("SuspiciousMethodCalls")
+ private boolean ignore(ServiceReference> serviceReference) {
+ return !suppliers.isEmpty() && !suppliers.contains(serviceReference.getProperty("component.name"));
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ // no routes to add here as they will be added by the listener
+ }
+ };
+ }
+
+ @Override
+ public void serviceChanged(ServiceEvent serviceEvent) {
+ ServiceReference> serviceReference = serviceEvent.getServiceReference();
+ if (ignore(serviceReference)) {
+ LOG.debug("Ignoring CamelRouteSupplier service: {}", serviceReference.getProperties());
+ return;
+ }
+ if (serviceEvent.getType() == ServiceEvent.REGISTERED) {
+ if (camelContext.getBundleContext().getService(serviceReference) instanceof CamelRouteSupplier supplier) {
+ LOG.info("CamelRouteSupplier service registered: {} from the class {}", serviceReference.getProperties(),
+ supplier.getClass().getName());
+ addRoutes(supplier);
+ }
+ } else if (serviceEvent.getType() == ServiceEvent.UNREGISTERING
+ && camelContext.getBundleContext().getService(serviceReference) instanceof CamelRouteSupplier supplier) {
+ LOG.info("CamelRouteSupplier service unregistered: {}", supplier.getClass().getName());
+ removeRoutes(supplier);
+ }
+ }
+
+ private void removeRoutes(CamelRouteSupplier supplier) {
+ try {
+ List routeDefinitions = routes.remove(supplier.getClass().getName());
+ if (routeDefinitions == null) {
+ return;
+ }
+ camelContext.removeRouteDefinitions(routeDefinitions);
+ LOG.info("Route(s) removed from CamelRouteSupplier service: {}", supplier.getClass().getName());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void addRoutes(CamelRouteSupplier supplier) {
+ try {
+ List before = new ArrayList<>(camelContext.getRouteDefinitions());
+ camelContext.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() {
+ supplier.configure(camelContext);
+ supplier.createRoutes(this);
+ }
+ });
+ List added = new ArrayList<>(camelContext.getRouteDefinitions());
+ added.removeAll(before);
+ if (routes.putIfAbsent(supplier.getClass().getName(), added) == null) {
+ LOG.info("Route(s) created from CamelRouteSupplier service: {}", supplier.getClass().getName());
+ } else {
+ LOG.warn("Route(s) already created from CamelRouteSupplier service: {}", supplier.getClass().getName());
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/ExternalResource.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/ExternalResource.java
new file mode 100644
index 000000000..22f6fe09b
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/ExternalResource.java
@@ -0,0 +1,46 @@
+/**
+ * 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.karaf.camel.itests;
+
+import java.util.Map;
+
+/**
+ * An interface representing an external resource to set up before a test and guarantee to tear it down afterward.
+ * Compared to an {@link org.junit.rules.ExternalResource}, the methods {@link #before()} and {@link #after()} are
+ * executed outside Karaf container, so it can be used to set up external resources like a database, a message broker,
+ * etc.
+ * @see TemporaryFile
+ * @see GenericContainerResource
+ */
+public interface ExternalResource {
+
+ /**
+ * Sets up the external resource.
+ */
+ void before();
+
+ /**
+ * Tears down the external resource.
+ */
+ void after();
+
+ /**
+ * Gives access to the properties of the external resource like a username, a password or a path, that will be
+ * provided to the Karaf instance as System properties.
+ */
+ Map properties();
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/GenericContainerResource.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/GenericContainerResource.java
new file mode 100644
index 000000000..8a188ceed
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/GenericContainerResource.java
@@ -0,0 +1,97 @@
+/**
+ * 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.karaf.camel.itests;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+
+/**
+ * A JUnit ExternalResource that starts and stops a TestContainer.
+ *
+ * @param the type of the TestContainer
+ */
+public class GenericContainerResource> implements ExternalResource {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GenericContainerResource.class);
+ private final T container;
+ private final Map properties = new HashMap<>();
+ private final List dependencies = new ArrayList<>();
+ private final Consumer> onStarted;
+
+ public GenericContainerResource(T container) {
+ this(container, t -> {});
+ }
+
+ /**
+ * Create a GenericContainerResource with the given TestContainer and a callback to be called when the container is
+ * started.
+ * @param container the TestContainer
+ * @param onStarted the callback to be called when the container is started
+ */
+ public GenericContainerResource(T container, Consumer> onStarted) {
+ this.container = container;
+ this.onStarted = onStarted;
+ }
+
+ @Override
+ public void before() {
+ container.start();
+ onStarted.accept(this);
+ for (ExternalResource dependency : dependencies) {
+ dependency.properties().forEach(this::setProperty);
+ }
+ LOG.info("Container {} started", container.getDockerImageName());
+ }
+
+ @Override
+ public void after() {
+ container.stop();
+ for (ExternalResource dependency : dependencies) {
+ try {
+ dependency.after();
+ } catch (Exception e) {
+ LOG.warn("Error cleaning dependency: {}", dependency.getClass().getName(), e);
+ }
+ }
+ LOG.info("Container {} stopped", container.getDockerImageName());
+ }
+
+ @Override
+ public Map properties() {
+ return properties;
+ }
+
+ public T getContainer() {
+ return container;
+ }
+
+ public void setProperty(String key, String value) {
+ properties.put(key, value);
+ }
+
+ public void addDependency(ExternalResource dependency) {
+ dependencies.add(dependency);
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/PaxExamWithExternalResource.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/PaxExamWithExternalResource.java
new file mode 100644
index 000000000..f8cdd5f3e
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/PaxExamWithExternalResource.java
@@ -0,0 +1,139 @@
+/**
+ * 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.karaf.camel.itests;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.junit.runner.Description;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+import org.junit.runner.manipulation.Filterable;
+import org.junit.runner.manipulation.NoTestsRemainException;
+import org.junit.runner.manipulation.Sortable;
+import org.junit.runner.manipulation.Sorter;
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.ParentRunner;
+import org.junit.runners.model.InitializationError;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.junit.impl.ProbeRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A fork of {@link PaxExam} that supports external resources which can be created and destroyed outside Karaf.
+ *
+ * This runner is intended to be used with {@link CamelKarafTestHint} annotation where
+ * {@link CamelKarafTestHint#externalResourceProvider()} is properly set in order to create the
+ * external resources that are needed by the test. Please note that due to the way PaxExam works, the class cannot be
+ * the same as the test class, but it can be a static inner class of it otherwise the class will need to be resolved
+ * within Karaf which is what we want to avoid.
+ *
+ * @see CamelKarafTestHint
+ */
+public class PaxExamWithExternalResource extends Runner implements Filterable, Sortable {
+ private static final Logger LOG = LoggerFactory.getLogger(PaxExamWithExternalResource.class);
+ private static final ThreadLocal current = new ThreadLocal<>();
+ private final ParentRunner> delegate;
+ private final List externalResources;
+
+ public PaxExamWithExternalResource(Class> testClass) throws InitializationError, InvocationTargetException,
+ IllegalAccessException {
+ this.externalResources = beforeAll(testClass);
+ try {
+ current.set(this);
+ this.delegate = new ProbeRunner(testClass);
+ } finally {
+ current.remove();
+ }
+ }
+
+ private List beforeAll(Class> testClass) throws InvocationTargetException, IllegalAccessException {
+ CamelKarafTestHint annotation = testClass.getAnnotation(CamelKarafTestHint.class);
+ if (annotation != null && annotation.externalResourceProvider() != Object.class) {
+ List result = new ArrayList<>();
+ for (Method m : annotation.externalResourceProvider().getMethods()) {
+ if (isExternalResourceSupplier(m)) {
+ ExternalResource externalResource = (ExternalResource) m.invoke(null);
+ externalResource.before();
+ result.add(externalResource);
+ }
+ }
+ return result;
+ }
+ LOG.warn("Class {} is not annotated with @CamelKarafTestHint or externalResourceProvider is not set", testClass.getName());
+ return List.of();
+ }
+
+ private boolean isExternalResourceSupplier(Method m) {
+ return ExternalResource.class.isAssignableFrom(m.getReturnType()) && m.getParameterTypes().length == 0
+ && Modifier.isStatic(m.getModifiers());
+ }
+
+ @Override
+ public Description getDescription() {
+ return delegate.getDescription();
+ }
+
+ @Override
+ public void run(RunNotifier notifier) {
+ try {
+ delegate.run(notifier);
+ } finally {
+ afterAll();
+ }
+ }
+
+ private void afterAll() {
+ for (int i = externalResources.size() - 1; i >= 0; i--) {
+ try {
+ externalResources.get(i).after();
+ } catch (Exception e) {
+ LOG.warn("Error while cleaning up external resource", e);
+ }
+ }
+ }
+
+ @Override
+ public void filter(Filter filter) throws NoTestsRemainException {
+ delegate.filter(filter);
+ }
+
+ @Override
+ public void sort(Sorter sorter) {
+ delegate.sort(sorter);
+ }
+
+ static Map systemProperties() {
+ PaxExamWithExternalResource value = current.get();
+ if (value == null) {
+ return Map.of();
+ }
+ return value.externalResources.stream()
+ .map(ExternalResource::properties)
+ .map(Map::entrySet)
+ .flatMap(Set::stream)
+ .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/TemporaryFile.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/TemporaryFile.java
new file mode 100644
index 000000000..9e6094025
--- /dev/null
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/TemporaryFile.java
@@ -0,0 +1,74 @@
+/**
+ * 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.karaf.camel.itests;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A temporary file that is deleted when the test is finished.
+ */
+public class TemporaryFile implements ExternalResource {
+ private static final Logger LOG = LoggerFactory.getLogger(TemporaryFile.class);
+ private final String key;
+ private final Path path;
+
+ /**
+ * Create a temporary file with the given key.
+ *
+ * @param key the key to store the path of the temporary file
+ * @param prefix the prefix of the temporary file
+ * @param suffix the suffix of the temporary file
+ * @throws IOException if an I/O error occurs
+ */
+ public TemporaryFile(String key, String prefix, String suffix) throws IOException {
+ this.key = key;
+ this.path = Files.createTempFile(prefix, suffix);
+ }
+
+ @Override
+ public void before() {
+ // Do nothing
+ }
+
+ @Override
+ public void after() {
+ try {
+ if (Files.deleteIfExists(path)) {
+ LOG.debug("Deleted temporary file: {}", path);
+ }
+ } catch (IOException e) {
+ LOG.warn("Failed to delete temporary file: {}", path, e);
+ }
+ }
+
+ @Override
+ public Map properties() {
+ return Map.of(key, path.toString());
+ }
+
+ public Path getPath() {
+ return path;
+ }
+}
diff --git a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/Utils.java b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/Utils.java
index 673905899..9d06ffe51 100644
--- a/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/Utils.java
+++ b/tests/camel-integration-test/src/main/java/org/apache/karaf/camel/itests/Utils.java
@@ -16,7 +16,24 @@
*/
package org.apache.karaf.camel.itests;
-final class Utils {
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.function.IntPredicate;
+
+import org.jetbrains.annotations.NotNull;
+import org.ops4j.pax.exam.MavenUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class Utils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Utils.class);
private Utils() {
}
@@ -24,4 +41,82 @@ private Utils() {
static String toKebabCase(String name) {
return name.replaceAll("([a-z0-9])([A-Z])", "$1-$2").toLowerCase();
}
+
+ public static int getAvailablePort(int min, int max) {
+ return getAvailablePort(min, max, null);
+ }
+
+ public static int getAvailablePort(int min, int max, IntPredicate filter) {
+ for (int port = min; port <= max; port++) {
+ try (ServerSocket socket = new ServerSocket()) {
+ socket.setReuseAddress(true);
+ socket.bind(new InetSocketAddress(InetAddress.getByName("localhost"), port), 1);
+ if (filter == null || filter.test(port)) {
+ return socket.getLocalPort();
+ }
+ } catch (Exception e) {
+ LOG.debug("Port {} not available, trying next one", port);
+ }
+ }
+ throw new IllegalStateException("Can't find available network ports");
+ }
+
+ public static int getNextAvailablePort() {
+ return getNextAvailablePort(null);
+ }
+
+ public static int getNextAvailablePort(IntPredicate filter) {
+ return getAvailablePort(30000, 40000, filter);
+ }
+
+ /**
+ * Get the Camel context name from the given class.
+ *
+ * @param clazz the class from which the Camel context name should be extracted
+ * @return the Camel context name if it can be found, {@code null} otherwise.
+ */
+ public static String getCamelContextName(Class> clazz) {
+ CamelKarafTestHint hint = clazz.getAnnotation(CamelKarafTestHint.class);
+ if (hint == null || hint.camelContextName().isEmpty()) {
+ return null;
+ }
+ return hint.camelContextName();
+ }
+
+ static String loadCamelKarafVersion() {
+ try {
+ String version = MavenUtils.asInProject().getVersion("org.apache.camel.karaf", "camel-integration-test");
+ LOG.info("Detected Camel Karaf version: {}", version);
+ return version;
+ } catch (Exception e) {
+ LOG.debug("Can't detect Camel Karaf version", e);
+ }
+ return null;
+ }
+
+ static String loadUsersFileIfAbsent(String baseDir) {
+ Path location = Paths.get(baseDir, "camel-karaf-itest-resources", "users.properties");
+ if (Files.exists(location)) {
+ LOG.debug("Detected users file at {}", location);
+ return location.toString();
+ }
+ return loadUsersFile(location);
+ }
+
+ @NotNull
+ private static String loadUsersFile(Path location) {
+ try (InputStream is = Utils.class.getResourceAsStream("/etc/users.properties")) {
+ if (is != null) {
+ Files.createDirectories(location.getParent());
+ try (OutputStream os = Files.newOutputStream(location)) {
+ is.transferTo(os);
+ }
+ return location.toString();
+ }
+ } catch (Exception e) {
+ LOG.debug("Can't load the users.properties file", e);
+ }
+ throw new IllegalStateException("Can't find the users.properties file, please provide it using the system " +
+ "property users.file.location");
+ }
}
diff --git a/tests/components/camel-file/src/test/java/org/apache/karaf/camel/itests/CamelFileITest.java b/tests/components/camel-file/src/test/java/org/apache/karaf/camel/itests/CamelFileITest.java
deleted file mode 100644
index a91208bb9..000000000
--- a/tests/components/camel-file/src/test/java/org/apache/karaf/camel/itests/CamelFileITest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.apache.karaf.camel.itests;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
-import org.ops4j.pax.exam.spi.reactors.PerSuite;
-
-
-@RunWith(PaxExam.class)
-@ExamReactorStrategy(PerSuite.class)
-public class CamelFileITest extends AbstractCamelKarafResultFileBasedITest {
-
- @Test
- public void testResultFileContent() throws Exception {
- assertResultFileContains("OK");
- }
-}
\ No newline at end of file
diff --git a/tests/examples/blueprint-dsl-only/pom.xml b/tests/examples/blueprint-dsl-only/pom.xml
new file mode 100644
index 000000000..85ea09186
--- /dev/null
+++ b/tests/examples/blueprint-dsl-only/pom.xml
@@ -0,0 +1,32 @@
+
+
+
+ 4.0.0
+
+ org.apache.camel.karaf
+ camel-karaf-examples-test
+ 4.6.0-SNAPSHOT
+
+
+ camel-karaf-examples-blueprint-dsl-only-test
+ Apache Camel :: Karaf :: Tests :: Samples :: Blueprint DSL Only
+
\ No newline at end of file
diff --git a/tests/examples/blueprint-dsl-only/src/main/resources/OSGI-INF/blueprint/route1.xml b/tests/examples/blueprint-dsl-only/src/main/resources/OSGI-INF/blueprint/route1.xml
new file mode 100644
index 000000000..711edafb8
--- /dev/null
+++ b/tests/examples/blueprint-dsl-only/src/main/resources/OSGI-INF/blueprint/route1.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/examples/blueprint-dsl-only/src/main/resources/OSGI-INF/blueprint/route2.xml b/tests/examples/blueprint-dsl-only/src/main/resources/OSGI-INF/blueprint/route2.xml
new file mode 100644
index 000000000..3800cb794
--- /dev/null
+++ b/tests/examples/blueprint-dsl-only/src/main/resources/OSGI-INF/blueprint/route2.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/examples/blueprint-dsl-only/src/test/java/org/apache/karaf/camel/examples/itest/CamelBlueprintExampleWithBothTest.java b/tests/examples/blueprint-dsl-only/src/test/java/org/apache/karaf/camel/examples/itest/CamelBlueprintExampleWithBothTest.java
new file mode 100644
index 000000000..8609581bc
--- /dev/null
+++ b/tests/examples/blueprint-dsl-only/src/test/java/org/apache/karaf/camel/examples/itest/CamelBlueprintExampleWithBothTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.apache.karaf.camel.examples.itest;
+
+import java.util.List;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.karaf.camel.itests.AbstractCamelRouteWithBundleITest;
+import org.apache.karaf.camel.itests.CamelKarafTestHint;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import static org.junit.Assert.assertNotNull;
+
+@CamelKarafTestHint(isBlueprintTest = true)
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class CamelBlueprintExampleWithBothTest extends AbstractCamelRouteWithBundleITest {
+
+ @Override
+ protected List getRequiredFeatures() {
+ return List.of();
+ }
+
+ @Override
+ protected String getTestBundleName() {
+ return "camel-karaf-examples-blueprint-dsl-only-test";
+ }
+
+
+ @Test
+ public void testBlueprintDSL1() throws Exception {
+ verify("ctx1", 1);
+ }
+
+
+ @Test
+ public void testBlueprintDSL2() throws Exception {
+ verify("ctx2",2);
+ }
+
+ private void verify(String contextName, int id) throws InterruptedException {
+ Endpoint endpoint = getContext(contextName).hasEndpoint("direct:example%d".formatted(id));
+ assertNotNull(endpoint);
+ MockEndpoint mock = getContext(contextName).getEndpoint("mock:example%d".formatted(id), MockEndpoint.class);
+ mock.expectedBodiesReceived("Hello World");
+ getTemplate(contextName).sendBody("direct:example%d".formatted(id), "Hello World");
+ mock.assertIsSatisfied();
+ }
+}
\ No newline at end of file
diff --git a/tests/examples/java-dsl-only/pom.xml b/tests/examples/java-dsl-only/pom.xml
new file mode 100644
index 000000000..e8addc900
--- /dev/null
+++ b/tests/examples/java-dsl-only/pom.xml
@@ -0,0 +1,32 @@
+
+
+
+ 4.0.0
+
+ org.apache.camel.karaf
+ camel-karaf-examples-test
+ 4.6.0-SNAPSHOT
+
+
+ camel-karaf-examples-java-dsl-only-test
+ Apache Camel :: Karaf :: Tests :: Samples :: Java DSL Only
+
\ No newline at end of file
diff --git a/tests/examples/java-dsl-only/src/main/java/org/apache/karaf/camel/examples/test/CamelExampleRouteFirstSupplier.java b/tests/examples/java-dsl-only/src/main/java/org/apache/karaf/camel/examples/test/CamelExampleRouteFirstSupplier.java
new file mode 100644
index 000000000..972480715
--- /dev/null
+++ b/tests/examples/java-dsl-only/src/main/java/org/apache/karaf/camel/examples/test/CamelExampleRouteFirstSupplier.java
@@ -0,0 +1,35 @@
+/**
+ * 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.karaf.camel.examples.test;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.karaf.camel.itests.CamelRouteSupplier;
+import org.osgi.service.component.annotations.Component;
+
+@Component(
+ name = "camel-karaf-examples-java-dsl-only-test-1",
+ immediate = true,
+ service = CamelRouteSupplier.class
+)
+public class CamelExampleRouteFirstSupplier implements CamelRouteSupplier {
+ @Override
+ public void createRoutes(RouteBuilder builder) {
+ builder.from("direct:example1")
+ .to("mock:example1");
+ }
+}
diff --git a/tests/examples/java-dsl-only/src/main/java/org/apache/karaf/camel/examples/test/CamelExampleRouteSecondSupplier.java b/tests/examples/java-dsl-only/src/main/java/org/apache/karaf/camel/examples/test/CamelExampleRouteSecondSupplier.java
new file mode 100644
index 000000000..768b81ce1
--- /dev/null
+++ b/tests/examples/java-dsl-only/src/main/java/org/apache/karaf/camel/examples/test/CamelExampleRouteSecondSupplier.java
@@ -0,0 +1,35 @@
+/**
+ * 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.karaf.camel.examples.test;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.karaf.camel.itests.CamelRouteSupplier;
+import org.osgi.service.component.annotations.Component;
+
+@Component(
+ name = "camel-karaf-examples-java-dsl-only-test-2",
+ immediate = true,
+ service = CamelRouteSupplier.class
+)
+public class CamelExampleRouteSecondSupplier implements CamelRouteSupplier {
+ @Override
+ public void createRoutes(RouteBuilder builder) {
+ builder.from("direct:example2")
+ .to("mock:example2");
+ }
+}
diff --git a/tests/examples/java-dsl-only/src/test/java/org/apache/karaf/camel/examples/itest/CamelJavaExampleFirstOnlyTest.java b/tests/examples/java-dsl-only/src/test/java/org/apache/karaf/camel/examples/itest/CamelJavaExampleFirstOnlyTest.java
new file mode 100644
index 000000000..69d4df296
--- /dev/null
+++ b/tests/examples/java-dsl-only/src/test/java/org/apache/karaf/camel/examples/itest/CamelJavaExampleFirstOnlyTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.apache.karaf.camel.examples.itest;
+
+import java.util.List;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.karaf.camel.itests.AbstractCamelRouteWithBundleITest;
+import org.apache.karaf.camel.itests.CamelKarafTestHint;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+
+@CamelKarafTestHint(camelRouteSuppliers = "camel-karaf-examples-java-dsl-only-test-1")
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class CamelJavaExampleFirstOnlyTest extends AbstractCamelRouteWithBundleITest {
+
+ @Override
+ protected List getRequiredFeatures() {
+ return List.of();
+ }
+
+ @Override
+ protected String getTestBundleName() {
+ return "camel-karaf-examples-java-dsl-only-test";
+ }
+
+ @Test
+ public void testJavaDSL() throws Exception {
+ Endpoint endpoint = getContext().hasEndpoint("direct:example1");
+ assertNotNull(endpoint);
+ MockEndpoint mock = getContext().getEndpoint("mock:example1", MockEndpoint.class);
+ mock.expectedBodiesReceived("Hello World");
+ getTemplate().sendBody("direct:example1", "Hello World");
+ mock.assertIsSatisfied();
+ assertNull("The second route supplier should be ignored", getContext().hasEndpoint("direct:example2"));
+ }
+}
\ No newline at end of file
diff --git a/tests/examples/java-dsl-only/src/test/java/org/apache/karaf/camel/examples/itest/CamelJavaExampleWithBothTest.java b/tests/examples/java-dsl-only/src/test/java/org/apache/karaf/camel/examples/itest/CamelJavaExampleWithBothTest.java
new file mode 100644
index 000000000..e7281ce92
--- /dev/null
+++ b/tests/examples/java-dsl-only/src/test/java/org/apache/karaf/camel/examples/itest/CamelJavaExampleWithBothTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.apache.karaf.camel.examples.itest;
+
+import java.util.List;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.karaf.camel.itests.AbstractCamelRouteWithBundleITest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import static org.junit.Assert.assertNotNull;
+
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class CamelJavaExampleWithBothTest extends AbstractCamelRouteWithBundleITest {
+
+ @Override
+ protected List getRequiredFeatures() {
+ return List.of();
+ }
+
+ @Override
+ protected String getTestBundleName() {
+ return "camel-karaf-examples-java-dsl-only-test";
+ }
+
+ @Test
+ public void testJavaDSL1() throws Exception {
+ verify(1);
+ }
+
+
+ @Test
+ public void testJavaDSL2() throws Exception {
+ verify(2);
+ }
+
+ private void verify(int id) throws InterruptedException {
+ Endpoint endpoint = getContext().hasEndpoint("direct:example%d".formatted(id));
+ assertNotNull(endpoint);
+ MockEndpoint mock = getContext().getEndpoint("mock:example%d".formatted(id), MockEndpoint.class);
+ mock.expectedBodiesReceived("Hello World");
+ getTemplate().sendBody("direct:example%d".formatted(id), "Hello World");
+ mock.assertIsSatisfied();
+ }
+}
\ No newline at end of file
diff --git a/tests/examples/mixed/pom.xml b/tests/examples/mixed/pom.xml
new file mode 100644
index 000000000..0edbcb5d8
--- /dev/null
+++ b/tests/examples/mixed/pom.xml
@@ -0,0 +1,32 @@
+
+
+
+ 4.0.0
+
+ org.apache.camel.karaf
+ camel-karaf-examples-test
+ 4.6.0-SNAPSHOT
+
+
+ camel-karaf-examples-mixed-test
+ Apache Camel :: Karaf :: Tests :: Samples :: Mixed
+
\ No newline at end of file
diff --git a/tests/examples/mixed/src/main/java/org/apache/karaf/camel/examples/test/CamelExampleRouteSupplier.java b/tests/examples/mixed/src/main/java/org/apache/karaf/camel/examples/test/CamelExampleRouteSupplier.java
new file mode 100644
index 000000000..3f36a95e4
--- /dev/null
+++ b/tests/examples/mixed/src/main/java/org/apache/karaf/camel/examples/test/CamelExampleRouteSupplier.java
@@ -0,0 +1,73 @@
+/**
+ * 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.karaf.camel.examples.test;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.karaf.camel.itests.CamelRouteSupplier;
+import org.osgi.service.component.annotations.Component;
+
+@Component(
+ name = "camel-karaf-examples-mixed-test",
+ immediate = true,
+ service = CamelRouteSupplier.class
+)
+public class CamelExampleRouteSupplier implements CamelRouteSupplier {
+ @Override
+ public void createRoutes(RouteBuilder builder) {
+ builder.fromF("jetty:http://0.0.0.0:%s/example", System.getProperty("java.dsl.jetty.port"))
+ .id("example-http-inbound")
+ .convertBodyTo(String.class)
+ .log("[EXAMPLE INBOUND] Received: ${body}")
+ .choice()
+ .when().simple("${headers.CamelHttpMethod} == 'POST'")
+ .setHeader("type").jsonpath("$.notification.type")
+ .choice()
+ .when().simple("${header.type} == 'email'")
+ .log("[EXAMPLE INBOUND] Received email notification")
+ .to("direct:email")
+ .setHeader("Exchange.HTTP_RESPONSE_CODE", builder.constant(200))
+ .when().simple("${header.type} == 'http'")
+ .log("[EXAMPLE INBOUND] Received http notification")
+ .to("direct:http")
+ .setHeader("Exchange.HTTP_RESPONSE_CODE", builder.constant(200))
+ .otherwise()
+ .log("[EXAMPLE INBOUND] Unknown notification")
+ .setBody(builder.constant("{ \"status\": \"reject\", \"type\": \"unknown\" }"))
+ .setHeader("Exchange.HTTP_RESPONSE_CODE", builder.constant(400))
+ .otherwise()
+ .log("[EXAMPLE INBOUND] only POST is accepted (${headers.CamelHttpMethod})")
+ .setBody(builder.constant("{ \"error\": \"only POST is accepted\" }"))
+ .setHeader("Exchange.HTTP_RESPONSE_CODE", builder.constant(500));
+
+ builder.from("direct:email")
+ .id("example-email")
+ .log("[EXAMPLE EMAIL] Sending notification email")
+ .setHeader("to").jsonpath("$.notification.to")
+ .setHeader("subject", builder.constant("Notification"))
+ .setHeader("payload").jsonpath("$.notification.message")
+ //.to("smtp://localhost");
+ .setBody(builder.simple("{ \"status\": \"email sent\", \"to\": \"${header.to}\", \"subject\": \"${header.subject}\" }"));
+
+ builder.from("direct:http")
+ .id("example-http")
+ .log("[EXAMPLE HTTP] Sending http notification")
+ .setHeader("service").jsonpath("$.notification.service")
+ // send to HTTP service
+ .setBody(builder.simple("{ \"status\": \"http requested\", \"service\": \"${header.service}\" }"));
+ }
+}
diff --git a/tests/examples/mixed/src/main/resources/OSGI-INF/blueprint/route.xml b/tests/examples/mixed/src/main/resources/OSGI-INF/blueprint/route.xml
new file mode 100644
index 000000000..60a0a1165
--- /dev/null
+++ b/tests/examples/mixed/src/main/resources/OSGI-INF/blueprint/route.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+ ${headers.CamelHttpMethod} == 'POST'
+
+ $.notification.type
+
+
+
+ ${header.type} == 'email'
+
+
+ 200
+
+
+ ${header.type} == 'http'
+
+
+ 200
+
+
+
+ { "status": "reject", "type": "unknown" }
+ 400
+
+
+
+
+
+ { "error": "only POST is accepted" }
+ 500
+
+
+
+
+
+
+ $.notification.to
+ Notification
+ $.notification.message
+
+ { "status": "email sent", "to": "${header.to}", "subject": "${header.subject}" }
+
+
+
+
+ $.notification.service
+
+ { "status": "http requested", "service": "${header.service}" }
+
+
+
\ No newline at end of file
diff --git a/tests/examples/mixed/src/test/java/org/apache/karaf/camel/examples/itest/CamelExampleTest.java b/tests/examples/mixed/src/test/java/org/apache/karaf/camel/examples/itest/CamelExampleTest.java
new file mode 100644
index 000000000..99dd98506
--- /dev/null
+++ b/tests/examples/mixed/src/test/java/org/apache/karaf/camel/examples/itest/CamelExampleTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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.apache.karaf.camel.examples.itest;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.karaf.camel.itests.AbstractCamelRouteWithBundleITest;
+import org.apache.karaf.camel.itests.AvailablePortProvider;
+import org.apache.karaf.camel.itests.CamelKarafTestHint;
+import org.apache.karaf.camel.itests.PaxExamWithExternalResource;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import static org.junit.Assert.assertEquals;
+
+
+@CamelKarafTestHint(isBlueprintTest = true, externalResourceProvider = CamelExampleTest.ExternalResourceProviders.class)
+@RunWith(PaxExamWithExternalResource.class)
+@ExamReactorStrategy(PerClass.class)
+public class CamelExampleTest extends AbstractCamelRouteWithBundleITest {
+
+ public static final String BLUEPRINT_DSL_JETTY_PORT = "blueprint.dsl.jetty.port";
+ public static final String JAVA_DSL_JETTY_PORT = "java.dsl.jetty.port";
+
+ @Override
+ protected List getRequiredFeatures() {
+ return List.of("camel-jetty", "camel-jsonpath", "camel-mail");
+ }
+
+ @Override
+ protected String getTestBundleName() {
+ return "camel-karaf-examples-mixed-test";
+ }
+
+ @Test(timeout = 60000)
+ public void testBlueprintDSL() throws Exception {
+ verify(System.getProperty(BLUEPRINT_DSL_JETTY_PORT));
+ }
+
+ @Test(timeout = 60000)
+ public void testJavaDSL() throws Exception {
+ verify(System.getProperty(JAVA_DSL_JETTY_PORT));
+ }
+
+ private static void verify(String port) throws IOException {
+ URL url = new URL("http://localhost:%s/example".formatted(port));
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+
+ try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()))) {
+ writer.println("{ \"notification\": { \"type\": \"email\", \"to\": \"foo@bar.com\", \"message\": \"this is a test\" }}");
+ writer.flush();
+ }
+
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
+ String line;
+ StringBuilder buffer = new StringBuilder();
+ while ((line = reader.readLine()) != null) {
+ buffer.append(line);
+ }
+ assertEquals("{ \"status\": \"email sent\", \"to\": \"foo@bar.com\", \"subject\": \"Notification\" }", buffer.toString());
+ }
+
+ connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+
+ try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()))) {
+ writer.println("{ \"notification\": { \"type\": \"http\", \"service\": \"http://foo\" }}");
+ writer.flush();
+ }
+
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
+ StringBuilder buffer = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ buffer.append(line);
+ }
+ assertEquals("{ \"status\": \"http requested\", \"service\": \"http://foo\" }", buffer.toString());
+ }
+ }
+
+ public static final class ExternalResourceProviders {
+
+ public static AvailablePortProvider createAvailablePortProvider() {
+ return new AvailablePortProvider(List.of(BLUEPRINT_DSL_JETTY_PORT, JAVA_DSL_JETTY_PORT));
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/components/pom.xml b/tests/examples/pom.xml
similarity index 92%
rename from tests/components/pom.xml
rename to tests/examples/pom.xml
index ac03e8fd8..24071442e 100644
--- a/tests/components/pom.xml
+++ b/tests/examples/pom.xml
@@ -28,17 +28,14 @@
../pom.xml
- camel-karaf-components-test
+ camel-karaf-examples-test
pom
- Apache Camel :: Karaf :: Tests :: Components
-
-
- ${project.basedir}/../../camel-integration-test/src/main/resources
-
+ Apache Camel :: Karaf :: Tests :: Examples
- camel-file
- camel-seda
+ mixed
+ java-dsl-only
+ blueprint-dsl-only
@@ -160,7 +157,7 @@
-
+
org.apache.servicemix.tooling
depends-maven-plugin
@@ -181,7 +178,7 @@
- org.apache.karaf.camel.test;version=${camel.version}
+ org.apache.karaf.camel.examples.test;version=${project.version}
org.apache.camel*;${camel.osgi.import.camel.version},
@@ -231,8 +228,7 @@
${project.version}
${project.build.directory}
- ${integration.test.project.resources}
- ERROR
+ WARN
5
diff --git a/tests/features/camel-amqp/pom.xml b/tests/features/camel-amqp/pom.xml
new file mode 100644
index 000000000..9fcbc5b15
--- /dev/null
+++ b/tests/features/camel-amqp/pom.xml
@@ -0,0 +1,41 @@
+
+
+
+ 4.0.0
+
+ org.apache.camel.karaf
+ camel-karaf-features-test
+ 4.6.0-SNAPSHOT
+
+
+ camel-amqp-test
+ Apache Camel :: Karaf :: Tests :: Features :: AMQP
+
+
+
+ org.testcontainers
+ rabbitmq
+ ${testcontainers-version}
+ test
+
+
+
\ No newline at end of file
diff --git a/tests/features/camel-amqp/src/main/resources/OSGI-INF/blueprint/route.xml b/tests/features/camel-amqp/src/main/resources/OSGI-INF/blueprint/route.xml
new file mode 100644
index 000000000..8f98b9a65
--- /dev/null
+++ b/tests/features/camel-amqp/src/main/resources/OSGI-INF/blueprint/route.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This is header
+
+
+ Hello Camel
+
+
+
+
+
+
+
+
+
+
+ ${header.theHeader} != "This is header"
+
+
+
+
+
+
+
+
+
+ ${body} != "Hello Camel"
+
+
+
+
+
+
+
+
+ OK
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/features/camel-amqp/src/test/java/org/apache/karaf/camel/itest/CamelAmqpITest.java b/tests/features/camel-amqp/src/test/java/org/apache/karaf/camel/itest/CamelAmqpITest.java
new file mode 100644
index 000000000..bf190cb44
--- /dev/null
+++ b/tests/features/camel-amqp/src/test/java/org/apache/karaf/camel/itest/CamelAmqpITest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.apache.karaf.camel.itest;
+
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.karaf.camel.itests.AbstractCamelSingleFeatureResultMockBasedRouteITest;
+import org.apache.karaf.camel.itests.CamelKarafTestHint;
+import org.apache.karaf.camel.itests.GenericContainerResource;
+import org.apache.karaf.camel.itests.PaxExamWithExternalResource;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.testcontainers.containers.RabbitMQContainer;
+
+
+@CamelKarafTestHint(
+ externalResourceProvider = CamelAmqpITest.ExternalResourceProviders.class,
+ isBlueprintTest = true)
+@RunWith(PaxExamWithExternalResource.class)
+@ExamReactorStrategy(PerClass.class)
+public class CamelAmqpITest extends AbstractCamelSingleFeatureResultMockBasedRouteITest {
+
+ @Override
+ public void configureMock(MockEndpoint mock) {
+ mock.expectedBodiesReceived("OK");
+ }
+
+ @Test
+ public void testResultMock() throws Exception {
+ assertMockEndpointsSatisfied();
+ }
+
+ public static final class ExternalResourceProviders {
+ private static final String PASSWORD = "s3cret";
+
+ public static GenericContainerResource createRabbitMQContainer() {
+ final RabbitMQContainer rabbitMQContainer =
+ new RabbitMQContainer("rabbitmq:3.13.1")
+ .withAdminPassword(PASSWORD);
+ return new GenericContainerResource<>(rabbitMQContainer,
+ resource -> {
+ try {
+ rabbitMQContainer.execInContainer("rabbitmq-plugins", "enable", "rabbitmq_amqp1_0");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ resource.setProperty("amqp.host", rabbitMQContainer.getHost());
+ resource.setProperty("amqp.port", Integer.toString(rabbitMQContainer.getAmqpPort()));
+ resource.setProperty("amqp.username", rabbitMQContainer.getAdminUsername());
+ resource.setProperty("amqp.password", rabbitMQContainer.getAdminPassword());
+ }
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/components/camel-file/pom.xml b/tests/features/camel-core/pom.xml
similarity index 87%
rename from tests/components/camel-file/pom.xml
rename to tests/features/camel-core/pom.xml
index 00ed971be..00959e4da 100644
--- a/tests/components/camel-file/pom.xml
+++ b/tests/features/camel-core/pom.xml
@@ -23,14 +23,12 @@
4.0.0
org.apache.camel.karaf
- camel-karaf-components-test
+ camel-karaf-features-test
4.6.0-SNAPSHOT
../pom.xml
- camel-file-test
- Apache Camel :: Karaf :: Tests :: Components :: File
-
-
+ camel-core-test
+ Apache Camel :: Karaf :: Tests :: Features :: Core
\ No newline at end of file
diff --git a/tests/components/camel-file/src/main/java/org/apache/karaf/camel/test/CamelFileComponent.java b/tests/features/camel-core/src/main/java/org/apache/karaf/camel/test/CamelFileRouteSupplier.java
similarity index 84%
rename from tests/components/camel-file/src/main/java/org/apache/karaf/camel/test/CamelFileComponent.java
rename to tests/features/camel-core/src/main/java/org/apache/karaf/camel/test/CamelFileRouteSupplier.java
index 2a7b0f5b9..93b0d832b 100644
--- a/tests/components/camel-file/src/main/java/org/apache/karaf/camel/test/CamelFileComponent.java
+++ b/tests/features/camel-core/src/main/java/org/apache/karaf/camel/test/CamelFileRouteSupplier.java
@@ -19,13 +19,15 @@
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.RouteDefinition;
-import org.apache.karaf.camel.itests.AbstractCamelComponentResultFileBased;
+import org.apache.karaf.camel.itests.AbstractCamelSingleFeatureResultFileBasedRouteSupplier;
+import org.apache.karaf.camel.itests.CamelRouteSupplier;
import org.osgi.service.component.annotations.Component;
@Component(
name = "karaf-camel-file-test",
- immediate = true
+ immediate = true,
+ service = CamelRouteSupplier.class
)
-public class CamelFileComponent extends AbstractCamelComponentResultFileBased {
+public class CamelFileRouteSupplier extends AbstractCamelSingleFeatureResultFileBasedRouteSupplier {
@Override
protected Function consumerRoute() {
@@ -39,6 +41,4 @@ protected void configureProducer(RouteBuilder builder, RouteDefinition producerR
.setBody(builder.constant("OK")) // Set the body of the message to "OK"
.toF("file:%s?fileName=testResult.txt", getBaseDir());
}
-
-
}
\ No newline at end of file
diff --git a/tests/components/camel-seda/src/main/java/org/apache/karaf/camel/test/CamelSedaComponent.java b/tests/features/camel-core/src/main/java/org/apache/karaf/camel/test/CamelSedaRouteSupplier.java
similarity index 55%
rename from tests/components/camel-seda/src/main/java/org/apache/karaf/camel/test/CamelSedaComponent.java
rename to tests/features/camel-core/src/main/java/org/apache/karaf/camel/test/CamelSedaRouteSupplier.java
index b5626f12c..527a21c48 100644
--- a/tests/components/camel-seda/src/main/java/org/apache/karaf/camel/test/CamelSedaComponent.java
+++ b/tests/features/camel-core/src/main/java/org/apache/karaf/camel/test/CamelSedaRouteSupplier.java
@@ -1,32 +1,36 @@
-/*
+/**
* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
+ * 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.
+ * 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.karaf.camel.test;
import java.util.function.Function;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.RouteDefinition;
-import org.apache.karaf.camel.itests.AbstractCamelComponentResultMockBased;
+import org.apache.karaf.camel.itests.AbstractCamelSingleFeatureResultMockBasedRouteSupplier;
+import org.apache.karaf.camel.itests.CamelRouteSupplier;
import org.osgi.service.component.annotations.Component;
@Component(
name = "karaf-camel-seda-test",
- immediate = true
+ immediate = true,
+ service = CamelRouteSupplier.class
)
-public class CamelSedaComponent extends AbstractCamelComponentResultMockBased {
+public class CamelSedaRouteSupplier extends AbstractCamelSingleFeatureResultMockBasedRouteSupplier {
@Override
protected Function consumerRoute() {
@@ -40,4 +44,4 @@ protected void configureProducer(RouteBuilder builder, RouteDefinition producerR
// send it to the seda queue that is async
.to("seda:next");
}
-}
\ No newline at end of file
+}
diff --git a/tests/features/camel-core/src/test/java/org/apache/karaf/camel/itest/CamelCoreITest.java b/tests/features/camel-core/src/test/java/org/apache/karaf/camel/itest/CamelCoreITest.java
new file mode 100644
index 000000000..5a2648ab5
--- /dev/null
+++ b/tests/features/camel-core/src/test/java/org/apache/karaf/camel/itest/CamelCoreITest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.apache.karaf.camel.itest;
+
+import java.util.List;
+
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.karaf.camel.itests.AbstractCamelRouteWithBundleITest;
+import org.apache.karaf.camel.itests.AbstractCamelSingleFeatureResultFileBasedRoute;
+import org.apache.karaf.camel.itests.AbstractCamelSingleFeatureResultMockBasedRoute;
+import org.apache.karaf.camel.itests.CamelContextProvider;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class CamelCoreITest extends AbstractCamelRouteWithBundleITest {
+
+ @Override
+ protected String getTestBundleName() {
+ return "camel-core-test";
+ }
+
+ @Override
+ protected List getRequiredFeatures() {
+ return List.of();
+ }
+
+ @Test
+ public void testCamelFile() throws Exception {
+ new CamelFileITest(this, getBaseDir()).testRoutes();
+ }
+
+ @Test
+ public void testCamelSeda() throws Exception {
+ new CamelSedaITest(this).testRoutes();
+ }
+
+ public static class CamelFileITest extends AbstractCamelSingleFeatureResultFileBasedRoute {
+
+ public CamelFileITest(CamelContextProvider provider, String baseDir) {
+ super(provider, baseDir);
+ }
+
+ @Override
+ protected void executeTest() throws Exception {
+ assertResultFileContains("OK");
+ }
+ }
+
+ public static class CamelSedaITest extends AbstractCamelSingleFeatureResultMockBasedRoute {
+
+ public CamelSedaITest(CamelContextProvider provider) {
+ super(provider);
+ }
+
+ @Override
+ public void configureMock(MockEndpoint mock) {
+ mock.expectedBodiesReceived("OK");
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/features/camel-elasticsearch/pom.xml b/tests/features/camel-elasticsearch/pom.xml
new file mode 100644
index 000000000..c356faf4f
--- /dev/null
+++ b/tests/features/camel-elasticsearch/pom.xml
@@ -0,0 +1,49 @@
+
+
+
+ 4.0.0
+
+ org.apache.camel.karaf
+ camel-karaf-features-test
+ 4.6.0-SNAPSHOT
+ ../pom.xml
+
+
+ camel-elasticsearch-test
+ Apache Camel :: Karaf :: Tests :: Features :: ElasticSearch Java API Client
+
+
+
+ org.apache.camel
+ camel-elasticsearch
+ ${camel.version}
+
+
+ org.testcontainers
+ elasticsearch
+ ${testcontainers-version}
+ test
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/features/camel-elasticsearch/src/main/java/org/apache/karaf/camel/test/CamelElasticsearchRouteSupplier.java b/tests/features/camel-elasticsearch/src/main/java/org/apache/karaf/camel/test/CamelElasticsearchRouteSupplier.java
new file mode 100644
index 000000000..cb340416d
--- /dev/null
+++ b/tests/features/camel-elasticsearch/src/main/java/org/apache/karaf/camel/test/CamelElasticsearchRouteSupplier.java
@@ -0,0 +1,80 @@
+/*
+ * 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.karaf.camel.test;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.es.ElasticsearchComponent;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.karaf.camel.itests.AbstractCamelSingleFeatureResultMockBasedRouteSupplier;
+import org.apache.karaf.camel.itests.CamelRouteSupplier;
+import org.osgi.service.component.annotations.Component;
+
+@Component(name = "karaf-camel-elasticsearch-test", immediate = true, service = CamelRouteSupplier.class)
+public class CamelElasticsearchRouteSupplier extends AbstractCamelSingleFeatureResultMockBasedRouteSupplier {
+
+ private static final String INDEX_NAME = "testindex";
+
+ @Override
+ public void configure(CamelContext camelContext) {
+ final ElasticsearchComponent elasticsearchComponent = new ElasticsearchComponent();
+ elasticsearchComponent.setEnableSSL(true);
+ elasticsearchComponent.setHostAddresses(
+ "%s:%s".formatted(System.getProperty("elasticsearch.host"), System.getProperty("elasticsearch.port"))
+ );
+ elasticsearchComponent.setUser(System.getProperty("elasticsearch.username"));
+ elasticsearchComponent.setPassword(System.getProperty("elasticsearch.password"));
+ elasticsearchComponent.setCertificatePath("file:%s".formatted(System.getProperty("elasticsearch.cafile")));
+
+ camelContext.addComponent("elasticsearch",elasticsearchComponent);
+ }
+
+ @Override
+ protected void configureProducer(RouteBuilder builder, RouteDefinition producerRoute) {
+ //to add the mock endpoint at the end of the route, call configureConsumer
+ configureConsumer(
+ producerRoute.toF("elasticsearch://elasticsearch?operation=Exists&indexName=%s", INDEX_NAME)
+ .log("Index exist: ${body}")
+ .setBody(builder.simple("""
+ {"date": "${header.CamelTimerFiredTime}", "someKey": "someValue"}
+ """))
+ .toF("elasticsearch://elasticsearch?operation=Index&indexName=%s", INDEX_NAME)
+ .log("Index doc : ${body}")
+ .setHeader("_ID", builder.simple("${body}"))
+ .toF("elasticsearch://elasticsearch?operation=GetById&indexName=%s", INDEX_NAME)
+ .log("Get doc: ${body}")
+ .setHeader("indexId", builder.simple("${header._ID}"))
+ .setBody(builder.constant("""
+ {"doc": {"someKey": "someValue2"}}
+ """))
+ .toF("elasticsearch://elasticsearch?operation=Update&indexName=%s", INDEX_NAME)
+ .log("Update doc: ${body} ")
+ .setBody(builder.simple("${header._ID}"))
+ .toF("elasticsearch://elasticsearch?operation=GetById&indexName=%s", INDEX_NAME)
+ .log("Get doc: ${body}")
+ .setBody(builder.simple("${header._ID}"))
+ .toF("elasticsearch://elasticsearch?operation=Delete&indexName=%s", INDEX_NAME)
+ .log("Delete doc: ${body}")
+ .setBody(builder.constant("OK"))
+ );
+
+ }
+
+ @Override
+ protected boolean consumerEnabled() {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/tests/features/camel-elasticsearch/src/test/java/org/apache/karaf/camel/itest/CamelElasticsearchITest.java b/tests/features/camel-elasticsearch/src/test/java/org/apache/karaf/camel/itest/CamelElasticsearchITest.java
new file mode 100644
index 000000000..6a45f89c1
--- /dev/null
+++ b/tests/features/camel-elasticsearch/src/test/java/org/apache/karaf/camel/itest/CamelElasticsearchITest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.apache.karaf.camel.itest;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.time.Duration;
+
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.karaf.camel.itests.AbstractCamelSingleFeatureResultMockBasedRouteITest;
+import org.apache.karaf.camel.itests.CamelKarafTestHint;
+import org.apache.karaf.camel.itests.GenericContainerResource;
+import org.apache.karaf.camel.itests.PaxExamWithExternalResource;
+import org.apache.karaf.camel.itests.TemporaryFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
+import org.testcontainers.elasticsearch.ElasticsearchContainer;
+
+@CamelKarafTestHint(externalResourceProvider = CamelElasticsearchITest.ExternalResourceProviders.class)
+@RunWith(PaxExamWithExternalResource.class)
+@ExamReactorStrategy(PerClass.class)
+public class CamelElasticsearchITest extends AbstractCamelSingleFeatureResultMockBasedRouteITest {
+
+ @Override
+ public void configureMock(MockEndpoint mock) {
+ mock.expectedBodiesReceived("OK");
+ }
+
+ @Test
+ public void testResultMock() throws Exception {
+ assertMockEndpointsSatisfied();
+ }
+
+ public static final class ExternalResourceProviders {
+
+ private static final String USER_NAME = "elastic";
+ private static final String PASSWORD = "s3cret";
+ private static final int ELASTIC_SEARCH_PORT = 9200;
+
+ public static GenericContainerResource createElasticsearchContainer() {
+ final ElasticsearchContainer elasticsearchContainer =
+ new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:8.11.1").withPassword(PASSWORD);
+ // Increase the timeout from 60 seconds to 90 seconds to ensure that it will be long enough
+ // on the build pipeline
+ elasticsearchContainer.setWaitStrategy(
+ new LogMessageWaitStrategy()
+ .withRegEx(".*(\"message\":\\s?\"started[\\s?|\"].*|] started\n$)")
+ .withStartupTimeout(Duration.ofSeconds(90)));
+ return new GenericContainerResource<>(elasticsearchContainer,
+ resource -> {
+ resource.getContainer().caCertAsBytes().ifPresent(content -> {
+ try {
+ TemporaryFile tempFile = new TemporaryFile("elasticsearch.cafile", "http_ca", ".crt");
+ Files.write(tempFile.getPath(), content);
+ resource.addDependency(tempFile);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ resource.setProperty("elasticsearch.host", elasticsearchContainer.getHost());
+ resource.setProperty("elasticsearch.port", Integer.toString(elasticsearchContainer.getMappedPort(ELASTIC_SEARCH_PORT)));
+ resource.setProperty("elasticsearch.username", USER_NAME);
+ resource.setProperty("elasticsearch.password", PASSWORD);
+ }
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/components/camel-seda/pom.xml b/tests/features/camel-jetty/pom.xml
similarity index 87%
rename from tests/components/camel-seda/pom.xml
rename to tests/features/camel-jetty/pom.xml
index 152053086..63a399b89 100644
--- a/tests/components/camel-seda/pom.xml
+++ b/tests/features/camel-jetty/pom.xml
@@ -23,12 +23,12 @@
4.0.0
org.apache.camel.karaf
- camel-karaf-components-test
+ camel-karaf-features-test
4.6.0-SNAPSHOT
- camel-seda-test
- Apache Camel :: Karaf :: Tests :: Components :: Seda
+ camel-jetty-test
+ Apache Camel :: Karaf :: Tests :: Features :: Jetty
\ No newline at end of file
diff --git a/tests/features/camel-jetty/src/main/java/org/apache/karaf/camel/test/CamelJettyRouteSupplier.java b/tests/features/camel-jetty/src/main/java/org/apache/karaf/camel/test/CamelJettyRouteSupplier.java
new file mode 100644
index 000000000..7e9442bfc
--- /dev/null
+++ b/tests/features/camel-jetty/src/main/java/org/apache/karaf/camel/test/CamelJettyRouteSupplier.java
@@ -0,0 +1,72 @@
+/*
+ * 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.karaf.camel.test;
+
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.function.Function;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.karaf.camel.itests.AbstractCamelSingleFeatureResultMockBasedRouteSupplier;
+import org.apache.karaf.camel.itests.CamelRouteSupplier;
+import org.apache.karaf.camel.itests.Utils;
+import org.osgi.service.component.annotations.Component;
+
+@Component(
+ name = "karaf-camel-jetty-test",
+ immediate = true,
+ service = CamelRouteSupplier.class
+)
+public class CamelJettyRouteSupplier extends AbstractCamelSingleFeatureResultMockBasedRouteSupplier {
+
+ private final int port = Utils.getNextAvailablePort();
+
+ @Override
+ protected Function consumerRoute() {
+ return builder -> builder.from("jetty://http://localhost:%s/jettyTest".formatted(port)).transform(builder.constant("OK"));
+ }
+
+ @Override
+ protected void configureProducer(RouteBuilder builder, RouteDefinition producerRoute) {
+ producerRoute.log("calling http endpoint")
+ .process(new HttpClientProcessor());
+ }
+
+ class HttpClientProcessor implements Processor {
+
+ @Override
+ public void process(Exchange exchange) throws Exception {
+
+ HttpClient client = HttpClient.newHttpClient();
+
+ // Create a URI for the request
+ URI uri = URI.create("http://localhost:%s/jettyTest".formatted(port));
+
+ // Create a HttpRequest
+ HttpRequest request = HttpRequest.newBuilder()
+ .uri(uri)
+ .build();
+
+ client.send(request, HttpResponse.BodyHandlers.ofString());
+ }
+ }
+}
+
diff --git a/tests/components/camel-seda/src/test/java/org/apache/karaf/camel/itests/CamelSedaITest.java b/tests/features/camel-jetty/src/test/java/org/apache/karaf/camel/itest/CamelJettyITest.java
similarity index 73%
rename from tests/components/camel-seda/src/test/java/org/apache/karaf/camel/itests/CamelSedaITest.java
rename to tests/features/camel-jetty/src/test/java/org/apache/karaf/camel/itest/CamelJettyITest.java
index de76109a6..d5e743dd1 100644
--- a/tests/components/camel-seda/src/test/java/org/apache/karaf/camel/itests/CamelSedaITest.java
+++ b/tests/features/camel-jetty/src/test/java/org/apache/karaf/camel/itest/CamelJettyITest.java
@@ -11,22 +11,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.karaf.camel.itests;
+package org.apache.karaf.camel.itest;
import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.karaf.camel.itests.AbstractCamelSingleFeatureResultMockBasedRouteITest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.PaxExam;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
-import org.ops4j.pax.exam.spi.reactors.PerSuite;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
@RunWith(PaxExam.class)
-@ExamReactorStrategy(PerSuite.class)
-public class CamelSedaITest extends AbstractCamelKarafResultMockBasedITest {
+@ExamReactorStrategy(PerClass.class)
+public class CamelJettyITest extends AbstractCamelSingleFeatureResultMockBasedRouteITest {
@Override
- protected void configureMock(MockEndpoint mock) {
+ public void configureMock(MockEndpoint mock) {
mock.expectedBodiesReceived("OK");
}
diff --git a/tests/features/pom.xml b/tests/features/pom.xml
new file mode 100644
index 000000000..451b6745c
--- /dev/null
+++ b/tests/features/pom.xml
@@ -0,0 +1,248 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.camel.karaf
+ camel-karaf-tests
+ 4.6.0-SNAPSHOT
+ ../pom.xml
+
+
+ camel-karaf-features-test
+ pom
+ Apache Camel :: Karaf :: Tests :: Features
+
+
+ ${project.basedir}/../../camel-integration-test/src/main/resources/etc/users.properties
+
+
+
+ camel-amqp
+ camel-core
+ camel-elasticsearch
+ camel-jetty
+
+
+
+
+
+ org.apache.karaf
+ karaf-bom
+ ${karaf.version}
+ pom
+ import
+
+
+ org.apache.karaf.itests
+ common
+ ${karaf.version}
+ test
+
+
+
+
+
+
+ org.apache.camel.karaf
+ camel-integration-test
+ ${project.version}
+ compile
+
+
+ org.apache.camel.karaf
+ camel-core-osgi
+ ${project.version}
+ provided
+
+
+ org.apache.camel
+ camel-core-engine
+ ${camel.version}
+ provided
+
+
+ org.apache.camel
+ camel-mock
+ ${camel.version}
+ provided
+
+
+
+ org.apache.camel.karaf
+ camel-api
+ ${project.version}
+ provided
+
+
+ org.osgi
+ osgi.core
+ provided
+
+
+ org.osgi
+ org.osgi.service.component
+ provided
+
+
+ org.osgi
+ org.osgi.service.component.annotations
+ provided
+
+
+
+ org.apache.karaf.itests
+ common
+ test
+
+
+
+ org.apache.karaf
+ apache-karaf
+ test
+ tar.gz
+
+
+ org.apache.karaf
+ org.apache.karaf.client
+
+
+
+
+
+ org.apache.karaf.shell
+ org.apache.karaf.shell.core
+ test
+
+
+
+ org.ops4j.pax.exam
+ pax-exam-container-karaf
+ test
+
+
+
+ org.ops4j.pax.exam
+ pax-exam-junit4
+
+
+ org.apache.geronimo.specs
+ geronimo-atinject_1.0_spec
+ test
+
+
+ org.awaitility
+ awaitility
+
+
+ org.apache.servicemix.bundles
+ org.apache.servicemix.bundles.hamcrest
+ runtime
+
+
+
+
+
+
+
+ org.apache.servicemix.tooling
+ depends-maven-plugin
+
+
+ generate-depends-file
+
+ generate-depends-file
+
+
+
+
+
+ org.apache.felix
+ maven-bundle-plugin
+ true
+ true
+
+
+
+ org.apache.karaf.camel.test;version=${project.version}
+
+
+ org.apache.camel*;${camel.osgi.import.camel.version},
+ *
+
+
+
+
+
+ cleanVersions
+ generate-sources
+
+ cleanVersions
+
+
+
+ ${project.version}
+
+
+
+
+ bundle
+ package
+
+ bundle
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ default-test
+
+ test
+
+ integration-test
+
+
+ none
+
+
+ **/*Test.java
+
+
+ ${project.version}
+ ${project.version}
+ ${project.build.directory}
+ ${users.file.location}
+ WARN
+
+ 5
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/pom.xml b/tests/pom.xml
index 3cc280261..b9097d1c1 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -35,8 +35,8 @@
camel-test-scr
camel-integration-test
- components
-
+ features
+ examples
\ No newline at end of file