This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 0eebd4977602 CAMEL-26616: camel-azure-cosmosdb - run the integration
tests on Floci AZ (#29249)
0eebd4977602 is described below
commit 0eebd4977602cc98d27b100bec64d0d793ebe1f9
Author: Andrea Cosentino <[email protected]>
AuthorDate: Mon Nov 9 13:41:40 2026 +0100
CAMEL-26616: camel-azure-cosmosdb - run the integration tests on Floci AZ
(#29249)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Andrea Cosentino <[email protected]>
---
.../catalog/docs/azure-cosmosdb-component.adoc | 19 ++++-
.../apache/camel/catalog/test-infra/metadata.json | 11 +++
.../camel-azure/camel-azure-cosmosdb/pom.xml | 9 +++
.../src/main/docs/azure-cosmosdb-component.adoc | 19 ++++-
.../azure/cosmosdb/CosmosDbTestUtils.java | 41 ++++++----
.../integration/BaseCamelCosmosDbTestSupport.java | 5 ++
.../cosmosdb/integration/CosmosDbConsumerIT.java | 9 +--
.../cosmosdb/integration/CosmosDbProducerIT.java | 11 +--
.../operations/CosmosDbClientOperationsIT.java | 29 +++----
.../operations/CosmosDbContainerOperationsIT.java | 54 ++++++++-----
.../operations/CosmosDbDatabaseOperationsIT.java | 29 +++----
test-infra/camel-test-infra-all/pom.xml | 11 +++
.../src/generated/resources/META-INF/metadata.json | 11 +++
test-infra/camel-test-infra-azure-cosmosdb/pom.xml | 58 ++++++++++++++
.../cosmosdb/clients/AzureCosmosDbClientUtils.java | 87 ++++++++++++++++++++
.../cosmosdb/common/AzureCosmosDbProperties.java | 38 +++++++++
.../services/AzureCosmosDbInfraService.java | 37 +++++++++
.../AzureCosmosDbLocalContainerInfraService.java | 93 ++++++++++++++++++++++
.../services/AzureCosmosDbRemoteInfraService.java | 52 ++++++++++++
.../cosmosdb/services/AzureCosmosDbService.java | 24 ++++++
.../services/AzureCosmosDbServiceFactory.java | 78 ++++++++++++++++++
.../src/main/resources/META-INF/MANIFEST.MF | 0
test-infra/pom.xml | 1 +
23 files changed, 627 insertions(+), 99 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/azure-cosmosdb-component.adoc
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/azure-cosmosdb-component.adoc
index 9234de22d05e..0235305ad4ec 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/azure-cosmosdb-component.adoc
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/azure-cosmosdb-component.adoc
@@ -907,14 +907,27 @@ YAML::
== Important Development Notes
-When developing on this component, you will need to obtain your Azure
accessKey in order to run the integration tests. In addition to the mocked unit
tests,
+When developing on this component, in addition to the mocked unit tests,
you *will need to run the integration tests with every change you make or even
client upgrade as the Azure client can break things even on minor versions
upgrade.*
-To run the integration tests, on this component directory, run the following
maven command:
+The integration tests run against a local
https://github.com/floci-io/floci-az[Floci AZ] container, which needs Docker.
+To run them, on this component directory, run the following maven command:
[source,bash]
----
-mvn clean install -Dendpoint={{dbaddress}} -DaccessKey={{accessKey}}
+mvn verify
----
+
+Floci AZ does not emulate the change feed, the throughput of the databases,
and the queries of the databases and containers,
+so six tests run against an Azure Cosmos DB account only:
`CosmosDbConsumerIT`, `CosmosDbContainerOperationsIT.testCaptureChangeFeed`,
+`CosmosDbProducerIT.testReplaceDatabaseThroughput`,
`CosmosDbProducerIT.testQueryContainers`,
+`CosmosDbClientOperationsIT.testQueryAndReadAllDatabases` and
`CosmosDbDatabaseOperationsIT.testQueryAndReadAllContainers`.
+To run all the integration tests against an account in Azure, run the
following maven command instead:
+
+[source,bash]
+----
+mvn verify -Dendpoint={{dbaddress}} -DaccessKey={{accessKey}}
+----
+
Whereby `endpoint` is your Azure CosmosDB endpoint name and `accessKey` is the
access key being generated from Azure CosmosDB portal.
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 cc8303394261..4e20c62fb386 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
@@ -900,6 +900,17 @@
"version" : "4.24.0-SNAPSHOT",
"serviceVersion" : "v1.0.0.rc0",
"uiSupported" : false
+}, {
+ "service" :
"org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbInfraService",
+ "description" : "Local Azure Cosmos DB service with Floci AZ",
+ "implementation" :
"org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbLocalContainerInfraService",
+ "alias" : [ "azure" ],
+ "aliasImplementation" : [ "cosmos-db" ],
+ "groupId" : "org.apache.camel",
+ "artifactId" : "camel-test-infra-azure-cosmosdb",
+ "version" : "4.24.0-SNAPSHOT",
+ "serviceVersion" : "0.16.0",
+ "uiSupported" : false
}, {
"service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService",
"description" : "Embedded FTP Server",
diff --git a/components/camel-azure/camel-azure-cosmosdb/pom.xml
b/components/camel-azure/camel-azure-cosmosdb/pom.xml
index d733962c4ba9..a055ba8e4785 100644
--- a/components/camel-azure/camel-azure-cosmosdb/pom.xml
+++ b/components/camel-azure/camel-azure-cosmosdb/pom.xml
@@ -33,6 +33,9 @@
<description>Camel Azure CosmosDB Component</description>
<properties>
+ <!-- Floci AZ is not available on these platforms -->
+ <skipITs.ppc64le>true</skipITs.ppc64le>
+ <skipITs.s390x>true</skipITs.s390x>
</properties>
<dependencies>
@@ -84,5 +87,11 @@
<artifactId>commons-lang3</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-infra-azure-cosmosdb</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git
a/components/camel-azure/camel-azure-cosmosdb/src/main/docs/azure-cosmosdb-component.adoc
b/components/camel-azure/camel-azure-cosmosdb/src/main/docs/azure-cosmosdb-component.adoc
index 9234de22d05e..0235305ad4ec 100644
---
a/components/camel-azure/camel-azure-cosmosdb/src/main/docs/azure-cosmosdb-component.adoc
+++
b/components/camel-azure/camel-azure-cosmosdb/src/main/docs/azure-cosmosdb-component.adoc
@@ -907,14 +907,27 @@ YAML::
== Important Development Notes
-When developing on this component, you will need to obtain your Azure
accessKey in order to run the integration tests. In addition to the mocked unit
tests,
+When developing on this component, in addition to the mocked unit tests,
you *will need to run the integration tests with every change you make or even
client upgrade as the Azure client can break things even on minor versions
upgrade.*
-To run the integration tests, on this component directory, run the following
maven command:
+The integration tests run against a local
https://github.com/floci-io/floci-az[Floci AZ] container, which needs Docker.
+To run them, on this component directory, run the following maven command:
[source,bash]
----
-mvn clean install -Dendpoint={{dbaddress}} -DaccessKey={{accessKey}}
+mvn verify
----
+
+Floci AZ does not emulate the change feed, the throughput of the databases,
and the queries of the databases and containers,
+so six tests run against an Azure Cosmos DB account only:
`CosmosDbConsumerIT`, `CosmosDbContainerOperationsIT.testCaptureChangeFeed`,
+`CosmosDbProducerIT.testReplaceDatabaseThroughput`,
`CosmosDbProducerIT.testQueryContainers`,
+`CosmosDbClientOperationsIT.testQueryAndReadAllDatabases` and
`CosmosDbDatabaseOperationsIT.testQueryAndReadAllContainers`.
+To run all the integration tests against an account in Azure, run the
following maven command instead:
+
+[source,bash]
+----
+mvn verify -Dendpoint={{dbaddress}} -DaccessKey={{accessKey}}
+----
+
Whereby `endpoint` is your Azure CosmosDB endpoint name and `accessKey` is the
access key being generated from Azure CosmosDB portal.
diff --git
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/CosmosDbTestUtils.java
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/CosmosDbTestUtils.java
index 87c31165df27..2ae9c114914f 100644
---
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/CosmosDbTestUtils.java
+++
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/CosmosDbTestUtils.java
@@ -22,8 +22,12 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import com.azure.cosmos.CosmosAsyncClient;
-import com.azure.cosmos.CosmosClientBuilder;
+import
org.apache.camel.test.infra.azure.cosmosdb.clients.AzureCosmosDbClientUtils;
+import
org.apache.camel.test.infra.azure.cosmosdb.common.AzureCosmosDbProperties;
+import
org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbService;
+import
org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbServiceFactory;
import org.apache.camel.test.junit6.TestSupport;
+import org.apache.camel.util.ObjectHelper;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.function.Executable;
@@ -38,26 +42,29 @@ public final class CosmosDbTestUtils {
return TestSupport.loadExternalProperties(CosmosDbTestUtils.class,
"azure_key.properties");
}
- public static Properties loadAzureAccessFromJvmEnv() throws Exception {
- final Properties properties = new Properties();
- if (System.getProperty("endpoint") == null ||
System.getProperty("accessKey") == null) {
- throw new Exception(
- "Make sure to supply azure CosmosDB endpoint and
accessKey, e.g: mvn verify -Dendpoint=myacc-azure.com -DaccessKey=mykey");
+ /**
+ * The Cosmos DB account the integration tests run against: a local Floci
AZ container, unless the endpoint and
+ * accessKey system properties give an account on Azure, for example
+ * {@code mvn verify -Dendpoint=https://myaccount.documents.azure.com:443/
-DaccessKey=mykey}
+ */
+ public static AzureCosmosDbService createService() {
+ final String endpoint = System.getProperty("endpoint");
+ final String accessKey = System.getProperty("accessKey");
+
+ if (ObjectHelper.isNotEmpty(endpoint) &&
ObjectHelper.isNotEmpty(accessKey)) {
+ System.setProperty(AzureCosmosDbProperties.ENDPOINT, endpoint);
+ System.setProperty(AzureCosmosDbProperties.ACCESS_KEY, accessKey);
+ System.setProperty(AzureCosmosDbProperties.INSTANCE_TYPE,
"remote");
}
- properties.setProperty("endpoint", System.getProperty("endpoint"));
- properties.setProperty("access_key", System.getProperty("accessKey"));
- return properties;
+ return AzureCosmosDbServiceFactory.createSingletonService();
}
- public static CosmosAsyncClient createAsyncClient() throws Exception {
- final Properties properties = loadAzureAccessFromJvmEnv();
-
- return new CosmosClientBuilder()
- .key(properties.getProperty("access_key"))
- .endpoint(properties.getProperty("endpoint"))
- .contentResponseOnWriteEnabled(true)
- .buildAsyncClient();
+ /**
+ * A client of the account of {@link #createService()}
+ */
+ public static CosmosAsyncClient createAsyncClient() {
+ return AzureCosmosDbClientUtils.createAsyncClient();
}
public static void assertIllegalArgumentException(final Executable
executable) {
diff --git
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/BaseCamelCosmosDbTestSupport.java
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/BaseCamelCosmosDbTestSupport.java
index 01833bff3486..3de616aec07d 100644
---
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/BaseCamelCosmosDbTestSupport.java
+++
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/BaseCamelCosmosDbTestSupport.java
@@ -20,10 +20,15 @@ import com.azure.cosmos.CosmosAsyncClient;
import org.apache.camel.CamelContext;
import org.apache.camel.component.azure.cosmosdb.CosmosDbComponent;
import org.apache.camel.component.azure.cosmosdb.CosmosDbTestUtils;
+import
org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbService;
import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.extension.RegisterExtension;
public abstract class BaseCamelCosmosDbTestSupport extends CamelTestSupport {
+ @RegisterExtension
+ static AzureCosmosDbService service = CosmosDbTestUtils.createService();
+
protected CosmosAsyncClient client;
@Override
diff --git
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/CosmosDbConsumerIT.java
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/CosmosDbConsumerIT.java
index 9078aa4b9cdd..16c99e026f6c 100644
---
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/CosmosDbConsumerIT.java
+++
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/CosmosDbConsumerIT.java
@@ -27,17 +27,12 @@ import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledIfSystemProperties;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
import static org.junit.jupiter.api.Assertions.assertEquals;
-@EnabledIfSystemProperties({
- @EnabledIfSystemProperty(named = "endpoint", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB endpoint, e.g: mvn clean install -Dendpoint="),
- @EnabledIfSystemProperty(named = "accessKey", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB accessKey, e.g: mvn clean install -DaccessKey=")
-})
+@EnabledIfSystemProperty(named = "azure.instance.type", matches = "remote",
+ disabledReason = "Floci AZ does not emulate the
change feed: supply a Cosmos DB account, e.g: mvn verify -Dendpoint=...
-DaccessKey=...")
class CosmosDbConsumerIT extends BaseCamelCosmosDbTestSupport {
private static final String DATABASE_NAME =
RandomStringUtils.secure().nextAlphabetic(10).toLowerCase();
diff --git
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/CosmosDbProducerIT.java
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/CosmosDbProducerIT.java
index c028a12dc4a6..b7d46b599d35 100644
---
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/CosmosDbProducerIT.java
+++
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/CosmosDbProducerIT.java
@@ -33,19 +33,12 @@ import org.apache.camel.component.mock.MockEndpoint;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledIfSystemProperties;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
-@EnabledIfSystemProperties({
- @EnabledIfSystemProperty(named = "endpoint", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB endpoint, e.g: mvn clean install -Dendpoint="),
- @EnabledIfSystemProperty(named = "accessKey", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB accessKey, e.g: mvn clean install -DaccessKey=")
-})
public class CosmosDbProducerIT extends BaseCamelCosmosDbTestSupport {
@EndpointInject
private ProducerTemplate template;
@@ -191,6 +184,8 @@ public class CosmosDbProducerIT extends
BaseCamelCosmosDbTestSupport {
}
@Test
+ @EnabledIfSystemProperty(named = "azure.instance.type", matches = "remote",
+ disabledReason = "Floci AZ does not emulate the
throughput (offers) of the databases: supply a Cosmos DB account, e.g: mvn
verify -Dendpoint=... -DaccessKey=...")
void testReplaceDatabaseThroughput() throws InterruptedException {
final String databaseName =
RandomStringUtils.secure().nextAlphabetic(10).toLowerCase();
@@ -214,6 +209,8 @@ public class CosmosDbProducerIT extends
BaseCamelCosmosDbTestSupport {
}
@Test
+ @EnabledIfSystemProperty(named = "azure.instance.type", matches = "remote",
+ disabledReason = "Floci AZ does not emulate the
queries of the containers: supply a Cosmos DB account, e.g: mvn verify
-Dendpoint=... -DaccessKey=...")
void testQueryContainers() throws InterruptedException {
// create bunch of containers to test
final String prefixContainerNames =
RandomStringUtils.secure().nextAlphabetic(10).toLowerCase();
diff --git
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbClientOperationsIT.java
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbClientOperationsIT.java
index e0a5c125fb26..926218a786c6 100644
---
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbClientOperationsIT.java
+++
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbClientOperationsIT.java
@@ -16,49 +16,36 @@
*/
package org.apache.camel.component.azure.cosmosdb.integration.operations;
-import java.util.Properties;
-
-import com.azure.cosmos.CosmosAsyncClient;
-import com.azure.cosmos.CosmosClientBuilder;
import com.azure.cosmos.models.CosmosDatabaseProperties;
import com.azure.cosmos.models.CosmosDatabaseResponse;
import org.apache.camel.component.azure.cosmosdb.CosmosDbTestUtils;
import
org.apache.camel.component.azure.cosmosdb.client.CosmosAsyncClientWrapper;
import
org.apache.camel.component.azure.cosmosdb.operations.CosmosDbClientOperations;
+import
org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbService;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.condition.EnabledIfSystemProperties;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
+import org.junit.jupiter.api.extension.RegisterExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-@EnabledIfSystemProperties({
- @EnabledIfSystemProperty(named = "endpoint", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB endpoint, e.g: mvn clean install -Dendpoint="),
- @EnabledIfSystemProperty(named = "accessKey", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB accessKey, e.g: mvn clean install -DaccessKey=")
-})
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CosmosDbClientOperationsIT {
+ @RegisterExtension
+ static AzureCosmosDbService service = CosmosDbTestUtils.createService();
+
private CosmosAsyncClientWrapper clientWrapper;
@BeforeAll
- void prepare() throws Exception {
- final Properties properties =
CosmosDbTestUtils.loadAzureAccessFromJvmEnv();
-
- final CosmosAsyncClient client = new CosmosClientBuilder()
- .key(properties.getProperty("access_key"))
- .endpoint(properties.getProperty("endpoint"))
- .buildAsyncClient();
-
- clientWrapper = new CosmosAsyncClientWrapper(client);
+ void prepare() {
+ clientWrapper = new
CosmosAsyncClientWrapper(CosmosDbTestUtils.createAsyncClient());
}
@AfterEach
@@ -121,6 +108,8 @@ class CosmosDbClientOperationsIT {
}
@Test
+ @EnabledIfSystemProperty(named = "azure.instance.type", matches = "remote",
+ disabledReason = "Floci AZ does not emulate the
queries of the databases: supply a Cosmos DB account, e.g: mvn verify
-Dendpoint=... -DaccessKey=...")
void testQueryAndReadAllDatabases() {
// create bunch of databases
final String prefixDatabaseNames =
RandomStringUtils.secure().nextAlphabetic(10).toLowerCase();
diff --git
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbContainerOperationsIT.java
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbContainerOperationsIT.java
index 3fc43442d95d..075a4cd62b52 100644
---
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbContainerOperationsIT.java
+++
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbContainerOperationsIT.java
@@ -20,13 +20,11 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import java.util.function.Consumer;
import com.azure.cosmos.ChangeFeedProcessor;
-import com.azure.cosmos.CosmosAsyncClient;
import com.azure.cosmos.CosmosAsyncContainer;
-import com.azure.cosmos.CosmosClientBuilder;
+import com.azure.cosmos.CosmosException;
import com.azure.cosmos.models.CosmosItemResponse;
import com.azure.cosmos.models.PartitionKey;
import org.apache.camel.component.azure.cosmosdb.CosmosDbTestUtils;
@@ -34,14 +32,17 @@ import
org.apache.camel.component.azure.cosmosdb.client.CosmosAsyncClientWrapper
import
org.apache.camel.component.azure.cosmosdb.operations.CosmosDbClientOperations;
import
org.apache.camel.component.azure.cosmosdb.operations.CosmosDbContainerOperations;
import
org.apache.camel.component.azure.cosmosdb.operations.CosmosDbOperationsBuilder;
+import
org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbService;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.condition.EnabledIfSystemProperties;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -50,38 +51,45 @@ import static
org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-@EnabledIfSystemProperties({
- @EnabledIfSystemProperty(named = "endpoint", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB endpoint, e.g: mvn clean install -Dendpoint="),
- @EnabledIfSystemProperty(named = "accessKey", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB accessKey, e.g: mvn clean install -DaccessKey=")
-})
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CosmosDbContainerOperationsIT {
private static final String DATABASE_NAME =
RandomStringUtils.secure().nextAlphabetic(10).toLowerCase();
private static final String LEASE_DATABASE_NAME =
RandomStringUtils.secure().nextAlphabetic(10).toLowerCase();
+ private static final Logger LOG =
LoggerFactory.getLogger(CosmosDbContainerOperationsIT.class);
+
+ @RegisterExtension
+ static AzureCosmosDbService service = CosmosDbTestUtils.createService();
private CosmosAsyncClientWrapper clientWrapper;
private CosmosDbContainerOperations containerOperations;
private String containerId;
@BeforeAll
- void prepare() throws Exception {
- final Properties properties =
CosmosDbTestUtils.loadAzureAccessFromJvmEnv();
-
- final CosmosAsyncClient client = new CosmosClientBuilder()
- .contentResponseOnWriteEnabled(true)
- .key(properties.getProperty("access_key"))
- .endpoint(properties.getProperty("endpoint"))
- .buildAsyncClient();
-
- clientWrapper = new CosmosAsyncClientWrapper(client);
+ void prepare() {
+ clientWrapper = new
CosmosAsyncClientWrapper(CosmosDbTestUtils.createAsyncClient());
}
@AfterAll
void cleanup() {
- clientWrapper.getDatabase(DATABASE_NAME).delete().block();
- clientWrapper.getDatabase(LEASE_DATABASE_NAME).delete().block();
+ if (clientWrapper == null) {
+ return;
+ }
+ deleteDatabase(DATABASE_NAME);
+ // only testCaptureChangeFeed creates the lease database, and it does
not always run
+ deleteDatabase(LEASE_DATABASE_NAME);
+ }
+
+ // best effort, so that a failed cleanup does not hide the failure of a
test
+ private void deleteDatabase(String name) {
+ try {
+ clientWrapper.getDatabase(name).delete().block();
+ } catch (CosmosException e) {
+ if (e.getStatusCode() != 404) {
+ LOG.warn("Cannot delete the database {}: {}", name,
e.getMessage());
+ }
+ } catch (RuntimeException e) {
+ LOG.warn("Cannot delete the database {}: {}", name,
e.getMessage());
+ }
}
@BeforeEach
@@ -295,6 +303,8 @@ class CosmosDbContainerOperationsIT {
}
@Test
+ @EnabledIfSystemProperty(named = "azure.instance.type", matches = "remote",
+ disabledReason = "Floci AZ does not emulate the
change feed: supply a Cosmos DB account, e.g: mvn verify -Dendpoint=...
-DaccessKey=...")
void testCaptureChangeFeed() {
// we create our lease container first with our lease database
final Mono<CosmosAsyncContainer> leaseContainer =
CosmosDbOperationsBuilder.withClient(clientWrapper)
diff --git
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbDatabaseOperationsIT.java
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbDatabaseOperationsIT.java
index 8ec287aab0a4..5e9e4976e450 100644
---
a/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbDatabaseOperationsIT.java
+++
b/components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbDatabaseOperationsIT.java
@@ -16,10 +16,6 @@
*/
package org.apache.camel.component.azure.cosmosdb.integration.operations;
-import java.util.Properties;
-
-import com.azure.cosmos.CosmosAsyncClient;
-import com.azure.cosmos.CosmosClientBuilder;
import com.azure.cosmos.models.CosmosContainerProperties;
import com.azure.cosmos.models.CosmosContainerResponse;
import com.azure.cosmos.models.IndexingMode;
@@ -28,42 +24,33 @@ import
org.apache.camel.component.azure.cosmosdb.CosmosDbTestUtils;
import
org.apache.camel.component.azure.cosmosdb.client.CosmosAsyncClientWrapper;
import
org.apache.camel.component.azure.cosmosdb.operations.CosmosDbClientOperations;
import
org.apache.camel.component.azure.cosmosdb.operations.CosmosDbDatabaseOperations;
+import
org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbService;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.condition.EnabledIfSystemProperties;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
+import org.junit.jupiter.api.extension.RegisterExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-@EnabledIfSystemProperties({
- @EnabledIfSystemProperty(named = "endpoint", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB endpoint, e.g: mvn clean install -Dendpoint="),
- @EnabledIfSystemProperty(named = "accessKey", matches = ".*",
- disabledReason = "Make sure you supply
CosmosDB accessKey, e.g: mvn clean install -DaccessKey=")
-})
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CosmosDbDatabaseOperationsIT {
private static final String DATABASE_NAME =
RandomStringUtils.secure().nextAlphabetic(10).toLowerCase();
+ @RegisterExtension
+ static AzureCosmosDbService service = CosmosDbTestUtils.createService();
+
private CosmosAsyncClientWrapper clientWrapper;
private CosmosDbDatabaseOperations operations;
@BeforeAll
- void prepare() throws Exception {
- final Properties properties =
CosmosDbTestUtils.loadAzureAccessFromJvmEnv();
-
- final CosmosAsyncClient client = new CosmosClientBuilder()
- .key(properties.getProperty("access_key"))
- .endpoint(properties.getProperty("endpoint"))
- .buildAsyncClient();
-
- clientWrapper = new CosmosAsyncClientWrapper(client);
+ void prepare() {
+ clientWrapper = new
CosmosAsyncClientWrapper(CosmosDbTestUtils.createAsyncClient());
// create our testing database
clientWrapper.createDatabase(DATABASE_NAME).block();
@@ -127,6 +114,8 @@ class CosmosDbDatabaseOperationsIT {
}
@Test
+ @EnabledIfSystemProperty(named = "azure.instance.type", matches = "remote",
+ disabledReason = "Floci AZ does not emulate the
queries of the containers: supply a Cosmos DB account, e.g: mvn verify
-Dendpoint=... -DaccessKey=...")
void testQueryAndReadAllContainers() {
// create bunch of containers
final String prefixContainerNames =
RandomStringUtils.secure().nextAlphabetic(10).toLowerCase();
diff --git a/test-infra/camel-test-infra-all/pom.xml
b/test-infra/camel-test-infra-all/pom.xml
index b01eac332f60..bea09ffe17a5 100644
--- a/test-infra/camel-test-infra-all/pom.xml
+++ b/test-infra/camel-test-infra-all/pom.xml
@@ -71,6 +71,11 @@
<artifactId>camel-test-infra-rabbitmq</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-infra-azure-cosmosdb</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-infra-azure-eventgrid</artifactId>
@@ -443,6 +448,12 @@
<artifactId>camel-test-infra-rabbitmq</artifactId>
</dependency>
</fileSet>
+ <fileSet>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+
<artifactId>camel-test-infra-azure-cosmosdb</artifactId>
+ </dependency>
+ </fileSet>
<fileSet>
<dependency>
<groupId>org.apache.camel</groupId>
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 cc8303394261..4e20c62fb386 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
@@ -900,6 +900,17 @@
"version" : "4.24.0-SNAPSHOT",
"serviceVersion" : "v1.0.0.rc0",
"uiSupported" : false
+}, {
+ "service" :
"org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbInfraService",
+ "description" : "Local Azure Cosmos DB service with Floci AZ",
+ "implementation" :
"org.apache.camel.test.infra.azure.cosmosdb.services.AzureCosmosDbLocalContainerInfraService",
+ "alias" : [ "azure" ],
+ "aliasImplementation" : [ "cosmos-db" ],
+ "groupId" : "org.apache.camel",
+ "artifactId" : "camel-test-infra-azure-cosmosdb",
+ "version" : "4.24.0-SNAPSHOT",
+ "serviceVersion" : "0.16.0",
+ "uiSupported" : false
}, {
"service" : "org.apache.camel.test.infra.ftp.services.FtpInfraService",
"description" : "Embedded FTP Server",
diff --git a/test-infra/camel-test-infra-azure-cosmosdb/pom.xml
b/test-infra/camel-test-infra-azure-cosmosdb/pom.xml
new file mode 100644
index 000000000000..df2d6f78cd63
--- /dev/null
+++ b/test-infra/camel-test-infra-azure-cosmosdb/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>camel-test-infra-parent</artifactId>
+ <groupId>org.apache.camel</groupId>
+ <relativePath>../camel-test-infra-parent/pom.xml</relativePath>
+ <version>4.24.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>Camel :: Test Infra :: Azure Cosmos DB</name>
+ <artifactId>camel-test-infra-azure-cosmosdb</artifactId>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>com.azure</groupId>
+ <artifactId>azure-sdk-bom</artifactId>
+ <version>${azure-sdk-bom-version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-infra-azure-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- azure sdk -->
+ <dependency>
+ <groupId>com.azure</groupId>
+ <artifactId>azure-cosmos</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git
a/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/clients/AzureCosmosDbClientUtils.java
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/clients/AzureCosmosDbClientUtils.java
new file mode 100644
index 000000000000..c8f515c431c5
--- /dev/null
+++
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/clients/AzureCosmosDbClientUtils.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.test.infra.azure.cosmosdb.clients;
+
+import java.net.URI;
+import java.util.Objects;
+import java.util.Set;
+
+import com.azure.cosmos.CosmosAsyncClient;
+import com.azure.cosmos.CosmosClientBuilder;
+import
org.apache.camel.test.infra.azure.cosmosdb.common.AzureCosmosDbProperties;
+
+public final class AzureCosmosDbClientUtils {
+ /**
+ * The switch of the Cosmos DB SDK that skips the validation of the TLS
certificate of an emulator
+ */
+ public static final String EMULATOR_CERTIFICATE_VALIDATION_DISABLED
+ = "COSMOS.EMULATOR_SERVER_CERTIFICATE_VALIDATION_DISABLED";
+ /**
+ * The host of the emulator, for the SDK, when it is not a local one
+ */
+ public static final String EMULATOR_HOST = "COSMOS.EMULATOR_HOST";
+
+ // the hosts that the SDK takes as an emulator without COSMOS.EMULATOR_HOST
+ private static final Set<String> LOCAL_HOSTS = Set.of("localhost",
"127.0.0.1", "[::1]");
+
+ private AzureCosmosDbClientUtils() {
+
+ }
+
+ /**
+ * Builds a client of the account the tests run against: the local Floci
AZ container, unless the
+ * {@link AzureCosmosDbProperties#INSTANCE_TYPE} system property is {@code
remote}. Like the clients the
+ * azure-cosmosdb component builds by default, it returns the items it
writes.
+ * <p>
+ * For Floci AZ, the client works in gateway mode, the only one that Floci
AZ emulates (the component builds a
+ * direct-mode client, so a route uses the service through a client like
this one, set as its
+ * {@code cosmosAsyncClient}), keeps to the endpoint whatever locations
the emulator advertises, and does not
+ * validate the certificate that Floci AZ issues itself for its TLS.
+ */
+ public static CosmosAsyncClient createAsyncClient() {
+ String endpoint =
Objects.requireNonNull(System.getProperty(AzureCosmosDbProperties.ENDPOINT),
+ "The system property " + AzureCosmosDbProperties.ENDPOINT + "
gives the endpoint of the account");
+
+ CosmosClientBuilder builder = new CosmosClientBuilder()
+ .endpoint(endpoint)
+ .key(System.getProperty(AzureCosmosDbProperties.ACCESS_KEY))
+ .contentResponseOnWriteEnabled(true);
+
+ String instanceType =
System.getProperty(AzureCosmosDbProperties.INSTANCE_TYPE);
+ if (instanceType == null ||
instanceType.equals("local-azure-container")) {
+ trustEmulator(endpoint);
+ builder.gatewayMode()
+ .endpointDiscoveryEnabled(false);
+ }
+
+ return builder.buildAsyncClient();
+ }
+
+ /*
+ * The Cosmos DB SDK does not validate the certificate of an emulator, the
host localhost, 127.0.0.1, [::1] or the
+ * one of COSMOS.EMULATOR_HOST, when
COSMOS.EMULATOR_SERVER_CERTIFICATE_VALIDATION_DISABLED is true. It reads both
+ * when a client is built, so they apply to the clients built afterwards,
and to the emulator host only.
+ */
+ private static void trustEmulator(String endpoint) {
+ System.setProperty(EMULATOR_CERTIFICATE_VALIDATION_DISABLED, "true");
+ String host = URI.create(endpoint).getHost();
+ if (!LOCAL_HOSTS.contains(host)) {
+ System.setProperty(EMULATOR_HOST, host);
+ }
+ }
+}
diff --git
a/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/common/AzureCosmosDbProperties.java
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/common/AzureCosmosDbProperties.java
new file mode 100644
index 000000000000..834757c20524
--- /dev/null
+++
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/common/AzureCosmosDbProperties.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.test.infra.azure.cosmosdb.common;
+
+public final class AzureCosmosDbProperties {
+ /**
+ * The endpoint of the Cosmos DB account: registered by the local service,
read by the remote one
+ */
+ public static final String ENDPOINT = "azure.cosmosdb.endpoint";
+ /**
+ * The key of the Cosmos DB account: registered by the local service, read
by the remote one
+ */
+ public static final String ACCESS_KEY = "azure.cosmosdb.access.key";
+ /**
+ * The type of the service the tests run against: the local Floci AZ
container by default, {@code remote} for the
+ * account given by {@link #ENDPOINT} and {@link #ACCESS_KEY}
+ */
+ public static final String INSTANCE_TYPE = "azure.instance.type";
+
+ private AzureCosmosDbProperties() {
+
+ }
+}
diff --git
a/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbInfraService.java
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbInfraService.java
new file mode 100644
index 000000000000..3abf05b2e02f
--- /dev/null
+++
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbInfraService.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.test.infra.azure.cosmosdb.services;
+
+import org.apache.camel.test.infra.common.services.InfrastructureService;
+
+/**
+ * A Cosmos DB for NoSQL account. For the local one, of Floci AZ, a client
needs the gateway mode and the emulator
+ * certificate switch of the Cosmos DB SDK: see {@code
AzureCosmosDbLocalContainerInfraService}.
+ */
+public interface AzureCosmosDbInfraService extends InfrastructureService {
+
+ /**
+ * The endpoint of the account (the databaseEndpoint option of the
azure-cosmosdb component)
+ */
+ String endpoint();
+
+ /**
+ * The key of the account (the accountKey option of the azure-cosmosdb
component)
+ */
+ String accessKey();
+}
diff --git
a/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbLocalContainerInfraService.java
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbLocalContainerInfraService.java
new file mode 100644
index 000000000000..31a3c5fd5fa8
--- /dev/null
+++
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbLocalContainerInfraService.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.test.infra.azure.cosmosdb.services;
+
+import org.apache.camel.spi.annotations.InfraService;
+import org.apache.camel.test.infra.azure.common.AzureCredentialsHolder;
+import org.apache.camel.test.infra.azure.common.services.FlociAzContainer;
+import org.apache.camel.test.infra.azure.common.services.FlociAzInfraService;
+import
org.apache.camel.test.infra.azure.cosmosdb.common.AzureCosmosDbProperties;
+
+/**
+ * A local Cosmos DB for NoSQL account: Floci AZ emulates the gateway API of
the account in process (databases,
+ * containers, items and their SQL queries). The Java SDK connects to the
gateway over TLS only, so the container serves
+ * HTTPS next to HTTP on its port, with a certificate it issues when it starts.
+ * <p>
+ * A client of the service works in gateway mode, and skips the validation of
the certificate of the emulator with the
+ * {@code COSMOS.EMULATOR_SERVER_CERTIFICATE_VALIDATION_DISABLED} system
property, or the
+ * {@code COSMOS_EMULATOR_SERVER_CERTIFICATE_VALIDATION_DISABLED} environment
variable, set to {@code true}:
+ * {@code AzureCosmosDbClientUtils} builds such a client. The azure-cosmosdb
component builds a direct-mode client,
+ * which Floci AZ does not serve, so a route uses the service through a client
of its own, set as its
+ * {@code cosmosAsyncClient}.
+ * <p>
+ * Floci AZ does not emulate the change feed, the throughput of the databases
and containers, nor the queries of the
+ * databases and containers.
+ */
+@InfraService(service = AzureCosmosDbInfraService.class,
+ description = "Local Azure Cosmos DB service with Floci AZ",
+ serviceAlias = "azure", serviceImplementationAlias = "cosmos-db")
+public class AzureCosmosDbLocalContainerInfraService extends
FlociAzInfraService implements AzureCosmosDbInfraService {
+ /**
+ * The well-known key of the Cosmos DB emulator (Floci AZ accepts any key)
+ */
+ public static final String EMULATOR_KEY
+ =
"C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==";
+
+ @Override
+ protected FlociAzContainer initContainer(String imageName) {
+ return super.initContainer(imageName)
+ .withEnv("FLOCI_AZ_TLS_ENABLED", "true");
+ }
+
+ @Override
+ public void registerProperties() {
+ super.registerProperties();
+ System.setProperty(AzureCosmosDbProperties.ENDPOINT, endpoint());
+ System.setProperty(AzureCosmosDbProperties.ACCESS_KEY, accessKey());
+ }
+
+ /**
+ * The endpoint of the account, for example {@code
https://localhost:32768/devstoreaccount1-cosmos}. The Java SDK
+ * sends its requests to the root path of the endpoint, which Floci AZ
serves for this account too.
+ */
+ @Override
+ public String endpoint() {
+ return String.format("https://%s:%d/%s-cosmos", host(), port(),
accountName());
+ }
+
+ @Override
+ public String accessKey() {
+ return EMULATOR_KEY;
+ }
+
+ @Override
+ public AzureCredentialsHolder azureCredentials() {
+ String accountName = accountName();
+ return new AzureCredentialsHolder() {
+ @Override
+ public String accountName() {
+ return accountName;
+ }
+
+ @Override
+ public String accountKey() {
+ return EMULATOR_KEY;
+ }
+ };
+ }
+}
diff --git
a/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbRemoteInfraService.java
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbRemoteInfraService.java
new file mode 100644
index 000000000000..c2ee62c73686
--- /dev/null
+++
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbRemoteInfraService.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.test.infra.azure.cosmosdb.services;
+
+import
org.apache.camel.test.infra.azure.cosmosdb.common.AzureCosmosDbProperties;
+
+/**
+ * A Cosmos DB account on Azure, given by the {@link
AzureCosmosDbProperties#ENDPOINT} and
+ * {@link AzureCosmosDbProperties#ACCESS_KEY} system properties
+ */
+public class AzureCosmosDbRemoteInfraService implements
AzureCosmosDbInfraService {
+
+ @Override
+ public void registerProperties() {
+ // NO-OP
+ }
+
+ @Override
+ public void initialize() {
+ registerProperties();
+ }
+
+ @Override
+ public void shutdown() {
+ // NO-OP
+ }
+
+ @Override
+ public String endpoint() {
+ return System.getProperty(AzureCosmosDbProperties.ENDPOINT);
+ }
+
+ @Override
+ public String accessKey() {
+ return System.getProperty(AzureCosmosDbProperties.ACCESS_KEY);
+ }
+}
diff --git
a/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbService.java
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbService.java
new file mode 100644
index 000000000000..cd77f81de224
--- /dev/null
+++
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbService.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.test.infra.azure.cosmosdb.services;
+
+import org.apache.camel.test.infra.common.services.ContainerTestService;
+import org.apache.camel.test.infra.common.services.TestService;
+
+public interface AzureCosmosDbService extends AzureCosmosDbInfraService,
TestService, ContainerTestService {
+}
diff --git
a/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbServiceFactory.java
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbServiceFactory.java
new file mode 100644
index 000000000000..7055d9412494
--- /dev/null
+++
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbServiceFactory.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.test.infra.azure.cosmosdb.services;
+
+import org.apache.camel.test.infra.common.services.SimpleTestServiceBuilder;
+import org.apache.camel.test.infra.common.services.SingletonService;
+
+public final class AzureCosmosDbServiceFactory {
+
+ private static class SingletonAzureCosmosDbService extends
SingletonService<AzureCosmosDbService>
+ implements AzureCosmosDbService {
+ public SingletonAzureCosmosDbService(AzureCosmosDbService service,
String name) {
+ super(service, name);
+ }
+
+ @Override
+ public String endpoint() {
+ return getService().endpoint();
+ }
+
+ @Override
+ public String accessKey() {
+ return getService().accessKey();
+ }
+ }
+
+ private AzureCosmosDbServiceFactory() {
+
+ }
+
+ public static SimpleTestServiceBuilder<AzureCosmosDbService> builder() {
+ return new SimpleTestServiceBuilder<>("azure");
+ }
+
+ public static AzureCosmosDbService createService() {
+ return builder()
+ .addLocalMapping(AzureCosmosDbLocalContainerService::new)
+ .addRemoteMapping(AzureCosmosDbRemoteService::new)
+ .build();
+ }
+
+ public static AzureCosmosDbService createSingletonService() {
+ return SingletonServiceHolder.INSTANCE;
+ }
+
+ private static class SingletonServiceHolder {
+ static final AzureCosmosDbService INSTANCE;
+ static {
+ SimpleTestServiceBuilder<AzureCosmosDbService> instance =
builder();
+ instance.addLocalMapping(
+ () -> new SingletonAzureCosmosDbService(new
AzureCosmosDbLocalContainerService(), "azure-cosmos-db"))
+ .addRemoteMapping(AzureCosmosDbRemoteService::new);
+ INSTANCE = instance.build();
+ }
+ }
+
+ static class AzureCosmosDbLocalContainerService extends
AzureCosmosDbLocalContainerInfraService
+ implements AzureCosmosDbService {
+ }
+
+ static class AzureCosmosDbRemoteService extends
AzureCosmosDbRemoteInfraService implements AzureCosmosDbService {
+ }
+}
diff --git
a/test-infra/camel-test-infra-azure-cosmosdb/src/main/resources/META-INF/MANIFEST.MF
b/test-infra/camel-test-infra-azure-cosmosdb/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/test-infra/pom.xml b/test-infra/pom.xml
index 95570efda9ef..e8da1e527977 100644
--- a/test-infra/pom.xml
+++ b/test-infra/pom.xml
@@ -51,6 +51,7 @@
<module>camel-test-infra-mongodb</module>
<module>camel-test-infra-rabbitmq</module>
<module>camel-test-infra-azure-common</module>
+ <module>camel-test-infra-azure-cosmosdb</module>
<module>camel-test-infra-azure-eventgrid</module>
<module>camel-test-infra-azure-eventhubs</module>
<module>camel-test-infra-azure-functions</module>