oscerd commented on code in PR #29249:
URL: https://github.com/apache/camel/pull/29249#discussion_r4511022820


##########
test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/clients/AzureCosmosDbClientUtils.java:
##########
@@ -0,0 +1,151 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import com.azure.cosmos.CosmosAsyncClient;
+import com.azure.cosmos.CosmosClientBuilder;
+import 
org.apache.camel.test.infra.azure.cosmosdb.common.AzureCosmosDbProperties;
+
+public final class AzureCosmosDbClientUtils {
+    private static final String TRUST_STORE = "javax.net.ssl.trustStore";
+    private static final String TRUST_STORE_TYPE = 
"javax.net.ssl.trustStoreType";
+    private static final String TRUST_STORE_PASSWORD = 
"javax.net.ssl.trustStorePassword";
+    private static final String TRUST_STORE_PROVIDER = 
"javax.net.ssl.trustStoreProvider";
+
+    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.
+     */
+    public static CosmosAsyncClient createAsyncClient() {
+        CosmosClientBuilder builder = new CosmosClientBuilder()
+                .endpoint(System.getProperty(AzureCosmosDbProperties.ENDPOINT))
+                .key(System.getProperty(AzureCosmosDbProperties.ACCESS_KEY))
+                .contentResponseOnWriteEnabled(true);
+
+        String instanceType = 
System.getProperty(AzureCosmosDbProperties.INSTANCE_TYPE);
+        if (instanceType == null || 
instanceType.equals("local-azure-container")) {
+            // Floci AZ emulates the gateway API only, and the client keeps to 
the endpoint whatever locations the
+            // emulator advertises
+            builder.gatewayMode()
+                    .endpointDiscoveryEnabled(false);
+
+            return buildTrusting(builder, 
System.getProperty(AzureCosmosDbProperties.CERTIFICATE_URL));
+        }
+
+        return builder.buildAsyncClient();
+    }
+
+    /*
+     * The Cosmos DB SDK has no option for the certificates a client trusts: a 
client trusts the default trust store of
+     * the JVM, which it loads when it is built. The default trust store holds 
the certificate of the emulator, next to the
+     * certificates the JVM trusts, only while the client is built: the client 
trusts the emulator, and the trust of the
+     * JVM is the same once the client is built.
+     */
+    private static synchronized CosmosAsyncClient 
buildTrusting(CosmosClientBuilder builder, String certificateUrl) {
+        Map<String, String> previous = new HashMap<>();
+        for (String name : new String[] { TRUST_STORE, TRUST_STORE_TYPE, 
TRUST_STORE_PASSWORD, TRUST_STORE_PROVIDER }) {
+            previous.put(name, System.getProperty(name));
+        }
+
+        Path trustStoreFile = null;
+        try {
+            String password = UUID.randomUUID().toString();
+            trustStoreFile = Files.createTempFile("floci-az-cosmos-trust", 
".p12");
+            try (OutputStream out = Files.newOutputStream(trustStoreFile)) {
+                trustStore(readCertificate(certificateUrl)).store(out, 
password.toCharArray());
+            }
+
+            System.setProperty(TRUST_STORE, trustStoreFile.toString());
+            System.setProperty(TRUST_STORE_TYPE, "PKCS12");
+            System.setProperty(TRUST_STORE_PASSWORD, password);
+            System.clearProperty(TRUST_STORE_PROVIDER);
+
+            return builder.buildAsyncClient();

Review Comment:
   No longer applies after 58115fec3209: the client builds no temporary trust 
store any more. It sets the emulator switch of the Cosmos DB SDK, which the SDK 
reads when the client is built, so there is no file to delete and no reliance 
on when the SDK loads its `SslContext`.
   
   _Claude Code on behalf of Andrea Cosentino_



##########
components/camel-azure/camel-azure-cosmosdb/src/test/java/org/apache/camel/component/azure/cosmosdb/integration/operations/CosmosDbContainerOperationsIT.java:
##########
@@ -50,38 +49,31 @@
 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();
 
+    @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();
+        // only testCaptureChangeFeed creates the lease database, and it does 
not always run
+        clientWrapper.readAllDatabases()
+                .filter(database -> 
LEASE_DATABASE_NAME.equals(database.getId()))
+                .flatMap(database -> 
clientWrapper.getDatabase(LEASE_DATABASE_NAME).delete())
+                .blockLast();
     }

Review Comment:
   Fixed in 58115fec3209: the cleanup is best effort. It deletes each database 
directly, ignores a 404 (the lease database exists only when the change feed 
test ran), and logs any other failure at WARN instead of throwing it.
   
   _Claude Code on behalf of Andrea Cosentino_



##########
test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/clients/AzureCosmosDbClientUtils.java:
##########
@@ -0,0 +1,151 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import com.azure.cosmos.CosmosAsyncClient;
+import com.azure.cosmos.CosmosClientBuilder;
+import 
org.apache.camel.test.infra.azure.cosmosdb.common.AzureCosmosDbProperties;
+
+public final class AzureCosmosDbClientUtils {
+    private static final String TRUST_STORE = "javax.net.ssl.trustStore";
+    private static final String TRUST_STORE_TYPE = 
"javax.net.ssl.trustStoreType";
+    private static final String TRUST_STORE_PASSWORD = 
"javax.net.ssl.trustStorePassword";
+    private static final String TRUST_STORE_PROVIDER = 
"javax.net.ssl.trustStoreProvider";
+
+    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.
+     */
+    public static CosmosAsyncClient createAsyncClient() {
+        CosmosClientBuilder builder = new CosmosClientBuilder()
+                .endpoint(System.getProperty(AzureCosmosDbProperties.ENDPOINT))
+                .key(System.getProperty(AzureCosmosDbProperties.ACCESS_KEY))
+                .contentResponseOnWriteEnabled(true);
+
+        String instanceType = 
System.getProperty(AzureCosmosDbProperties.INSTANCE_TYPE);
+        if (instanceType == null || 
instanceType.equals("local-azure-container")) {
+            // Floci AZ emulates the gateway API only, and the client keeps to 
the endpoint whatever locations the
+            // emulator advertises
+            builder.gatewayMode()
+                    .endpointDiscoveryEnabled(false);
+
+            return buildTrusting(builder, 
System.getProperty(AzureCosmosDbProperties.CERTIFICATE_URL));

Review Comment:
   No longer applies after 58115fec3209: the certificate URL property is gone 
with the trust store. The client now requires the endpoint property with a 
message that names it (`Objects.requireNonNull`).
   
   _Claude Code on behalf of Andrea Cosentino_



##########
test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/services/AzureCosmosDbInfraService.java:
##########
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.camel.test.infra.azure.cosmosdb.services;
+
+import org.apache.camel.test.infra.common.services.InfrastructureService;
+
+/**
+ * A Cosmos DB for NoSQL account
+ */
+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();

Review Comment:
   Thanks for trying it. With 58115fec3209 there is no certificate to fetch any 
more: a client needs the gateway mode and the emulator switch of the SDK 
(`COSMOS.EMULATOR_SERVER_CERTIFICATE_VALIDATION_DISABLED`, or the 
`COSMOS_EMULATOR_SERVER_CERTIFICATE_VALIDATION_DISABLED` environment variable 
for `camel infra run` users). The Javadoc of the interface and of the local 
service, and the PR description, now say so, including that a route needs a 
`cosmosAsyncClient` of its own because the component builds a direct-mode 
client. The connection-mode option is 
[CAMEL-26763](https://issues.apache.org/jira/browse/CAMEL-26763).
   
   _Claude Code on behalf of Andrea Cosentino_



##########
test-infra/camel-test-infra-azure-cosmosdb/src/main/java/org/apache/camel/test/infra/azure/cosmosdb/clients/AzureCosmosDbClientUtils.java:
##########
@@ -0,0 +1,151 @@
+/*
+ * 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.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import com.azure.cosmos.CosmosAsyncClient;
+import com.azure.cosmos.CosmosClientBuilder;
+import 
org.apache.camel.test.infra.azure.cosmosdb.common.AzureCosmosDbProperties;
+
+public final class AzureCosmosDbClientUtils {
+    private static final String TRUST_STORE = "javax.net.ssl.trustStore";
+    private static final String TRUST_STORE_TYPE = 
"javax.net.ssl.trustStoreType";
+    private static final String TRUST_STORE_PASSWORD = 
"javax.net.ssl.trustStorePassword";
+    private static final String TRUST_STORE_PROVIDER = 
"javax.net.ssl.trustStoreProvider";
+
+    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.
+     */
+    public static CosmosAsyncClient createAsyncClient() {
+        CosmosClientBuilder builder = new CosmosClientBuilder()
+                .endpoint(System.getProperty(AzureCosmosDbProperties.ENDPOINT))
+                .key(System.getProperty(AzureCosmosDbProperties.ACCESS_KEY))
+                .contentResponseOnWriteEnabled(true);
+
+        String instanceType = 
System.getProperty(AzureCosmosDbProperties.INSTANCE_TYPE);
+        if (instanceType == null || 
instanceType.equals("local-azure-container")) {
+            // Floci AZ emulates the gateway API only, and the client keeps to 
the endpoint whatever locations the
+            // emulator advertises
+            builder.gatewayMode()
+                    .endpointDiscoveryEnabled(false);
+
+            return buildTrusting(builder, 
System.getProperty(AzureCosmosDbProperties.CERTIFICATE_URL));
+        }
+
+        return builder.buildAsyncClient();
+    }
+
+    /*
+     * The Cosmos DB SDK has no option for the certificates a client trusts: a 
client trusts the default trust store of
+     * the JVM, which it loads when it is built. The default trust store holds 
the certificate of the emulator, next to the
+     * certificates the JVM trusts, only while the client is built: the client 
trusts the emulator, and the trust of the
+     * JVM is the same once the client is built.
+     */
+    private static synchronized CosmosAsyncClient 
buildTrusting(CosmosClientBuilder builder, String certificateUrl) {

Review Comment:
   Thanks, adopted in 58115fec3209: the client sets 
`COSMOS.EMULATOR_SERVER_CERTIFICATE_VALIDATION_DISABLED`, plus 
`COSMOS.EMULATOR_HOST` when the Docker host is not a local one. The trust-store 
swap, the CA download and the PKCS12 file are gone. Against Floci AZ 16 ITs 
pass and 6 are remote only, as before.
   
   _Claude Code on behalf of Andrea Cosentino_



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to