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 2025/06/30 06:21:29 UTC
(camel-quarkus) branch main updated: fixes #7460 Azure-storage-datalake: cover methods of authentication
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 2860b26a0b fixes #7460 Azure-storage-datalake: cover methods of authentication
2860b26a0b is described below
commit 2860b26a0b12d3ec13b831a264520388b5b28c85
Author: JiriOndrusek <on...@gmail.com>
AuthorDate: Mon Jun 30 08:21:24 2025 +0200
fixes #7460 Azure-storage-datalake: cover methods of authentication
---
.../azure/azure-storage-datalake/README.adoc | 24 ++
.../datalake/it/AzureStorageDatalakeProducers.java | 125 ++++++++++
.../datalake/it/AzureStorageDatalakeResource.java | 33 +--
.../datalake/it/AzureStorageDatalakeRoutes.java | 252 +++++++++++----------
.../datalake/it/AzureStorageDatalakeUtil.java | 49 ++++
.../datalake/it/AzureStorageDatalakeTest.java | 104 +++++++++
6 files changed, 440 insertions(+), 147 deletions(-)
diff --git a/integration-test-groups/azure/azure-storage-datalake/README.adoc b/integration-test-groups/azure/azure-storage-datalake/README.adoc
index e20e1a785b..23aaac7ad2 100644
--- a/integration-test-groups/azure/azure-storage-datalake/README.adoc
+++ b/integration-test-groups/azure/azure-storage-datalake/README.adoc
@@ -21,4 +21,28 @@ Export Your credentials for *datalake* via specific variables
----
export AZURE_STORAGE_DATALAKE_ACCOUNT_KEY=<your-account-key>
export AZURE_STORAGE_DATALAKE_ACCOUNT_NAME=<your-acount-name>
+----
+
+Samo authentications tests require more parameters.
+Such test is enabled only if all the required parameters are present.
+
+For the test covering *SAS*, parameter is:
+
+[source,shell]
+----
+export AZURE_STORAGE_DATALAKE_SAS="<your sas token>"
+----
+
+For the test covering *client secret*, parameters are:
+
+[source,shell]
+----
+export AZURE_TENANT_ID=<your tenant id>
+export AZURE_CLIENT_ID=<your client id>
+export AZURE_CLIENT_SECRET=<your client secret>
+#or use datalake specific properties in case you've already exported the same properties for other storage tests and you need different credentials for the datalake.
+#export AZURE_DATALAKE_TENANT_ID=<your tenant id>
+#export AZURE_DATALAKE_CLIENT_ID=<your client id>
+#export AZURE_DATALAKE_CLIENT_SECRET=<your client secret>
+# Datalake specified properties ignore value in CAMEL_QUARKUS_DISABLE_IDENTITY_EXCEPT_KEY_VAULT!
----
\ No newline at end of file
diff --git a/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeProducers.java b/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeProducers.java
new file mode 100644
index 0000000000..23d886eac8
--- /dev/null
+++ b/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeProducers.java
@@ -0,0 +1,125 @@
+/*
+ * 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.datalake.it;
+
+import java.util.Optional;
+
+import com.azure.core.http.policy.HttpLogDetailLevel;
+import com.azure.core.http.policy.HttpLogOptions;
+import com.azure.storage.common.StorageSharedKeyCredential;
+import com.azure.storage.file.datalake.DataLakeServiceClient;
+import com.azure.storage.file.datalake.DataLakeServiceClientBuilder;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Named;
+import jakarta.ws.rs.Produces;
+import org.apache.camel.component.azure.storage.datalake.CredentialType;
+import org.apache.camel.component.azure.storage.datalake.DataLakeComponent;
+import org.apache.camel.component.azure.storage.datalake.DataLakeConfiguration;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+
+@ApplicationScoped
+public class AzureStorageDatalakeProducers {
+
+ @ConfigProperty(name = "azure.storage.account-name")
+ Optional<String> azureStorageAccountName;
+
+ @ConfigProperty(name = "azure.storage.account-key")
+ Optional<String> azureStorageAccountKey;
+
+ @ConfigProperty(name = "azure.datalake.service.url")
+ Optional<String> serviceUrl;
+
+ @jakarta.enterprise.inject.Produces
+ @Named("azureDatalakeServiceClient")
+ public DataLakeServiceClient createDatalakeServiceClient() throws Exception {
+ StorageSharedKeyCredential credentials = new StorageSharedKeyCredential(azureStorageAccountName.get(),
+ azureStorageAccountKey.get());
+ return new DataLakeServiceClientBuilder()
+ .endpoint(serviceUrl.get())
+ .credential(credentials)
+ .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS).setPrettyPrintBody(true))
+ .buildClient();
+ }
+
+ @SuppressWarnings("OptionalGetWithoutIsPresent")
+ @jakarta.enterprise.inject.Produces
+ @Named("azureDatalakeSasComponent")
+ public DataLakeComponent azureDatalakeSasComponent() throws Exception {
+ if (!AzureStorageDatalakeUtil.isSasTokenProvided()) {
+ return null;
+ }
+
+ DataLakeComponent dc = new DataLakeComponent();
+ dc.setAutowiredEnabled(false);
+
+ DataLakeConfiguration configuration = new DataLakeConfiguration();
+ configuration.setCredentialType(CredentialType.AZURE_SAS);
+ configuration.setSasSignature(AzureStorageDatalakeUtil.getSasToken().get());
+ dc.setConfiguration(configuration);
+
+ return dc;
+ }
+
+ @jakarta.enterprise.inject.Produces
+ @Named("azureDatalakeClientInstanceComponent")
+ public DataLakeComponent azureDatalakeClientInstanceComponent() throws Exception {
+ DataLakeComponent dc = new DataLakeComponent();
+
+ DataLakeConfiguration configuration = new DataLakeConfiguration();
+ configuration.setCredentialType(CredentialType.CLIENT_SECRET);
+ dc.setConfiguration(configuration);
+
+ return dc;
+ }
+
+ @jakarta.enterprise.inject.Produces
+ @Named("azureDatalakeSharedkeyCredentialComponent")
+ public DataLakeComponent azureDatalakeSharedkeyCredentialComponent() throws Exception {
+ DataLakeComponent dc = new DataLakeComponent();
+ dc.setAutowiredEnabled(false);
+
+ DataLakeConfiguration configuration = new DataLakeConfiguration();
+ configuration.setCredentialType(CredentialType.SHARED_KEY_CREDENTIAL);
+ configuration.setAccountName(AzureStorageDatalakeUtil.getRealAccountNameFromEnv());
+ configuration.setAccountKey(AzureStorageDatalakeUtil.getRealAccountKeyFromEnv());
+ dc.setConfiguration(configuration);
+
+ return dc;
+ }
+
+ @SuppressWarnings("OptionalGetWithoutIsPresent")
+ @jakarta.enterprise.inject.Produces
+ @Named("azureDatalakeClientSecretComponent")
+ public DataLakeComponent azureDatalakeClientSecretComponent() throws Exception {
+ if (!AzureStorageDatalakeUtil.isRealClientSecretProvided()) {
+ return null;
+ }
+
+ DataLakeComponent dc = new DataLakeComponent();
+ dc.setAutowiredEnabled(false);
+
+ DataLakeConfiguration configuration = new DataLakeConfiguration();
+ configuration.setCredentialType(CredentialType.CLIENT_SECRET);
+ configuration.setClientId(AzureStorageDatalakeUtil.getClientId().get());
+ configuration.setClientSecret(AzureStorageDatalakeUtil.getClientSecret().get());
+ configuration.setTenantId(AzureStorageDatalakeUtil.getTenantId().get());
+ dc.setConfiguration(configuration);
+
+ return dc;
+ }
+
+}
diff --git a/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeResource.java b/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeResource.java
index a3edb33a83..001a11f243 100644
--- a/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeResource.java
+++ b/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeResource.java
@@ -24,16 +24,10 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
-import com.azure.core.http.policy.HttpLogDetailLevel;
-import com.azure.core.http.policy.HttpLogOptions;
-import com.azure.storage.common.StorageSharedKeyCredential;
-import com.azure.storage.file.datalake.DataLakeServiceClient;
-import com.azure.storage.file.datalake.DataLakeServiceClientBuilder;
import com.azure.storage.file.datalake.models.FileSystemItem;
import com.azure.storage.file.datalake.models.PathItem;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
-import jakarta.inject.Named;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
@@ -68,24 +62,6 @@ public class AzureStorageDatalakeResource {
@ConfigProperty(name = "azure.storage.account-name")
Optional<String> azureStorageAccountName;
- @ConfigProperty(name = "azure.storage.account-key")
- Optional<String> azureStorageAccountKey;
-
- @ConfigProperty(name = "azure.datalake.service.url")
- Optional<String> serviceUrl;
-
- @jakarta.enterprise.inject.Produces
- @Named("azureDatalakeServiceClient")
- public DataLakeServiceClient createDatalakeServiceClient() throws Exception {
- StorageSharedKeyCredential credentials = new StorageSharedKeyCredential(azureStorageAccountName.get(),
- azureStorageAccountKey.get());
- return new DataLakeServiceClientBuilder()
- .endpoint(serviceUrl.get())
- .credential(credentials)
- .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS).setPrettyPrintBody(true))
- .buildClient();
- }
-
@Path("/filesystem/{filesystem}")
@POST
@Produces(MediaType.TEXT_PLAIN)
@@ -211,16 +187,17 @@ public class AzureStorageDatalakeResource {
return ((List<FileSystemItem>) o).stream()
.map(FileSystemItem::getName)
.collect(Collectors.toList());
- case "datalakeListPaths":
- return ((List<PathItem>) o).stream()
- .map(PathItem::getName)
- .collect(Collectors.toList());
case "datalakeGetFile":
if (useOutputStream) {
return inMemoryStream.toString();
}
break;
}
+ if (routeName.endsWith("ListPaths")) {
+ return ((List<PathItem>) o).stream()
+ .map(PathItem::getName)
+ .collect(Collectors.toList());
+ }
return exchange.getIn().getBody(String.class);
}
diff --git a/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeRoutes.java b/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeRoutes.java
index d184524d2d..d1ff98ab70 100644
--- a/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeRoutes.java
+++ b/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeRoutes.java
@@ -39,124 +39,138 @@ public class AzureStorageDatalakeRoutes extends RouteBuilder {
@Override
public void configure() throws Exception {
- String tmpFolder = ConfigProvider.getConfig().getValue("cqDatalakeTmpFolder", String.class);
- String consumerFilesystem = ConfigProvider.getConfig().getValue("cqCDatalakeConsumerFilesystem", String.class);
-
- /* Consumer examples */
-
- //Consume a file from the storage datalake into a file using the file component
- from("azure-storage-datalake://" + AzureStorageDatalakeUtil.getRealAccountKeyFromEnv() + "/" + consumerFilesystem
- + "?fileName=" + CONSUMER_FILE_NAME
- + CLIENT_SUFFIX)
- .routeId("consumeWithFileComponent")
- .autoStartup(false)
- .to("file:" + tmpFolder + "/consumer-files?fileName=" + CONSUMER_FILE_NAME);
-
- //write to a file without using the file component
- from("azure-storage-datalake://" + AzureStorageDatalakeUtil.getRealAccountKeyFromEnv() + "/" + consumerFilesystem
- + "?fileName=" + CONSUMER_FILE_NAME2 + "&fileDir=" + tmpFolder + "/consumer-files&delay=3000000"
- + CLIENT_SUFFIX)
- .routeId("consumeWithoutFileComponent")
- .autoStartup(false)
- .log("File downloaded");
-
- //batch consumer
- from("azure-storage-datalake://" + AzureStorageDatalakeUtil.getRealAccountKeyFromEnv() + "/" + consumerFilesystem
- + "?fileDir=" + tmpFolder + "/consumer-files/batch&path=/&delay=3000000" + CLIENT_SUFFIX)
- .routeId("consumeBatch")
- .autoStartup(false)
- .log("File downloaded");
-
- /* Producer examples */
-
- //listFileSystem
- from("direct:datalakeListFileSystem")
- .process(exchange -> {
- exchange.getIn().setHeader(DataLakeConstants.LIST_FILESYSTEMS_OPTIONS,
- new ListFileSystemsOptions().setMaxResultsPerPage(10));
- })
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=listFileSystem"
- + CLIENT_SUFFIX);
-
- //createFileSystem
- from("direct:datalakeCreateFilesystem")
- .toD("azure-storage-datalake://${header.accountName}?operation=createFileSystem" + CLIENT_SUFFIX);
-
- //listPaths
- from("direct:datalakeListPaths")
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=listPaths"
- + CLIENT_SUFFIX);
-
- //getFile
- from("direct:datalakeGetFile")
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=getFile&fileName=${header.fileName}"
- + CLIENT_SUFFIX);
-
- //deleteFile
- from("direct:datalakeDeleteFile")
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=deleteFile&fileName="
- + FILE_NAME + CLIENT_SUFFIX);
-
- //downloadToFile
- from("direct:datalakeDownloadToFile")
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=downloadToFile&fileName="
- + FILE_NAME + "&fileDir=${header.tmpFolder}" + CLIENT_SUFFIX);
-
- //downloadLink
- from("direct:datalakeDownloadLink")
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=downloadLink&fileName="
- + FILE_NAME + CLIENT_SUFFIX);
-
- //appendToFile
- from("direct:datalakeAppendToFile")
- .process(exchange -> {
- final String data = exchange.getIn().getHeader("append", String.class);
- final InputStream inputStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
- exchange.getIn().setBody(inputStream);
- })
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=appendToFile&fileName="
- + FILE_NAME + CLIENT_SUFFIX);
-
- //flushToFile
- from("direct:datalakeFlushToFile")
- .process(exchange -> {
- exchange.getIn().setHeader(DataLakeConstants.POSITION, 8);
- })
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=flushToFile&fileName="
- + FILE_NAME + CLIENT_SUFFIX);
-
- //openQueryInputStream
- from("direct:openQueryInputStream")
- .process(exchange -> {
- exchange.getIn().setHeader(DataLakeConstants.QUERY_OPTIONS,
- new FileQueryOptions("SELECT * from BlobStorage"));
- })
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=openQueryInputStream&fileName="
- + FILE_NAME + CLIENT_SUFFIX);
-
- //upload
- from("direct:datalakeUpload")
- .process(exchange -> {
- String fileContent = exchange.getIn().getHeader("fileContent", String.class);
- final InputStream inputStream = new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8));
- exchange.getIn().setBody(inputStream);
- })
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=upload&fileName="
- + FILE_NAME + CLIENT_SUFFIX);
-
- // uploadFromFile
- from("direct:datalakeUploadFromFile")
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=uploadFromFile&fileName="
- + FILE_NAME2 + CLIENT_SUFFIX);
-
- // createFile
- from("direct:datalakeCreateFile")
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=createFile&fileName=${header.fileName}"
- + CLIENT_SUFFIX);
-
- //deleteDirectory
- from("direct:datalakeDeleteDirectory")
- .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=deleteDirectory"
- + CLIENT_SUFFIX);
+ if (AzureStorageDatalakeUtil.isRalAccountProvided()) {
+
+ String tmpFolder = ConfigProvider.getConfig().getValue("cqDatalakeTmpFolder", String.class);
+ String consumerFilesystem = ConfigProvider.getConfig().getValue("cqCDatalakeConsumerFilesystem", String.class);
+
+ /* Consumer examples */
+
+ //Consume a file from the storage datalake into a file using the file component
+ from("azure-storage-datalake://" + AzureStorageDatalakeUtil.getRealAccountKeyFromEnv() + "/" + consumerFilesystem
+ + "?fileName=" + CONSUMER_FILE_NAME)
+ .routeId("consumeWithFileComponent")
+ .autoStartup(false)
+ .to("file:" + tmpFolder + "/consumer-files?fileName=" + CONSUMER_FILE_NAME);
+
+ //write to a file without using the file component
+ from("azure-storage-datalake://" + AzureStorageDatalakeUtil.getRealAccountKeyFromEnv() + "/" + consumerFilesystem
+ + "?fileName=" + CONSUMER_FILE_NAME2 + "&fileDir=" + tmpFolder + "/consumer-files&delay=3000000")
+ .routeId("consumeWithoutFileComponent")
+ .autoStartup(false)
+ .log("File downloaded");
+
+ //batch consumer
+ from("azure-storage-datalake://" + AzureStorageDatalakeUtil.getRealAccountKeyFromEnv() + "/" + consumerFilesystem
+ + "?fileDir=" + tmpFolder + "/consumer-files/batch&path=/&delay=3000000")
+ .routeId("consumeBatch")
+ .autoStartup(false)
+ .log("File downloaded");
+
+ /* Producer examples */
+
+ //listFileSystem
+ from("direct:datalakeListFileSystem")
+ .process(exchange -> {
+ exchange.getIn().setHeader(DataLakeConstants.LIST_FILESYSTEMS_OPTIONS,
+ new ListFileSystemsOptions().setMaxResultsPerPage(10));
+ })
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=listFileSystem");
+
+ //createFileSystem
+ from("direct:datalakeCreateFilesystem")
+ .toD("azure-storage-datalake://${header.accountName}?operation=createFileSystem");
+
+ //listPaths
+ from("direct:datalakeListPaths")
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=listPaths");
+
+ //getFile
+ from("direct:datalakeGetFile")
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=getFile&fileName=${header.fileName}");
+
+ //deleteFile
+ from("direct:datalakeDeleteFile")
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=deleteFile&fileName="
+ + FILE_NAME);
+
+ //downloadToFile
+ from("direct:datalakeDownloadToFile")
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=downloadToFile&fileName="
+ + FILE_NAME + "&fileDir=${header.tmpFolder}");
+
+ //downloadLink
+ from("direct:datalakeDownloadLink")
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=downloadLink&fileName="
+ + FILE_NAME);
+
+ //appendToFile
+ from("direct:datalakeAppendToFile")
+ .process(exchange -> {
+ final String data = exchange.getIn().getHeader("append", String.class);
+ final InputStream inputStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+ exchange.getIn().setBody(inputStream);
+ })
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=appendToFile&fileName="
+ + FILE_NAME);
+
+ //flushToFile
+ from("direct:datalakeFlushToFile")
+ .process(exchange -> {
+ exchange.getIn().setHeader(DataLakeConstants.POSITION, 8);
+ })
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=flushToFile&fileName="
+ + FILE_NAME);
+
+ //openQueryInputStream
+ from("direct:openQueryInputStream")
+ .process(exchange -> {
+ exchange.getIn().setHeader(DataLakeConstants.QUERY_OPTIONS,
+ new FileQueryOptions("SELECT * from BlobStorage"));
+ })
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=openQueryInputStream&fileName="
+ + FILE_NAME);
+
+ //upload
+ from("direct:datalakeUpload")
+ .process(exchange -> {
+ String fileContent = exchange.getIn().getHeader("fileContent", String.class);
+ final InputStream inputStream = new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8));
+ exchange.getIn().setBody(inputStream);
+ })
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=upload&fileName="
+ + FILE_NAME);
+
+ // uploadFromFile
+ from("direct:datalakeUploadFromFile")
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=uploadFromFile&fileName="
+ + FILE_NAME2);
+
+ // createFile
+ from("direct:datalakeCreateFile")
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=createFile&fileName=${header.fileName}");
+
+ //deleteDirectory
+ from("direct:datalakeDeleteDirectory")
+ .toD("azure-storage-datalake://${header.accountName}/${header.filesystemName}?operation=deleteDirectory");
+
+ //listFileSystem
+
+ /* Authentications */
+
+ //SAS list paths
+ from("direct:datalakeSasListPaths")
+ .toD("azureDatalakeSasComponent://${header.accountName}/${header.filesystemName}?operation=listPaths");
+ //client instance list paths
+ from("direct:datalakeClientInstanceListPaths")
+ .toD("azureDatalakeClientInstanceComponent://${header.accountName}/${header.filesystemName}?operation=listPaths"
+ + CLIENT_SUFFIX);
+ //SHARED_KEY_CREDENTIAL
+ from("direct:datalakeSharedKeyCredentialsListPaths")
+ .toD("azureDatalakeSharedkeyCredentialComponent://${header.accountName}/${header.filesystemName}?operation=listPaths");
+ //client secret
+ from("direct:datalakeClientSecretListPaths")
+ .toD("azureDatalakeClientSecretComponent://${header.accountName}/${header.filesystemName}?operation=listPaths");
+ }
}
}
diff --git a/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeUtil.java b/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeUtil.java
index 87b42308a5..b1c63379a9 100644
--- a/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeUtil.java
+++ b/integration-test-groups/azure/azure-storage-datalake/src/main/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeUtil.java
@@ -18,6 +18,8 @@ package org.apache.camel.quarkus.component.azure.storage.datalake.it;
import java.util.Optional;
+import org.eclipse.microprofile.config.ConfigProvider;
+
public class AzureStorageDatalakeUtil {
public static String getRealAccountNameFromEnv() {
@@ -30,10 +32,57 @@ public class AzureStorageDatalakeUtil {
.orElseGet(() -> System.getenv("AZURE_STORAGE_ACCOUNT_KEY"));
}
+ public static Optional<String> getSasToken() {
+ return getDatalakePrioritizedConfigValue("azure.storage.datalake.sas", "azure.storage.sas", String.class);
+ }
+
+ public static Optional<String> getClientId() {
+ return getDatalakePrioritizedConfigValue("azure.datalake.client.id", "azure.client.id", String.class,
+ disableIdentityExceptKeyVault());
+ }
+
+ public static Optional<String> getClientSecret() {
+ return getDatalakePrioritizedConfigValue("azure.datalake.client.secret", "azure.client.secret", String.class,
+ disableIdentityExceptKeyVault());
+ }
+
+ public static Optional<String> getTenantId() {
+ return getDatalakePrioritizedConfigValue("azure.datalake.tenant.id", "azure.tenant.id", String.class,
+ disableIdentityExceptKeyVault());
+ }
+
+ public static boolean disableIdentityExceptKeyVault() {
+ return ConfigProvider.getConfig().getOptionalValue("CAMEL_QUARKUS_DISABLE_IDENTITY_EXCEPT_KEY_VAULT", Boolean.class)
+ .orElse(false);
+ }
+
public static boolean isRalAccountProvided() {
String realAzureStorageAccountName = AzureStorageDatalakeUtil.getRealAccountNameFromEnv();
String realAzureStorageAccountKey = AzureStorageDatalakeUtil.getRealAccountKeyFromEnv();
return realAzureStorageAccountName != null && realAzureStorageAccountKey != null;
}
+
+ public static boolean isRealClientSecretProvided() {
+ return getClientId().isPresent()
+ && getClientSecret().isPresent()
+ && getTenantId().isPresent();
+ }
+
+ public static boolean isSasTokenProvided() {
+ return getSasToken().isPresent();
+ }
+
+ private static <T> Optional<T> getDatalakePrioritizedConfigValue(String primaryName, String secondaryNajme, Class<T> type) {
+ return getDatalakePrioritizedConfigValue(primaryName, secondaryNajme, type, false);
+ }
+
+ private static <T> Optional<T> getDatalakePrioritizedConfigValue(String primaryName, String secondaryNajme, Class<T> type,
+ boolean ignoreSecondary) {
+ Optional<T> value = ConfigProvider.getConfig().getOptionalValue(primaryName, type);
+ if (value.isEmpty() && !ignoreSecondary) {
+ value = ConfigProvider.getConfig().getOptionalValue(secondaryNajme, type);
+ }
+ return value;
+ }
}
diff --git a/integration-test-groups/azure/azure-storage-datalake/src/test/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeTest.java b/integration-test-groups/azure/azure-storage-datalake/src/test/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeTest.java
index 978331a9ff..6af735d281 100644
--- a/integration-test-groups/azure/azure-storage-datalake/src/test/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeTest.java
+++ b/integration-test-groups/azure/azure-storage-datalake/src/test/java/org/apache/camel/quarkus/component/azure/storage/datalake/it/AzureStorageDatalakeTest.java
@@ -24,6 +24,8 @@ import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
+import java.util.function.BiConsumer;
+import java.util.function.Supplier;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
@@ -429,4 +431,106 @@ class AzureStorageDatalakeTest {
}
}
+
+ @Test
+ public void testAuthenticationWithSharedKeyCredentials() {
+ testAuthentications(
+ //if the test class is enabled, this test is enabled
+ () -> true,
+ (filesystem, filename) -> RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(Collections.emptyMap())
+ .post("/azure-storage-datalake/route/datalakeSharedKeyCredentialsListPaths/filesystem/" + filesystem)
+ .then()
+ .statusCode(200)
+ .body("", Matchers.hasItem(filename)));
+ }
+
+ @Test
+ public void testAuthenticationWithSas() {
+ testAuthentications(
+ AzureStorageDatalakeUtil::isSasTokenProvided,
+ (filesystem, filename) -> RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(Collections.emptyMap())
+ .post("/azure-storage-datalake/route/datalakeSasListPaths/filesystem/" + filesystem)
+ .then()
+ .statusCode(200)
+ .body("", Matchers.hasItem(filename)));
+ }
+
+ @Test
+ public void testAuthenticationWithClientInstance() {
+ testAuthentications(
+ //if the test class is enabled, this test is enabled
+ () -> true,
+ (filesystem, filename) -> RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(Collections.emptyMap())
+ .post("/azure-storage-datalake/route/datalakeClientInstanceListPaths/filesystem/" + filesystem)
+ .then()
+ .statusCode(200)
+ .body("", Matchers.hasItem(filename)));
+ }
+
+ @Test
+ public void testAuthenticationWithClientSecret() {
+ testAuthentications(
+ AzureStorageDatalakeUtil::isRealClientSecretProvided,
+ (filesystem, filename) -> RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(Collections.emptyMap())
+ .post("/azure-storage-datalake/route/datalakeClientSecretListPaths/filesystem/" + filesystem)
+ .then()
+ .statusCode(200)
+ .body("", Matchers.hasItem(filename)));
+ }
+
+ private void testAuthentications(Supplier<Boolean> enabled, BiConsumer<String, String> test) {
+ Assumptions.assumeTrue(enabled.get(), "Azure security configuration was not provided");
+
+ final String filesystem = "cqfsauth" + RandomStringUtils.randomNumeric(16);
+ final String filename = AzureStorageDatalakeRoutes.FILE_NAME;
+
+ /* The filesystem does not exist initially */
+ RestAssured.get("/azure-storage-datalake/filesystem/" + filesystem)
+ .then()
+ .statusCode(200)
+ .body("", Matchers.not(Matchers.hasItem(filesystem)));
+
+ try {
+ LOG.info("step - createFileSystem");
+ RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(Map.of(DataLakeConstants.FILESYSTEM_NAME, filesystem))
+ .post("/azure-storage-datalake/route/datalakeCreateFilesystem/filesystem/" + filesystem)
+ .then()
+ .statusCode(200);
+
+ /* Now it should exist */
+ RestAssured.get("/azure-storage-datalake/filesystem/" + filesystem)
+ .then()
+ .statusCode(200)
+ .body("", Matchers.hasItem(filesystem));
+
+ LOG.info("step - upload");
+ RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(Map.of("fileContent", "Hello World from Camel!"))
+ .post("/azure-storage-datalake/route/datalakeUpload/filesystem/" + filesystem)
+ .then()
+ .statusCode(200);
+
+ LOG.info("step - listPaths");
+ test.accept(filesystem, filename);
+
+ } finally {
+ /* Clean up */
+ RestAssured.given()
+ .delete("/azure-storage-datalake/filesystem/" + filesystem)
+ .then()
+ .statusCode(204);
+ }
+
+ }
}