This is an automated email from the ASF dual-hosted git repository.
fmariani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new cb315d5e2289 CAMEL-22292: Add --infra option to camel cmd send for
infrastructure services (#20767)
cb315d5e2289 is described below
commit cb315d5e22893983153c2f3ca0cf7759b8975748
Author: Pranjul Kalsi <[email protected]>
AuthorDate: Fri Jan 23 15:51:23 2026 +0530
CAMEL-22292: Add --infra option to camel cmd send for infrastructure
services (#20767)
* CAMEL-22292: Add --infra option to camel cmd send for infrastructure
services
* CAMEL-22292: camel send --infra refinements and add unit test
* CAMEL-22292: Refactor and add tests for camel send --infra option
* CAMEL-22292: Include credentials in InfraService endpointUri, remove
workarounds
* CAMEL-22292: Minor cleanup
* update correct version
---
.../modules/ROOT/pages/camel-jbang.adoc | 54 ++
.../pages/jbang-commands/camel-jbang-cmd-send.adoc | 1 +
.../META-INF/camel-jbang-commands-metadata.json | 2 +-
.../core/commands/action/CamelSendAction.java | 264 ++++++++-
.../commands/action/CamelSendActionInfraTest.java | 620 +++++++++++++++++++++
.../arangodb/services/ArangoDBInfraService.java | 8 +
.../artemis/services/ArtemisInfraService.java | 17 +
.../infra/aws/common/services/AWSInfraService.java | 8 +
.../azure/common/services/AzureInfraService.java | 12 +
.../cassandra/services/CassandraInfraService.java | 24 +
.../services/ChatScriptInfraService.java | 12 +
.../couchbase/services/CouchbaseInfraService.java | 9 +
.../couchdb/services/CouchDbInfraService.java | 13 +
.../docling/services/DoclingInfraService.java | 4 +
.../services/ElasticSearchInfraService.java | 15 +
.../test/infra/fhir/services/FhirInfraService.java | 7 +
.../test/infra/ftp/services/FtpInfraService.java | 9 +
.../pubsub/services/GooglePubSubInfraService.java | 9 +
.../vault/services/HashicorpVaultInfraService.java | 4 +
.../hazelcast/services/HazelcastInfraService.java | 8 +
.../infra/hivemq/services/HiveMQInfraService.java | 17 +
.../infra/ibmmq/services/IbmMQInfraService.java | 20 +
.../services/InfinispanInfraService.java | 5 +
.../keycloak/services/KeycloakInfraService.java | 20 +
.../lra/services/MicroprofileLRAInfraService.java | 8 +
.../infra/milvus/services/MilvusInfraService.java | 8 +
.../infra/minio/services/MinioInfraService.java | 4 +
.../mongodb/services/MongoDBInfraService.java | 6 +
.../mosquitto/services/MosquittoInfraService.java | 13 +
.../test/infra/nats/services/NatsInfraService.java | 5 +
.../infra/ollama/services/OllamaInfraService.java | 35 ++
.../openldap/services/OpenldapInfraService.java | 38 ++
.../postgres/services/PostgresInfraService.java | 32 ++
.../infra/pulsar/services/PulsarInfraService.java | 10 +
.../infra/qdrant/services/QdrantInfraService.java | 8 +
.../rabbitmq/services/RabbitMQInfraService.java | 24 +
.../infra/redis/services/RedisInfraService.java | 5 +
.../rocketmq/services/RocketMQInfraService.java | 4 +
.../test/infra/smb/services/SmbInfraService.java | 30 +
.../test/infra/solr/services/SolrInfraService.java | 10 +
.../services/TorchServeInfraService.java | 12 +
.../TorchServeLocalContainerInfraService.java | 5 +
.../test/infra/xmpp/services/XmppInfraService.java | 5 +
.../zookeeper/services/ZooKeeperInfraService.java | 13 +
44 files changed, 1434 insertions(+), 3 deletions(-)
diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
index 87ac3bd6a046..1421e00c100d 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
@@ -1550,6 +1550,60 @@ for components like Kafka or AWS. So for these you may
want to use a kamelet ins
$ camel cmd send --body=file:payload.json
--uri='kamelet:mqtt-sink?brokerUrl=tcp://mybroker:1883&topic=temperature'
----
+==== Sending messages to infrastructure services
+
+*Available since Camel 4.18*
+
+In Camel 4.17, you can use `camel cmd send` to send messages directly to
infrastructure services that are started with `camel infra run`.
+This eliminates the need to manually specify server connection details, as the
command automatically reads connection information from JSON files created by
infrastructure services.
+
+This is done by using the `--infra` option to specify which infrastructure
service to send to:
+
+[source,bash]
+----
+$ camel infra run nats
+$ camel cmd send --body=file:payload.json --infra=nats
+----
+
+The command automatically discovers the running infrastructure service, reads
its connection details from the JSON file (stored in `~/.camel/`), and
constructs the appropriate endpoint URI with the server information using the
Camel Catalog.
+
+===== Specifying a custom endpoint
+
+If you don't specify an `--endpoint`, the command automatically creates a
default endpoint based on the infrastructure service type (e.g.,
`kafka:default`, `nats:default`).
+
+You can also combine the `--infra` option with a specific endpoint to
customize the destination:
+
+[source,bash]
+----
+$ camel cmd send --endpoint='kafka:myTopic' --body=file:payload.json
--infra=kafka
+$ camel cmd send --endpoint='nats:mySubject' --body=file:payload.json
--infra=nats
+----
+
+NOTE: If your endpoint already contains query parameters (e.g.,
`kafka:myTopic?groupId=myGroup`), the connection details from the
infrastructure service will not override them.
+
+===== Automatic credential handling
+
+For services that support authentication (such as artemis, ftp, sftp), the
command automatically appends credentials from the connection details to the
endpoint URI if the Camel component supports them:
+
+[source,bash]
+----
+$ camel infra run artemis
+$ camel cmd send --endpoint='jms:myQueue' --body='Hello' --infra=artemis
+----
+
+The resulting endpoint will automatically include authentication parameters
like `username` and `password=RAW(...)`.
+
+===== Multiple service detection
+
+If multiple instances of the same infrastructure service are running, the
command will display an error and ask you to be more specific:
+
+[source,bash]
+----
+Multiple running infrastructure services found for: kafka. Found 2 services.
+----
+
+In this case, stop the unwanted service or specify the exact PID.
+
==== Poll messages via Camel
*Available since Camel 4.8*
diff --git
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-cmd-send.adoc
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-cmd-send.adoc
index 1a011d2ebaa5..a525a9003d2e 100644
---
a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-cmd-send.adoc
+++
b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-cmd-send.adoc
@@ -22,6 +22,7 @@ camel cmd send [options]
| `--body` | Message body to send (prefix with file: to refer to loading
message body from file) | | String
| `--endpoint,--uri` | Endpoint where to send the message (can be uri,
pattern, or refer to a route id) | | String
| `--header` | Message header (key=value) | | List
+| `--infra` | Send to infrastructure service (e.g., nats, kafka) | | String
| `--logging-color` | Use colored logging | true | boolean
| `--poll` | Poll instead of sending a message. This can be used to receive
latest message from a Kafka topic or JMS queue. | | boolean
| `--pretty` | Pretty print response message body (InOut) when using JSon or
XML format | | boolean
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
index 65955e46ff1a..bc094d14443a 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
+++
b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json
@@ -2,7 +2,7 @@
"commands": [
{ "name": "bind", "fullName": "bind", "description": "Bind source and sink
Kamelets as a new Camel integration", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.bind.Bind", "options": [ { "names":
"--error-handler", "description": "Add error handler
(none|log|sink:<endpoint>). Sink endpoints are expected in the format
[[apigroup\/]version:]kind:[namespace\/]name, plain Camel URIs or Kamelet
name.", "javaType": "java.lang.String", "type": "string" }, { "names":
"--output", "d [...]
{ "name": "catalog", "fullName": "catalog", "description": "List artifacts
from Camel Catalog", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.catalog.CatalogCommand", "options": [
{ "names": "-h,--help", "description": "Display the help and sub-commands",
"javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name":
"component", "fullName": "catalog component", "description": "List components
from the Camel Catalog", "sourceClass": "org.apache.camel.dsl.jbang.co [...]
- { "name": "cmd", "fullName": "cmd", "description": "Performs commands in
the running Camel integrations, such as start\/stop route, or change logging
levels.", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.action.CamelAction", "options": [ {
"names": "-h,--help", "description": "Display the help and sub-commands",
"javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name":
"browse", "fullName": "cmd browse", "description": "Browse pending messages on
endpoints [...]
+ { "name": "cmd", "fullName": "cmd", "description": "Performs commands in
the running Camel integrations, such as start\/stop route, or change logging
levels.", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.action.CamelAction", "options": [ {
"names": "-h,--help", "description": "Display the help and sub-commands",
"javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name":
"browse", "fullName": "cmd browse", "description": "Browse pending messages on
endpoints [...]
{ "name": "completion", "fullName": "completion", "description": "Generate
completion script for bash\/zsh", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.Complete", "options": [ { "names":
"-h,--help", "description": "Display the help and sub-commands", "javaType":
"boolean", "type": "boolean" } ] },
{ "name": "config", "fullName": "config", "description": "Get and set user
configuration values", "sourceClass":
"org.apache.camel.dsl.jbang.core.commands.config.ConfigCommand", "options": [ {
"names": "-h,--help", "description": "Display the help and sub-commands",
"javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "get",
"fullName": "config get", "description": "Display user configuration value",
"sourceClass": "org.apache.camel.dsl.jbang.core.commands.config. [...]
{ "name": "debug", "fullName": "debug", "description": "Debug local Camel
integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Debug",
"options": [ { "names": "--ago", "description": "Use ago instead of yyyy-MM-dd
HH:mm:ss in timestamp.", "javaType": "boolean", "type": "boolean" }, { "names":
"--background", "description": "Run in the background", "defaultValue":
"false", "javaType": "boolean", "type": "boolean" }, { "names":
"--background-wait", "description": "To [...]
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSendAction.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSendAction.java
index 2ddbeae59a23..747b8a6be403 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSendAction.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSendAction.java
@@ -18,17 +18,26 @@ package org.apache.camel.dsl.jbang.core.commands.action;
import java.io.File;
import java.io.IOException;
+import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
import org.apache.camel.dsl.jbang.core.commands.Run;
+import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
import org.apache.camel.dsl.jbang.core.common.PathUtils;
import org.apache.camel.main.KameletMain;
import org.apache.camel.util.StringHelper;
@@ -115,10 +124,16 @@ public class CamelSendAction extends ActionBaseCommand {
@CommandLine.Option(names = { "--logging-color" }, defaultValue = "true",
description = "Use colored logging")
boolean loggingColor = true;
+ @CommandLine.Option(names = { "--infra" },
+ description = "Send to infrastructure service (e.g.,
nats, kafka)")
+ String infra;
+
private volatile long pid;
private MessageTableHelper tableHelper;
+ private final CamelCatalog catalog = new DefaultCamelCatalog();
+
public CamelSendAction(CamelJBangMain main) {
super(main);
}
@@ -134,7 +149,9 @@ public class CamelSendAction extends ActionBaseCommand {
}
}
- if (name != null) {
+ if (infra != null) {
+ return doCallInfra(infra);
+ } else if (name != null) {
return doCall(name);
} else {
return doCallLocal();
@@ -361,7 +378,7 @@ public class CamelSendAction extends ActionBaseCommand {
c = Ansi.Color.RED;
} else if (replyFile != null) {
if (poll) {
- status = "Poll save to fill (success)";
+ status = "Poll save to file (success)";
} else {
status = "Reply save to file (success)";
}
@@ -386,4 +403,247 @@ public class CamelSendAction extends ActionBaseCommand {
}
}
+ private Integer doCallInfra(String infraService) throws Exception {
+ Map<Long, Path> infraPids = findInfraPids(infraService);
+
+ if (infraPids.isEmpty()) {
+ printer().println("No running infrastructure service found for: "
+ infraService);
+ return 1;
+ }
+
+ if (infraPids.size() > 1) {
+ printer().println("Multiple running infrastructure services found
for: " + infraService +
+ ". Found " + infraPids.size() + " services.");
+ return 1;
+ }
+
+ Map.Entry<Long, Path> entry = infraPids.entrySet().iterator().next();
+ Path jsonFile = entry.getValue();
+
+ JsonObject connectionDetails = readConnectionDetails(jsonFile);
+
+ if (connectionDetails == null) {
+ printer().println("Could not read connection details from: " +
jsonFile);
+ return 1;
+ }
+
+ String scheme = extractScheme(endpoint, infraService);
+
+ this.endpoint = updateEndpointWithConnectionDetails(endpoint,
infraService, connectionDetails);
+
+ Map<String, String> componentProps = buildComponentProperties(scheme,
connectionDetails);
+
+ Map<String, String> beanProps = buildBeanProperties(connectionDetails);
+
+ int additionalCount = componentProps.size() + beanProps.size();
+ if (additionalCount > 0) {
+ int existingCount = (property != null) ? property.length : 0;
+ String[] merged = new String[existingCount + additionalCount];
+ if (property != null) {
+ System.arraycopy(property, 0, merged, 0, existingCount);
+ }
+ int i = existingCount;
+ for (Map.Entry<String, String> compEntry :
componentProps.entrySet()) {
+ merged[i++] = "camel.component." + scheme + "." +
compEntry.getKey() + "=" + compEntry.getValue();
+ }
+ for (Map.Entry<String, String> beanEntry : beanProps.entrySet()) {
+ merged[i++] = beanEntry.getKey() + "=" + beanEntry.getValue();
+ }
+ property = merged;
+ }
+
+ return doCallLocal();
+ }
+
+ private String extractScheme(String endpoint, String infraService) {
+ if (endpoint != null && endpoint.contains(":")) {
+ return StringHelper.before(endpoint, ":");
+ }
+ return infraService;
+ }
+
+ private Map<Long, Path> findInfraPids(String serviceName) throws Exception
{
+ Map<Long, Path> pids = new HashMap<>();
+
+ Path camelDir = CommandLineHelper.getCamelDir();
+
+ try (Stream<Path> files = Files.list(camelDir)) {
+ List<Path> pidFiles = files
+ .filter(p -> {
+ String fileName = p.getFileName().toString();
+ return fileName.startsWith("infra-") &&
fileName.endsWith(".json");
+ })
+ .collect(Collectors.toList());
+
+ for (Path pidFile : pidFiles) {
+ String fileName = pidFile.getFileName().toString();
+ // Format: infra-{service}-{pid}.json
+ String withoutPrefix = fileName.substring("infra-".length());
+ String withoutExtension = withoutPrefix.substring(0,
withoutPrefix.lastIndexOf(".json"));
+
+ int lastDashIndex = withoutExtension.lastIndexOf('-');
+ if (lastDashIndex > 0) {
+ String service = withoutExtension.substring(0,
lastDashIndex);
+ String pidStr = withoutExtension.substring(lastDashIndex +
1);
+
+ if (service.equals(serviceName)) {
+ try {
+ long pid = Long.parseLong(pidStr);
+ pids.put(pid, pidFile);
+ } catch (NumberFormatException e) {
+ // Skip invalid PID
+ }
+ }
+ }
+ }
+ }
+
+ return pids;
+ }
+
+ private JsonObject readConnectionDetails(Path jsonFile) throws Exception {
+ String content = Files.readString(jsonFile);
+ return (JsonObject) Jsoner.deserialize(content);
+ }
+
+ String updateEndpointWithConnectionDetails(
+ String originalEndpoint, String infraService, JsonObject
connectionDetails) {
+
+ if (originalEndpoint == null) {
+ originalEndpoint = infraService + ":default";
+ }
+
+ if (originalEndpoint.contains("?")) {
+ return originalEndpoint;
+ }
+
+ String scheme;
+ String path;
+ if (originalEndpoint.contains(":")) {
+ scheme = StringHelper.before(originalEndpoint, ":");
+ path = StringHelper.after(originalEndpoint, ":");
+ } else {
+ scheme = originalEndpoint;
+ path = null;
+ }
+
+ String pathBasedEndpoint = buildPathBasedEndpoint(path,
connectionDetails);
+ if (pathBasedEndpoint != null) {
+ return pathBasedEndpoint;
+ }
+
+ Map<String, String> properties = buildPropertiesMap(scheme,
connectionDetails);
+
+ try {
+ String uri = catalog.asEndpointUri(scheme, properties, true);
+ if (uri != null && !uri.isEmpty()) {
+ String queryPart = "";
+ if (uri.contains("?")) {
+ queryPart = "?" + StringHelper.after(uri, "?");
+ }
+
+ if (path != null && !path.isEmpty()) {
+ return scheme + ":" + path + queryPart;
+ } else {
+ return uri;
+ }
+ }
+ } catch (URISyntaxException e) {
+ // Fall back to manual construction if catalog fails
+ }
+
+ return buildEndpointManually(originalEndpoint, properties);
+ }
+
+ private Map<String, String> buildBeanProperties(JsonObject
connectionDetails) {
+ Map<String, String> properties = new LinkedHashMap<>();
+
+ Object beanProps = connectionDetails.get("beanProperties");
+ if (beanProps instanceof Map<?, ?> beanMap) {
+ for (Map.Entry<?, ?> entry : beanMap.entrySet()) {
+ if (entry.getKey() != null && entry.getValue() != null) {
+ properties.put(String.valueOf(entry.getKey()),
String.valueOf(entry.getValue()));
+ }
+ }
+ }
+
+ return properties;
+ }
+
+ private Map<String, String> buildComponentProperties(String scheme,
JsonObject connectionDetails) {
+ Map<String, String> properties = new LinkedHashMap<>();
+
+ var componentModel = catalog.componentModel(scheme);
+ if (componentModel != null) {
+ componentModel.getComponentOptions().stream()
+ .map(opt -> opt.getName())
+ .filter(name -> isValidConnectionProperty(name,
connectionDetails))
+ .forEach(name -> properties.put(name,
String.valueOf(connectionDetails.get(name))));
+ }
+
+ return properties;
+ }
+
+ private Map<String, String> buildPropertiesMap(String scheme, JsonObject
connectionDetails) {
+ Map<String, String> properties = new LinkedHashMap<>();
+
+ var componentModel = catalog.componentModel(scheme);
+ if (componentModel != null) {
+ componentModel.getEndpointOptions().stream()
+ .map(opt -> opt.getName())
+ .filter(name -> isValidConnectionProperty(name,
connectionDetails))
+ .forEach(name -> properties.put(name,
String.valueOf(connectionDetails.get(name))));
+ }
+
+ return properties;
+ }
+
+ private boolean isValidConnectionProperty(String name, JsonObject
connectionDetails) {
+ if (!connectionDetails.containsKey(name)) {
+ return false;
+ }
+ Object value = connectionDetails.get(name);
+ return value != null && !(value instanceof Map);
+ }
+
+ private String buildPathBasedEndpoint(String path, JsonObject
connectionDetails) {
+ String uri = connectionDetails.getString("endpointUri");
+ if (uri == null) {
+ return null;
+ }
+
+ if (path != null && !path.isEmpty()) {
+ String connectionBase =
connectionDetails.getString("connectionBase");
+ if (connectionBase != null) {
+ String queryPart = StringHelper.after(uri, "?");
+ if (queryPart != null) {
+ queryPart = "?" + queryPart;
+ } else {
+ queryPart = "";
+ }
+
+ String newPath = path.startsWith("/") ? path : "/" + path;
+ return connectionBase + newPath + queryPart;
+ }
+ }
+
+ // fallback to original URI
+ return uri;
+ }
+
+ private String buildEndpointManually(String endpoint, Map<String, String>
properties) {
+ if (properties.isEmpty()) {
+ return endpoint;
+ }
+
+ StringBuilder queryParams = new StringBuilder();
+ for (Map.Entry<String, String> entry : properties.entrySet()) {
+ if (queryParams.length() > 0) {
+ queryParams.append("&");
+ }
+
queryParams.append(entry.getKey()).append("=").append(entry.getValue());
+ }
+
+ return endpoint + "?" + queryParams;
+ }
}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSendActionInfraTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSendActionInfraTest.java
new file mode 100644
index 000000000000..dad8c8c01375
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/action/CamelSendActionInfraTest.java
@@ -0,0 +1,620 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.action;
+
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.catalog.EndpointValidationResult;
+import org.apache.camel.dsl.jbang.core.commands.CamelCommandBaseTestSupport;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+// CamelSendAction's --infra option.
+public class CamelSendActionInfraTest extends CamelCommandBaseTestSupport {
+
+ private CamelSendAction sendAction;
+ private CamelCatalog catalog;
+
+ private static final Set<String> SKIP_CATALOG_VALIDATION = Set.of(
+ "openldap",
+ "docling",
+ "torch-serve",
+ "microprofile",
+ "artemis",
+ "ibmmq",
+ "rabbitmq",
+ "postgres",
+ "ollama");
+
+ @BeforeEach
+ public void setup() throws Exception {
+ super.setup();
+ sendAction = new CamelSendAction(new
CamelJBangMain().withPrinter(printer));
+ catalog = new DefaultCamelCatalog();
+ }
+
+ private String buildAndDecode(String endpoint, String service, JsonObject
json) {
+ String result =
sendAction.updateEndpointWithConnectionDetails(endpoint, service, json);
+ return URLDecoder.decode(result, StandardCharsets.UTF_8);
+ }
+
+ private void validateEndpointWithCatalog(String serviceName, String
decodedUri) {
+ if (SKIP_CATALOG_VALIDATION.contains(serviceName)) {
+ return;
+ }
+
+ EndpointValidationResult result =
catalog.validateEndpointProperties(decodedUri);
+
+ assertThat(result.getUnknown())
+ .describedAs("URI '%s' for service '%s' contains unknown
properties: %s",
+ decodedUri, serviceName, result.getUnknown())
+ .isNullOrEmpty();
+ }
+
+ static Stream<Arguments> infraServiceTestCases() {
+ List<Arguments> testCases = new ArrayList<>();
+
+ testCases.add(Arguments.of(
+ "nats",
+ createJson("servers", "localhost:4222"),
+ "nats:myTopic",
+ "servers", "localhost:4222"));
+
+ testCases.add(Arguments.of(
+ "kafka",
+ createJson("brokers", "localhost:9092"),
+ "kafka:myTopic",
+ "brokers", "localhost:9092"));
+
+ testCases.add(Arguments.of(
+ "mosquitto",
+ createJson("brokerUrl", "tcp://localhost:1883"),
+ "paho-mqtt5:myTopic",
+ "brokerUrl", "tcp://localhost:1883"));
+
+ testCases.add(Arguments.of(
+ "hive-mq",
+ createJson("brokerUrl", "tcp://localhost:1883"),
+ "paho-mqtt5:myTopic",
+ "brokerUrl", "tcp://localhost:1883"));
+
+ testCases.add(Arguments.of(
+ "artemis",
+ createJson("serviceAddress", "tcp://localhost:61616",
"userName", "admin", "password", "secret"),
+ "jms:myQueue",
+ "password", "RAW(secret)"));
+
+ testCases.add(Arguments.of(
+ "rabbitmq",
+ createJson("uri", "amqp://localhost:5672", "username",
"guest", "password", "guest"),
+ "spring-rabbitmq:myExchange",
+ "spring-rabbitmq", "myExchange"));
+
+ testCases.add(Arguments.of(
+ "mongodb",
+ createJson("hosts", "localhost:27017"),
+ "mongodb:myDatabase",
+ "hosts", "localhost:27017"));
+
+ testCases.add(Arguments.of(
+ "minio",
+ createJson("accessKey", "minioadmin", "secretKey",
"minioadmin", "endpoint", "http://localhost:9000"),
+ "minio:myBucket",
+ "endpoint", "http://localhost:9000"));
+
+ testCases.add(Arguments.of(
+ "infinispan",
+ createJson("hosts", "localhost:11222", "username", "admin",
"password", "secret"),
+ "infinispan:myCache",
+ "hosts", "localhost:11222"));
+
+ testCases.add(Arguments.of(
+ "zookeeper",
+ createJson("serverUrls", "localhost:2181",
+ "endpointUri", "zookeeper:localhost:2181/camel",
+ "connectionBase", "zookeeper:localhost:2181"),
+ "zookeeper:/myPath",
+ "localhost:2181", "/myPath"));
+
+ testCases.add(Arguments.of(
+ "couchdb",
+ createJson("host", "localhost", "port", 5984, "database",
"mydb",
+ "endpointUri", "couchdb:http:localhost:5984/mydb",
+ "connectionBase", "couchdb:http:localhost:5984"),
+ "couchdb:myDatabase",
+ "localhost", "myDatabase"));
+
+ testCases.add(Arguments.of(
+ "arangodb",
+ createJson("host", "localhost", "port", 8529),
+ "arangodb:myDatabase",
+ "host", "localhost"));
+
+ testCases.add(Arguments.of(
+ "hashicorp",
+ createJson("host", "localhost", "port", 8200, "token",
"mytoken"),
+ "hashicorp-vault:mySecret",
+ "host", "localhost"));
+
+ testCases.add(Arguments.of(
+ "keycloak",
+ createJson("serverUrl", "http://localhost:8080", "realm",
"myrealm"),
+ "http:localhost:8080/auth",
+ "http", "localhost"));
+
+ testCases.add(Arguments.of(
+ "smb",
+ createJson("address", "localhost:445", "shareName", "myShare",
+ "userName", "user", "password", "pass",
+ "endpointUri",
"smb:localhost:445/myShare?username=user&password=RAW(pass)",
+ "connectionBase", "smb:localhost:445"),
+ "smb:myShare",
+ "localhost", "myShare"));
+
+ testCases.add(Arguments.of(
+ "openldap",
+ createJson("host", "localhost", "port", 389,
+ "ldapUrl", "ldap://localhost:389",
+ "ldapContextFactory",
"com.sun.jndi.ldap.LdapCtxFactory",
+ "endpointUri", "ldap:ldapEnv"),
+ "ldap:ou=users",
+ "ldap", "ldapEnv"));
+
+ testCases.add(Arguments.of(
+ "ollama",
+ createJson("baseUrl", "http://localhost:11434", "modelName",
"llama2"),
+ "langchain4j-chat:myModel",
+ "langchain4j-chat", "myModel"));
+
+ testCases.add(Arguments.of(
+ "couchbase",
+ createJson("hostname", "localhost", "port", 8091, "bucket",
"myBucket",
+ "protocol", "http",
+ "endpointUri",
"couchbase:http://localhost:8091/myBucket",
+ "connectionBase", "couchbase:http://localhost:8091"),
+ "couchbase:myBucket",
+ "localhost", "myBucket"));
+
+ testCases.add(Arguments.of(
+ "postgres",
+ createJson("host", "localhost", "port", 5432, "userName",
"postgres", "password", "secret",
+ "jdbcUrl", "jdbc:postgresql://localhost:5432/postgres",
+ "endpointUri", "sql:SELECT 1?dataSource=#postgresDS"),
+ "sql:SELECT 1",
+ "sql", "SELECT"));
+
+ testCases.add(Arguments.of(
+ "ibmmq",
+ createJson("channel", "DEV.APP.SVRCONN", "queueManager",
"QM1", "listenerPort", 1414),
+ "jms:myQueue",
+ "jms", "myQueue"));
+
+ testCases.add(Arguments.of(
+ "rocketmq",
+ createJson("namesrvAddr", "localhost:9876"),
+ "rocketmq:myTopic",
+ "namesrvAddr", "localhost:9876"));
+
+ testCases.add(Arguments.of(
+ "milvus",
+ createJson("host", "localhost", "port", 19530),
+ "milvus:myCollection",
+ "host", "localhost"));
+
+ testCases.add(Arguments.of(
+ "qdrant",
+ createJson("host", "localhost", "port", 6333),
+ "qdrant:myCollection",
+ "host", "localhost"));
+
+ testCases.add(Arguments.of(
+ "ftp",
+ createJson("host", "localhost", "port", 21,
+ "username", "admin", "password", "admin",
+ "endpointUri",
"ftp:localhost:21/defaultdir?username=admin&password=RAW(admin)",
+ "connectionBase", "ftp:localhost:21"),
+ "ftp:mydir",
+ "username", "admin"));
+
+ testCases.add(Arguments.of(
+ "ftps",
+ createJson("host", "localhost", "port", 21,
+ "username", "admin", "password", "admin",
+ "endpointUri",
"ftps:localhost:21/defaultdir?username=admin&password=RAW(admin)",
+ "connectionBase", "ftps:localhost:21"),
+ "ftps:mydir",
+ "username", "admin"));
+
+ testCases.add(Arguments.of(
+ "sftp",
+ createJson("host", "localhost", "port", 22,
+ "username", "admin", "password", "admin",
+ "endpointUri",
"sftp:localhost:22/defaultdir?username=admin&password=RAW(admin)",
+ "connectionBase", "sftp:localhost:22"),
+ "sftp:mydir",
+ "username", "admin"));
+
+ testCases.add(Arguments.of(
+ "docling",
+ createJson("doclingServerUrl", "http://localhost:5000"),
+ "rest:post:/convert",
+ "rest", "post"));
+
+ testCases.add(Arguments.of(
+ "torch-serve",
+ createJson("inferencePort", 8080, "managementPort", 8081,
"metricsPort", 8082),
+ "rest:post:/predictions/model",
+ "rest", "post"));
+
+ testCases.add(Arguments.of(
+ "fhir",
+ createJson("serverUrl", "http://localhost:8080/fhir"),
+ "fhir:Patient/search",
+ "serverUrl", "http://localhost:8080/fhir"));
+
+ testCases.add(Arguments.of(
+ "pulsar",
+ createJson("serviceUrl", "pulsar://localhost:6650"),
+ "pulsar:persistent://public/default/myTopic",
+ "serviceUrl", "pulsar://localhost:6650"));
+
+ testCases.add(Arguments.of(
+ "aws",
+ createJson("amazonAWSHost", "localhost:4566", "region",
"us-east-1",
+ "accessKey", "test", "secretKey", "test"),
+ "aws2-s3:myBucket",
+ "region", "us-east-1"));
+
+ testCases.add(Arguments.of(
+ "azure",
+ createJson("host", "localhost", "port", 10000,
+ "accountName", "devstoreaccount1", "accessKey",
"testkey",
+ "containerName", "testcontainer",
+ "endpointUri",
"azure-storage-blob:devstoreaccount1/testcontainer",
+ "connectionBase",
"azure-storage-blob:devstoreaccount1"),
+ "azure-storage-blob:myContainer",
+ "devstoreaccount1", "myContainer"));
+
+ testCases.add(Arguments.of(
+ "google",
+ createJson("endpoint", "localhost:8085"),
+ "google-pubsub:myTopic",
+ "google-pubsub", "myTopic"));
+
+ testCases.add(Arguments.of(
+ "microprofile",
+ createJson("host", "localhost", "port", 8080),
+ "http:localhost:8080/lra-coordinator",
+ "host", "localhost"));
+
+ return testCases.stream();
+ }
+
+ @ParameterizedTest(name = "{0}: {2}")
+ @MethodSource("infraServiceTestCases")
+ @DisplayName("Test endpoint building for infra service")
+ void testEndpointBuilding(
+ String serviceName, JsonObject mockJson, String baseEndpoint,
+ String expectedKey, String expectedValue) {
+
+ String decoded = buildAndDecode(baseEndpoint, serviceName, mockJson);
+
+ boolean hasQueryParam = decoded.contains(expectedKey + "=" +
expectedValue);
+ boolean hasPathParts = decoded.contains(expectedKey) &&
decoded.contains(expectedValue);
+
+ assertThat(hasQueryParam || hasPathParts)
+ .describedAs("Endpoint for %s should contain '%s' and '%s'
(got: %s)",
+ serviceName, expectedKey, expectedValue, decoded)
+ .isTrue();
+
+ String expectedScheme = baseEndpoint.split(":")[0];
+ assertThat(decoded).startsWith(expectedScheme + ":");
+
+ validateEndpointWithCatalog(serviceName, decoded);
+ }
+
+ @Test
+ void testKafkaWithBrokersProperty() {
+ JsonObject json = new JsonObject();
+ json.put("brokers", "localhost:9092");
+ json.put("getBootstrapServers", "localhost:9092");
+
+ String decoded = buildAndDecode("kafka:myTopic", "kafka", json);
+
+ assertThat(decoded).contains("brokers=localhost:9092");
+ assertThat(decoded).doesNotContain("getBootstrapServers");
+ }
+
+ @Test
+ void testNatsWithCorrectProperty() {
+ JsonObject json = new JsonObject();
+ json.put("servers", "localhost:4222");
+
+ String decoded = buildAndDecode("nats:mySubject", "nats", json);
+
+ assertThat(decoded).contains("servers=localhost:4222");
+ }
+
+ @Test
+ void testMosquittoBrokerUrl() {
+ JsonObject json = new JsonObject();
+ json.put("brokerUrl", "tcp://localhost:1883");
+
+ String decoded = buildAndDecode("paho-mqtt5:myTopic", "mosquitto",
json);
+
+ assertThat(decoded).contains("brokerUrl=tcp://localhost:1883");
+ }
+
+ @Test
+ void testHiveMqBrokerUrl() {
+ JsonObject json = new JsonObject();
+ json.put("brokerUrl", "tcp://localhost:1883");
+
+ String decoded = buildAndDecode("paho-mqtt5:myTopic", "hive-mq", json);
+
+ assertThat(decoded).contains("brokerUrl=tcp://localhost:1883");
+ }
+
+ @Test
+ void testArtemisWithCredentials() {
+ JsonObject json = new JsonObject();
+ json.put("serviceAddress", "tcp://localhost:61616");
+ json.put("userName", "admin");
+ json.put("password", "secret");
+
+ String decoded = buildAndDecode("jms:myQueue", "artemis", json);
+
+ assertThat(decoded).contains("password=RAW(secret)");
+ }
+
+ @Test
+ void testEndpointWithExistingQueryParams() {
+ JsonObject json = new JsonObject();
+ json.put("brokers", "localhost:9092");
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "kafka:myTopic?groupId=myGroup", "kafka", json);
+
+ assertThat(result).isEqualTo("kafka:myTopic?groupId=myGroup");
+ }
+
+ @Test
+ void testHazelcastEmptyJson() {
+ JsonObject json = new JsonObject();
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "hazelcast-map:myMap", "hazelcast", json);
+
+ assertThat(result).isEqualTo("hazelcast-map:myMap");
+ }
+
+ @Test
+ void testNullEndpointCreatesDefault() {
+ JsonObject json = new JsonObject();
+ json.put("brokers", "localhost:9092");
+
+ String decoded = buildAndDecode(null, "kafka", json);
+
+ assertThat(decoded).startsWith("kafka:default");
+ assertThat(decoded).contains("brokers=localhost:9092");
+ }
+
+ @Test
+ void testEmptyJsonHandledGracefully() {
+ JsonObject json = new JsonObject();
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "kafka:myTopic", "kafka", json);
+
+ assertThat(result).isEqualTo("kafka:myTopic");
+ }
+
+ @Test
+ void testRedisPathBasedEndpoint() {
+ JsonObject json = new JsonObject();
+ json.put("host", "localhost");
+ json.put("port", 6379);
+ json.put("endpointUri", "spring-redis:localhost:6379");
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "spring-redis:COMMAND", "redis", json);
+
+ assertThat(result).contains("localhost");
+ assertThat(result).contains("6379");
+ assertThat(result).startsWith("spring-redis:");
+ }
+
+ @Test
+ void testXmppPathBasedEndpoint() {
+ JsonObject json = new JsonObject();
+ json.put("host", "localhost");
+ json.put("port", 5222);
+ json.put("endpointUri", "xmpp:localhost:5222");
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "xmpp:room", "xmpp", json);
+
+ assertThat(result).contains("localhost");
+ assertThat(result).contains("5222");
+ assertThat(result).startsWith("xmpp:");
+ }
+
+ @Test
+ void testChatScriptPathBasedEndpoint() {
+ JsonObject json = new JsonObject();
+ json.put("serviceAddress", "localhost:1024");
+ json.put("botName", "Harry");
+ json.put("endpointUri", "chatscript:localhost:1024/Harry");
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "chatscript:Harry", "chat-script", json);
+
+ assertThat(result).isEqualTo("chatscript:localhost:1024/Harry");
+ }
+
+ @Test
+ void testPulsarWithServiceUrl() {
+ JsonObject json = new JsonObject();
+ json.put("serviceUrl", "pulsar://localhost:6650");
+
+ String decoded =
buildAndDecode("pulsar:persistent://public/default/myTopic", "pulsar", json);
+
+ assertThat(decoded).contains("serviceUrl=pulsar://localhost:6650");
+ }
+
+ @Test
+ void testCassandraPathBasedEndpoint() {
+ JsonObject json = new JsonObject();
+ json.put("hosts", "localhost:9042");
+ json.put("port", 9042);
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "cql:cassandra-session:localhost:9042/mykeyspace",
"cassandra", json);
+
+ assertThat(result).contains("localhost");
+ assertThat(result).startsWith("cql:");
+ }
+
+ @Test
+ void testFtpPathBasedEndpoint() {
+ JsonObject json = new JsonObject();
+ json.put("host", "localhost");
+ json.put("port", 21);
+ json.put("username", "admin");
+ json.put("password", "secret");
+ json.put("endpointUri",
"ftp:localhost:21/mydir?username=admin&password=RAW(secret)");
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "ftp:mydir", "ftp", json);
+
+ assertThat(result).contains("localhost");
+ assertThat(result).contains("21");
+ assertThat(result).contains("username=admin");
+ assertThat(result).startsWith("ftp:");
+ }
+
+ @Test
+ void testElasticsearchWithHostAddresses() {
+ JsonObject json = new JsonObject();
+ json.put("hostAddresses", "localhost:9200");
+
+ String decoded = buildAndDecode("elasticsearch:myCluster",
"elasticsearch", json);
+
+ assertThat(decoded).contains("hostAddresses=localhost:9200");
+ }
+
+ @Test
+ void testSolrPathBasedEndpoint() {
+ JsonObject json = new JsonObject();
+ json.put("host", "localhost");
+ json.put("port", 8983);
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "solr:localhost:8983/solr", "solr", json);
+
+ assertThat(result).contains("localhost");
+ assertThat(result).startsWith("solr:");
+ }
+
+ @Test
+ void testOpenLdapWithBeanProperties() {
+ JsonObject json = new JsonObject();
+ json.put("host", "localhost");
+ json.put("port", 389);
+ json.put("ldapUrl", "ldap://localhost:389");
+ json.put("ldapContextFactory", "com.sun.jndi.ldap.LdapCtxFactory");
+ json.put("endpointUri", "ldap:ldapEnv");
+
+ JsonObject beanProps = new JsonObject();
+ beanProps.put("camel.beans.ldapEnv", "#class:java.util.Hashtable");
+ beanProps.put("camel.beans.ldapEnv[java.naming.factory.initial]",
"com.sun.jndi.ldap.LdapCtxFactory");
+ beanProps.put("camel.beans.ldapEnv[java.naming.provider.url]",
"ldap://localhost:389");
+ json.put("beanProperties", beanProps);
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "ldap:ou=users", "openldap", json);
+
+ assertThat(result).isEqualTo("ldap:ldapEnv");
+ }
+
+ @Test
+ void testPostgresWithBeanProperties() {
+ JsonObject json = new JsonObject();
+ json.put("host", "localhost");
+ json.put("port", 5432);
+ json.put("jdbcUrl", "jdbc:postgresql://localhost:5432/postgres");
+ json.put("endpointUri", "sql:SELECT 1?dataSource=#postgresDS");
+
+ JsonObject beanProps = new JsonObject();
+ beanProps.put("camel.beans.postgresDS",
"#class:org.postgresql.ds.PGSimpleDataSource");
+ beanProps.put("camel.beans.postgresDS.url",
"jdbc:postgresql://localhost:5432/postgres");
+ beanProps.put("camel.beans.postgresDS.user", "postgres");
+ beanProps.put("camel.beans.postgresDS.password", "secret");
+ json.put("beanProperties", beanProps);
+
+ String result = sendAction.updateEndpointWithConnectionDetails(
+ "sql:SELECT 1", "postgres", json);
+
+ assertThat(result).isEqualTo("sql:SELECT 1?dataSource=#postgresDS");
+ }
+
+ @Test
+ void testCatalogValidationCatchesInvalidProperties() {
+ String invalidUri =
"kafka:myTopic?brokers=localhost:9092&invalidFakeProperty=badvalue";
+
+ EndpointValidationResult result =
catalog.validateEndpointProperties(invalidUri);
+
+ assertThat(result.getUnknown())
+ .describedAs("Catalog should detect 'invalidFakeProperty' as
unknown")
+ .isNotNull()
+ .contains("invalidFakeProperty");
+ }
+
+ @Test
+ void testCatalogValidationPassesForValidProperties() {
+ String validUri = "kafka:myTopic?brokers=localhost:9092";
+
+ EndpointValidationResult result =
catalog.validateEndpointProperties(validUri);
+
+ assertThat(result.getUnknown())
+ .describedAs("Valid URI should have no unknown properties")
+ .isNullOrEmpty();
+ }
+
+ private static JsonObject createJson(Object... keyValues) {
+ JsonObject json = new JsonObject();
+ for (int i = 0; i < keyValues.length; i += 2) {
+ json.put((String) keyValues[i], keyValues[i + 1]);
+ }
+ return json;
+ }
+}
diff --git
a/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBInfraService.java
b/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBInfraService.java
index d7533dff4356..357f4439c463 100644
---
a/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBInfraService.java
+++
b/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBInfraService.java
@@ -50,4 +50,12 @@ public interface ArangoDBInfraService extends
InfrastructureService {
default String documentCollection() {
return "myCollection";
}
+
+ default String user() {
+ return "root";
+ }
+
+ default String password() {
+ return "";
+ }
}
diff --git
a/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisInfraService.java
b/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisInfraService.java
index efb2199bded9..105fcefff66d 100644
---
a/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisInfraService.java
+++
b/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisInfraService.java
@@ -24,12 +24,29 @@ public interface ArtemisInfraService extends
InfrastructureService {
String serviceAddress();
+ @Deprecated
String userName();
String password();
+ default String username() {
+ return userName();
+ }
+
int brokerPort();
+ default String host() {
+ return "localhost";
+ }
+
+ default int port() {
+ return brokerPort();
+ }
+
+ default String brokerUrl() {
+ return String.format("amqp://%s:%d", host(), port());
+ }
+
default String remoteURI() {
throw new IllegalArgumentException("Remote URI is not supported");
}
diff --git
a/test-infra/camel-test-infra-aws-common/src/main/java/org/apache/camel/test/infra/aws/common/services/AWSInfraService.java
b/test-infra/camel-test-infra-aws-common/src/main/java/org/apache/camel/test/infra/aws/common/services/AWSInfraService.java
index ddd88cf9d2b0..4f0d049db658 100644
---
a/test-infra/camel-test-infra-aws-common/src/main/java/org/apache/camel/test/infra/aws/common/services/AWSInfraService.java
+++
b/test-infra/camel-test-infra-aws-common/src/main/java/org/apache/camel/test/infra/aws/common/services/AWSInfraService.java
@@ -34,4 +34,12 @@ public interface AWSInfraService extends
InfrastructureService {
String accessKey();
String secretKey();
+
+ default String uriEndpointOverride() {
+ return String.format("%s://%s", protocol(), amazonAWSHost());
+ }
+
+ default boolean overrideEndpoint() {
+ return true;
+ }
}
diff --git
a/test-infra/camel-test-infra-azure-common/src/main/java/org/apache/camel/test/infra/azure/common/services/AzureInfraService.java
b/test-infra/camel-test-infra-azure-common/src/main/java/org/apache/camel/test/infra/azure/common/services/AzureInfraService.java
index 0f4e7fae3bcc..b1a22a039ead 100644
---
a/test-infra/camel-test-infra-azure-common/src/main/java/org/apache/camel/test/infra/azure/common/services/AzureInfraService.java
+++
b/test-infra/camel-test-infra-azure-common/src/main/java/org/apache/camel/test/infra/azure/common/services/AzureInfraService.java
@@ -40,4 +40,16 @@ public interface AzureInfraService extends
InfrastructureService {
default String credentialType() {
return "SHARED_KEY_CREDENTIAL";
}
+
+ default String containerName() {
+ return "testcontainer";
+ }
+
+ default String endpointUri() {
+ return String.format("azure-storage-blob:%s/%s", accountName(),
containerName());
+ }
+
+ default String connectionBase() {
+ return String.format("azure-storage-blob:%s", accountName());
+ }
}
diff --git
a/test-infra/camel-test-infra-cassandra/src/main/java/org/apache/camel/test/infra/cassandra/services/CassandraInfraService.java
b/test-infra/camel-test-infra-cassandra/src/main/java/org/apache/camel/test/infra/cassandra/services/CassandraInfraService.java
index e9c8efc3e7de..bcc47855dcba 100644
---
a/test-infra/camel-test-infra-cassandra/src/main/java/org/apache/camel/test/infra/cassandra/services/CassandraInfraService.java
+++
b/test-infra/camel-test-infra-cassandra/src/main/java/org/apache/camel/test/infra/cassandra/services/CassandraInfraService.java
@@ -35,4 +35,28 @@ public interface CassandraInfraService extends
InfrastructureService {
String hosts();
int port();
+
+ default String keyspace() {
+ return "camel";
+ }
+
+ default String datacenter() {
+ return "datacenter1";
+ }
+
+ default String username() {
+ return "cassandra";
+ }
+
+ default String password() {
+ return "cassandra";
+ }
+
+ default String endpointUri() {
+ return String.format("cql:%s:%d/%s?username=%s&password=RAW(%s)",
hosts(), port(), keyspace(), username(), password());
+ }
+
+ default String connectionBase() {
+ return String.format("cql:%s:%d", hosts(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-chatscript/src/main/java/org/apache/camel/test/infra/chatscript/services/ChatScriptInfraService.java
b/test-infra/camel-test-infra-chatscript/src/main/java/org/apache/camel/test/infra/chatscript/services/ChatScriptInfraService.java
index 26da3316c7b2..ba8e2e1bc50d 100644
---
a/test-infra/camel-test-infra-chatscript/src/main/java/org/apache/camel/test/infra/chatscript/services/ChatScriptInfraService.java
+++
b/test-infra/camel-test-infra-chatscript/src/main/java/org/apache/camel/test/infra/chatscript/services/ChatScriptInfraService.java
@@ -24,4 +24,16 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
public interface ChatScriptInfraService extends InfrastructureService {
String serviceAddress();
+
+ default String botName() {
+ return "Harry";
+ }
+
+ default String endpointUri() {
+ return String.format("chatscript:%s/%s", serviceAddress(), botName());
+ }
+
+ default String connectionBase() {
+ return String.format("chatscript:%s", serviceAddress());
+ }
}
diff --git
a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseInfraService.java
b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseInfraService.java
index bb734e333def..b09cd51b5ba0 100644
---
a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseInfraService.java
+++
b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseInfraService.java
@@ -54,4 +54,13 @@ public interface CouchbaseInfraService extends
InfrastructureService {
String viewName();
String designDocumentName();
+
+ default String endpointUri() {
+ return
String.format("couchbase:%s://%s:%d/%s?username=%s&password=RAW(%s)",
protocol(), hostname(), port(), bucket(),
+ username(), password());
+ }
+
+ default String connectionBase() {
+ return String.format("couchbase:%s://%s:%d", protocol(), hostname(),
port());
+ }
}
diff --git
a/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbInfraService.java
b/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbInfraService.java
index ee8ae667dbce..f9de00a66b59 100644
---
a/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbInfraService.java
+++
b/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbInfraService.java
@@ -27,7 +27,20 @@ public interface CouchDbInfraService extends
InfrastructureService {
int port();
+ @Deprecated
default String getServiceAddress() {
return String.format("%s:%d", host(), port());
}
+
+ default String database() {
+ return "testdb";
+ }
+
+ default String endpointUri() {
+ return String.format("couchdb:http:%s:%d/%s", host(), port(),
database());
+ }
+
+ default String connectionBase() {
+ return String.format("couchdb:http:%s:%d", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-docling/src/main/java/org/apache/camel/test/infra/docling/services/DoclingInfraService.java
b/test-infra/camel-test-infra-docling/src/main/java/org/apache/camel/test/infra/docling/services/DoclingInfraService.java
index 45b03ec8b3ea..f1aac5c02add 100644
---
a/test-infra/camel-test-infra-docling/src/main/java/org/apache/camel/test/infra/docling/services/DoclingInfraService.java
+++
b/test-infra/camel-test-infra-docling/src/main/java/org/apache/camel/test/infra/docling/services/DoclingInfraService.java
@@ -24,4 +24,8 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
public interface DoclingInfraService extends InfrastructureService {
String doclingServerUrl();
+
+ default String doclingServeUrl() {
+ return doclingServerUrl();
+ }
}
diff --git
a/test-infra/camel-test-infra-elasticsearch/src/main/java/org/apache/camel/test/infra/elasticsearch/services/ElasticSearchInfraService.java
b/test-infra/camel-test-infra-elasticsearch/src/main/java/org/apache/camel/test/infra/elasticsearch/services/ElasticSearchInfraService.java
index afcee5a9e1e1..8e04d75b273a 100644
---
a/test-infra/camel-test-infra-elasticsearch/src/main/java/org/apache/camel/test/infra/elasticsearch/services/ElasticSearchInfraService.java
+++
b/test-infra/camel-test-infra-elasticsearch/src/main/java/org/apache/camel/test/infra/elasticsearch/services/ElasticSearchInfraService.java
@@ -25,10 +25,13 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
public interface ElasticSearchInfraService extends InfrastructureService {
+ @Deprecated
int getPort();
+ @Deprecated
String getElasticSearchHost();
+ @Deprecated
default String getHttpHostAddress() {
return String.format("%s:%d", getElasticSearchHost(), getPort());
}
@@ -40,4 +43,16 @@ public interface ElasticSearchInfraService extends
InfrastructureService {
String getUsername();
String getPassword();
+
+ default String hostAddresses() {
+ return getHttpHostAddress();
+ }
+
+ default String user() {
+ return getUsername();
+ }
+
+ default String password() {
+ return getPassword();
+ }
}
diff --git
a/test-infra/camel-test-infra-fhir/src/main/java/org/apache/camel/test/infra/fhir/services/FhirInfraService.java
b/test-infra/camel-test-infra-fhir/src/main/java/org/apache/camel/test/infra/fhir/services/FhirInfraService.java
index 8f62b4245e2a..d8230016834b 100644
---
a/test-infra/camel-test-infra-fhir/src/main/java/org/apache/camel/test/infra/fhir/services/FhirInfraService.java
+++
b/test-infra/camel-test-infra-fhir/src/main/java/org/apache/camel/test/infra/fhir/services/FhirInfraService.java
@@ -23,9 +23,16 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
*/
public interface FhirInfraService extends InfrastructureService {
+ @Deprecated
String getServiceBaseURL();
+ @Deprecated
String getHost();
+ @Deprecated
Integer getPort();
+
+ default String serverUrl() {
+ return getServiceBaseURL();
+ }
}
diff --git
a/test-infra/camel-test-infra-ftp/src/main/java/org/apache/camel/test/infra/ftp/services/FtpInfraService.java
b/test-infra/camel-test-infra-ftp/src/main/java/org/apache/camel/test/infra/ftp/services/FtpInfraService.java
index 9b1a505c8e1b..95470f466c9b 100644
---
a/test-infra/camel-test-infra-ftp/src/main/java/org/apache/camel/test/infra/ftp/services/FtpInfraService.java
+++
b/test-infra/camel-test-infra-ftp/src/main/java/org/apache/camel/test/infra/ftp/services/FtpInfraService.java
@@ -71,4 +71,13 @@ public interface FtpInfraService extends
InfrastructureService {
default String knownHostsEntry() {
return null;
}
+
+ default String endpointUri() {
+ return String.format("ftp:%s:%d/%s?username=%s&password=RAW(%s)",
host(), port(), directoryName(), username(),
+ password());
+ }
+
+ default String connectionBase() {
+ return String.format("ftp:%s:%d", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-google-pubsub/src/main/java/org/apache/camel/test/infra/google/pubsub/services/GooglePubSubInfraService.java
b/test-infra/camel-test-infra-google-pubsub/src/main/java/org/apache/camel/test/infra/google/pubsub/services/GooglePubSubInfraService.java
index a978569aeefb..ce61df3e2db9 100644
---
a/test-infra/camel-test-infra-google-pubsub/src/main/java/org/apache/camel/test/infra/google/pubsub/services/GooglePubSubInfraService.java
+++
b/test-infra/camel-test-infra-google-pubsub/src/main/java/org/apache/camel/test/infra/google/pubsub/services/GooglePubSubInfraService.java
@@ -23,5 +23,14 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
*/
public interface GooglePubSubInfraService extends InfrastructureService {
+ @Deprecated
String getServiceAddress();
+
+ default String endpoint() {
+ return getServiceAddress();
+ }
+
+ default boolean authenticate() {
+ return false;
+ }
}
diff --git
a/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultInfraService.java
b/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultInfraService.java
index 5dbb39e3f8f6..bb83f4db7f3b 100644
---
a/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultInfraService.java
+++
b/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultInfraService.java
@@ -28,4 +28,8 @@ public interface HashicorpVaultInfraService extends
InfrastructureService {
int port();
String host();
+
+ default String scheme() {
+ return "http";
+ }
}
diff --git
a/test-infra/camel-test-infra-hazelcast/src/main/java/org/apache/camel/test/infra/hazelcast/services/HazelcastInfraService.java
b/test-infra/camel-test-infra-hazelcast/src/main/java/org/apache/camel/test/infra/hazelcast/services/HazelcastInfraService.java
index b575e26909ca..dd9798dad144 100644
---
a/test-infra/camel-test-infra-hazelcast/src/main/java/org/apache/camel/test/infra/hazelcast/services/HazelcastInfraService.java
+++
b/test-infra/camel-test-infra-hazelcast/src/main/java/org/apache/camel/test/infra/hazelcast/services/HazelcastInfraService.java
@@ -25,4 +25,12 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
public interface HazelcastInfraService extends InfrastructureService {
Config createConfiguration(String name, int port, String instanceName,
String componentName);
+
+ default String endpointUri() {
+ return "hazelcast-map:default";
+ }
+
+ default String hazelcastInstanceName() {
+ return "camel-hazelcast";
+ }
}
diff --git
a/test-infra/camel-test-infra-hivemq/src/main/java/org/apache/camel/test/infra/hivemq/services/HiveMQInfraService.java
b/test-infra/camel-test-infra-hivemq/src/main/java/org/apache/camel/test/infra/hivemq/services/HiveMQInfraService.java
index e03c106ce5f5..9d98485ecbc7 100644
---
a/test-infra/camel-test-infra-hivemq/src/main/java/org/apache/camel/test/infra/hivemq/services/HiveMQInfraService.java
+++
b/test-infra/camel-test-infra-hivemq/src/main/java/org/apache/camel/test/infra/hivemq/services/HiveMQInfraService.java
@@ -20,17 +20,34 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
public interface HiveMQInfraService extends InfrastructureService {
+ @Deprecated
int getMqttPort();
+ @Deprecated
String getMqttHost();
boolean isRunning();
+ @Deprecated
String getUserName();
+ @Deprecated
char[] getUserPassword();
+ @Deprecated
default String getMqttHostAddress() {
return String.format("tcp://%s:%d", getMqttHost(), getMqttPort());
}
+
+ default String brokerUrl() {
+ return getMqttHostAddress();
+ }
+
+ default String userName() {
+ return getUserName();
+ }
+
+ default String password() {
+ return getUserPassword() != null ? new String(getUserPassword()) :
null;
+ }
}
diff --git
a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
index 82472f2f83a9..0d668c697ee6 100644
---
a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
+++
b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQInfraService.java
@@ -28,4 +28,24 @@ public interface IbmMQInfraService extends
InfrastructureService {
String queueManager();
int listenerPort();
+
+ default String host() {
+ return "localhost";
+ }
+
+ default int port() {
+ return listenerPort();
+ }
+
+ default String username() {
+ return "app";
+ }
+
+ default String password() {
+ return "";
+ }
+
+ default String brokerUrl() {
+ return String.format("amqp://%s:%d", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanInfraService.java
b/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanInfraService.java
index 711cc160b6e6..87124267fe75 100644
---
a/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanInfraService.java
+++
b/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanInfraService.java
@@ -31,5 +31,10 @@ public interface InfinispanInfraService extends
InfrastructureService {
String host();
+ @Deprecated
String getServiceAddress();
+
+ default String hosts() {
+ return String.format("%s:%d", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakInfraService.java
b/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakInfraService.java
index 3dc8d05e41d7..3108955e5fd6 100644
---
a/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakInfraService.java
+++
b/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakInfraService.java
@@ -24,12 +24,16 @@ import org.keycloak.admin.client.Keycloak;
*/
public interface KeycloakInfraService extends InfrastructureService {
+ @Deprecated
String getKeycloakServerUrl();
+ @Deprecated
String getKeycloakRealm();
+ @Deprecated
String getKeycloakUsername();
+ @Deprecated
String getKeycloakPassword();
/**
@@ -38,4 +42,20 @@ public interface KeycloakInfraService extends
InfrastructureService {
* @return Keycloak admin client instance
*/
Keycloak getKeycloakAdminClient();
+
+ default String serverUrl() {
+ return getKeycloakServerUrl();
+ }
+
+ default String realm() {
+ return getKeycloakRealm();
+ }
+
+ default String username() {
+ return getKeycloakUsername();
+ }
+
+ default String password() {
+ return getKeycloakPassword();
+ }
}
diff --git
a/test-infra/camel-test-infra-microprofile-lra/src/main/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAInfraService.java
b/test-infra/camel-test-infra-microprofile-lra/src/main/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAInfraService.java
index 70a748d4f4ed..10d6670bcc6f 100644
---
a/test-infra/camel-test-infra-microprofile-lra/src/main/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAInfraService.java
+++
b/test-infra/camel-test-infra-microprofile-lra/src/main/java/org/apache/camel/test/infra/microprofile/lra/services/MicroprofileLRAInfraService.java
@@ -32,4 +32,12 @@ public interface MicroprofileLRAInfraService extends
InfrastructureService {
default String getServiceAddress() {
return String.format("http://%s:%d", host(), port());
}
+
+ default String endpointUri() {
+ return String.format("http:%s:%d/lra-coordinator/start", host(),
port());
+ }
+
+ default String coordinatorUrl() {
+ return String.format("http://%s:%d/lra-coordinator", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-milvus/src/main/java/org/apache/camel/test/infra/milvus/services/MilvusInfraService.java
b/test-infra/camel-test-infra-milvus/src/main/java/org/apache/camel/test/infra/milvus/services/MilvusInfraService.java
index 3b375ee8280d..a248df86070e 100644
---
a/test-infra/camel-test-infra-milvus/src/main/java/org/apache/camel/test/infra/milvus/services/MilvusInfraService.java
+++
b/test-infra/camel-test-infra-milvus/src/main/java/org/apache/camel/test/infra/milvus/services/MilvusInfraService.java
@@ -38,4 +38,12 @@ public interface MilvusInfraService extends
InfrastructureService {
String host();
int port();
+
+ default String collection() {
+ return "testcollection";
+ }
+
+ default String token() {
+ return "";
+ }
}
diff --git
a/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioInfraService.java
b/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioInfraService.java
index 751f991edea4..2594ae1c475d 100644
---
a/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioInfraService.java
+++
b/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioInfraService.java
@@ -36,4 +36,8 @@ public interface MinioInfraService extends
InfrastructureService {
String consoleUsername();
String consolePassword();
+
+ default String endpoint() {
+ return String.format("http://%s:%d", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBInfraService.java
b/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBInfraService.java
index 2317e486cfa5..392eaa2784aa 100644
---
a/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBInfraService.java
+++
b/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBInfraService.java
@@ -26,6 +26,7 @@ public interface MongoDBInfraService extends
InfrastructureService {
*
* @return the replica set URL
*/
+ @Deprecated
String getReplicaSetUrl();
/**
@@ -33,5 +34,10 @@ public interface MongoDBInfraService extends
InfrastructureService {
*
* @return the connection address
*/
+ @Deprecated
String getConnectionAddress();
+
+ default String hosts() {
+ return getConnectionAddress();
+ }
}
diff --git
a/test-infra/camel-test-infra-mosquitto/src/main/java/org/apache/camel/test/infra/mosquitto/services/MosquittoInfraService.java
b/test-infra/camel-test-infra-mosquitto/src/main/java/org/apache/camel/test/infra/mosquitto/services/MosquittoInfraService.java
index e160abfbdde0..c6051e00e5fa 100644
---
a/test-infra/camel-test-infra-mosquitto/src/main/java/org/apache/camel/test/infra/mosquitto/services/MosquittoInfraService.java
+++
b/test-infra/camel-test-infra-mosquitto/src/main/java/org/apache/camel/test/infra/mosquitto/services/MosquittoInfraService.java
@@ -23,5 +23,18 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
*/
public interface MosquittoInfraService extends InfrastructureService {
+ @Deprecated
Integer getPort();
+
+ default String host() {
+ return "localhost";
+ }
+
+ default int port() {
+ return getPort();
+ }
+
+ default String brokerUrl() {
+ return String.format("tcp://%s:%d", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-nats/src/main/java/org/apache/camel/test/infra/nats/services/NatsInfraService.java
b/test-infra/camel-test-infra-nats/src/main/java/org/apache/camel/test/infra/nats/services/NatsInfraService.java
index 5fbea42615c5..e6a70c650c8e 100644
---
a/test-infra/camel-test-infra-nats/src/main/java/org/apache/camel/test/infra/nats/services/NatsInfraService.java
+++
b/test-infra/camel-test-infra-nats/src/main/java/org/apache/camel/test/infra/nats/services/NatsInfraService.java
@@ -23,5 +23,10 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
*/
public interface NatsInfraService extends InfrastructureService {
+ @Deprecated
String getServiceAddress();
+
+ default String servers() {
+ return getServiceAddress();
+ }
}
diff --git
a/test-infra/camel-test-infra-ollama/src/main/java/org/apache/camel/test/infra/ollama/services/OllamaInfraService.java
b/test-infra/camel-test-infra-ollama/src/main/java/org/apache/camel/test/infra/ollama/services/OllamaInfraService.java
index 707149879e82..d3933b2bd1e2 100644
---
a/test-infra/camel-test-infra-ollama/src/main/java/org/apache/camel/test/infra/ollama/services/OllamaInfraService.java
+++
b/test-infra/camel-test-infra-ollama/src/main/java/org/apache/camel/test/infra/ollama/services/OllamaInfraService.java
@@ -33,4 +33,39 @@ public interface OllamaInfraService extends
InfrastructureService {
String baseUrlV1();
String apiKey();
+
+ default String host() {
+ // Extract host from baseUrl (e.g., "http://localhost:11434" ->
"localhost")
+ String url = baseUrl();
+ if (url != null) {
+ url = url.replace("http://", "").replace("https://", "");
+ int colonIdx = url.indexOf(':');
+ if (colonIdx > 0) {
+ return url.substring(0, colonIdx);
+ }
+ return url;
+ }
+ return "localhost";
+ }
+
+ default int port() {
+ // Extract port from baseUrl (e.g., "http://localhost:11434" -> 11434)
+ String url = baseUrl();
+ if (url != null) {
+ url = url.replace("http://", "").replace("https://", "");
+ int colonIdx = url.indexOf(':');
+ if (colonIdx > 0) {
+ try {
+ return Integer.parseInt(url.substring(colonIdx + 1));
+ } catch (NumberFormatException e) {
+ // Fall through to default
+ }
+ }
+ }
+ return 11434;
+ }
+
+ default String endpointUri() {
+ return String.format("http:%s:%d/api/generate", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-openldap/src/main/java/org/apache/camel/test/infra/openldap/services/OpenldapInfraService.java
b/test-infra/camel-test-infra-openldap/src/main/java/org/apache/camel/test/infra/openldap/services/OpenldapInfraService.java
index aa0314e2b1ef..aa0ac6ea44be 100644
---
a/test-infra/camel-test-infra-openldap/src/main/java/org/apache/camel/test/infra/openldap/services/OpenldapInfraService.java
+++
b/test-infra/camel-test-infra-openldap/src/main/java/org/apache/camel/test/infra/openldap/services/OpenldapInfraService.java
@@ -16,6 +16,9 @@
*/
package org.apache.camel.test.infra.openldap.services;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
import org.apache.camel.test.infra.common.services.InfrastructureService;
/**
@@ -23,9 +26,44 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
*/
public interface OpenldapInfraService extends InfrastructureService {
+ @Deprecated
Integer getPort();
+ @Deprecated
Integer getSslPort();
+ @Deprecated
String getHost();
+
+ default String host() {
+ return getHost();
+ }
+
+ default int port() {
+ return getPort();
+ }
+
+ default int sslPort() {
+ return getSslPort();
+ }
+
+ default String ldapUrl() {
+ return String.format("ldap://%s:%d", host(), port());
+ }
+
+ default String ldapContextFactory() {
+ return "com.sun.jndi.ldap.LdapCtxFactory";
+ }
+
+ default String endpointUri() {
+ return "ldap:ldapEnv";
+ }
+
+ default Map<String, String> beanProperties() {
+ Map<String, String> properties = new LinkedHashMap<>();
+ properties.put("camel.beans.ldapEnv", "#class:java.util.Hashtable");
+ properties.put("camel.beans.ldapEnv[java.naming.factory.initial]",
ldapContextFactory());
+ properties.put("camel.beans.ldapEnv[java.naming.provider.url]",
ldapUrl());
+ return properties;
+ }
}
diff --git
a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresInfraService.java
b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresInfraService.java
index 01ef149e98f1..4d6b5a313874 100644
---
a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresInfraService.java
+++
b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresInfraService.java
@@ -16,6 +16,9 @@
*/
package org.apache.camel.test.infra.postgres.services;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
import org.apache.camel.test.infra.common.services.InfrastructureService;
/**
@@ -32,4 +35,33 @@ public interface PostgresInfraService extends
InfrastructureService {
String password();
String getServiceAddress();
+
+ default String database() {
+ return "postgres";
+ }
+
+ default String jdbcUrl() {
+ return String.format("jdbc:postgresql://%s:%d/%s", host(), port(),
database());
+ }
+
+ default String jdbcDriver() {
+ return "org.postgresql.Driver";
+ }
+
+ default String username() {
+ return userName();
+ }
+
+ default String endpointUri() {
+ return "sql:SELECT 1?dataSource=#postgresDS";
+ }
+
+ default Map<String, String> beanProperties() {
+ Map<String, String> properties = new LinkedHashMap<>();
+ properties.put("camel.beans.postgresDS",
"#class:org.postgresql.ds.PGSimpleDataSource");
+ properties.put("camel.beans.postgresDS.url", jdbcUrl());
+ properties.put("camel.beans.postgresDS.user", username());
+ properties.put("camel.beans.postgresDS.password", password());
+ return properties;
+ }
}
diff --git
a/test-infra/camel-test-infra-pulsar/src/main/java/org/apache/camel/test/infra/pulsar/services/PulsarInfraService.java
b/test-infra/camel-test-infra-pulsar/src/main/java/org/apache/camel/test/infra/pulsar/services/PulsarInfraService.java
index b5d54886a2bb..34ced80cb28e 100644
---
a/test-infra/camel-test-infra-pulsar/src/main/java/org/apache/camel/test/infra/pulsar/services/PulsarInfraService.java
+++
b/test-infra/camel-test-infra-pulsar/src/main/java/org/apache/camel/test/infra/pulsar/services/PulsarInfraService.java
@@ -23,7 +23,17 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
*/
public interface PulsarInfraService extends InfrastructureService {
+ @Deprecated
String getPulsarAdminUrl();
+ @Deprecated
String getPulsarBrokerUrl();
+
+ default String serviceUrl() {
+ return getPulsarBrokerUrl();
+ }
+
+ default String adminUrl() {
+ return getPulsarAdminUrl();
+ }
}
diff --git
a/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantInfraService.java
b/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantInfraService.java
index 4bb872b371d4..4bfe745236bc 100644
---
a/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantInfraService.java
+++
b/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantInfraService.java
@@ -44,6 +44,14 @@ public interface QdrantInfraService extends
InfrastructureService {
int port();
+ default String collection() {
+ return "testcollection";
+ }
+
+ default String apiKey() {
+ return "";
+ }
+
default HttpResponse<byte[]> put(String path, Map<Object, Object> body)
throws Exception {
final String reqPath = !path.startsWith("/") ? "/" + path : path;
final String reqUrl = String.format("http://%s:%d%s", getHttpHost(),
getHttpPort(), reqPath);
diff --git
a/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQInfraService.java
b/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQInfraService.java
index 43783f50634b..8c3682211964 100644
---
a/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQInfraService.java
+++
b/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQInfraService.java
@@ -65,4 +65,28 @@ public interface RabbitMQInfraService extends
InfrastructureService {
String managementPassword();
String managementUri();
+
+ default String hostname() {
+ return connectionProperties().hostname();
+ }
+
+ default int port() {
+ return connectionProperties().port();
+ }
+
+ default String username() {
+ return connectionProperties().username();
+ }
+
+ default String password() {
+ return connectionProperties().password();
+ }
+
+ default String host() {
+ return connectionProperties().hostname();
+ }
+
+ default String brokerUrl() {
+ return String.format("amqp://%s:%d", hostname(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisInfraService.java
b/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisInfraService.java
index 196320b0f680..0d7635248d90 100644
---
a/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisInfraService.java
+++
b/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisInfraService.java
@@ -27,7 +27,12 @@ public interface RedisInfraService extends
InfrastructureService {
int port();
+ @Deprecated
default String getServiceAddress() {
return String.format("%s:%d", host(), port());
}
+
+ default String endpointUri() {
+ return String.format("spring-redis:%s:%d", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-rocketmq/src/main/java/org/apache/camel/test/infra/rocketmq/services/RocketMQInfraService.java
b/test-infra/camel-test-infra-rocketmq/src/main/java/org/apache/camel/test/infra/rocketmq/services/RocketMQInfraService.java
index 87a1b584ba95..198efd15e518 100644
---
a/test-infra/camel-test-infra-rocketmq/src/main/java/org/apache/camel/test/infra/rocketmq/services/RocketMQInfraService.java
+++
b/test-infra/camel-test-infra-rocketmq/src/main/java/org/apache/camel/test/infra/rocketmq/services/RocketMQInfraService.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import org.apache.camel.test.infra.common.services.InfrastructureService;
public interface RocketMQInfraService extends InfrastructureService {
+ @Deprecated
String nameserverAddress();
default String defaultCluster() {
@@ -31,4 +32,7 @@ public interface RocketMQInfraService extends
InfrastructureService {
void deleteTopic(String topic) throws IOException, InterruptedException;
+ default String namesrvAddr() {
+ return nameserverAddress();
+ }
}
diff --git
a/test-infra/camel-test-infra-smb/src/main/java/org/apache/camel/test/infra/smb/services/SmbInfraService.java
b/test-infra/camel-test-infra-smb/src/main/java/org/apache/camel/test/infra/smb/services/SmbInfraService.java
index 899c0a21adeb..bd8f752ca1cc 100644
---
a/test-infra/camel-test-infra-smb/src/main/java/org/apache/camel/test/infra/smb/services/SmbInfraService.java
+++
b/test-infra/camel-test-infra-smb/src/main/java/org/apache/camel/test/infra/smb/services/SmbInfraService.java
@@ -24,9 +24,39 @@ public interface SmbInfraService extends
InfrastructureService {
String shareName();
+ @Deprecated
String userName();
String password();
String smbFile(String file);
+
+ default String hostname() {
+ String addr = address();
+ if (addr != null && addr.contains(":")) {
+ return addr.substring(0, addr.indexOf(':'));
+ }
+ return addr;
+ }
+
+ default int port() {
+ String addr = address();
+ if (addr != null && addr.contains(":")) {
+ return Integer.parseInt(addr.substring(addr.indexOf(':') + 1));
+ }
+ return 445; // default SMB port
+ }
+
+ default String username() {
+ return userName();
+ }
+
+ default String endpointUri() {
+ return String.format("smb:%s:%d/%s?username=%s&password=RAW(%s)",
hostname(), port(), shareName(), username(),
+ password());
+ }
+
+ default String connectionBase() {
+ return String.format("smb:%s:%d", hostname(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrInfraService.java
b/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrInfraService.java
index 6f8f4d7e69af..5f5d8c79b42c 100644
---
a/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrInfraService.java
+++
b/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrInfraService.java
@@ -21,12 +21,22 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
public interface SolrInfraService extends InfrastructureService {
+ @Deprecated
int getPort();
+ @Deprecated
String getSolrHost();
+ @Deprecated
default String getHttpHostAddress() {
return String.format("%s:%d", getSolrHost(), getPort());
}
+ default String host() {
+ return getSolrHost();
+ }
+
+ default int port() {
+ return getPort();
+ }
}
diff --git
a/test-infra/camel-test-infra-torchserve/src/main/java/org/apache/camel/test/infra/torchserve/services/TorchServeInfraService.java
b/test-infra/camel-test-infra-torchserve/src/main/java/org/apache/camel/test/infra/torchserve/services/TorchServeInfraService.java
index 6ab7640fab5d..ca7b2a77e603 100644
---
a/test-infra/camel-test-infra-torchserve/src/main/java/org/apache/camel/test/infra/torchserve/services/TorchServeInfraService.java
+++
b/test-infra/camel-test-infra-torchserve/src/main/java/org/apache/camel/test/infra/torchserve/services/TorchServeInfraService.java
@@ -25,4 +25,16 @@ public interface TorchServeInfraService extends
InfrastructureService {
int managementPort();
int metricsPort();
+
+ default String host() {
+ return "localhost";
+ }
+
+ default String inferenceAddress() {
+ return host();
+ }
+
+ default String managementAddress() {
+ return host();
+ }
}
diff --git
a/test-infra/camel-test-infra-torchserve/src/main/java/org/apache/camel/test/infra/torchserve/services/TorchServeLocalContainerInfraService.java
b/test-infra/camel-test-infra-torchserve/src/main/java/org/apache/camel/test/infra/torchserve/services/TorchServeLocalContainerInfraService.java
index 9996916d00f0..7c9b9c738f43 100644
---
a/test-infra/camel-test-infra-torchserve/src/main/java/org/apache/camel/test/infra/torchserve/services/TorchServeLocalContainerInfraService.java
+++
b/test-infra/camel-test-infra-torchserve/src/main/java/org/apache/camel/test/infra/torchserve/services/TorchServeLocalContainerInfraService.java
@@ -125,4 +125,9 @@ public class TorchServeLocalContainerInfraService
implements TorchServeInfraServ
public int metricsPort() {
return container.getMappedPort(METRICS_PORT);
}
+
+ @Override
+ public String host() {
+ return container.getHost();
+ }
}
diff --git
a/test-infra/camel-test-infra-xmpp/src/main/java/org/apache/camel/test/infra/xmpp/services/XmppInfraService.java
b/test-infra/camel-test-infra-xmpp/src/main/java/org/apache/camel/test/infra/xmpp/services/XmppInfraService.java
index e50863c742ec..f5eedc2e24bd 100644
---
a/test-infra/camel-test-infra-xmpp/src/main/java/org/apache/camel/test/infra/xmpp/services/XmppInfraService.java
+++
b/test-infra/camel-test-infra-xmpp/src/main/java/org/apache/camel/test/infra/xmpp/services/XmppInfraService.java
@@ -26,5 +26,10 @@ public interface XmppInfraService extends
InfrastructureService {
int port();
+ @Deprecated
String getUrl();
+
+ default String endpointUri() {
+ return String.format("xmpp:%s:%d", host(), port());
+ }
}
diff --git
a/test-infra/camel-test-infra-zookeeper/src/main/java/org/apache/camel/test/infra/zookeeper/services/ZooKeeperInfraService.java
b/test-infra/camel-test-infra-zookeeper/src/main/java/org/apache/camel/test/infra/zookeeper/services/ZooKeeperInfraService.java
index e2b6a87ebff0..994d3f0ff5b6 100644
---
a/test-infra/camel-test-infra-zookeeper/src/main/java/org/apache/camel/test/infra/zookeeper/services/ZooKeeperInfraService.java
+++
b/test-infra/camel-test-infra-zookeeper/src/main/java/org/apache/camel/test/infra/zookeeper/services/ZooKeeperInfraService.java
@@ -22,5 +22,18 @@ import
org.apache.camel.test.infra.common.services.InfrastructureService;
* Test infra service for ZooKeeper
*/
public interface ZooKeeperInfraService extends InfrastructureService {
+ @Deprecated
String getConnectionString();
+
+ default String serverUrls() {
+ return getConnectionString();
+ }
+
+ default String endpointUri() {
+ return String.format("zookeeper:%s/camel", serverUrls());
+ }
+
+ default String connectionBase() {
+ return String.format("zookeeper:%s", serverUrls());
+ }
}