diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json index 11e895795c962..71c1c305f7870 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json @@ -7,7 +7,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-milvus", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v2.6.20" + "serviceVersion" : "v2.6.20", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -17,7 +18,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -27,7 +29,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -37,7 +40,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.iggy.services.IggyInfraService", "description" : "Iggy is a persistent message streaming platform", @@ -47,7 +51,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-iggy", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.8.0" + "serviceVersion" : "0.8.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -57,7 +62,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.zookeeper.services.ZooKeeperInfraService", "description" : "Zookeeper is a server for highly reliable distributed coordination of cloud applications", @@ -67,7 +73,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-zookeeper", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.9.5" + "serviceVersion" : "3.9.5", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -77,7 +84,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.redis.services.RedisInfraService", "description" : "Redis is an open source in-memory data store", @@ -87,7 +95,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-redis", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "7.4.9-alpine" + "serviceVersion" : "7.4.9-alpine", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.elasticsearch.services.ElasticSearchInfraService", "description" : "Elasticsearch is a distributed search and analytics engine", @@ -97,7 +106,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-elasticsearch", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "9.1.0" + "serviceVersion" : "9.1.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService", "description" : "Apache Kafka, Distributed event streaming platform", @@ -107,7 +117,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-kafka", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.51.0-kafka-4.2.0" + "serviceVersion" : "0.51.0-kafka-4.2.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService", "description" : "Apache Kafka, Distributed event streaming platform", @@ -117,7 +128,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-kafka", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "8.3.0" + "serviceVersion" : "8.3.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.nats.services.NatsInfraService", "description" : "NATS is a high-performance messaging system for cloud native applications", @@ -127,7 +139,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-nats", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.14.2" + "serviceVersion" : "2.14.2", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -137,7 +150,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.postgres.services.PostgresInfraService", "description" : "PostgreSQL is an open source object-relational database", @@ -147,7 +161,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-postgres", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "17.10-alpine" + "serviceVersion" : "17.10-alpine", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService", "description" : "Apache Kafka, Distributed event streaming platform", @@ -157,7 +172,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-kafka", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v26.1.12" + "serviceVersion" : "v26.1.12", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.hashicorp.vault.services.HashicorpVaultInfraService", "description" : "HashiCorp Vault is a tool for securely accessing secrets", @@ -167,7 +183,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-hashicorp-vault", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.0.3" + "serviceVersion" : "2.0.3", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -177,7 +194,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.artemis.services.ArtemisInfraService", "description" : "Apache Artemis is an open source message broker", @@ -187,7 +205,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-artemis", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "latest" + "serviceVersion" : "latest", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.solr.services.SolrInfraService", "description" : "Apache Solr is an open source search platform", @@ -197,7 +216,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-solr", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "9.10.1-slim" + "serviceVersion" : "9.10.1-slim", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.couchbase.services.CouchbaseInfraService", "description" : "Couchbase is a distributed NoSQL cloud database", @@ -207,7 +227,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-couchbase", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "8.0.0" + "serviceVersion" : "8.0.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -217,7 +238,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.couchdb.services.CouchDbInfraService", "description" : "Apache CouchDB is an open source NoSQL document database", @@ -227,7 +249,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-couchdb", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.5.1" + "serviceVersion" : "3.5.1", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.keycloak.services.KeycloakInfraService", "description" : "Keycloak is an open source identity and access management solution", @@ -237,7 +260,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-keycloak", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "26.6.4" + "serviceVersion" : "26.6.4", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.hivemq.services.HiveMQInfraService", "description" : "HiveMQ is an MQTT-based messaging platform for IoT", @@ -247,7 +271,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-hivemq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2025.5" + "serviceVersion" : "2025.5", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.ibmmq.services.IbmMQInfraService", "description" : "IBM MQ is enterprise messaging middleware for reliable communication", @@ -257,7 +282,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ibmmq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "9.4.5.0-r2" + "serviceVersion" : "9.4.5.0-r2", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -267,7 +293,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.smb.services.SmbLocalContainerInfraService", "description" : "Samba provides file sharing services using the SMB protocol", @@ -277,7 +304,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-smb", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.14.0" + "serviceVersion" : "0.14.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.openldap.services.OpenldapInfraService", "description" : "OpenLDAP is an implementation of the Lightweight Directory Access Protocol", @@ -287,7 +315,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-openldap", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.0" + "serviceVersion" : "1.5.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.xmpp.services.XmppInfraService", "description" : "XMPP is an open communication protocol for messaging", @@ -297,7 +326,19 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-xmpp", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.3" + "serviceVersion" : "0.3", + "uiSupported" : false +}, { + "service" : "org.apache.camel.test.infra.opensearch.services.OpenSearchInfraService", + "description" : "OpenSearch is a distributed search and analytics engine", + "implementation" : "org.apache.camel.test.infra.opensearch.services.OpenSearchLocalContainerInfraService", + "alias" : [ "opensearch" ], + "aliasImplementation" : [ ], + "groupId" : "org.apache.camel", + "artifactId" : "camel-test-infra-opensearch", + "version" : "4.22.0-SNAPSHOT", + "serviceVersion" : "3.7.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.pulsar.services.PulsarInfraService", "description" : "Apache Pulsar is a distributed messaging and streaming platform", @@ -307,7 +348,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-pulsar", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "4.2.1" + "serviceVersion" : "4.2.1", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.artemis.services.ArtemisInfraService", "description" : "Apache Artemis is an open source message broker", @@ -317,7 +359,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-artemis", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "latest" + "serviceVersion" : "latest", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -327,7 +370,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -337,7 +381,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.google.pubsub.services.GooglePubSubInfraService", "description" : "Google Cloud Pub/Sub is a messaging service for event-driven systems", @@ -347,7 +392,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-google-pubsub", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "emulators" + "serviceVersion" : "emulators", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.chatscript.services.ChatScriptInfraService", "description" : "ChatScript is an open source chatbot engine", @@ -357,7 +403,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-chatscript", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "latest" + "serviceVersion" : "latest", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.arangodb.services.ArangoDBInfraService", "description" : "ArangoDB is a multi-model database for high-performance applications.", @@ -367,7 +414,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-arangodb", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.12.5.2" + "serviceVersion" : "3.12.5.2", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.ignite.services.IgniteInfraService", "description" : "Apache Ignite is a distributed database for high-performance computing", @@ -377,7 +425,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ignite", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.18.0" + "serviceVersion" : "2.18.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.rabbitmq.services.RabbitMQInfraService", "description" : "RabbitMQ is an open source message and streaming broker", @@ -387,7 +436,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-rabbitmq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "4.2.5-management" + "serviceVersion" : "4.2.5-management", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.mosquitto.services.MosquittoInfraService", "description" : "Mosquitto is a message broker that implements MQTT protocol", @@ -397,7 +447,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-mosquitto", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.0.22" + "serviceVersion" : "2.0.22", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.neo4j.services.Neo4jInfraService", "description" : "Neo4j is a graph database management system", @@ -407,7 +458,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-neo4j", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2026.05-community-ubi10" + "serviceVersion" : "2026.05-community-ubi10", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.rocketmq.services.RocketMQInfraService", "description" : "Apache RocketMQ is a distributed messaging and streaming platform", @@ -417,7 +469,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-rocketmq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "5.3.3" + "serviceVersion" : "5.3.3", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -427,7 +480,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -437,7 +491,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -447,7 +502,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.cassandra.services.CassandraInfraService", "description" : "Apache Cassandra is a distributed NoSQL database", @@ -457,7 +513,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-cassandra", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "5.0.8" + "serviceVersion" : "5.0.8", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -467,7 +524,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.hazelcast.services.HazelcastInfraService", "description" : "Hazelcast is a distributed in-memory computing platform", @@ -477,7 +535,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-hazelcast", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "5.4.0" + "serviceVersion" : "5.4.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.hivemq.services.HiveMQInfraService", "description" : "HiveMQ is an MQTT-based messaging platform for IoT", @@ -487,7 +546,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-hivemq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "camel" + "serviceVersion" : "camel", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.postgres.services.PostgresInfraService", "description" : "PostgreSQL with pgvector extension for vector similarity search", @@ -497,7 +557,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-postgres", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "pg18" + "serviceVersion" : "pg18", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.microprofile.lra.services.MicroprofileLRAInfraService", "description" : "Transaction Manager for microservices that is based on the SAGA pattern for distributed transaction.", @@ -507,7 +568,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-microprofile-lra", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "5.13.1.Final-2.16.6.Final" + "serviceVersion" : "5.13.1.Final-2.16.6.Final", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.minio.services.MinioInfraService", "description" : "MinIO is a high-performance S3 compatible object storage", @@ -517,7 +579,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-minio", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "RELEASE.2025-09-07T16-13-09Z-cpuv1" + "serviceVersion" : "RELEASE.2025-09-07T16-13-09Z-cpuv1", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService", "description" : "Apache Kafka, Distributed event streaming platform", @@ -527,7 +590,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-kafka", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "4.3.1" + "serviceVersion" : "4.3.1", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.azure.common.services.AzureInfraService", "description" : "Local Azure services with Azurite", @@ -537,7 +601,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-azure-storage-queue", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.35.0" + "serviceVersion" : "3.35.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService", "description" : "Embedded SFTP Server", @@ -547,7 +612,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ftp", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.19.0" + "serviceVersion" : "2.19.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.jaeger.services.JaegerInfraService", "description" : "Jaeger is a distributed tracing backend with OTLP collector and UI", @@ -557,7 +623,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-jaeger", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.19.0" + "serviceVersion" : "2.19.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.infinispan.services.InfinispanInfraService", "description" : "Infinispan is a distributed in-memory key/value data store", @@ -567,7 +634,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-infinispan", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "16.2" + "serviceVersion" : "16.2", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.weaviate.services.WeaviateInfraService", "description" : "Weaviate is an open source vector database", @@ -577,7 +645,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-weaviate", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.37.4" + "serviceVersion" : "1.37.4", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.consul.services.ConsulInfraService", "description" : "Consul is a service networking solution", @@ -587,7 +656,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-consul", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.0.1" + "serviceVersion" : "2.0.1", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.qdrant.services.QdrantInfraService", "description" : "Qdrant is a vector similarity search engine and database", @@ -597,7 +667,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-qdrant", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v1.18.2-unprivileged" + "serviceVersion" : "v1.18.2-unprivileged", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService", "description" : "Embedded FTPS Server", @@ -607,7 +678,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ftp", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.2.1" + "serviceVersion" : "1.2.1", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.ollama.services.OllamaInfraService", "description" : "Ollama is a tool for running large language models locally", @@ -617,7 +689,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ollama", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.31.2" + "serviceVersion" : "0.31.2", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.azure.common.services.AzureInfraService", "description" : "Local Azure services with Azurite", @@ -627,7 +700,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-azure-storage-blob", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.35.0" + "serviceVersion" : "3.35.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.docling.services.DoclingInfraService", "description" : "Docling is a document processing and conversion toolkit", @@ -637,7 +711,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-docling", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v1.26.0" + "serviceVersion" : "v1.26.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -647,7 +722,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.fhir.services.FhirInfraService", "description" : "HAPI FHIR RESTful test server", @@ -657,7 +733,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-fhir", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v8.10.0-2" + "serviceVersion" : "v8.10.0-2", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.pinecone.services.PineconeInfraService", "description" : "Pinecone is a vector database for machine learning applications", @@ -667,7 +744,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-pinecone", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v1.0.0.rc0" + "serviceVersion" : "v1.0.0.rc0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService", "description" : "Embedded FTP Server", @@ -677,7 +755,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ftp", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.2.1" + "serviceVersion" : "1.2.1", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.mongodb.services.MongoDBInfraService", "description" : "MongoDB is a document-oriented NoSQL database", @@ -687,5 +766,6 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-mongodb", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "7.0.31-jammy" + "serviceVersion" : "7.0.31-jammy", + "uiSupported" : true } ] \ No newline at end of file diff --git a/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/InfraService.java b/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/InfraService.java index fb6051e05581a..e4ef026135a79 100644 --- a/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/InfraService.java +++ b/core/camel-api/src/generated/java/org/apache/camel/spi/annotations/InfraService.java @@ -81,4 +81,13 @@ * @return */ String serviceVersion() default ""; + + /** + * Whether this service supports a web UI (built-in or via companion container). + * + * When true, the service interface should provide a {@code uiUrl()} method that returns the UI URL when available. + * + * @return true if the service has UI support + */ + boolean uiSupported() default false; } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java index e59bfd51653ad..8c6b0e7e9a541 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java @@ -167,6 +167,9 @@ public int listServices(Consumer> serviceConsumer) throws IOException if (service.aliasImplementation() != null) { services.get(alias).getAliasImplementation().addAll(service.aliasImplementation()); } + if (service.uiSupported()) { + services.get(alias).setUiSupported(true); + } } } @@ -182,7 +185,8 @@ public int listServices(Consumer> serviceConsumer) throws IOException .sorted() .collect(Collectors.joining(", ")), entry.getValue().getDescription(), - getServiceData(entry.getKey(), pid))); + getServiceData(entry.getKey(), pid), + entry.getValue().isUiSupported())); } rows.sort(Comparator.comparing(InfraList.Row::alias)); @@ -195,7 +199,7 @@ public int listServices(Consumer> serviceConsumer) throws IOException Jsoner.serialize( rows.stream().map(row -> new InfraBaseDTO( row.alias, row.aliasImplementation, row.description, - parseServiceData(row.serviceData()))) + parseServiceData(row.serviceData()), row.uiSupported())) .map(InfraBaseDTO::toMap) .collect(Collectors.toList()))); } else { @@ -204,19 +208,22 @@ public int listServices(Consumer> serviceConsumer) throws IOException // IMPLEMENTATION is capped and SERVICE_DATA keeps a compact fixed width; both truncate with an ellipsis // instead of overflowing the terminal (the full, structured service data is available via --json). int serviceDataWidth = 30; + int uiWidth = 4; int aliasWidth = width + 2; int pidWidth = showPidColumn() ? CamelTableColumns.measure("PID", Integer.MAX_VALUE, rows, r -> r.pid) : 0; int implWidth = CamelTableColumns.measure("IMPLEMENTATION", 35, rows, Row::aliasImplementation); - int overhead = TerminalWidthHelper.noBorderOverhead(showPidColumn() ? 5 : 4); + int overhead = TerminalWidthHelper.noBorderOverhead(showPidColumn() ? 6 : 5); int descWidth = CamelTableColumns.lastColumnWidth( - tw, overhead, pidWidth, aliasWidth, implWidth, serviceDataWidth); + tw, overhead, pidWidth, aliasWidth, implWidth, uiWidth, serviceDataWidth); printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().header("PID").visible(showPidColumn()).headerAlign(HorizontalAlign.CENTER).with(r -> r.pid), new Column().header("ALIAS").minWidth(aliasWidth).dataAlign(HorizontalAlign.LEFT) .with(Row::alias), new Column().header("IMPLEMENTATION").maxWidth(implWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .dataAlign(HorizontalAlign.LEFT).with(Row::aliasImplementation), + new Column().header("UI").maxWidth(uiWidth).dataAlign(HorizontalAlign.CENTER) + .with(r -> r.uiSupported() ? "x" : ""), CamelTableColumns.lastText("DESCRIPTION", descWidth).with(Row::description), new Column().header("SERVICE_DATA").maxWidth(serviceDataWidth, OverflowBehaviour.ELLIPSIS_RIGHT) .dataAlign(HorizontalAlign.LEFT).with(Row::serviceData)))); @@ -286,15 +293,18 @@ record TestInfraService( String groupId, String artifactId, String version, - String serviceVersion) { + String serviceVersion, + boolean uiSupported) { } - record Row(String pid, String alias, String aliasImplementation, String description, String serviceData) { + record Row(String pid, String alias, String aliasImplementation, String description, String serviceData, + boolean uiSupported) { } private static class InfraServiceAlias { private final String description; private final Set aliasImplementation = new HashSet<>(); + private boolean uiSupported; public InfraServiceAlias(String description) { this.description = description; @@ -307,5 +317,13 @@ public String getDescription() { public Set getAliasImplementation() { return aliasImplementation; } + + public boolean isUiSupported() { + return uiSupported; + } + + public void setUiSupported(boolean uiSupported) { + this.uiSupported = uiSupported; + } } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java index cfca1893cb33e..6016cc331f302 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraRun.java @@ -169,7 +169,6 @@ protected Integer doRun(String testService, String testServiceImplementation, Te if (port != null) { System.setProperty("camel.infra.port", String.valueOf(port)); } - Object actualService = cl.loadClass(serviceImpl).newInstance(); // Make sure the actualService can be run with initialize method @@ -364,4 +363,5 @@ public boolean isLogToStdout() { public void setLogToStdout(boolean logToStdout) { this.logToStdout = logToStdout; } + } diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/model/InfraBaseDTO.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/model/InfraBaseDTO.java index 8f69b30c8f2db..e92a0bac7f80f 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/model/InfraBaseDTO.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/model/InfraBaseDTO.java @@ -26,15 +26,18 @@ public class InfraBaseDTO { private String aliasImplementation; private String description; private Object serviceData; + private boolean uiSupported; public InfraBaseDTO() { } - public InfraBaseDTO(String alias, String aliasImplementation, String description, Object serviceData) { + public InfraBaseDTO(String alias, String aliasImplementation, String description, Object serviceData, + boolean uiSupported) { this.alias = alias; this.aliasImplementation = aliasImplementation; this.description = description; this.serviceData = serviceData; + this.uiSupported = uiSupported; } public String getAlias() { @@ -69,6 +72,14 @@ public void setServiceData(Object serviceData) { this.serviceData = serviceData; } + public boolean isUiSupported() { + return uiSupported; + } + + public void setUiSupported(boolean uiSupported) { + this.uiSupported = uiSupported; + } + public Map toMap() { JsonObject jo = new JsonObject(); jo.put("alias", alias); @@ -81,6 +92,7 @@ public Map toMap() { if (serviceData != null) { jo.put("serviceData", serviceData); } + jo.put("uiSupported", uiSupported); return jo; } } diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java index e8983b74be705..794fa260c8b48 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java +++ b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java @@ -77,7 +77,7 @@ public void serviceDataInJsonIsNestedNotEscaped() { String rawServiceData = "{\"host\":\"localhost\",\"port\":61616}"; Object serviceData = InfraBaseCommand.parseServiceData(rawServiceData); - InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", serviceData); + InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", serviceData, true); String json = Jsoner.serialize(List.of(dto.toMap())); // serviceData is embedded as a nested JSON object (so --json is machine-parseable), not a string-escaped blob @@ -93,7 +93,7 @@ public void malformedServiceDataIsOmittedFromJson() { // unparseable content is dropped rather than emitted as an escaped string Assertions.assertThat(serviceData).isNull(); - InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", serviceData); + InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", serviceData, true); String json = Jsoner.serialize(List.of(dto.toMap())); Assertions.assertThat(json).contains("\"alias\":\"artemis\""); diff --git a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json index 11e895795c962..71c1c305f7870 100644 --- a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json +++ b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json @@ -7,7 +7,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-milvus", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v2.6.20" + "serviceVersion" : "v2.6.20", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -17,7 +18,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -27,7 +29,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -37,7 +40,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.iggy.services.IggyInfraService", "description" : "Iggy is a persistent message streaming platform", @@ -47,7 +51,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-iggy", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.8.0" + "serviceVersion" : "0.8.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -57,7 +62,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.zookeeper.services.ZooKeeperInfraService", "description" : "Zookeeper is a server for highly reliable distributed coordination of cloud applications", @@ -67,7 +73,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-zookeeper", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.9.5" + "serviceVersion" : "3.9.5", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -77,7 +84,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.redis.services.RedisInfraService", "description" : "Redis is an open source in-memory data store", @@ -87,7 +95,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-redis", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "7.4.9-alpine" + "serviceVersion" : "7.4.9-alpine", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.elasticsearch.services.ElasticSearchInfraService", "description" : "Elasticsearch is a distributed search and analytics engine", @@ -97,7 +106,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-elasticsearch", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "9.1.0" + "serviceVersion" : "9.1.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService", "description" : "Apache Kafka, Distributed event streaming platform", @@ -107,7 +117,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-kafka", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.51.0-kafka-4.2.0" + "serviceVersion" : "0.51.0-kafka-4.2.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService", "description" : "Apache Kafka, Distributed event streaming platform", @@ -117,7 +128,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-kafka", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "8.3.0" + "serviceVersion" : "8.3.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.nats.services.NatsInfraService", "description" : "NATS is a high-performance messaging system for cloud native applications", @@ -127,7 +139,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-nats", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.14.2" + "serviceVersion" : "2.14.2", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -137,7 +150,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.postgres.services.PostgresInfraService", "description" : "PostgreSQL is an open source object-relational database", @@ -147,7 +161,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-postgres", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "17.10-alpine" + "serviceVersion" : "17.10-alpine", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService", "description" : "Apache Kafka, Distributed event streaming platform", @@ -157,7 +172,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-kafka", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v26.1.12" + "serviceVersion" : "v26.1.12", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.hashicorp.vault.services.HashicorpVaultInfraService", "description" : "HashiCorp Vault is a tool for securely accessing secrets", @@ -167,7 +183,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-hashicorp-vault", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.0.3" + "serviceVersion" : "2.0.3", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -177,7 +194,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.artemis.services.ArtemisInfraService", "description" : "Apache Artemis is an open source message broker", @@ -187,7 +205,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-artemis", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "latest" + "serviceVersion" : "latest", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.solr.services.SolrInfraService", "description" : "Apache Solr is an open source search platform", @@ -197,7 +216,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-solr", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "9.10.1-slim" + "serviceVersion" : "9.10.1-slim", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.couchbase.services.CouchbaseInfraService", "description" : "Couchbase is a distributed NoSQL cloud database", @@ -207,7 +227,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-couchbase", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "8.0.0" + "serviceVersion" : "8.0.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -217,7 +238,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.couchdb.services.CouchDbInfraService", "description" : "Apache CouchDB is an open source NoSQL document database", @@ -227,7 +249,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-couchdb", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.5.1" + "serviceVersion" : "3.5.1", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.keycloak.services.KeycloakInfraService", "description" : "Keycloak is an open source identity and access management solution", @@ -237,7 +260,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-keycloak", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "26.6.4" + "serviceVersion" : "26.6.4", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.hivemq.services.HiveMQInfraService", "description" : "HiveMQ is an MQTT-based messaging platform for IoT", @@ -247,7 +271,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-hivemq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2025.5" + "serviceVersion" : "2025.5", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.ibmmq.services.IbmMQInfraService", "description" : "IBM MQ is enterprise messaging middleware for reliable communication", @@ -257,7 +282,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ibmmq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "9.4.5.0-r2" + "serviceVersion" : "9.4.5.0-r2", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -267,7 +293,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.smb.services.SmbLocalContainerInfraService", "description" : "Samba provides file sharing services using the SMB protocol", @@ -277,7 +304,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-smb", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.14.0" + "serviceVersion" : "0.14.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.openldap.services.OpenldapInfraService", "description" : "OpenLDAP is an implementation of the Lightweight Directory Access Protocol", @@ -287,7 +315,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-openldap", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.0" + "serviceVersion" : "1.5.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.xmpp.services.XmppInfraService", "description" : "XMPP is an open communication protocol for messaging", @@ -297,7 +326,19 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-xmpp", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.3" + "serviceVersion" : "0.3", + "uiSupported" : false +}, { + "service" : "org.apache.camel.test.infra.opensearch.services.OpenSearchInfraService", + "description" : "OpenSearch is a distributed search and analytics engine", + "implementation" : "org.apache.camel.test.infra.opensearch.services.OpenSearchLocalContainerInfraService", + "alias" : [ "opensearch" ], + "aliasImplementation" : [ ], + "groupId" : "org.apache.camel", + "artifactId" : "camel-test-infra-opensearch", + "version" : "4.22.0-SNAPSHOT", + "serviceVersion" : "3.7.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.pulsar.services.PulsarInfraService", "description" : "Apache Pulsar is a distributed messaging and streaming platform", @@ -307,7 +348,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-pulsar", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "4.2.1" + "serviceVersion" : "4.2.1", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.artemis.services.ArtemisInfraService", "description" : "Apache Artemis is an open source message broker", @@ -317,7 +359,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-artemis", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "latest" + "serviceVersion" : "latest", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -327,7 +370,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -337,7 +381,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.google.pubsub.services.GooglePubSubInfraService", "description" : "Google Cloud Pub/Sub is a messaging service for event-driven systems", @@ -347,7 +392,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-google-pubsub", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "emulators" + "serviceVersion" : "emulators", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.chatscript.services.ChatScriptInfraService", "description" : "ChatScript is an open source chatbot engine", @@ -357,7 +403,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-chatscript", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "latest" + "serviceVersion" : "latest", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.arangodb.services.ArangoDBInfraService", "description" : "ArangoDB is a multi-model database for high-performance applications.", @@ -367,7 +414,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-arangodb", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.12.5.2" + "serviceVersion" : "3.12.5.2", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.ignite.services.IgniteInfraService", "description" : "Apache Ignite is a distributed database for high-performance computing", @@ -377,7 +425,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ignite", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.18.0" + "serviceVersion" : "2.18.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.rabbitmq.services.RabbitMQInfraService", "description" : "RabbitMQ is an open source message and streaming broker", @@ -387,7 +436,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-rabbitmq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "4.2.5-management" + "serviceVersion" : "4.2.5-management", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.mosquitto.services.MosquittoInfraService", "description" : "Mosquitto is a message broker that implements MQTT protocol", @@ -397,7 +447,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-mosquitto", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.0.22" + "serviceVersion" : "2.0.22", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.neo4j.services.Neo4jInfraService", "description" : "Neo4j is a graph database management system", @@ -407,7 +458,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-neo4j", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2026.05-community-ubi10" + "serviceVersion" : "2026.05-community-ubi10", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.rocketmq.services.RocketMQInfraService", "description" : "Apache RocketMQ is a distributed messaging and streaming platform", @@ -417,7 +469,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-rocketmq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "5.3.3" + "serviceVersion" : "5.3.3", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -427,7 +480,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -437,7 +491,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -447,7 +502,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.cassandra.services.CassandraInfraService", "description" : "Apache Cassandra is a distributed NoSQL database", @@ -457,7 +513,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-cassandra", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "5.0.8" + "serviceVersion" : "5.0.8", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -467,7 +524,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.hazelcast.services.HazelcastInfraService", "description" : "Hazelcast is a distributed in-memory computing platform", @@ -477,7 +535,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-hazelcast", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "5.4.0" + "serviceVersion" : "5.4.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.hivemq.services.HiveMQInfraService", "description" : "HiveMQ is an MQTT-based messaging platform for IoT", @@ -487,7 +546,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-hivemq", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "camel" + "serviceVersion" : "camel", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.postgres.services.PostgresInfraService", "description" : "PostgreSQL with pgvector extension for vector similarity search", @@ -497,7 +557,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-postgres", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "pg18" + "serviceVersion" : "pg18", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.microprofile.lra.services.MicroprofileLRAInfraService", "description" : "Transaction Manager for microservices that is based on the SAGA pattern for distributed transaction.", @@ -507,7 +568,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-microprofile-lra", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "5.13.1.Final-2.16.6.Final" + "serviceVersion" : "5.13.1.Final-2.16.6.Final", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.minio.services.MinioInfraService", "description" : "MinIO is a high-performance S3 compatible object storage", @@ -517,7 +579,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-minio", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "RELEASE.2025-09-07T16-13-09Z-cpuv1" + "serviceVersion" : "RELEASE.2025-09-07T16-13-09Z-cpuv1", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.kafka.services.KafkaInfraService", "description" : "Apache Kafka, Distributed event streaming platform", @@ -527,7 +590,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-kafka", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "4.3.1" + "serviceVersion" : "4.3.1", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.azure.common.services.AzureInfraService", "description" : "Local Azure services with Azurite", @@ -537,7 +601,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-azure-storage-queue", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.35.0" + "serviceVersion" : "3.35.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService", "description" : "Embedded SFTP Server", @@ -547,7 +612,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ftp", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.19.0" + "serviceVersion" : "2.19.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.jaeger.services.JaegerInfraService", "description" : "Jaeger is a distributed tracing backend with OTLP collector and UI", @@ -557,7 +623,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-jaeger", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.19.0" + "serviceVersion" : "2.19.0", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.infinispan.services.InfinispanInfraService", "description" : "Infinispan is a distributed in-memory key/value data store", @@ -567,7 +634,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-infinispan", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "16.2" + "serviceVersion" : "16.2", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.weaviate.services.WeaviateInfraService", "description" : "Weaviate is an open source vector database", @@ -577,7 +645,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-weaviate", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.37.4" + "serviceVersion" : "1.37.4", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.consul.services.ConsulInfraService", "description" : "Consul is a service networking solution", @@ -587,7 +656,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-consul", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "2.0.1" + "serviceVersion" : "2.0.1", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.qdrant.services.QdrantInfraService", "description" : "Qdrant is a vector similarity search engine and database", @@ -597,7 +667,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-qdrant", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v1.18.2-unprivileged" + "serviceVersion" : "v1.18.2-unprivileged", + "uiSupported" : true }, { "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService", "description" : "Embedded FTPS Server", @@ -607,7 +678,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ftp", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.2.1" + "serviceVersion" : "1.2.1", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.ollama.services.OllamaInfraService", "description" : "Ollama is a tool for running large language models locally", @@ -617,7 +689,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ollama", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "0.31.2" + "serviceVersion" : "0.31.2", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.azure.common.services.AzureInfraService", "description" : "Local Azure services with Azurite", @@ -627,7 +700,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-azure-storage-blob", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "3.35.0" + "serviceVersion" : "3.35.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.docling.services.DoclingInfraService", "description" : "Docling is a document processing and conversion toolkit", @@ -637,7 +711,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-docling", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v1.26.0" + "serviceVersion" : "v1.26.0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.aws.common.services.AWSInfraService", "description" : "Local AWS Services with LocalStack", @@ -647,7 +722,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-aws-v2", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.5.28" + "serviceVersion" : "1.5.28", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.fhir.services.FhirInfraService", "description" : "HAPI FHIR RESTful test server", @@ -657,7 +733,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-fhir", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v8.10.0-2" + "serviceVersion" : "v8.10.0-2", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.pinecone.services.PineconeInfraService", "description" : "Pinecone is a vector database for machine learning applications", @@ -667,7 +744,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-pinecone", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "v1.0.0.rc0" + "serviceVersion" : "v1.0.0.rc0", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService", "description" : "Embedded FTP Server", @@ -677,7 +755,8 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-ftp", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "1.2.1" + "serviceVersion" : "1.2.1", + "uiSupported" : false }, { "service" : "org.apache.camel.test.infra.mongodb.services.MongoDBInfraService", "description" : "MongoDB is a document-oriented NoSQL database", @@ -687,5 +766,6 @@ "groupId" : "org.apache.camel", "artifactId" : "camel-test-infra-mongodb", "version" : "4.22.0-SNAPSHOT", - "serviceVersion" : "7.0.31-jammy" + "serviceVersion" : "7.0.31-jammy", + "uiSupported" : true } ] \ No newline at end of file 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 357f4439c4634..9d5440b4e209c 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 @@ -58,4 +58,8 @@ default String user() { default String password() { return ""; } + + default String uiUrl() { + return String.format("http://%s:%d", host(), port()); + } } diff --git a/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBLocalContainerInfraService.java b/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBLocalContainerInfraService.java index 555231e0259ed..759f0304a2673 100644 --- a/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-arangodb/src/main/java/org/apache/camel/test/infra/arangodb/services/ArangoDBLocalContainerInfraService.java @@ -26,7 +26,8 @@ @InfraService(service = ArangoDBInfraService.class, description = "ArangoDB is a multi-model database for high-performance applications.", - serviceAlias = "arangodb") + serviceAlias = "arangodb", + uiSupported = true) public class ArangoDBLocalContainerInfraService implements ArangoDBInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(ArangoDBLocalContainerInfraService.class); diff --git a/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisAllInfraService.java b/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisAllInfraService.java index 3426db9d8eaba..3e8028c07dcbf 100644 --- a/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisAllInfraService.java +++ b/test-infra/camel-test-infra-artemis/src/main/java/org/apache/camel/test/infra/artemis/services/ArtemisAllInfraService.java @@ -25,7 +25,8 @@ @InfraService(service = ArtemisInfraService.class, description = "Apache Artemis is an open source message broker", - serviceAlias = "artemis") + serviceAlias = "artemis", + uiSupported = true) public class ArtemisAllInfraService implements ArtemisInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(ArtemisAllInfraService.class); @@ -102,4 +103,9 @@ public ArtemisContainer getContainer() { public String remoteURI() { return serviceAddress(); } + + @Override + public String uiUrl() { + return container.adminURL(); + } } 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 105fcefff66d7..09d97457de15b 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 @@ -59,6 +59,10 @@ default void registerProperties() { System.setProperty(ArtemisProperties.ARTEMIS_PASSWORD, password()); } + default String uiUrl() { + return null; + } + void restart(); long countMessages(String queue) throws Exception; diff --git a/test-infra/camel-test-infra-common/src/main/java/org/apache/camel/test/infra/common/services/ContainerEnvironmentUtil.java b/test-infra/camel-test-infra-common/src/main/java/org/apache/camel/test/infra/common/services/ContainerEnvironmentUtil.java index 72cbfc840e78b..7da3d1814fb8c 100644 --- a/test-infra/camel-test-infra-common/src/main/java/org/apache/camel/test/infra/common/services/ContainerEnvironmentUtil.java +++ b/test-infra/camel-test-infra-common/src/main/java/org/apache/camel/test/infra/common/services/ContainerEnvironmentUtil.java @@ -35,6 +35,7 @@ public final class ContainerEnvironmentUtil { public static final String STARTUP_ATTEMPTS_PROPERTY = ".startup.attempts"; public static final String INFRA_PORT_PROPERTY = "camel.infra.port"; public static final String INFRA_FIXED_PORT_PROPERTY = "camel.infra.fixedPort"; + private static final Logger LOG = LoggerFactory.getLogger(ContainerEnvironmentUtil.class); private static final AtomicInteger INSTANCE_COUNTER = new AtomicInteger(0); @@ -108,6 +109,17 @@ public static boolean isFixedPort(@SuppressWarnings("rawtypes") Class cls) { return fixedPort; } + /** + * Determines if companion UI containers should be started alongside infrastructure services. Returns true when in + * fixed port mode (Camel CLI). This ensures UI containers are never started during tests (which don't set + * fixedPort). + * + * @return true if companion UI containers should be started + */ + public static boolean isWithUi() { + return Boolean.parseBoolean(System.getProperty(INFRA_FIXED_PORT_PROPERTY, "false")); + } + public static String containerName(Class cls) { InfraService annotation = findAnnotation(cls); String name = null; diff --git a/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulInfraService.java b/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulInfraService.java index 08b0bc40cc6a7..c130c7fe0f727 100644 --- a/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulInfraService.java +++ b/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulInfraService.java @@ -28,4 +28,8 @@ public interface ConsulInfraService extends InfrastructureService { String host(); int port(); + + default String uiUrl() { + return getConsulUrl() + "/ui"; + } } diff --git a/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulLocalContainerInfraService.java b/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulLocalContainerInfraService.java index 25b8a248e2bcc..a44a53b99e40d 100644 --- a/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-consul/src/main/java/org/apache/camel/test/infra/consul/services/ConsulLocalContainerInfraService.java @@ -28,7 +28,8 @@ @InfraService(service = ConsulInfraService.class, description = "Consul is a service networking solution", - serviceAlias = { "consul" }) + serviceAlias = { "consul" }, + uiSupported = true) public class ConsulLocalContainerInfraService implements ConsulInfraService, ContainerService> { public static final String CONTAINER_NAME = "consul"; 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 b09cd51b5ba01..41fc41f1eed4a 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 @@ -63,4 +63,8 @@ default String endpointUri() { default String connectionBase() { return String.format("couchbase:%s://%s:%d", protocol(), hostname(), port()); } + + default String uiUrl() { + return String.format("http://%s:%d", hostname(), port()); + } } diff --git a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java index 1f22bd4a9e7ae..f5f74412d7007 100644 --- a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java @@ -37,7 +37,8 @@ @InfraService(service = CouchbaseInfraService.class, description = "Couchbase is a distributed NoSQL cloud database", - serviceAlias = { "couchbase" }) + serviceAlias = { "couchbase" }, + uiSupported = true) public class CouchbaseLocalContainerInfraService implements CouchbaseInfraService, ContainerService { private class CustomCouchbaseContainer extends CouchbaseContainer { 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 f9de00a66b592..95f238c71ce1c 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 @@ -43,4 +43,8 @@ default String endpointUri() { default String connectionBase() { return String.format("couchdb:http:%s:%d", host(), port()); } + + default String uiUrl() { + return String.format("http://%s:%d/_utils", host(), port()); + } } diff --git a/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbLocalContainerInfraService.java b/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbLocalContainerInfraService.java index 1a036ffac97a9..e74bd823d329f 100644 --- a/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-couchdb/src/main/java/org/apache/camel/test/infra/couchdb/services/CouchDbLocalContainerInfraService.java @@ -29,7 +29,8 @@ @InfraService(service = CouchDbInfraService.class, description = "Apache CouchDB is an open source NoSQL document database", - serviceAlias = { "couchdb" }) + serviceAlias = { "couchdb" }, + uiSupported = true) public class CouchDbLocalContainerInfraService implements CouchDbInfraService, ContainerService> { public static final String CONTAINER_NAME = "couchdb"; 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 bb83f4db7f3b4..cb12baf62cbbe 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 @@ -32,4 +32,8 @@ public interface HashicorpVaultInfraService extends InfrastructureService { default String scheme() { return "http"; } + + default String uiUrl() { + return String.format("%s://%s:%d/ui", scheme(), host(), port()); + } } diff --git a/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultLocalContainerInfraService.java b/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultLocalContainerInfraService.java index 55b05d1a86aa1..316fe5fda02e6 100644 --- a/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-hashicorp-vault/src/main/java/org/apache/camel/test/infra/hashicorp/vault/services/HashicorpVaultLocalContainerInfraService.java @@ -35,7 +35,8 @@ @InfraService(service = HashicorpVaultInfraService.class, description = "HashiCorp Vault is a tool for securely accessing secrets", serviceAlias = "hashicorp", - serviceImplementationAlias = "vault") + serviceImplementationAlias = "vault", + uiSupported = true) public class HashicorpVaultLocalContainerInfraService implements HashicorpVaultInfraService, ContainerService> { public static final String CONTAINER_NAME = "hashicorp-vault"; 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 0d668c697ee61..60bd1cee7f313 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 @@ -48,4 +48,8 @@ default String password() { default String brokerUrl() { return String.format("amqp://%s:%d", host(), port()); } + + default String uiUrl() { + return null; + } } diff --git a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java index 00d32805b8a98..41b577c539a1c 100644 --- a/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-ibmmq/src/main/java/org/apache/camel/test/infra/ibmmq/services/IbmMQLocalContainerInfraService.java @@ -39,7 +39,8 @@ @InfraService(service = IbmMQInfraService.class, description = "IBM MQ is enterprise messaging middleware for reliable communication", - serviceAlias = "ibmmq") + serviceAlias = "ibmmq", + uiSupported = true) public class IbmMQLocalContainerInfraService implements IbmMQInfraService, ContainerService> { public static final String CONTAINER_NAME = "ibmmq"; @@ -148,4 +149,9 @@ public String queueManager() { public int listenerPort() { return container.getMappedPort(MQ_LISTENER_PORT); } + + @Override + public String uiUrl() { + return String.format("https://%s:%d/ibmmq/console", container.getHost(), container.getMappedPort(WEB_CONSOLE_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 87124267fe753..1a55f60e62eed 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 @@ -37,4 +37,8 @@ public interface InfinispanInfraService extends InfrastructureService { default String hosts() { return String.format("%s:%d", host(), port()); } + + default String uiUrl() { + return String.format("http://%s:%d/console", host(), port()); + } } diff --git a/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanLocalContainerInfraService.java b/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanLocalContainerInfraService.java index 1c415377de072..15962f2ea89ca 100644 --- a/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-infinispan/src/main/java/org/apache/camel/test/infra/infinispan/services/InfinispanLocalContainerInfraService.java @@ -34,7 +34,8 @@ @InfraService(service = InfinispanInfraService.class, description = "Infinispan is a distributed in-memory key/value data store", - serviceAlias = { "infinispan" }) + serviceAlias = { "infinispan" }, + uiSupported = true) public class InfinispanLocalContainerInfraService implements InfinispanInfraService, ContainerService> { public static final String CONTAINER_NAME = "infinispan"; private static final String DEFAULT_USERNAME = "admin"; diff --git a/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerInfraService.java b/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerInfraService.java index d89088ea5b16f..03f5d468d65a6 100644 --- a/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerInfraService.java +++ b/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerInfraService.java @@ -45,4 +45,8 @@ default String collectorHttpEndpoint() { default String queryUiUrl() { return String.format("http://%s:%d", host(), queryUiPort()); } + + default String uiUrl() { + return queryUiUrl(); + } } diff --git a/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerLocalContainerInfraService.java b/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerLocalContainerInfraService.java index 94fa4c279dc74..9067785463f11 100644 --- a/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-jaeger/src/main/java/org/apache/camel/test/infra/jaeger/services/JaegerLocalContainerInfraService.java @@ -28,7 +28,8 @@ */ @InfraService(service = JaegerInfraService.class, description = "Jaeger is a distributed tracing backend with OTLP collector and UI", - serviceAlias = { "jaeger" }) + serviceAlias = { "jaeger" }, + uiSupported = true) public class JaegerLocalContainerInfraService implements JaegerInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(JaegerLocalContainerInfraService.class); diff --git a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ConfluentInfraService.java b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ConfluentInfraService.java index 93c95805f865e..2033f566b4aab 100644 --- a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ConfluentInfraService.java +++ b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ConfluentInfraService.java @@ -28,7 +28,7 @@ @InfraService(service = KafkaInfraService.class, description = "Apache Kafka, Distributed event streaming platform", - serviceAlias = "kafka", serviceImplementationAlias = "confluent") + serviceAlias = "kafka", serviceImplementationAlias = "confluent", uiSupported = true) public class ConfluentInfraService implements KafkaInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(ConfluentInfraService.class); diff --git a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ContainerLocalKafkaInfraService.java b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ContainerLocalKafkaInfraService.java index 80fc7143d1f89..be80531e52b56 100644 --- a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ContainerLocalKafkaInfraService.java +++ b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/ContainerLocalKafkaInfraService.java @@ -24,19 +24,25 @@ import org.apache.camel.test.infra.kafka.common.KafkaProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.testcontainers.Testcontainers; +import org.testcontainers.containers.GenericContainer; import org.testcontainers.kafka.KafkaContainer; import org.testcontainers.utility.DockerImageName; @InfraService(service = KafkaInfraService.class, description = "Apache Kafka, Distributed event streaming platform", - serviceAlias = "kafka") + serviceAlias = "kafka", uiSupported = true) public class ContainerLocalKafkaInfraService implements KafkaInfraService, ContainerService { public static final String KAFKA_IMAGE_NAME = LocalPropertyResolver.getProperty( ContainerLocalKafkaInfraService.class, KafkaProperties.KAFKA_CONTAINER); + private static final String KAFKA_UI_CONTAINER_IMAGE = "kafka-ui.container.image"; + private static final int KAFKA_UI_PORT = 9080; + private static final Logger LOG = LoggerFactory.getLogger(ContainerLocalKafkaInfraService.class); protected KafkaContainer kafka; + private GenericContainer uiContainer; public ContainerLocalKafkaInfraService() { kafka = initContainer(); @@ -87,14 +93,52 @@ public void initialize() { registerProperties(); LOG.info("Kafka bootstrap server running at address {}", kafka.getBootstrapServers()); + + if (ContainerEnvironmentUtil.isWithUi()) { + try { + startUiContainer(); + } catch (Exception e) { + LOG.warn("Failed to start Kafka UI container: {}", e.getMessage()); + } + } + } + + private void startUiContainer() { + String uiImage = LocalPropertyResolver.getProperty( + ContainerLocalKafkaInfraService.class, KAFKA_UI_CONTAINER_IMAGE); + int kafkaPort = ContainerEnvironmentUtil.getConfiguredPort(9092); + Testcontainers.exposeHostPorts(kafkaPort); + + uiContainer = new GenericContainer<>(uiImage) + .withEnv("DYNAMIC_CONFIG_ENABLED", "true") + .withEnv("KAFKA_CLUSTERS_0_NAME", "camel-infra") + .withEnv("KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS", "host.testcontainers.internal:" + kafkaPort) + .withEnv("SERVER_PORT", String.valueOf(KAFKA_UI_PORT)) + .withAccessToHost(true); + ContainerEnvironmentUtil.configurePort(uiContainer, true, KAFKA_UI_PORT); + uiContainer.start(); + + LOG.info("Kafka UI running at http://{}:{}", uiContainer.getHost(), uiContainer.getMappedPort(KAFKA_UI_PORT)); } @Override public void shutdown() { + if (uiContainer != null) { + LOG.info("Shutting down Kafka UI container"); + uiContainer.stop(); + } LOG.info("Shutting down Kafka container"); kafka.stop(); } + @Override + public String uiUrl() { + if (uiContainer != null && uiContainer.isRunning()) { + return String.format("http://%s:%d", uiContainer.getHost(), uiContainer.getMappedPort(KAFKA_UI_PORT)); + } + return null; + } + @Override public KafkaContainer getContainer() { return kafka; diff --git a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/KafkaInfraService.java b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/KafkaInfraService.java index 108982f577756..934cb23245e88 100644 --- a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/KafkaInfraService.java +++ b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/KafkaInfraService.java @@ -33,4 +33,7 @@ public interface KafkaInfraService extends InfrastructureService { String brokers(); + default String uiUrl() { + return null; + } } diff --git a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/RedpandaInfraService.java b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/RedpandaInfraService.java index 301791202efcf..b35bb07752355 100644 --- a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/RedpandaInfraService.java +++ b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/RedpandaInfraService.java @@ -28,7 +28,7 @@ @InfraService(service = KafkaInfraService.class, description = "Apache Kafka, Distributed event streaming platform", - serviceAlias = "kafka", serviceImplementationAlias = "redpanda") + serviceAlias = "kafka", serviceImplementationAlias = "redpanda", uiSupported = true) public class RedpandaInfraService implements KafkaInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(RedpandaInfraService.class); diff --git a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/StrimziInfraService.java b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/StrimziInfraService.java index f6cada56317fe..e7c5ab3aafe1e 100644 --- a/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/StrimziInfraService.java +++ b/test-infra/camel-test-infra-kafka/src/main/java/org/apache/camel/test/infra/kafka/services/StrimziInfraService.java @@ -28,7 +28,7 @@ @InfraService(service = KafkaInfraService.class, description = "Apache Kafka, Distributed event streaming platform", - serviceAlias = "kafka", serviceImplementationAlias = "strimzi") + serviceAlias = "kafka", serviceImplementationAlias = "strimzi", uiSupported = true) public class StrimziInfraService implements KafkaInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(StrimziInfraService.class); diff --git a/test-infra/camel-test-infra-kafka/src/main/resources/org/apache/camel/test/infra/kafka/services/container.properties b/test-infra/camel-test-infra-kafka/src/main/resources/org/apache/camel/test/infra/kafka/services/container.properties index e83a87bb99813..0abfcfe8e75be 100644 --- a/test-infra/camel-test-infra-kafka/src/main/resources/org/apache/camel/test/infra/kafka/services/container.properties +++ b/test-infra/camel-test-infra-kafka/src/main/resources/org/apache/camel/test/infra/kafka/services/container.properties @@ -25,3 +25,4 @@ kafka.container.image.version.freeze.major=true redpanda.container.image.version.exclude=fips,amd64,arm64 strimzi.container.image.version.freeze.major=true confluent.container.image.version.freeze.major=true +kafka-ui.container.image=mirror.gcr.io/provectuslabs/kafka-ui:v0.7.2 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 3108955e5fd61..8d2e9240e1054 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 @@ -58,4 +58,8 @@ default String username() { default String password() { return getKeycloakPassword(); } + + default String uiUrl() { + return serverUrl() + "/admin"; + } } diff --git a/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakLocalContainerInfraService.java b/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakLocalContainerInfraService.java index 16a3ced4b56b5..60abddf65c0a3 100644 --- a/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-keycloak/src/main/java/org/apache/camel/test/infra/keycloak/services/KeycloakLocalContainerInfraService.java @@ -33,7 +33,8 @@ @InfraService(service = KeycloakInfraService.class, description = "Keycloak is an open source identity and access management solution", - serviceAlias = { "keycloak" }) + serviceAlias = { "keycloak" }, + uiSupported = true) public class KeycloakLocalContainerInfraService implements KeycloakInfraService, ContainerService> { private static final Logger LOG = LoggerFactory.getLogger(KeycloakLocalContainerInfraService.class); 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 2594ae1c475d2..7ecdb6d32e3d1 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 @@ -40,4 +40,8 @@ public interface MinioInfraService extends InfrastructureService { default String endpoint() { return String.format("http://%s:%d", host(), port()); } + + default String uiUrl() { + return String.format("http://%s:%d", host(), consolePort()); + } } diff --git a/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioLocalContainerInfraService.java b/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioLocalContainerInfraService.java index 12a85538ff626..420006bc634f5 100644 --- a/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-minio/src/main/java/org/apache/camel/test/infra/minio/services/MinioLocalContainerInfraService.java @@ -30,7 +30,8 @@ @InfraService(service = MinioInfraService.class, description = "MinIO is a high-performance S3 compatible object storage", - serviceAlias = { "minio" }) + serviceAlias = { "minio" }, + uiSupported = true) public class MinioLocalContainerInfraService implements MinioInfraService, ContainerService> { public static final String CONTAINER_NAME = "minio"; private static final String ACCESS_KEY = System.getProperty(MinioProperties.ACCESS_KEY, "testAccessKey"); 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 392eaa2784aa0..acf146e486de0 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 @@ -40,4 +40,8 @@ public interface MongoDBInfraService extends InfrastructureService { default String hosts() { return getConnectionAddress(); } + + default String uiUrl() { + return null; + } } diff --git a/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBLocalContainerInfraService.java b/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBLocalContainerInfraService.java index caa92fe76048d..3e640ea871679 100644 --- a/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-mongodb/src/main/java/org/apache/camel/test/infra/mongodb/services/MongoDBLocalContainerInfraService.java @@ -24,16 +24,22 @@ import org.apache.camel.test.infra.mongodb.common.MongoDBProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.testcontainers.Testcontainers; +import org.testcontainers.containers.GenericContainer; import org.testcontainers.mongodb.MongoDBContainer; import org.testcontainers.utility.DockerImageName; @InfraService(service = MongoDBInfraService.class, description = "MongoDB is a document-oriented NoSQL database", - serviceAlias = { "mongodb" }) + serviceAlias = { "mongodb" }, uiSupported = true) public class MongoDBLocalContainerInfraService implements MongoDBInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(MongoDBLocalContainerInfraService.class); private static final int DEFAULT_MONGODB_PORT = 27017; + private static final String MONGO_EXPRESS_CONTAINER_IMAGE = "mongo-express.container.image"; + private static final int MONGO_EXPRESS_PORT = 8081; + private final MongoDBContainer container; + private GenericContainer uiContainer; public MongoDBLocalContainerInfraService() { this(LocalPropertyResolver.getProperty(MongoDBLocalContainerInfraService.class, MongoDBProperties.MONGODB_CONTAINER)); @@ -87,14 +93,46 @@ public void initialize() { container.start(); registerProperties(); LOG.info("MongoDB service running at {}", container.getReplicaSetUrl()); + + if (ContainerEnvironmentUtil.isWithUi()) { + try { + String uiImage = LocalPropertyResolver.getProperty( + MongoDBLocalContainerInfraService.class, MONGO_EXPRESS_CONTAINER_IMAGE); + int mongoPort = ContainerEnvironmentUtil.getConfiguredPort(DEFAULT_MONGODB_PORT); + Testcontainers.exposeHostPorts(mongoPort); + uiContainer = new GenericContainer<>(uiImage) + .withEnv("ME_CONFIG_MONGODB_URL", + "mongodb://host.testcontainers.internal:" + mongoPort + "/?directConnection=true") + .withEnv("ME_CONFIG_BASICAUTH", "false") + .withAccessToHost(true); + ContainerEnvironmentUtil.configurePort(uiContainer, true, MONGO_EXPRESS_PORT); + uiContainer.start(); + LOG.info("Mongo Express running at http://{}:{}", uiContainer.getHost(), + uiContainer.getMappedPort(MONGO_EXPRESS_PORT)); + } catch (Exception e) { + LOG.warn("Failed to start Mongo Express UI container: {}", e.getMessage()); + } + } } @Override public void shutdown() { + if (uiContainer != null) { + LOG.info("Stopping the Mongo Express container"); + uiContainer.stop(); + } LOG.info("Stopping the MongoDB container"); container.stop(); } + @Override + public String uiUrl() { + if (uiContainer != null && uiContainer.isRunning()) { + return String.format("http://%s:%d", uiContainer.getHost(), uiContainer.getMappedPort(MONGO_EXPRESS_PORT)); + } + return null; + } + @Override public MongoDBContainer getContainer() { return container; diff --git a/test-infra/camel-test-infra-mongodb/src/main/resources/org/apache/camel/test/infra/mongodb/services/container.properties b/test-infra/camel-test-infra-mongodb/src/main/resources/org/apache/camel/test/infra/mongodb/services/container.properties index 1b8c67213bc6d..773aea4f6ac96 100644 --- a/test-infra/camel-test-infra-mongodb/src/main/resources/org/apache/camel/test/infra/mongodb/services/container.properties +++ b/test-infra/camel-test-infra-mongodb/src/main/resources/org/apache/camel/test/infra/mongodb/services/container.properties @@ -19,3 +19,4 @@ mongodb.container.ppc64le=icr.io/ppc64le-oss/mongodb-ppc64le:4.4.24 mongodb.container.version.include=jammy mongodb.container.ppc64le.version.exclude=bv mongodb.container.ppc64le.version.freeze.major=true +mongo-express.container.image=mirror.gcr.io/library/mongo-express:1.0.2 diff --git a/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jInfraService.java b/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jInfraService.java index ece157e2ae0a5..a0ed56cbba02d 100644 --- a/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jInfraService.java +++ b/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jInfraService.java @@ -25,4 +25,8 @@ public interface Neo4jInfraService extends InfrastructureService { String getNeo4jDatabaseUser(); String getNeo4jDatabasePassword(); + + default String uiUrl() { + return null; + } } diff --git a/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jLocalContainerInfraService.java b/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jLocalContainerInfraService.java index fee77cd820617..f1901dd49766f 100644 --- a/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-neo4j/src/main/java/org/apache/camel/test/infra/neo4j/services/Neo4jLocalContainerInfraService.java @@ -30,7 +30,8 @@ @InfraService(service = Neo4jInfraService.class, description = "Neo4j is a graph database management system", - serviceAlias = { "neo4j" }) + serviceAlias = { "neo4j" }, + uiSupported = true) public class Neo4jLocalContainerInfraService implements Neo4jInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(Neo4jLocalContainerInfraService.class); @@ -110,4 +111,9 @@ public String getNeo4jDatabaseUser() { public String getNeo4jDatabasePassword() { return container.getAdminPassword(); } + + @Override + public String uiUrl() { + return String.format("http://%s:%d", container.getHost(), container.getMappedPort(7474)); + } } diff --git a/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchInfraService.java b/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchInfraService.java index 1a06dfc8b3596..b43715f081e83 100644 --- a/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchInfraService.java +++ b/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchInfraService.java @@ -32,4 +32,8 @@ default String getHttpHostAddress() { String getUsername(); String getPassword(); + + default String uiUrl() { + return null; + } } diff --git a/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchLocalContainerInfraService.java b/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchLocalContainerInfraService.java index 577ad23abbd36..aa4f68489b8c7 100644 --- a/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-opensearch/src/main/java/org/apache/camel/test/infra/opensearch/services/OpenSearchLocalContainerInfraService.java @@ -19,6 +19,7 @@ import java.time.Duration; +import org.apache.camel.spi.annotations.InfraService; import org.apache.camel.test.infra.common.LocalPropertyResolver; import org.apache.camel.test.infra.common.services.ContainerEnvironmentUtil; import org.apache.camel.test.infra.common.services.ContainerService; @@ -26,17 +27,27 @@ import org.opensearch.testcontainers.OpensearchContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.testcontainers.Testcontainers; +import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; import org.testcontainers.utility.DockerImageName; +@InfraService(service = OpenSearchInfraService.class, + description = "OpenSearch is a distributed search and analytics engine", + serviceAlias = { "opensearch" }, uiSupported = true) public class OpenSearchLocalContainerInfraService implements OpenSearchInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(OpenSearchLocalContainerInfraService.class); private static final int OPEN_SEARCH_PORT = 9200; private static final String USER_NAME = "admin"; // NOTE: default value used for testing purposes only. private static final String PASSWORD = "admin"; // NOSONAR + + private static final String OPENSEARCH_DASHBOARDS_CONTAINER_IMAGE = "opensearch-dashboards.container.image"; + private static final int OPENSEARCH_DASHBOARDS_PORT = 5601; + private final OpensearchContainer container; + private GenericContainer uiContainer; public OpenSearchLocalContainerInfraService() { this(LocalPropertyResolver.getProperty(OpenSearchLocalContainerInfraService.class, @@ -112,10 +123,39 @@ public void initialize() { registerProperties(); LOG.info("OpenSearch instance running at {}", getHttpHostAddress()); + + if (ContainerEnvironmentUtil.isWithUi()) { + try { + startUiContainer(); + } catch (Exception e) { + LOG.warn("Failed to start OpenSearch Dashboards UI container: {}", e.getMessage()); + } + } + } + + private void startUiContainer() { + String uiImage = LocalPropertyResolver.getProperty( + OpenSearchLocalContainerInfraService.class, OPENSEARCH_DASHBOARDS_CONTAINER_IMAGE); + int opensearchPort = ContainerEnvironmentUtil.getConfiguredPort(OPEN_SEARCH_PORT); + Testcontainers.exposeHostPorts(opensearchPort); + + uiContainer = new GenericContainer<>(uiImage) + .withEnv("OPENSEARCH_HOSTS", "[\"http://host.testcontainers.internal:" + opensearchPort + "\"]") + .withEnv("DISABLE_SECURITY_DASHBOARDS_PLUGIN", "true") + .withAccessToHost(true); + ContainerEnvironmentUtil.configurePort(uiContainer, true, OPENSEARCH_DASHBOARDS_PORT); + uiContainer.start(); + + LOG.info("OpenSearch Dashboards running at http://{}:{}", + uiContainer.getHost(), uiContainer.getMappedPort(OPENSEARCH_DASHBOARDS_PORT)); } @Override public void shutdown() { + if (uiContainer != null) { + LOG.info("Shutting down OpenSearch Dashboards container"); + uiContainer.stop(); + } LOG.info("Stopping the OpenSearch container"); container.stop(); } @@ -134,4 +174,13 @@ public String getUsername() { public String getPassword() { return PASSWORD; } + + @Override + public String uiUrl() { + if (uiContainer != null && uiContainer.isRunning()) { + return String.format("http://%s:%d", uiContainer.getHost(), + uiContainer.getMappedPort(OPENSEARCH_DASHBOARDS_PORT)); + } + return null; + } } diff --git a/test-infra/camel-test-infra-opensearch/src/main/resources/org/apache/camel/test/infra/opensearch/services/container.properties b/test-infra/camel-test-infra-opensearch/src/main/resources/org/apache/camel/test/infra/opensearch/services/container.properties index fa19956c85a6d..39403ac6b92d9 100644 --- a/test-infra/camel-test-infra-opensearch/src/main/resources/org/apache/camel/test/infra/opensearch/services/container.properties +++ b/test-infra/camel-test-infra-opensearch/src/main/resources/org/apache/camel/test/infra/opensearch/services/container.properties @@ -16,3 +16,4 @@ ## --------------------------------------------------------------------------- opensearch.container=mirror.gcr.io/opensearchproject/opensearch:3.7.0 opensearch.container.ppc64le=icr.io/ppc64le-oss/opensearch-ppc64le:3.3.0 +opensearch-dashboards.container.image=mirror.gcr.io/opensearchproject/opensearch-dashboards:2.21.0 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 4d6b5a3138745..aef2ac36aa1d7 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 @@ -64,4 +64,8 @@ default Map beanProperties() { properties.put("camel.beans.postgresDS.password", password()); return properties; } + + default String uiUrl() { + return null; + } } diff --git a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresLocalContainerInfraService.java b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresLocalContainerInfraService.java index cc09fcad11cde..87b40c04cd3f2 100644 --- a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresLocalContainerInfraService.java @@ -25,20 +25,27 @@ import org.apache.camel.test.infra.postgres.common.PostgresProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.testcontainers.Testcontainers; +import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.output.Slf4jLogConsumer; import org.testcontainers.postgresql.PostgreSQLContainer; import org.testcontainers.utility.DockerImageName; @InfraService(service = PostgresInfraService.class, description = "PostgreSQL is an open source object-relational database", - serviceAlias = { "postgres" }) + serviceAlias = { "postgres" }, uiSupported = true) public class PostgresLocalContainerInfraService implements PostgresInfraService, ContainerService { public static final String DEFAULT_POSTGRES_CONTAINER = LocalPropertyResolver.getProperty(PostgresLocalContainerInfraService.class, PostgresProperties.POSTGRES_CONTAINER); + + private static final String PGADMIN_CONTAINER_IMAGE = "pgadmin.container.image"; + private static final int PGADMIN_PORT = 5050; + private static final Logger LOG = LoggerFactory.getLogger(PostgresLocalContainerInfraService.class); private final PostgreSQLContainer container; + private GenericContainer uiContainer; public PostgresLocalContainerInfraService() { this(DEFAULT_POSTGRES_CONTAINER); @@ -96,10 +103,39 @@ public void initialize() { registerProperties(); LOG.info("Postgres instance running at {}", getServiceAddress()); + + if (ContainerEnvironmentUtil.isWithUi()) { + try { + startUiContainer(); + } catch (Exception e) { + LOG.warn("Failed to start pgAdmin UI container: {}", e.getMessage()); + } + } + } + + private void startUiContainer() { + String uiImage = LocalPropertyResolver.getProperty( + PostgresLocalContainerInfraService.class, PGADMIN_CONTAINER_IMAGE); + int pgPort = ContainerEnvironmentUtil.getConfiguredPort(5432); + Testcontainers.exposeHostPorts(pgPort); + + uiContainer = new GenericContainer<>(uiImage) + .withEnv("PGADMIN_DEFAULT_EMAIL", "admin@camel.apache.org") + .withEnv("PGADMIN_DEFAULT_PASSWORD", "admin") + .withEnv("PGADMIN_LISTEN_PORT", "5050") + .withAccessToHost(true); + ContainerEnvironmentUtil.configurePort(uiContainer, true, PGADMIN_PORT); + uiContainer.start(); + + LOG.info("pgAdmin running at http://{}:{}", uiContainer.getHost(), uiContainer.getMappedPort(PGADMIN_PORT)); } @Override public void shutdown() { + if (uiContainer != null) { + LOG.info("Shutting down pgAdmin container"); + uiContainer.stop(); + } LOG.info("Stopping the Postgres container"); container.stop(); } @@ -133,4 +169,12 @@ public String userName() { public String password() { return container.getPassword(); } + + @Override + public String uiUrl() { + if (uiContainer != null && uiContainer.isRunning()) { + return String.format("http://%s:%d", uiContainer.getHost(), uiContainer.getMappedPort(PGADMIN_PORT)); + } + return null; + } } diff --git a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresVectorLocalContainerInfraService.java b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresVectorLocalContainerInfraService.java index 3ac2a518edc40..169604470f3ee 100644 --- a/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresVectorLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-postgres/src/main/java/org/apache/camel/test/infra/postgres/services/PostgresVectorLocalContainerInfraService.java @@ -22,7 +22,7 @@ @InfraService(service = PostgresInfraService.class, description = "PostgreSQL with pgvector extension for vector similarity search", - serviceAlias = { "postgres-vector", "pgvector" }) + serviceAlias = { "postgres-vector", "pgvector" }, uiSupported = true) public class PostgresVectorLocalContainerInfraService extends PostgresLocalContainerInfraService { public static final String DEFAULT_POSTGRES_VECTOR_CONTAINER diff --git a/test-infra/camel-test-infra-postgres/src/main/resources/org/apache/camel/test/infra/postgres/services/container.properties b/test-infra/camel-test-infra-postgres/src/main/resources/org/apache/camel/test/infra/postgres/services/container.properties index 23cf52bd9544b..4445846efb37f 100644 --- a/test-infra/camel-test-infra-postgres/src/main/resources/org/apache/camel/test/infra/postgres/services/container.properties +++ b/test-infra/camel-test-infra-postgres/src/main/resources/org/apache/camel/test/infra/postgres/services/container.properties @@ -18,3 +18,4 @@ postgres.container=mirror.gcr.io/postgres:17.10-alpine postgres.container.version.include=alpine postgres.container.version.freeze.major=true postgres.vector.container=mirror.gcr.io/pgvector/pgvector:pg18 +pgadmin.container.image=mirror.gcr.io/dpage/pgadmin4:9 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 7ffc6998d81a4..2d54a24db7945 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 @@ -51,6 +51,10 @@ default String apiKey() { return ""; } + default String uiUrl() { + return String.format("http://%s:%d/dashboard", getHttpHost(), getHttpPort()); + } + default HttpResponse put(String path, Map 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-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantLocalContainerInfraService.java b/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantLocalContainerInfraService.java index 08605b8f43d19..2bfa142e730c4 100644 --- a/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-qdrant/src/main/java/org/apache/camel/test/infra/qdrant/services/QdrantLocalContainerInfraService.java @@ -29,7 +29,8 @@ @InfraService(service = QdrantInfraService.class, description = "Qdrant is a vector similarity search engine and database", - serviceAlias = { "qdrant" }) + serviceAlias = { "qdrant" }, + uiSupported = true) public class QdrantLocalContainerInfraService implements QdrantInfraService, ContainerService { public static final int HTTP_PORT = 6333; public static final int GRPC_PORT = 6334; 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 8c3682211964c..24e828942f237 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 @@ -89,4 +89,8 @@ default String host() { default String brokerUrl() { return String.format("amqp://%s:%d", hostname(), port()); } + + default String uiUrl() { + return managementUri(); + } } diff --git a/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQLocalContainerInfraService.java b/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQLocalContainerInfraService.java index 2aa1e46271ff3..704110fe12354 100644 --- a/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-rabbitmq/src/main/java/org/apache/camel/test/infra/rabbitmq/services/RabbitMQLocalContainerInfraService.java @@ -29,7 +29,8 @@ @InfraService(service = RabbitMQInfraService.class, description = "RabbitMQ is an open source message and streaming broker", - serviceAlias = { "rabbitmq" }) + serviceAlias = { "rabbitmq" }, + uiSupported = true) public class RabbitMQLocalContainerInfraService implements RabbitMQInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(RabbitMQLocalContainerInfraService.class); 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 0d7635248d908..9ad9dd05dada9 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 @@ -35,4 +35,8 @@ default String getServiceAddress() { default String endpointUri() { return String.format("spring-redis:%s:%d", host(), port()); } + + default String uiUrl() { + return null; + } } diff --git a/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisLocalContainerInfraService.java b/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisLocalContainerInfraService.java index 56ab2aaf41900..ae5297413cff9 100644 --- a/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-redis/src/main/java/org/apache/camel/test/infra/redis/services/RedisLocalContainerInfraService.java @@ -17,19 +17,25 @@ package org.apache.camel.test.infra.redis.services; import org.apache.camel.spi.annotations.InfraService; +import org.apache.camel.test.infra.common.LocalPropertyResolver; import org.apache.camel.test.infra.common.services.ContainerEnvironmentUtil; import org.apache.camel.test.infra.common.services.ContainerService; import org.apache.camel.test.infra.redis.common.RedisProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.testcontainers.Testcontainers; +import org.testcontainers.containers.GenericContainer; @InfraService(service = RedisInfraService.class, description = "Redis is an open source in-memory data store", - serviceAlias = { "redis" }) + serviceAlias = { "redis" }, uiSupported = true) public class RedisLocalContainerInfraService implements RedisInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(RedisLocalContainerInfraService.class); + private static final String REDIS_COMMANDER_CONTAINER_IMAGE = "redis-commander.container.image"; + private static final int REDIS_COMMANDER_PORT = 8082; private final RedisContainer container; + private GenericContainer uiContainer; public RedisLocalContainerInfraService() { container = initContainer(); @@ -71,14 +77,45 @@ public void initialize() { registerProperties(); LOG.info("Redis instance running at {}", getServiceAddress()); + + if (ContainerEnvironmentUtil.isWithUi()) { + try { + String uiImage = LocalPropertyResolver.getProperty( + RedisLocalContainerInfraService.class, REDIS_COMMANDER_CONTAINER_IMAGE); + int redisPort = ContainerEnvironmentUtil.getConfiguredPort(RedisProperties.DEFAULT_PORT); + Testcontainers.exposeHostPorts(redisPort); + uiContainer = new GenericContainer<>(uiImage) + .withEnv("REDIS_HOSTS", "local:host.testcontainers.internal:" + redisPort) + .withEnv("PORT", String.valueOf(REDIS_COMMANDER_PORT)) + .withAccessToHost(true); + ContainerEnvironmentUtil.configurePort(uiContainer, true, REDIS_COMMANDER_PORT); + uiContainer.start(); + LOG.info("Redis Commander running at http://{}:{}", uiContainer.getHost(), + uiContainer.getMappedPort(REDIS_COMMANDER_PORT)); + } catch (Exception e) { + LOG.warn("Failed to start Redis Commander UI container: {}", e.getMessage()); + } + } } @Override public void shutdown() { + if (uiContainer != null) { + LOG.info("Stopping the Redis Commander container"); + uiContainer.stop(); + } LOG.info("Stopping the Redis container"); container.stop(); } + @Override + public String uiUrl() { + if (uiContainer != null && uiContainer.isRunning()) { + return String.format("http://%s:%d", uiContainer.getHost(), uiContainer.getMappedPort(REDIS_COMMANDER_PORT)); + } + return null; + } + @Override public RedisContainer getContainer() { return container; diff --git a/test-infra/camel-test-infra-redis/src/main/resources/org/apache/camel/test/infra/redis/services/container.properties b/test-infra/camel-test-infra-redis/src/main/resources/org/apache/camel/test/infra/redis/services/container.properties index f2bf442ee54e7..72e89609a3b01 100644 --- a/test-infra/camel-test-infra-redis/src/main/resources/org/apache/camel/test/infra/redis/services/container.properties +++ b/test-infra/camel-test-infra-redis/src/main/resources/org/apache/camel/test/infra/redis/services/container.properties @@ -18,3 +18,4 @@ redis.container=mirror.gcr.io/redis:7.4.9-alpine redis.container.version.include=alpine redis.container.version.exclude=rc,beta redis.container.version.freeze.major=true +redis-commander.container.image=mirror.gcr.io/rediscommander/redis-commander:latest 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 5f5d8c79b42c2..1fac820bbba84 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 @@ -39,4 +39,8 @@ default String host() { default int port() { return getPort(); } + + default String uiUrl() { + return String.format("http://%s:%d/solr", host(), port()); + } } diff --git a/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrLocalContainerInfraService.java b/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrLocalContainerInfraService.java index 1abd2e3141ae7..70105cc8cee87 100644 --- a/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrLocalContainerInfraService.java +++ b/test-infra/camel-test-infra-solr/src/main/java/org/apache/camel/test/infra/solr/services/SolrLocalContainerInfraService.java @@ -25,7 +25,8 @@ @InfraService(service = SolrInfraService.class, description = "Apache Solr is an open source search platform", - serviceAlias = { "solr" }) + serviceAlias = { "solr" }, + uiSupported = true) public class SolrLocalContainerInfraService implements SolrInfraService, ContainerService { private static final Logger LOG = LoggerFactory.getLogger(SolrLocalContainerInfraService.class); diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CamelTestInfraGenerateMetadataMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CamelTestInfraGenerateMetadataMojo.java index 5332a0dcd18ba..27181414c3776 100644 --- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CamelTestInfraGenerateMetadataMojo.java +++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CamelTestInfraGenerateMetadataMojo.java @@ -119,6 +119,8 @@ public void execute() throws MojoExecutionException, MojoFailureException { infrastructureServiceModel.setDescription(av.asString()); } else if (av.name().equals("serviceVersion")) { annotationServiceVersion = av.asString(); + } else if (av.name().equals("uiSupported")) { + infrastructureServiceModel.setUiSupported(av.asBoolean()); } } @@ -378,6 +380,7 @@ private class InfrastructureServiceModel { private String artifactId; private String version; private String serviceVersion; + private boolean uiSupported; public String getService() { return service; @@ -450,5 +453,13 @@ public String getServiceVersion() { public void setServiceVersion(String serviceVersion) { this.serviceVersion = serviceVersion; } + + public boolean isUiSupported() { + return uiSupported; + } + + public void setUiSupported(boolean uiSupported) { + this.uiSupported = uiSupported; + } } } diff --git a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/InfraService.java b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/InfraService.java index fb6051e05581a..e4ef026135a79 100644 --- a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/InfraService.java +++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/annotations/InfraService.java @@ -81,4 +81,13 @@ * @return */ String serviceVersion() default ""; + + /** + * Whether this service supports a web UI (built-in or via companion container). + * + * When true, the service interface should provide a {@code uiUrl()} method that returns the UI URL when available. + * + * @return true if the service has UI support + */ + boolean uiSupported() default false; }