You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2022/08/02 06:27:27 UTC
[camel-quarkus] branch main updated: Test Azure Storage Blob with credentialType AZURE_IDENTITY
This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new cf4974d5ec Test Azure Storage Blob with credentialType AZURE_IDENTITY
cf4974d5ec is described below
commit cf4974d5ec4317ad036f832ad263bbfc6a6467ca
Author: James Netherton <ja...@gmail.com>
AuthorDate: Mon Aug 1 10:21:08 2022 +0100
Test Azure Storage Blob with credentialType AZURE_IDENTITY
Fixes #3822
---
integration-test-groups/azure/README.adoc | 18 +++++-
integration-test-groups/azure/azure-resources.sh | 31 +++++++++-
.../azure/azure-storage-blob/pom.xml | 4 ++
.../storage/blob/it/AzureStorageBlobProducers.java | 58 ++++++++++++++++---
.../storage/blob/it/AzureStorageBlobRoutes.java | 12 ++++
.../azure/storage/blob/it/AzureStorageHelper.java | 66 ++++++++++++++++++++++
.../storage/blob/it/AzureStorageBlobTest.java | 60 +++++++++++++++++++-
integration-test-groups/azure/certs/azure-cert.pem | 54 ++++++++++++++++++
integration-tests/azure-grouped/pom.xml | 4 ++
9 files changed, 296 insertions(+), 11 deletions(-)
diff --git a/integration-test-groups/azure/README.adoc b/integration-test-groups/azure/README.adoc
index 7115205941..4a234eb335 100644
--- a/integration-test-groups/azure/README.adoc
+++ b/integration-test-groups/azure/README.adoc
@@ -27,8 +27,7 @@ To create all of the above, you can use `azure-resources.sh` script as follows.
$ ./azure-resources.sh create
----
-The script outputs a set of export commands that you may want to paste to your shell,
-or to your `.bashrc`.
+The script outputs a set of export commands that you may want to paste to your shell.
Here are the environment variables you need to set:
@@ -36,6 +35,13 @@ Here are the environment variables you need to set:
----
export AZURE_STORAGE_ACCOUNT_NAME=<your-azure-storage-account-name>
export AZURE_STORAGE_ACCOUNT_KEY=<your-azure-storage-account-key>
+
+# optional to test alternate authentication methods
+export AZURE_CLIENT_ID=<your-azure-app-client-id>
+export AZURE_CLIENT_SECRET=<your-azure-app-client-secret>
+export AZURE_TENANT_ID=<your-azure-app-tenant-id>
+export AZURE_CLIENT_CERTIFICATE_PATH=<your-azure-app-certificate-pem-file>
+
# the container has to exist before you run the test
export AZURE_EVENT_HUBS_BLOB_CONTAINER_NAME=<your-container-name>
export AZURE_EVENT_HUBS_CONNECTION_STRING="Endpoint=sb://<your-namespace>.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<your-key>;EntityPath=<your-hub-name>"
@@ -50,4 +56,12 @@ $ ./azure-resources.sh delete
You may want to `export CAMEL_QUARKUS_START_MOCK_BACKEND=false` to avoid starting the local Azurite container and make sure that you test against the real remote Azure API.
+==== Regenerating client certificates
+
+For convenience, a certificate is stored in this project to be used for client certificate authentication. It can be regenerated as follows.
+[source,shell]
+----
+openssl req -nodes -new -x509 -sha256 -days 1825 -out /tmp/azure-cert.pem -keyout /tmp/azure-cert-key.pem
+cat /tmp/azure-cert.pem /tmp/azure-cert-key.pem > ${PWD}/certs/azure-cert.pem
+----
diff --git a/integration-test-groups/azure/azure-resources.sh b/integration-test-groups/azure/azure-resources.sh
index 1e65e5b760..0e774bc022 100755
--- a/integration-test-groups/azure/azure-resources.sh
+++ b/integration-test-groups/azure/azure-resources.sh
@@ -28,6 +28,8 @@ suffix="$(az ad signed-in-user show --query displayName -o tsv | tr '[:upper:]'
suffix="${suffix}4"
export AZURE_STORAGE_ACCOUNT_NAME=cqacc${suffix}
export AZURE_BLOB_CONTAINER_NAME=cq-container-${suffix}
+export AZURE_APP_NAME=cq-app-${suffix}
+export AZURE_APP_CERT_PATH=${PWD}/certs/azure-cert.pem
export RESOURCE_GROUP=cq-res-group-${suffix}
export ZONE=westeurope
@@ -42,11 +44,30 @@ function createResources() {
az storage account create --name ${AZURE_STORAGE_ACCOUNT_NAME} --resource-group ${RESOURCE_GROUP} --location ${ZONE} --sku Standard_LRS --kind StorageV2
az storage account blob-service-properties update --enable-change-feed true --enable-delete-retention true --delete-retention-days 1 -n ${AZURE_STORAGE_ACCOUNT_NAME} -g ${RESOURCE_GROUP}
+ AZURE_APP_CREDENTIALS=/tmp/app-credentials.json
+ AZURE_CLIENT_ID=$(az ad app create --display-name ${AZURE_APP_NAME} --query 'appId' -o tsv)
+ az ad app credential reset --id ${AZURE_CLIENT_ID} > ${AZURE_APP_CREDENTIALS}
+ if [[ ! -f ${AZURE_APP_CREDENTIALS} ]]; then
+ echo "Credentials generation for application ${AZURE_APP_NAME} failed"
+ exit 1
+ fi
+
+ export AZURE_CLIENT_SECRET=$(grep password ${AZURE_APP_CREDENTIALS} | cut -f4 -d\" )
+ export AZURE_TENANT_ID=$(grep tenant ${AZURE_APP_CREDENTIALS} | cut -f4 -d\" )
+ rm -f ${AZURE_APP_CREDENTIALS}
+
+ az ad app credential reset --id ${AZURE_CLIENT_ID} --cert "@${AZURE_APP_CERT_PATH}" --append
+
SUBSCRIPTION_ID="$(az account list --query '[0].id' -o tsv)"
USER_ID="$(az ad signed-in-user show --query objectId -o tsv)"
- az role assignment create --role "Storage Blob Data Contributor" --assignee ${USER_ID} --scope "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Storage/storageAccounts/${AZURE_STORAGE_ACCOUNT_NAME}"
+ az role assignment create --role "Storage Blob Data Contributor" --assignee ${USER_ID} --scope "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Storage/storageAccounts/${AZURE_STORAGE_ACCOUNT_NAME}"
+
+ az ad sp create --id ${AZURE_CLIENT_ID}
+ az role assignment create --role "Storage Blob Data Contributor" --assignee ${AZURE_CLIENT_ID} --scope "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.Storage/storageAccounts/${AZURE_STORAGE_ACCOUNT_NAME}"
+ echo "Waiting for Azure resources to become available..."
sleep 30
+ echo
az storage container create --account-name ${AZURE_STORAGE_ACCOUNT_NAME} --name ${AZURE_BLOB_CONTAINER_NAME} --auth-mode login
@@ -64,6 +85,13 @@ function createResources() {
echo 'export AZURE_STORAGE_ACCOUNT_KEY="'${AZURE_STORAGE_ACCOUNT_KEY}'"'
echo 'export AZURE_EVENT_HUBS_BLOB_CONTAINER_NAME="'${AZURE_BLOB_CONTAINER_NAME}'"'
echo 'export AZURE_EVENT_HUBS_CONNECTION_STRING="'$AZURE_EVENT_HUBS_CONNECTION_STRING';EntityPath='${EH_NAME}'"'
+ echo
+ echo
+ echo "Optionally set the following to test alternate authentication mechanisms:"
+ echo 'export AZURE_CLIENT_ID="'${AZURE_CLIENT_ID}'"'
+ echo 'export AZURE_CLIENT_SECRET="'${AZURE_CLIENT_SECRET}'"'
+ echo 'export AZURE_TENANT_ID="'${AZURE_TENANT_ID}'"'
+ echo 'export AZURE_CLIENT_CERTIFICATE_PATH="'${AZURE_APP_CERT_PATH}'"'
}
@@ -75,6 +103,7 @@ function deleteResources() {
az storage container delete --account-name ${AZURE_STORAGE_ACCOUNT_NAME} --name ${AZURE_BLOB_CONTAINER_NAME}
az storage account delete --name ${AZURE_STORAGE_ACCOUNT_NAME} --resource-group ${RESOURCE_GROUP} --yes
az group delete --name ${RESOURCE_GROUP} --yes
+ az ad app delete --id $(az ad app list --display-name ${AZURE_APP_NAME} --query '[0].appId' -o tsv)
}
case "$1" in
diff --git a/integration-test-groups/azure/azure-storage-blob/pom.xml b/integration-test-groups/azure/azure-storage-blob/pom.xml
index def22f98ac..d54482424a 100644
--- a/integration-test-groups/azure/azure-storage-blob/pom.xml
+++ b/integration-test-groups/azure/azure-storage-blob/pom.xml
@@ -51,6 +51,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-integration-test-support-mock-backend</artifactId>
+ </dependency>
<!-- test dependencies -->
<dependency>
diff --git a/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobProducers.java b/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobProducers.java
index f15cabf492..44be3faff4 100644
--- a/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobProducers.java
+++ b/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobProducers.java
@@ -16,6 +16,8 @@
*/
package org.apache.camel.quarkus.component.azure.storage.blob.it;
+import java.io.IOException;
+
import javax.inject.Named;
import com.azure.core.http.policy.HttpLogDetailLevel;
@@ -24,6 +26,8 @@ import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.common.StorageSharedKeyCredential;
import org.apache.camel.component.azure.storage.blob.BlobComponent;
+import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
+import org.apache.camel.component.azure.storage.blob.CredentialType;
import org.eclipse.microprofile.config.inject.ConfigProperty;
public class AzureStorageBlobProducers {
@@ -37,21 +41,61 @@ public class AzureStorageBlobProducers {
@ConfigProperty(name = "azure.blob.service.url")
String azureBlobServiceUrl;
+ @Named("azureStorageSharedKeyCredential")
+ public StorageSharedKeyCredential azureStorageSharedKeyCredential() {
+ return new StorageSharedKeyCredential(azureStorageAccountName, azureStorageAccountKey);
+ }
+
@Named("azureBlobServiceClient")
- public BlobServiceClient createBlobClient() throws Exception {
- StorageSharedKeyCredential credentials = new StorageSharedKeyCredential(azureStorageAccountName,
- azureStorageAccountKey);
- return new BlobServiceClientBuilder()
- .endpoint(azureBlobServiceUrl)
- .credential(credentials)
- .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS).setPrettyPrintBody(true))
+ public BlobServiceClient createBlobClient(StorageSharedKeyCredential credential) {
+ return getBlobClientBuilder()
+ .credential(credential)
.buildClient();
}
@Named("azure-storage-blob-managed-client")
public BlobComponent azureBlobComponentWithManagedClient() {
+ BlobConfiguration configuration = new BlobConfiguration();
+ configuration.setCredentialType(CredentialType.SHARED_KEY_CREDENTIAL);
+
BlobComponent component = new BlobComponent();
component.setAutowiredEnabled(false);
+ component.setConfiguration(configuration);
return component;
}
+
+ @Named("azure-storage-blob-client-secret-auth")
+ public BlobComponent azureStorageBlobClientSecretAuth() {
+ if (AzureStorageHelper.isClientSecretAuthEnabled()) {
+ BlobConfiguration configuration = new BlobConfiguration();
+ configuration.setCredentialType(CredentialType.AZURE_IDENTITY);
+
+ BlobComponent component = new BlobComponent();
+ component.setAutowiredEnabled(false);
+ component.setConfiguration(configuration);
+ return component;
+ }
+ return null;
+ }
+
+ @Named("azure-storage-blob-client-certificate-auth")
+ public BlobComponent azureStorageBlobClientCertificateAuth() throws IOException {
+ if (AzureStorageHelper.isClientCertificateAuthEnabled()) {
+ BlobConfiguration configuration = new BlobConfiguration();
+ configuration.setCredentialType(CredentialType.AZURE_IDENTITY);
+
+ BlobComponent component = new BlobComponent();
+ component.setAutowiredEnabled(false);
+ component.setConfiguration(configuration);
+ return component;
+ }
+ return null;
+ }
+
+ private BlobServiceClientBuilder getBlobClientBuilder() {
+ return new BlobServiceClientBuilder().endpoint(azureBlobServiceUrl)
+ .httpLogOptions(new HttpLogOptions()
+ .setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)
+ .setPrettyPrintBody(true));
+ }
}
diff --git a/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobRoutes.java b/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobRoutes.java
index 7f6cfa8d7f..d3260a0d0c 100644
--- a/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobRoutes.java
+++ b/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobRoutes.java
@@ -54,6 +54,18 @@ public class AzureStorageBlobRoutes extends RouteBuilder {
.to(componentUri("azure-storage-blob-managed-client", BlobOperationsDefinition.getBlob)
+ "&autowiredEnabled=false");
+ if (AzureStorageHelper.isClientSecretAuthEnabled()) {
+ from("direct:readWithClientSecret")
+ .to(componentUri("azure-storage-blob-client-secret-auth", BlobOperationsDefinition.getBlob)
+ + "&autowiredEnabled=false");
+ }
+
+ if (AzureStorageHelper.isClientCertificateAuthEnabled()) {
+ from("direct:readWithClientCertificate")
+ .to(componentUri("azure-storage-blob-client-certificate-auth", BlobOperationsDefinition.getBlob)
+ + "&autowiredEnabled=false");
+ }
+
from("direct:update")
.to(componentUri(BlobOperationsDefinition.uploadBlockBlob));
diff --git a/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageHelper.java b/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageHelper.java
new file mode 100644
index 0000000000..b9a6c7a498
--- /dev/null
+++ b/integration-test-groups/azure/azure-storage-blob/src/main/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageHelper.java
@@ -0,0 +1,66 @@
+/*
+ * 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.quarkus.component.azure.storage.blob.it;
+
+import java.util.function.BooleanSupplier;
+
+import org.apache.camel.quarkus.test.mock.backend.MockBackendUtils;
+import org.eclipse.microprofile.config.ConfigProvider;
+
+public class AzureStorageHelper {
+
+ private static final BooleanSupplier clientSecretAuthEnabled = new ClientSecretAuthEnabled();
+ private static final BooleanSupplier clientCertificateAuthEnabled = new ClientCertificateAuthEnabled();
+
+ public static class ClientSecretAuthEnabled implements BooleanSupplier {
+ @Override
+ public boolean getAsBoolean() {
+ return !MockBackendUtils.startMockBackend() &&
+ isAzureConfigValuePresent("azure.client.id") &&
+ isAzureConfigValuePresent("azure.tenant.id") &&
+ isAzureConfigValuePresent("azure.client.secret");
+ }
+ }
+
+ public static class ClientCertificateAuthEnabled implements BooleanSupplier {
+ @Override
+ public boolean getAsBoolean() {
+ return !MockBackendUtils.startMockBackend() &&
+ isAzureConfigValuePresent("azure.client.id") &&
+ isAzureConfigValuePresent("azure.tenant.id") &&
+ isAzureConfigValuePresent("azure.client.certificate.path");
+ }
+ }
+
+ private AzureStorageHelper() {
+ // Utility class
+ }
+
+ public static boolean isClientSecretAuthEnabled() {
+ return clientSecretAuthEnabled.getAsBoolean();
+ }
+
+ public static boolean isClientCertificateAuthEnabled() {
+ return clientCertificateAuthEnabled.getAsBoolean();
+ }
+
+ private static boolean isAzureConfigValuePresent(String name) {
+ return ConfigProvider.getConfig()
+ .getOptionalValue(name, String.class)
+ .isPresent();
+ }
+}
diff --git a/integration-test-groups/azure/azure-storage-blob/src/test/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobTest.java b/integration-test-groups/azure/azure-storage-blob/src/test/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobTest.java
index de772d5902..f55e462205 100644
--- a/integration-test-groups/azure/azure-storage-blob/src/test/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobTest.java
+++ b/integration-test-groups/azure/azure-storage-blob/src/test/java/org/apache/camel/quarkus/component/azure/storage/blob/it/AzureStorageBlobTest.java
@@ -33,6 +33,8 @@ import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.path.json.JsonPath;
+import org.apache.camel.quarkus.component.azure.storage.blob.it.AzureStorageHelper.ClientCertificateAuthEnabled;
+import org.apache.camel.quarkus.component.azure.storage.blob.it.AzureStorageHelper.ClientSecretAuthEnabled;
import org.apache.camel.quarkus.test.EnabledIf;
import org.apache.camel.quarkus.test.mock.backend.MockBackendDisabled;
import org.apache.camel.quarkus.test.support.azure.AzureStorageTestResource;
@@ -45,9 +47,9 @@ import org.testcontainers.shaded.org.awaitility.Awaitility;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.StringEndsWith.endsWith;
-import static org.hamcrest.text.MatchesPattern.matchesPattern;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
@@ -544,4 +546,60 @@ class AzureStorageBlobTest {
.statusCode(anyOf(is(204), is(404)));
}
}
+
+ // Authentication with client secrets is not possible with Azurite
+ @EnabledIf({ ClientSecretAuthEnabled.class })
+ @Test
+ public void readWithClientSecretAuth() {
+ try {
+ // Create
+ RestAssured.given()
+ .contentType(ContentType.TEXT)
+ .body(BLOB_CONTENT)
+ .post("/azure-storage-blob/blob/create")
+ .then()
+ .statusCode(201);
+
+ // Read
+ RestAssured.given()
+ .queryParam("uri", "direct:readWithClientSecret")
+ .get("/azure-storage-blob/blob/read")
+ .then()
+ .statusCode(200)
+ .body(is(BLOB_CONTENT));
+ } finally {
+ // Delete
+ RestAssured.delete("/azure-storage-blob/blob/delete")
+ .then()
+ .statusCode(anyOf(is(204), is(404)));
+ }
+ }
+
+ // Authentication with client certificates is not possible with Azurite
+ @EnabledIf({ ClientCertificateAuthEnabled.class })
+ @Test
+ public void readWithClientCertificateAuth() {
+ try {
+ // Create
+ RestAssured.given()
+ .contentType(ContentType.TEXT)
+ .body(BLOB_CONTENT)
+ .post("/azure-storage-blob/blob/create")
+ .then()
+ .statusCode(201);
+
+ // Read
+ RestAssured.given()
+ .queryParam("uri", "direct:readWithClientCertificate")
+ .get("/azure-storage-blob/blob/read")
+ .then()
+ .statusCode(200)
+ .body(is(BLOB_CONTENT));
+ } finally {
+ // Delete
+ RestAssured.delete("/azure-storage-blob/blob/delete")
+ .then()
+ .statusCode(anyOf(is(204), is(404)));
+ }
+ }
}
diff --git a/integration-test-groups/azure/certs/azure-cert.pem b/integration-test-groups/azure/certs/azure-cert.pem
new file mode 100644
index 0000000000..1d5ba8261a
--- /dev/null
+++ b/integration-test-groups/azure/certs/azure-cert.pem
@@ -0,0 +1,54 @@
+-----BEGIN CERTIFICATE-----
+MIIEUTCCAzmgAwIBAgIUdmqSX4JJGabAaZ7KRAKRLqRphWswDQYJKoZIhvcNAQEL
+BQAwgbcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApTb21lLVN0YXRlMRIwEAYDVQQH
+DAlUZXN0IENpdHkxJDAiBgNVBAoMG0NhbWVsIFF1YXJrdXMgQXp1cmUgVGVzdGlu
+ZzEkMCIGA1UECwwbQ2FtZWwgUXVhcmt1cyBBenVyZSBUZXN0aW5nMRIwEAYDVQQD
+DAlsb2NhbGhvc3QxHzAdBgkqhkiG9w0BCQEWEGNhbWVsQGFwYWNoZS5vcmcwHhcN
+MjIwODAxMDgzMTMwWhcNMjcwNzMxMDgzMTMwWjCBtzELMAkGA1UEBhMCVVMxEzAR
+BgNVBAgMClNvbWUtU3RhdGUxEjAQBgNVBAcMCVRlc3QgQ2l0eTEkMCIGA1UECgwb
+Q2FtZWwgUXVhcmt1cyBBenVyZSBUZXN0aW5nMSQwIgYDVQQLDBtDYW1lbCBRdWFy
+a3VzIEF6dXJlIFRlc3RpbmcxEjAQBgNVBAMMCWxvY2FsaG9zdDEfMB0GCSqGSIb3
+DQEJARYQY2FtZWxAYXBhY2hlLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBALV4k8KkQ9g1jG3cimE11r6/kNkGQ5uG7EtGMMYB0k2T+JftlHFM59id
+R/lBIUelRmKacLmYymJdGLXgz5B1shBQHtIaN2PPSi3qp6vc+1S0Xz9bIF2My1aF
+hevfrg21+WUernAIrDdBSiI5/7BZOsEiq4suWBSGRiay1Mq/mHN6IdW07KjJNvIy
+V2Kx4qBU2wz3IzsB+xiCbgJSEUCJE787M6HJctBWqIOX2o4ZTBfxn2AUiSALmXwy
+3rsg2YA3tPTFIQRr66QYHJcwvQeXyZZyIi0l40MUYigwfEBLV93fdzzix/QOOz2R
+IPmGsXaSRjS6teVd02Qd3ohXm9CTnSMCAwEAAaNTMFEwHQYDVR0OBBYEFIxzv9Sk
+Ge8mm0NHmLGuAzZ82xhXMB8GA1UdIwQYMBaAFIxzv9SkGe8mm0NHmLGuAzZ82xhX
+MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGiMRb4wgsCh0v2Z
+YNW1RpZ/Bl+ER7ZkLwc5xMNFWklAjCrTI6tTXUvP462bItYrWqlxd2e6fUvNgcnb
+JJUsNaYmTYxAFhUVdXkXjIXsg4+av6JIB8/2AdMQiSxekqqi8AEfElFgONWoj8w4
+TbXwMYZWan6Bj/sN4lGIHvo6zhuLH4g4HbyKffXdRe83k+082WLby/3raAa/Sy2t
+S86BYWqdu+E59PuUEU/3rY1T4wSCZXjS4DAFfYcUmXI6gDgpCi3lb8GHKX9YvZCT
+3e4IQMZaXDIA1lyYLULvrGi+NP3tpWV+b3G/Hk6xmophoMsRd5NVOh7pR8ZDYYiL
+IScC1sY=
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1eJPCpEPYNYxt
+3IphNda+v5DZBkObhuxLRjDGAdJNk/iX7ZRxTOfYnUf5QSFHpUZimnC5mMpiXRi1
+4M+QdbIQUB7SGjdjz0ot6qer3PtUtF8/WyBdjMtWhYXr364NtfllHq5wCKw3QUoi
+Of+wWTrBIquLLlgUhkYmstTKv5hzeiHVtOyoyTbyMldiseKgVNsM9yM7AfsYgm4C
+UhFAiRO/OzOhyXLQVqiDl9qOGUwX8Z9gFIkgC5l8Mt67INmAN7T0xSEEa+ukGByX
+ML0Hl8mWciItJeNDFGIoMHxAS1fd33c84sf0Djs9kSD5hrF2kkY0urXlXdNkHd6I
+V5vQk50jAgMBAAECggEAFXIffDQvdGC3rNAQZnaXX0mCU7OCz+F9EVRFNVFHyjU/
+fqzsCwu8poPH2rQQu8fTbpmz0qs017UK04uy2+6c0YK2cbv5ack4if6ePBhMd3Et
+hG4/f+7ApQP4lKyFhEdKJuIeWU0dFRaZLTxPdEbHQ8XWIgejDyHjLnWZ4jAMUzEb
+mOXeyXipfk6KkbVSWrXWS37jv3/6D6vXmVxWms7I2HggRVpIetuvxhoHo33MjohT
+MuR26FUWBQizouXmSQV4OGocHVtnr/mdktAh6QC00Pen3Gpi7xQHgXmVOVET0Qt6
+fZSdaYm9EmrU2EgTcjKwI80O/2SUapfXXtmmmu+z+QKBgQDtlhX+fuTReCGh+70b
+OTYiPOuVHhtgwazvg5Pmj7WiM/AeeyRuHYwKx4nFOgiVasaUqwEawDwdZzJCaphm
+4EfRvKqlbehN/kSk7Gq50+LjmISRPTzl8XzF0kuSWf6EHQKaEy1j+cckCuQks0U5
+U2F7zdiBNoaqkfvIpVVOo4K49wKBgQDDiR3VXLa3rp6Lrig9xEI4pybZbdutOXPY
+S4MI+KN2EGaobAF5icQ3RoXgyfxqxkJ8Vp6xSAuQgVQEBFOnth/GM7JHxw17GB2F
+u9a/LFkuQgC1uTLA6hpJBhmT9q9KFMaq0gOP//2xBjBU66AcVq8C11vAHwFXlgAK
+oCyHZaS+NQKBgQDQu62zG/UYe3zA/ZSVGFyRFAi9x+exyDaRb34/cD7ZtNvfS70j
+6V2iEtDdsDDeZSL2do7P29h01Ld5VoFy0NUIVcNu9/LCowPYCcVyYc/Suaqul6ir
+NNC0VCAFAn/zvjENAJA+Z7In3lG2VLIavUDGLoFqdGc38G3PSEJ8hndQ3QKBgQCH
+JpT6TnT0jLuFLEEgQDDNW6tcibRXDOjnTXoqj0DccAWkz9JNIU4ALryGXNYdLx/x
+NSXGv1dO8DUT+bGgsB9SLZVCS3Ej7c0qDGUoCg0yDejTskhEUwsMAi1Xuh/6glW2
+6CYSOAwveWmaqKooLDoXKqd+KXASC9nHfmKIy1aNKQKBgEIh4B9PoYT00HNfAwqL
+d8QDMjFmV+JktkgjGTc7CJUUn6WuE1WHZ6HrzRHCvNwMcRRZvUf79uzTj8GxNVdq
+bJwaxuW2g+/e0snnsgy3g0opN7veW0i+RvtLabE/hEazruY264Bin59VBgfoSraB
+/7a0gQ6Ez1OoP7+sAM+b5sc/
+-----END PRIVATE KEY-----
diff --git a/integration-tests/azure-grouped/pom.xml b/integration-tests/azure-grouped/pom.xml
index 659aed4c09..c41606cd5d 100644
--- a/integration-tests/azure-grouped/pom.xml
+++ b/integration-tests/azure-grouped/pom.xml
@@ -72,6 +72,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-seda</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+ <artifactId>camel-quarkus-integration-test-support-mock-backend</artifactId>
+ </dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>