This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 87aa119d4f48b82accdc7f6293622302cb9eb0d2
Author: Andrea Cosentino <[email protected]>
AuthorDate: Tue Nov 16 15:02:43 2021 +0100

    CAMEL-17161 - Support for Azure Copy Blob Operation in Camel component
---
 .../storage/blob/BlobComponentConfigurer.java      |  6 +++
 .../azure/storage/blob/BlobEndpointConfigurer.java |  6 +++
 .../azure/storage/blob/BlobEndpointUriFactory.java |  6 ++-
 .../azure/storage/blob/azure-storage-blob.json     |  6 ++-
 .../azure/storage/blob/BlobConfiguration.java      | 14 ++++++
 .../azure/storage/blob/BlobConstants.java          |  3 ++
 .../storage/blob/BlobOperationsDefinition.java     |  7 ++-
 .../component/azure/storage/blob/BlobProducer.java |  3 ++
 .../storage/blob/client/BlobClientWrapper.java     | 48 +++++++++++--------
 .../storage/blob/operations/BlobOperations.java    | 19 ++++++++
 .../AzureStorageBlobComponentBuilderFactory.java   | 18 ++++++++
 .../endpoint/dsl/BlobEndpointBuilderFactory.java   | 54 +++++++++++++++++++++-
 12 files changed, 165 insertions(+), 25 deletions(-)

diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
 
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
index 7b5ee4f..a98ba42 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
@@ -81,6 +81,8 @@ public class BlobComponentConfigurer extends 
PropertyConfigurerSupport implement
         case "regex": 
getOrCreateConfiguration(target).setRegex(property(camelContext, 
java.lang.String.class, value)); return true;
         case "serviceclient":
         case "serviceClient": 
getOrCreateConfiguration(target).setServiceClient(property(camelContext, 
com.azure.storage.blob.BlobServiceClient.class, value)); return true;
+        case "sourceblobaccesskey":
+        case "sourceBlobAccessKey": 
getOrCreateConfiguration(target).setSourceBlobAccessKey(property(camelContext, 
java.lang.String.class, value)); return true;
         case "timeout": 
getOrCreateConfiguration(target).setTimeout(property(camelContext, 
java.time.Duration.class, value)); return true;
         default: return false;
         }
@@ -147,6 +149,8 @@ public class BlobComponentConfigurer extends 
PropertyConfigurerSupport implement
         case "regex": return java.lang.String.class;
         case "serviceclient":
         case "serviceClient": return 
com.azure.storage.blob.BlobServiceClient.class;
+        case "sourceblobaccesskey":
+        case "sourceBlobAccessKey": return java.lang.String.class;
         case "timeout": return java.time.Duration.class;
         default: return null;
         }
@@ -209,6 +213,8 @@ public class BlobComponentConfigurer extends 
PropertyConfigurerSupport implement
         case "regex": return getOrCreateConfiguration(target).getRegex();
         case "serviceclient":
         case "serviceClient": return 
getOrCreateConfiguration(target).getServiceClient();
+        case "sourceblobaccesskey":
+        case "sourceBlobAccessKey": return 
getOrCreateConfiguration(target).getSourceBlobAccessKey();
         case "timeout": return getOrCreateConfiguration(target).getTimeout();
         default: return null;
         }
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
 
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
index 5a72e7a..18bfc3f 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
@@ -100,6 +100,8 @@ public class BlobEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "sendEmptyMessageWhenIdle": 
target.setSendEmptyMessageWhenIdle(property(camelContext, boolean.class, 
value)); return true;
         case "serviceclient":
         case "serviceClient": 
target.getConfiguration().setServiceClient(property(camelContext, 
com.azure.storage.blob.BlobServiceClient.class, value)); return true;
+        case "sourceblobaccesskey":
+        case "sourceBlobAccessKey": 
target.getConfiguration().setSourceBlobAccessKey(property(camelContext, 
java.lang.String.class, value)); return true;
         case "startscheduler":
         case "startScheduler": target.setStartScheduler(property(camelContext, 
boolean.class, value)); return true;
         case "timeunit":
@@ -198,6 +200,8 @@ public class BlobEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "sendEmptyMessageWhenIdle": return boolean.class;
         case "serviceclient":
         case "serviceClient": return 
com.azure.storage.blob.BlobServiceClient.class;
+        case "sourceblobaccesskey":
+        case "sourceBlobAccessKey": return java.lang.String.class;
         case "startscheduler":
         case "startScheduler": return boolean.class;
         case "timeunit":
@@ -292,6 +296,8 @@ public class BlobEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "sendEmptyMessageWhenIdle": return 
target.isSendEmptyMessageWhenIdle();
         case "serviceclient":
         case "serviceClient": return 
target.getConfiguration().getServiceClient();
+        case "sourceblobaccesskey":
+        case "sourceBlobAccessKey": return 
target.getConfiguration().getSourceBlobAccessKey();
         case "startscheduler":
         case "startScheduler": return target.isStartScheduler();
         case "timeunit":
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
 
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
index 6ab32be..3ca1ac0 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
@@ -20,7 +20,7 @@ public class BlobEndpointUriFactory extends 
org.apache.camel.support.component.E
     private static final Set<String> PROPERTY_NAMES;
     private static final Set<String> SECRET_PROPERTY_NAMES;
     static {
-        Set<String> props = new HashSet<>(49);
+        Set<String> props = new HashSet<>(50);
         props.add("blobName");
         props.add("prefix");
         props.add("initialDelay");
@@ -70,9 +70,11 @@ public class BlobEndpointUriFactory extends 
org.apache.camel.support.component.E
         props.add("changeFeedContext");
         props.add("pageBlobSize");
         props.add("operation");
+        props.add("sourceBlobAccessKey");
         PROPERTY_NAMES = Collections.unmodifiableSet(props);
-        Set<String> secretProps = new HashSet<>(1);
+        Set<String> secretProps = new HashSet<>(2);
         secretProps.add("accessKey");
+        secretProps.add("sourceBlobAccessKey");
         SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps);
     }
 
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
 
b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
index ce3be7c..dfa64d7 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
@@ -51,7 +51,8 @@
     "operation": { "kind": "property", "displayName": "Operation", "group": 
"producer", "label": "producer", "required": false, "type": "object", 
"javaType": 
"org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition", 
"enum": [ "listBlobContainers", "createBlobContainer", "deleteBlobContainer", 
"listBlobs", "getBlob", "deleteBlob", "downloadBlobToFile", "downloadLink", 
"uploadBlockBlob", "stageBlockBlobList", "commitBlobBlockList", 
"getBlobBlockList", "createAppendBlob", "c [...]
     "pageBlobSize": { "kind": "property", "displayName": "Page Blob Size", 
"group": "producer", "label": "producer", "required": false, "type": "integer", 
"javaType": "java.lang.Long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "512", "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Specifies the maximum 
size for the page blob, up to 8 TB. The page blob size must  [...]
     "autowiredEnabled": { "kind": "property", "displayName": "Autowired 
Enabled", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether autowiring is 
enabled. This is used for automatic autowiring options (the option must be 
marked as autowired) by looking up in the registry to find if there is a single 
instance of matching type, which t [...]
-    "accessKey": { "kind": "property", "displayName": "Access Key", "group": 
"security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Access key for the 
associated azure account name to be used for authentication with azure blob 
services" }
+    "accessKey": { "kind": "property", "displayName": "Access Key", "group": 
"security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Access key for the 
associated azure account name to be used for authentication with azure blob 
services" },
+    "sourceBlobAccessKey": { "kind": "property", "displayName": "Source Blob 
Access Key", "group": "security", "label": "security", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": true, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Source Blob Access Key: 
for copyblob operation, sadly, we need to have an accessKey for th [...]
   },
   "properties": {
     "accountName": { "kind": "path", "displayName": "Account Name", "group": 
"common", "label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Azure account name to be 
used for authentication with azure blob services" },
@@ -102,6 +103,7 @@
     "startScheduler": { "kind": "parameter", "displayName": "Start Scheduler", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether the scheduler 
should be auto started." },
     "timeUnit": { "kind": "parameter", "displayName": "Time Unit", "group": 
"scheduler", "label": "consumer,scheduler", "required": false, "type": 
"object", "javaType": "java.util.concurrent.TimeUnit", "enum": [ "NANOSECONDS", 
"MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", "DAYS" ], 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"MILLISECONDS", "description": "Time unit for initialDelay and delay options." 
},
     "useFixedDelay": { "kind": "parameter", "displayName": "Use Fixed Delay", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Controls if fixed delay 
or fixed rate is used. See ScheduledExecutorService in JDK for details." },
-    "accessKey": { "kind": "parameter", "displayName": "Access Key", "group": 
"security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Access key for the 
associated azure account name to be used for authentication with azure blob 
services" }
+    "accessKey": { "kind": "parameter", "displayName": "Access Key", "group": 
"security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Access key for the 
associated azure account name to be used for authentication with azure blob 
services" },
+    "sourceBlobAccessKey": { "kind": "parameter", "displayName": "Source Blob 
Access Key", "group": "security", "label": "security", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": true, "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Source Blob Access Key: 
for copyblob operation, sadly, we need to have an accessKey for t [...]
   }
 }
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
index b6a5bff..7674dbd 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
@@ -95,6 +95,8 @@ public class BlobConfiguration implements Cloneable {
     private Context changeFeedContext;
     @UriParam(label = "common")
     private String regex;
+    @UriParam(label = "security", secret = true)
+    private String sourceBlobAccessKey;
 
     /**
      * Azure account name to be used for authentication with azure blob 
services
@@ -423,6 +425,18 @@ public class BlobConfiguration implements Cloneable {
         this.regex = regex;
     }
 
+    public String getSourceBlobAccessKey() {
+        return sourceBlobAccessKey;
+    }
+
+    /**
+     * Source Blob Access Key: for copyblob operation, sadly, we need to have 
an accessKey for the source blob we want
+     * to copy Passing an accessKey as header, it's unsafe so we could set as 
key.
+     */
+    public void setSourceBlobAccessKey(String sourceBlobAccessKey) {
+        this.sourceBlobAccessKey = sourceBlobAccessKey;
+    }
+
     // *************************************************
     //
     // *************************************************
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConstants.java
 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConstants.java
index 3f4bb2d..5fb7691 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConstants.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConstants.java
@@ -81,6 +81,9 @@ public final class BlobConstants {
     public static final String LIST_BLOB_CONTAINERS_OPTIONS = HEADER_PREFIX + 
"ListBlobContainersOptions";
     public static final String PARALLEL_TRANSFER_OPTIONS = HEADER_PREFIX + 
"ParallelTransferOptions";
     public static final String DOWNLOAD_LINK_EXPIRATION = HEADER_PREFIX + 
"DownloadLinkExpiration";
+    public static final String SOURCE_BLOB_ACCOUNT_NAME = HEADER_PREFIX + 
"SourceBlobAccountName";
+    public static final String SOURCE_BLOB_CONTAINER_NAME = HEADER_PREFIX + 
"SourceBlobContainerName";
+    public static final String DESTINATION_BLOB_NAME = HEADER_PREFIX + 
"DestinationBlobContainerName";
     // changefeed
     public static final String CHANGE_FEED_START_TIME = HEADER_PREFIX + 
"ChangeFeedStartTime";
     public static final String CHANGE_FEED_END_TIME = HEADER_PREFIX + 
"ChangeFeedEndTime";
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobOperationsDefinition.java
 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobOperationsDefinition.java
index 6b3ad4c..8591f03 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobOperationsDefinition.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobOperationsDefinition.java
@@ -123,5 +123,10 @@ public enum BlobOperationsDefinition {
      * Returns transaction logs of all the changes that occur to the blobs and 
the blob metadata in your storage
      * account. The change feed provides ordered, guaranteed, durable, 
immutable, read-only log of these changes.
      */
-    getChangeFeed
+    getChangeFeed,
+    /**
+     * Returns transaction logs of all the changes that occur to the blobs and 
the blob metadata in your storage
+     * account. The change feed provides ordered, guaranteed, durable, 
immutable, read-only log of these changes.
+     */
+    copyBlob
 }
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobProducer.java
 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobProducer.java
index fd71cb9..87077a0 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobProducer.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobProducer.java
@@ -123,6 +123,9 @@ public class BlobProducer extends DefaultProducer {
             case getChangeFeed:
                 setResponse(exchange, 
getBlobChangeFeedOperations().getEvents(exchange));
                 break;
+            case copyBlob:
+                setResponse(exchange, 
getBlobOperations(exchange).copyBlob(exchange));
+                break;
             default:
                 throw new IllegalArgumentException("Unsupported operation");
         }
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientWrapper.java
 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientWrapper.java
index 8a8d548..f195efd 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientWrapper.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientWrapper.java
@@ -19,8 +19,10 @@ package org.apache.camel.component.azure.storage.blob.client;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.time.Duration;
+import java.time.OffsetDateTime;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 import com.azure.core.http.HttpHeaders;
@@ -28,33 +30,21 @@ import com.azure.core.http.rest.Response;
 import com.azure.core.http.rest.ResponseBase;
 import com.azure.core.util.Context;
 import com.azure.storage.blob.BlobClient;
-import com.azure.storage.blob.models.AccessTier;
-import com.azure.storage.blob.models.AppendBlobItem;
-import com.azure.storage.blob.models.AppendBlobRequestConditions;
-import com.azure.storage.blob.models.BlobDownloadHeaders;
-import com.azure.storage.blob.models.BlobHttpHeaders;
-import com.azure.storage.blob.models.BlobProperties;
-import com.azure.storage.blob.models.BlobRange;
-import com.azure.storage.blob.models.BlobRequestConditions;
-import com.azure.storage.blob.models.BlockBlobItem;
-import com.azure.storage.blob.models.BlockList;
-import com.azure.storage.blob.models.BlockListType;
-import com.azure.storage.blob.models.DeleteSnapshotsOptionType;
-import com.azure.storage.blob.models.DownloadRetryOptions;
-import com.azure.storage.blob.models.PageBlobItem;
-import com.azure.storage.blob.models.PageBlobRequestConditions;
-import com.azure.storage.blob.models.PageList;
-import com.azure.storage.blob.models.PageRange;
-import com.azure.storage.blob.models.ParallelTransferOptions;
+import com.azure.storage.blob.BlobContainerClient;
+import com.azure.storage.blob.BlobServiceClient;
+import com.azure.storage.blob.BlobServiceClientBuilder;
+import com.azure.storage.blob.models.*;
+import com.azure.storage.blob.sas.BlobSasPermission;
 import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
 import com.azure.storage.blob.specialized.AppendBlobClient;
 import com.azure.storage.blob.specialized.BlobInputStream;
 import com.azure.storage.blob.specialized.BlockBlobClient;
 import com.azure.storage.blob.specialized.PageBlobClient;
+import com.azure.storage.common.StorageSharedKeyCredential;
 import org.apache.camel.util.ObjectHelper;
 
 public class BlobClientWrapper {
-
+    private static final String SERVICE_URI_SEGMENT = ".blob.core.windows.net";
     private final BlobClient client;
 
     public BlobClientWrapper(final BlobClient client) {
@@ -148,6 +138,26 @@ public class BlobClientWrapper {
                 Context.NONE);
     }
 
+    public String copyBlob(String sourceBlobName, String accountName, String 
containerName, String accessKey) {
+        BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
+                .endpoint(String.format(Locale.ROOT, "https://%s"; + 
SERVICE_URI_SEGMENT, accountName))
+                .credential(new StorageSharedKeyCredential(accountName, 
accessKey))
+                .buildClient();
+        BlobContainerClient sourceContainerClient = 
blobServiceClient.getBlobContainerClient(containerName);
+        BlobClient sourceBlob = 
sourceContainerClient.getBlobClient(sourceBlobName);
+
+        OffsetDateTime expiryTime = OffsetDateTime.now().plusSeconds(5L);
+        BlobSasPermission permission = new 
BlobSasPermission().setReadPermission(true);
+        BlobServiceSasSignatureValues values = new 
BlobServiceSasSignatureValues(expiryTime, permission)
+                .setStartTime(OffsetDateTime.now());
+        String sasToken = sourceBlob.generateSas(values);
+
+        String res = client.copyFromUrl(sourceBlob.getBlobUrl() + "?" + 
sasToken);
+
+        return res;
+
+    }
+
     public boolean appendBlobExists() {
         return getAppendBlobClient().exists();
     }
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperations.java
 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperations.java
index 7d63d72..f042e73 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperations.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperations.java
@@ -296,6 +296,25 @@ public class BlobOperations {
         return BlobOperationResponse.createWithEmptyBody(response);
     }
 
+    public BlobOperationResponse copyBlob(final Exchange exchange) {
+        LOG.trace("Creating an append blob [{}] from exchange [{}]...", 
configurationProxy.getBlobName(exchange), exchange);
+
+        String sourceBlobName = configurationProxy.getBlobName(exchange);
+        String sourceAccountName = 
exchange.getMessage().getHeader(BlobConstants.SOURCE_BLOB_ACCOUNT_NAME, 
String.class);
+        if (ObjectHelper.isEmpty(sourceAccountName)) {
+            throw new IllegalArgumentException("Source Account Name must be 
specified for copyBlob Operation");
+        }
+        String sourceContainerName = 
exchange.getMessage().getHeader(BlobConstants.SOURCE_BLOB_CONTAINER_NAME, 
String.class);
+        if (ObjectHelper.isEmpty(sourceAccountName)) {
+            throw new IllegalArgumentException("Source Container Name must be 
specified for copyBlob Operation");
+        }
+        final String response
+                = client.copyBlob(sourceBlobName, sourceAccountName, 
sourceContainerName,
+                        
configurationProxy.getConfiguration().getSourceBlobAccessKey());
+
+        return BlobOperationResponse.create(response);
+    }
+
     public BlobOperationResponse commitAppendBlob(final Exchange exchange) 
throws IOException {
         ObjectHelper.notNull(exchange, "exchange cannot be null");
 
diff --git 
a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AzureStorageBlobComponentBuilderFactory.java
 
b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AzureStorageBlobComponentBuilderFactory.java
index 2368e3e..2c3252d 100644
--- 
a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AzureStorageBlobComponentBuilderFactory.java
+++ 
b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/AzureStorageBlobComponentBuilderFactory.java
@@ -583,6 +583,23 @@ public interface AzureStorageBlobComponentBuilderFactory {
             doSetProperty("accessKey", accessKey);
             return this;
         }
+        /**
+         * Source Blob Access Key: for copyblob operation, sadly, we need to
+         * have an accessKey for the source blob we want to copy Passing an
+         * accessKey as header, it's unsafe so we could set as key.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: security
+         * 
+         * @param sourceBlobAccessKey the value to set
+         * @return the dsl builder
+         */
+        default AzureStorageBlobComponentBuilder sourceBlobAccessKey(
+                java.lang.String sourceBlobAccessKey) {
+            doSetProperty("sourceBlobAccessKey", sourceBlobAccessKey);
+            return this;
+        }
     }
 
     class AzureStorageBlobComponentBuilderImpl
@@ -637,6 +654,7 @@ public interface AzureStorageBlobComponentBuilderFactory {
             case "pageBlobSize": getOrCreateConfiguration((BlobComponent) 
component).setPageBlobSize((java.lang.Long) value); return true;
             case "autowiredEnabled": ((BlobComponent) 
component).setAutowiredEnabled((boolean) value); return true;
             case "accessKey": getOrCreateConfiguration((BlobComponent) 
component).setAccessKey((java.lang.String) value); return true;
+            case "sourceBlobAccessKey": 
getOrCreateConfiguration((BlobComponent) 
component).setSourceBlobAccessKey((java.lang.String) value); return true;
             default: return false;
             }
         }
diff --git 
a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
 
b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
index c3c78e1..acfb9db 100644
--- 
a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
+++ 
b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
@@ -1042,6 +1042,23 @@ public interface BlobEndpointBuilderFactory {
             doSetProperty("accessKey", accessKey);
             return this;
         }
+        /**
+         * Source Blob Access Key: for copyblob operation, sadly, we need to
+         * have an accessKey for the source blob we want to copy Passing an
+         * accessKey as header, it's unsafe so we could set as key.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: security
+         * 
+         * @param sourceBlobAccessKey the value to set
+         * @return the dsl builder
+         */
+        default BlobEndpointConsumerBuilder sourceBlobAccessKey(
+                String sourceBlobAccessKey) {
+            doSetProperty("sourceBlobAccessKey", sourceBlobAccessKey);
+            return this;
+        }
     }
 
     /**
@@ -2086,6 +2103,23 @@ public interface BlobEndpointBuilderFactory {
             doSetProperty("accessKey", accessKey);
             return this;
         }
+        /**
+         * Source Blob Access Key: for copyblob operation, sadly, we need to
+         * have an accessKey for the source blob we want to copy Passing an
+         * accessKey as header, it's unsafe so we could set as key.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: security
+         * 
+         * @param sourceBlobAccessKey the value to set
+         * @return the dsl builder
+         */
+        default BlobEndpointProducerBuilder sourceBlobAccessKey(
+                String sourceBlobAccessKey) {
+            doSetProperty("sourceBlobAccessKey", sourceBlobAccessKey);
+            return this;
+        }
     }
 
     /**
@@ -2543,6 +2577,23 @@ public interface BlobEndpointBuilderFactory {
             doSetProperty("accessKey", accessKey);
             return this;
         }
+        /**
+         * Source Blob Access Key: for copyblob operation, sadly, we need to
+         * have an accessKey for the source blob we want to copy Passing an
+         * accessKey as header, it's unsafe so we could set as key.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: security
+         * 
+         * @param sourceBlobAccessKey the value to set
+         * @return the dsl builder
+         */
+        default BlobEndpointBuilder sourceBlobAccessKey(
+                String sourceBlobAccessKey) {
+            doSetProperty("sourceBlobAccessKey", sourceBlobAccessKey);
+            return this;
+        }
     }
 
     /**
@@ -2602,7 +2653,8 @@ public interface BlobEndpointBuilderFactory {
         resizePageBlob,
         clearPageBlob,
         getPageBlobRanges,
-        getChangeFeed;
+        getChangeFeed,
+        copyBlob;
     }
 
     public interface BlobBuilders {

Reply via email to