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

davsclaus pushed a commit to branch fix/CAMEL-23806-split-azure-blob-docs
in repository https://gitbox.apache.org/repos/asf/camel.git

commit a0293cdeaec2befe9de6e503c5ecca45834a7e73
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Jun 20 17:13:12 2026 +0200

    CAMEL-23806: Split azure-storage-blob docs into focused sub-pages
    
    Split the Azure Storage Blob component documentation (1,956 lines)
    into 2 focused sub-pages, reducing the main page to 264 lines.
    
    - azure-storage-blob-operations: all 30 producer operation examples,
      blob snapshots/versions, and SAS token generation
    - azure-storage-blob-consumer: consumer patterns including delete
      after read and move after read
    
    Co-Authored-By: Claude <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../main/docs/azure-storage-blob-component.adoc    | 1699 +-------------------
 .../src/main/docs/azure-storage-blob-consumer.adoc |  282 ++++
 ...ent.adoc => azure-storage-blob-operations.adoc} |  547 +------
 docs/components/modules/others/nav.adoc            |    2 +
 .../others/pages/azure-storage-blob-consumer.adoc  |    1 +
 .../pages/azure-storage-blob-operations.adoc       |    1 +
 6 files changed, 297 insertions(+), 2235 deletions(-)

diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
 
b/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
index 6c02d53d2284..250efd0ace8a 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
@@ -239,1703 +239,12 @@ and existing blocks together. Any blocks not specified 
in the block list and per
 
 Refer to the example section in this page to learn how to use these operations 
into your camel application.
 
-== Examples
+== Sub-Pages
 
-=== Consumer Examples
+For more details on specific features, see:
 
-To consume a blob into a file using the file component, this can be done like 
this:
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey")
-    .to("file://blobdirectory");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;accountName=yourAccountName&amp;accessKey=yourAccessKey"/>
-    <to uri="file://blobdirectory"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/container1
-      parameters:
-        blobName: hello.txt
-        accountName: yourAccountName
-        accessKey: yourAccessKey
-    steps:
-      - to:
-          uri: file://blobdirectory
-----
-====
-
-However, you can also write to file directly without using the file component, 
you will need to specify `fileDir` folder path to save your blob in your 
machine.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir")
-    .to("mock:results");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;accountName=yourAccountName&amp;accessKey=yourAccessKey&amp;fileDir=/var/to/awesome/dir"/>
-    <to uri="mock:results"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/container1
-      parameters:
-        blobName: hello.txt
-        accountName: yourAccountName
-        accessKey: yourAccessKey
-        fileDir: /var/to/awesome/dir
-    steps:
-      - to:
-          uri: mock:results
-----
-====
-
-Also, the component supports batch consumer, hence you can consume multiple 
blobs with only specifying the container name, the consumer will
-return multiple exchanges depending on the number of the blobs in the 
container. Example:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/container1?accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir")
-    .to("mock:results");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from 
uri="azure-storage-blob://camelazure/container1?accountName=yourAccountName&amp;accessKey=yourAccessKey&amp;fileDir=/var/to/awesome/dir"/>
-    <to uri="mock:results"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/container1
-      parameters:
-        accountName: yourAccountName
-        accessKey: yourAccessKey
-        fileDir: /var/to/awesome/dir
-    steps:
-      - to:
-          uri: mock:results
-----
-====
-
-==== Delete After Read
-
-The consumer supports automatic deletion of blobs after they have been 
successfully processed. This is useful when you want to ensure that blobs are 
only processed once.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/container1?deleteAfterRead=true&accessKey=RAW(yourAccessKey)")
-    .log("Processing blob: ${header.CamelAzureStorageBlobBlobName}")
-    .to("direct:processBlob");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from 
uri="azure-storage-blob://camelazure/container1?deleteAfterRead=true&amp;accessKey=RAW(yourAccessKey)"/>
-  <log message="Processing blob: ${header.CamelAzureStorageBlobBlobName}"/>
-  <to uri="direct:processBlob"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/container1
-      parameters:
-        deleteAfterRead: true
-        accessKey: "RAW(yourAccessKey)"
-      steps:
-        - log:
-            message: "Processing blob: ${header.CamelAzureStorageBlobBlobName}"
-        - to:
-            uri: direct:processBlob
-----
-====
-
-IMPORTANT: The delete operation is only performed if the Exchange is 
successfully committed. If processing fails or a rollback occurs, the blob will 
not be deleted and can be reprocessed on the next poll.
-
-NOTE: When `deleteAfterRead` is set to `false` (the default), the same blobs 
will be retrieved repeatedly in subsequent polls. In this case, you should use 
the Idempotent Consumer EIP to filter out duplicates based on the 
`CamelAzureStorageBlobBlobName` header.
-
-==== Move After Read
-
-The consumer can move blobs to a different container after successful 
processing. This is useful for archiving processed blobs or implementing a 
processing pipeline across containers.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/incoming?moveAfterRead=true&destinationContainer=archive&accessKey=RAW(yourAccessKey)")
-    .log("Processing blob: ${header.CamelAzureStorageBlobBlobName}")
-    .to("direct:processBlob");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from 
uri="azure-storage-blob://camelazure/incoming?moveAfterRead=true&amp;destinationContainer=archive&amp;accessKey=RAW(yourAccessKey)"/>
-  <log message="Processing blob: ${header.CamelAzureStorageBlobBlobName}"/>
-  <to uri="direct:processBlob"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/incoming
-      parameters:
-        moveAfterRead: true
-        destinationContainer: archive
-        accessKey: "RAW(yourAccessKey)"
-      steps:
-        - log:
-            message: "Processing blob: ${header.CamelAzureStorageBlobBlobName}"
-        - to:
-            uri: direct:processBlob
-----
-====
-
-You can also customize the destination blob name by adding a prefix and/or 
suffix:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/source?moveAfterRead=true&destinationContainer=archive&prefix=incoming/&removePrefixOnMove=true&destinationBlobPrefix=processed/&destinationBlobSuffix=.done&accessKey=RAW(yourAccessKey)")
-    .log("Processing: ${header.CamelAzureStorageBlobBlobName}")
-    .to("direct:processBlob");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from 
uri="azure-storage-blob://camelazure/source?moveAfterRead=true&amp;destinationContainer=archive&amp;prefix=incoming/&amp;removePrefixOnMove=true&amp;destinationBlobPrefix=processed/&amp;destinationBlobSuffix=.done&amp;accessKey=RAW(yourAccessKey)"/>
-  <log message="Processing: ${header.CamelAzureStorageBlobBlobName}"/>
-  <to uri="direct:processBlob"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/source
-      parameters:
-        moveAfterRead: true
-        destinationContainer: archive
-        prefix: "incoming/"
-        removePrefixOnMove: true
-        destinationBlobPrefix: "processed/"
-        destinationBlobSuffix: ".done"
-        accessKey: "RAW(yourAccessKey)"
-      steps:
-        - log:
-            message: "Processing: ${header.CamelAzureStorageBlobBlobName}"
-        - to:
-            uri: direct:processBlob
-----
-====
-
-The move operation works as follows:
-
-1. The blob is copied to the destination container with the new name
-2. The original blob is deleted from the source container
-3. Both operations only occur after the Exchange is successfully committed
-
-The following options control the move behavior:
-
-[width="100%",cols="25%,75%",options="header",]
-|===
-|Option |Description
-|`moveAfterRead` |Enable moving blobs after successful processing
-|`destinationContainer` |Target container for moved blobs (required when 
`moveAfterRead=true`)
-|`destinationBlobPrefix` |Prefix to add to the blob name in the destination
-|`destinationBlobSuffix` |Suffix to add to the blob name in the destination
-|`removePrefixOnMove` |Remove the source prefix from the blob name before 
adding destination prefix
-|===
-
-=== Producer Operations Examples
-- `listBlobContainers`:
-
-NOTE: The `CamelAzureStorageBlobListBlobContainersOptions` header requires a 
`ListBlobContainersOptions` object, which must be set from a bean or processor.
-
-._Java-only: programmatic ListBlobContainersOptions_
-
-[source,java]
-----
-from("direct:start")
-    .process(exchange -> {
-        
exchange.getIn().setHeader("CamelAzureStorageBlobListBlobContainersOptions",
-                new ListBlobContainersOptions().setMaxResultsPerPage(10));
-    })
-    
.to("azure-storage-blob://camelazure?operation=listBlobContainers&serviceClient=#client")
-    .to("mock:result");
-----
-
-- `createBlobContainer`:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    .setHeader("CamelAzureStorageBlobBlobContainerName", 
constant("newContainerName"))
-    
.to("azure-storage-blob://camelazure/container1?operation=createBlobContainer&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <setHeader name="CamelAzureStorageBlobBlobContainerName">
-    <constant>newContainerName</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?operation=createBlobContainer&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobBlobContainerName
-            constant: newContainerName
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              operation: createBlobContainer
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `deleteBlobContainer`:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    .setHeader("CamelAzureStorageBlobBlobContainerName", 
constant("overridenName"))
-    
.to("azure-storage-blob://camelazure/container1?operation=deleteBlobContainer&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <setHeader name="CamelAzureStorageBlobBlobContainerName">
-    <constant>overridenName</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?operation=deleteBlobContainer&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobBlobContainerName
-            constant: overridenName
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              operation: deleteBlobContainer
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `listBlobs`:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    .setHeader("CamelAzureStorageBlobBlobContainerName", 
constant("overridenName"))
-    
.to("azure-storage-blob://camelazure/container1?operation=listBlobs&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <setHeader name="CamelAzureStorageBlobBlobContainerName">
-    <constant>overridenName</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?operation=listBlobs&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobBlobContainerName
-            constant: overridenName
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              operation: listBlobs
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-
-- `listBlobVersions`:
-
-Returns every version of every blob in the container. Versioning must be 
enabled on the storage
-account. Each `BlobItem` in the result carries its own `versionId` and 
`isCurrentVersion` flag.
-The `prefix` and `regex` options can be used to narrow the result down to a 
single blob name.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    .setHeader("CamelAzureStorageBlobPrefix", constant("invoice.pdf"))
-    
.to("azure-storage-blob://camelazure/container1?operation=listBlobVersions&serviceClient=#client")
-    .log("${body}")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <setHeader name="CamelAzureStorageBlobPrefix">
-    <constant>invoice.pdf</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?operation=listBlobVersions&amp;serviceClient=#client"/>
-  <log message="${body}"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobPrefix
-            constant: invoice.pdf
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              operation: listBlobVersions
-              serviceClient: "#client"
-        - log:
-            message: "${body}"
-        - to:
-            uri: mock:result
-----
-====
-
-
-- `getBlob`:
-
-We can either set an `outputStream` in the exchange body and write the data to 
it:
-
-._Java-only: programmatic OutputStream handling_
-
-[source,java]
-----
-from("direct:start")
-    .process(exchange -> {
-        exchange.getIn().setHeader("CamelAzureStorageBlobBlobContainerName", 
"overridenName");
-        exchange.getIn().setBody(outputStream);
-    })
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=getBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-If we don't set a body, then this operation will give us an `InputStream` 
instance which can be processed further downstream:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=getBlob&serviceClient=#client")
-    .log("${body}")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=blob&amp;operation=getBlob&amp;serviceClient=#client"/>
-  <log message="${body}"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: blob
-              operation: getBlob
-              serviceClient: "#client"
-        - log:
-            message: "${body}"
-        - to:
-            uri: mock:result
-----
-====
-
-- `deleteBlob`:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    .setHeader("CamelAzureStorageBlobBlobName", constant("overridenName"))
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=deleteBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <setHeader name="CamelAzureStorageBlobBlobName">
-    <constant>overridenName</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=blob&amp;operation=deleteBlob&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobBlobName
-            constant: overridenName
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: blob
-              operation: deleteBlob
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `downloadBlobToFile`:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    .setHeader("CamelAzureStorageBlobBlobName", constant("overridenName"))
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=downloadBlobToFile&fileDir=/var/mydir&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <setHeader name="CamelAzureStorageBlobBlobName">
-    <constant>overridenName</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=blob&amp;operation=downloadBlobToFile&amp;fileDir=/var/mydir&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobBlobName
-            constant: overridenName
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: blob
-              operation: downloadBlobToFile
-              fileDir: /var/mydir
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `downloadLink`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=downloadLink&serviceClient=#client")
-    .log("My link ${header.CamelAzureStorageBlobDownloadLink}")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=blob&amp;operation=downloadLink&amp;serviceClient=#client"/>
-  <log message="My link ${header.CamelAzureStorageBlobDownloadLink}"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: blob
-              operation: downloadLink
-              serviceClient: "#client"
-        - log:
-            message: "My link ${header.CamelAzureStorageBlobDownloadLink}"
-        - to:
-            uri: mock:result
-----
-====
-
-- `uploadBlockBlob`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    .setHeader("CamelAzureStorageBlobBlobName", constant("overridenName"))
-    .setBody(constant("Block Blob"))
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=uploadBlockBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <setHeader name="CamelAzureStorageBlobBlobName">
-    <constant>overridenName</constant>
-  </setHeader>
-  <setBody>
-    <constant>Block Blob</constant>
-  </setBody>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=blob&amp;operation=uploadBlockBlob&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobBlobName
-            constant: overridenName
-        - setBody:
-            constant: Block Blob
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: blob
-              operation: uploadBlockBlob
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `uploadBlockBlobChunked`
-
-This operation is recommended for uploading large files (larger than 256MB) as 
it uses chunked parallel uploads for memory efficiency.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("file://data?noop=true")
-    .log("Uploading file: ${header.CamelFileName}")
-    
.toD("azure-storage-blob://camelazure/container1?blobName=${header.CamelFileName}&operation=uploadBlockBlobChunked&blockSize=52428800&maxConcurrency=4&serviceClient=#client")
-    .log("Upload completed: ${header.CamelFileName}");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="file://data?noop=true"/>
-  <log message="Uploading file: ${header.CamelFileName}"/>
-  <toD 
uri="azure-storage-blob://camelazure/container1?blobName=${header.CamelFileName}&amp;operation=uploadBlockBlobChunked&amp;blockSize=52428800&amp;maxConcurrency=4&amp;serviceClient=#client"/>
-  <log message="Upload completed: ${header.CamelFileName}"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: file://data
-      parameters:
-        noop: true
-      steps:
-        - log:
-            message: "Uploading file: ${header.CamelFileName}"
-        - toD:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: "${header.CamelFileName}"
-              operation: uploadBlockBlobChunked
-              blockSize: 52428800
-              maxConcurrency: 4
-              serviceClient: "#client"
-        - log:
-            message: "Upload completed: ${header.CamelFileName}"
-----
-====
-
-The `blockSize` and `maxConcurrency` options control memory usage and upload 
speed:
-
-* `blockSize`: Size of each chunk (default: 4MB, max: 4000MB). Larger blocks = 
fewer requests but more memory.
-* `maxConcurrency`: Number of parallel uploads (default: auto-detected based 
on CPU cores). Higher = faster but more memory.
-* Memory usage is approximately `blockSize × maxConcurrency`.
-
-- `stageBlockBlobList`
-
-._Java-only: requires BlobBlock objects in the body_
-
-[source,java]
-----
-from("direct:start")
-    .process(exchange -> {
-        final List<BlobBlock> blocks = new LinkedList<>();
-        blocks.add(BlobBlock.createBlobBlock(new 
ByteArrayInputStream("Hello".getBytes())));
-        blocks.add(BlobBlock.createBlobBlock(new 
ByteArrayInputStream("From".getBytes())));
-        blocks.add(BlobBlock.createBlobBlock(new 
ByteArrayInputStream("Camel".getBytes())));
-        exchange.getIn().setBody(blocks);
-    })
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=stageBlockBlobList&serviceClient=#client")
-    .to("mock:result");
-----
-
-- `commitBlockBlobList`
-
-._Java-only: requires Block objects in the body_
-
-[source,java]
-----
-from("direct:start")
-    .process(exchange -> {
-        final List<Block> blockIds = new LinkedList<>();
-        blockIds.add(new Block().setName("id-1"));
-        blockIds.add(new Block().setName("id-2"));
-        blockIds.add(new Block().setName("id-3"));
-        exchange.getIn().setBody(blockIds);
-    })
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=commitBlockBlobList&serviceClient=#client")
-    .to("mock:result");
-----
-
-- `getBlobBlockList`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=getBlobBlockList&serviceClient=#client")
-    .log("${body}")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=blob&amp;operation=getBlobBlockList&amp;serviceClient=#client"/>
-  <log message="${body}"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: blob
-              operation: getBlobBlockList
-              serviceClient: "#client"
-        - log:
-            message: "${body}"
-        - to:
-            uri: mock:result
-----
-====
-
-
-- `createAppendBlob`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=createAppendBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=blob&amp;operation=createAppendBlob&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: blob
-              operation: createAppendBlob
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `commitAppendBlob`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    .setBody(constant("Hello world from my awesome tests!"))
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=commitAppendBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <setBody>
-    <constant>Hello world from my awesome tests!</constant>
-  </setBody>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=blob&amp;operation=commitAppendBlob&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - setBody:
-            constant: "Hello world from my awesome tests!"
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: blob
-              operation: commitAppendBlob
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `createPageBlob`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:start")
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=createPageBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:start"/>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=blob&amp;operation=createPageBlob&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:start
-      steps:
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: blob
-              operation: createPageBlob
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `uploadPageBlob`
-
-NOTE: The `CamelAzureStorageBlobPageBlobRange` header requires a `PageRange` 
object, which must be set from a bean or processor.
-
-._Java-only: requires PageRange object_
-
-[source,java]
-----
-from("direct:start")
-    .process(exchange -> {
-        byte[] dataBytes = new byte[512];
-        new Random().nextBytes(dataBytes);
-        final InputStream dataStream = new ByteArrayInputStream(dataBytes);
-        final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
-        exchange.getIn().setHeader("CamelAzureStorageBlobPageBlobRange", 
pageRange);
-        exchange.getIn().setBody(dataStream);
-    })
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=uploadPageBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-- `resizePageBlob`
-
-._Java-only: requires PageRange object_
-
-[source,java]
-----
-from("direct:start")
-    .process(exchange -> {
-        exchange.getIn().setHeader("CamelAzureStorageBlobPageBlobRange",
-                new PageRange().setStart(0).setEnd(511));
-    })
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=resizePageBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-- `clearPageBlob`
-
-._Java-only: requires PageRange object_
-
-[source,java]
-----
-from("direct:start")
-    .process(exchange -> {
-        exchange.getIn().setHeader("CamelAzureStorageBlobPageBlobRange",
-                new PageRange().setStart(0).setEnd(511));
-    })
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=clearPageBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-- `getPageBlobRanges`
-
-._Java-only: requires PageRange object_
-
-[source,java]
-----
-from("direct:start")
-    .process(exchange -> {
-        exchange.getIn().setHeader("CamelAzureStorageBlobPageBlobRange",
-                new PageRange().setStart(0).setEnd(511));
-    })
-    
.to("azure-storage-blob://camelazure/container1?blobName=blob&operation=getPageBlobRanges&serviceClient=#client")
-    .log("${body}")
-    .to("mock:result");
-----
-
-- `copyBlob`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:copyBlob")
-    .setHeader("CamelAzureStorageBlobBlobName", constant("file.txt"))
-    .setHeader("CamelAzureStorageBlobSourceBlobContainerName", 
constant("containerblob1"))
-    .setHeader("CamelAzureStorageBlobSourceBlobAccountName", 
constant("account"))
-    
.to("azure-storage-blob://account/containerblob2?operation=copyBlob&sourceBlobAccessKey=RAW(accessKey)")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:copyBlob"/>
-  <setHeader name="CamelAzureStorageBlobBlobName">
-    <constant>file.txt</constant>
-  </setHeader>
-  <setHeader name="CamelAzureStorageBlobSourceBlobContainerName">
-    <constant>containerblob1</constant>
-  </setHeader>
-  <setHeader name="CamelAzureStorageBlobSourceBlobAccountName">
-    <constant>account</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://account/containerblob2?operation=copyBlob&amp;sourceBlobAccessKey=RAW(accessKey)"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:copyBlob
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobBlobName
-            constant: file.txt
-        - setHeader:
-            name: CamelAzureStorageBlobSourceBlobContainerName
-            constant: containerblob1
-        - setHeader:
-            name: CamelAzureStorageBlobSourceBlobAccountName
-            constant: account
-        - to:
-            uri: azure-storage-blob://account/containerblob2
-            parameters:
-              operation: copyBlob
-              sourceBlobAccessKey: "RAW(accessKey)"
-        - to:
-            uri: mock:result
-----
-====
-
-In this way the `file.txt` in the container `containerblob1` of the account 
`account`, will be copied to the container `containerblob2` of the same account.
-
-- `createBlobSnapshot`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:createBlobSnapshot")
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=createBlobSnapshot&serviceClient=#client")
-    .log("Snapshot ID: ${header.CamelAzureStorageBlobSnapshotId}")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:createBlobSnapshot"/>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;operation=createBlobSnapshot&amp;serviceClient=#client"/>
-  <log message="Snapshot ID: ${header.CamelAzureStorageBlobSnapshotId}"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:createBlobSnapshot
-      steps:
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: hello.txt
-              operation: createBlobSnapshot
-              serviceClient: "#client"
-        - log:
-            message: "Snapshot ID: ${header.CamelAzureStorageBlobSnapshotId}"
-        - to:
-            uri: mock:result
-----
-====
-
-=== Reading a specific blob snapshot
-
-The `getBlob`, `downloadBlobToFile` and `downloadLink` operations can target a 
specific snapshot by setting the
-`snapshotId` URI parameter or the `CamelAzureStorageBlobSnapshotId` exchange 
header. When set, the read is scoped
-to the snapshot version of the blob instead of the live one. The header takes 
precedence over the URI parameter.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:readSnapshot")
-    .setHeader("CamelAzureStorageBlobSnapshotId", 
constant("2026-04-15T10:00:00.0000000Z"))
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=getBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:readSnapshot"/>
-  <setHeader name="CamelAzureStorageBlobSnapshotId">
-    <constant>2026-04-15T10:00:00.0000000Z</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;operation=getBlob&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:readSnapshot
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobSnapshotId
-            constant: "2026-04-15T10:00:00.0000000Z"
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: hello.txt
-              operation: getBlob
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-=== Reading a specific blob version
-
-When blob versioning is enabled on the storage account, the `getBlob`, 
`downloadBlobToFile` and `downloadLink`
-operations can target a specific version by setting the `versionId` URI 
parameter or the
-`CamelAzureStorageBlobVersionId` exchange header. When set, the read is scoped 
to the version of the blob instead
-of the live one. The header takes precedence over the URI parameter.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:readVersion")
-    .setHeader("CamelAzureStorageBlobVersionId", 
constant("2026-04-15T10:00:00.0000000Z"))
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=getBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:readVersion"/>
-  <setHeader name="CamelAzureStorageBlobVersionId">
-    <constant>2026-04-15T10:00:00.0000000Z</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;operation=getBlob&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:readVersion
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobVersionId
-            constant: "2026-04-15T10:00:00.0000000Z"
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: hello.txt
-              operation: getBlob
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `setBlobTags`
-
-NOTE: The `CamelAzureStorageBlobTags` header requires a `Map<String, String>` 
value, which must be set from a bean or processor in XML/YAML.
-
-._Java-only: Map.of() for blob tags_
-
-[source,java]
-----
-from("direct:setBlobTags")
-    .setHeader("CamelAzureStorageBlobTags", constant(Map.of("status", 
"quarantine", "category", "document")))
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=setBlobTags&serviceClient=#client")
-    .to("mock:result");
-----
-
-- `getBlobTags`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:getBlobTags")
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=getBlobTags&serviceClient=#client")
-    .log("Tags: ${body}")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:getBlobTags"/>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;operation=getBlobTags&amp;serviceClient=#client"/>
-  <log message="Tags: ${body}"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:getBlobTags
-      steps:
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: hello.txt
-              operation: getBlobTags
-              serviceClient: "#client"
-        - log:
-            message: "Tags: ${body}"
-        - to:
-            uri: mock:result
-----
-====
-
-- `findBlobsByTags`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:findBlobsByTags")
-    .setHeader("CamelAzureStorageBlobTagFilter", constant("\"Environment\" = 
'Production' AND \"Status\" = 'Active'"))
-    
.to("azure-storage-blob://camelazure?operation=findBlobsByTags&serviceClient=#client")
-    .log("Matching blobs: ${body}")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:findBlobsByTags"/>
-  <setHeader name="CamelAzureStorageBlobTagFilter">
-    <constant>"Environment" = 'Production' AND "Status" = 'Active'</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure?operation=findBlobsByTags&amp;serviceClient=#client"/>
-  <log message="Matching blobs: ${body}"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:findBlobsByTags
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobTagFilter
-            constant: "\"Environment\" = 'Production' AND \"Status\" = 
'Active'"
-        - to:
-            uri: azure-storage-blob://camelazure
-            parameters:
-              operation: findBlobsByTags
-              serviceClient: "#client"
-        - log:
-            message: "Matching blobs: ${body}"
-        - to:
-            uri: mock:result
-----
-====
-
-- `setBlobLegalHold`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-// place a legal hold on the blob
-from("direct:setLegalHold")
-    .setHeader("CamelAzureStorageBlobLegalHold", constant(true))
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=setBlobLegalHold&serviceClient=#client")
-    .to("mock:result");
-
-// clear the legal hold
-from("direct:clearLegalHold")
-    .setHeader("CamelAzureStorageBlobLegalHold", constant(false))
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=setBlobLegalHold&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:setLegalHold"/>
-  <setHeader name="CamelAzureStorageBlobLegalHold">
-    <constant>true</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;operation=setBlobLegalHold&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-
-<route>
-  <from uri="direct:clearLegalHold"/>
-  <setHeader name="CamelAzureStorageBlobLegalHold">
-    <constant>false</constant>
-  </setHeader>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;operation=setBlobLegalHold&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:setLegalHold
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobLegalHold
-            constant: true
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: hello.txt
-              operation: setBlobLegalHold
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-
-- route:
-    from:
-      uri: direct:clearLegalHold
-      steps:
-        - setHeader:
-            name: CamelAzureStorageBlobLegalHold
-            constant: false
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: hello.txt
-              operation: setBlobLegalHold
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `setBlobImmutabilityPolicy`
-
-._Java-only: requires OffsetDateTime and BlobImmutabilityPolicyMode objects_
-
-[source,java]
-----
-from("direct:setImmutabilityPolicy")
-    .setHeader("CamelAzureStorageBlobImmutabilityPolicyExpiryTime", 
constant(OffsetDateTime.now().plusDays(7)))
-    .setHeader("CamelAzureStorageBlobImmutabilityPolicyMode", 
constant(BlobImmutabilityPolicyMode.UNLOCKED))
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=setBlobImmutabilityPolicy&serviceClient=#client")
-    .to("mock:result");
-----
-
-- `undeleteBlob`
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:undeleteBlob")
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=undeleteBlob&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:undeleteBlob"/>
-  <to 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;operation=undeleteBlob&amp;serviceClient=#client"/>
-  <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:undeleteBlob
-      steps:
-        - to:
-            uri: azure-storage-blob://camelazure/container1
-            parameters:
-              blobName: hello.txt
-              operation: undeleteBlob
-              serviceClient: "#client"
-        - to:
-            uri: mock:result
-----
-====
-
-- `setBlobTier`
-
-._Java-only: requires AccessTier and RehydratePriority enum objects_
-
-[source,java]
-----
-// move a blob to the COOL tier for less frequent access
-from("direct:moveToCool")
-    .setHeader("CamelAzureStorageBlobAccessTier", constant(AccessTier.COOL))
-    
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=setBlobTier&serviceClient=#client")
-    .to("mock:result");
-
-// rehydrate a blob from ARCHIVE to HOT with high priority
-from("direct:rehydrate")
-    .setHeader("CamelAzureStorageBlobAccessTier", constant(AccessTier.HOT))
-    .setHeader("CamelAzureStorageBlobRehydratePriority", 
constant(RehydratePriority.HIGH))
-    
.to("azure-storage-blob://camelazure/container1?blobName=archived.txt&operation=setBlobTier&serviceClient=#client")
-    .to("mock:result");
-----
-
-=== Blob modification during download (ConditionNotMet)
-
-When downloading a blob via streaming (the `getBlob` operation or the consumer 
without `fileDir`), the Azure SDK reads the blob in chunks.
-On the first chunk it captures the blob's ETag and uses it as an `if-match` 
condition on subsequent chunk requests.
-If the blob is modified by another process between chunks (which changes its 
ETag), Azure returns HTTP 412 `ConditionNotMet`.
-
-This is by design in the Azure SDK — it ensures read consistency so that you 
do not receive half of one version concatenated with half of another.
-The error is more likely with larger blobs and slower network connections 
(e.g., in real Azure environments versus local emulators).
-
-Workarounds:
-
-* Use the `fileDir` option so the consumer downloads the blob atomically to a 
file via `downloadBlobToFile` instead of streaming.
-* Use blob snapshots — read from an immutable snapshot ID via the `snapshotId` 
option or the `CamelAzureStorageBlobSnapshotId` header, which cannot be 
modified.
-* Use blob versioning — read from a specific version via the `versionId` 
option or the `CamelAzureStorageBlobVersionId` header.
-* Avoid modifying blobs while they are being consumed.
-
-=== SAS Token generation example
-
-SAS Blob Container tokens can be generated programmatically or via Azure UI. 
To generate the token with Java code, the following can be done:
-
-._Java-only: programmatic SAS token generation_
-
-[source,java]
-----
-BlobContainerClient blobClient = new BlobContainerClientBuilder()
-        .endpoint(String.format("https://%s.blob.core.windows.net/%s";, 
accountName, accessKey))
-        .containerName(containerName)
-        .credential(new StorageSharedKeyCredential(accountName, accessKey))
-        .buildClient();
-
-OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
-
-BlobContainerSasPermission blobContainerSasPermission = new 
BlobContainerSasPermission()
-        .setWritePermission(true)
-        .setListPermission(true)
-        .setCreatePermission(true)
-        .setDeletePermission(true)
-        .setAddPermission(true)
-        .setReadPermission(true);
-
-BlobServiceSasSignatureValues sasSignatureValues = new 
BlobServiceSasSignatureValues(expiryTime, blobContainerSasPermission);
-
-return blobClient.generateSas(sasSignatureValues);
-----
-
-The generated SAS token can be then stored to an application.properties file 
so that it can be loaded by the Camel route, for example:
-
-[source,properties]
-----
-camel.component.azure-storage-blob.sas-token=MY_TOKEN_HERE
-----
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("direct:uploadBlob")
-    
.to("azure-storage-blob://account/containerblob2?operation=uploadBlockBlob&credentialType=AZURE_SAS");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from uri="direct:uploadBlob"/>
-  <to 
uri="azure-storage-blob://account/containerblob2?operation=uploadBlockBlob&amp;credentialType=AZURE_SAS"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: direct:uploadBlob
-      steps:
-        - to:
-            uri: azure-storage-blob://account/containerblob2
-            parameters:
-              operation: uploadBlockBlob
-              credentialType: AZURE_SAS
-----
-====
+* xref:others:azure-storage-blob-operations.adoc[Producer Operations] - All 
producer operation examples, blob snapshots/versions, and SAS token generation
+* xref:others:azure-storage-blob-consumer.adoc[Consumer Examples] - Consumer 
patterns including delete after read and move after read
 
 == Important Development Notes
 
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-consumer.adoc
 
b/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-consumer.adoc
new file mode 100644
index 000000000000..a49f9cc45a4a
--- /dev/null
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-consumer.adoc
@@ -0,0 +1,282 @@
+= Azure Storage Blob - Consumer Examples
+:tabs-sync-option:
+
+xref:ROOT:azure-storage-blob-component.adoc[Back to Azure Storage Blob 
Component]
+
+== Consumer Examples
+
+To consume a blob into a file using the file component, this can be done like 
this:
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("azure-storage-blob://camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey")
+    .to("file://blobdirectory");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;accountName=yourAccountName&amp;accessKey=yourAccessKey"/>
+    <to uri="file://blobdirectory"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: azure-storage-blob://camelazure/container1
+      parameters:
+        blobName: hello.txt
+        accountName: yourAccountName
+        accessKey: yourAccessKey
+    steps:
+      - to:
+          uri: file://blobdirectory
+----
+====
+
+However, you can also write to file directly without using the file component, 
you will need to specify `fileDir` folder path to save your blob in your 
machine.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("azure-storage-blob://camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir")
+    .to("mock:results");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;accountName=yourAccountName&amp;accessKey=yourAccessKey&amp;fileDir=/var/to/awesome/dir"/>
+    <to uri="mock:results"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: azure-storage-blob://camelazure/container1
+      parameters:
+        blobName: hello.txt
+        accountName: yourAccountName
+        accessKey: yourAccessKey
+        fileDir: /var/to/awesome/dir
+    steps:
+      - to:
+          uri: mock:results
+----
+====
+
+Also, the component supports batch consumer, hence you can consume multiple 
blobs with only specifying the container name, the consumer will
+return multiple exchanges depending on the number of the blobs in the 
container. Example:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("azure-storage-blob://camelazure/container1?accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir")
+    .to("mock:results");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+    <from 
uri="azure-storage-blob://camelazure/container1?accountName=yourAccountName&amp;accessKey=yourAccessKey&amp;fileDir=/var/to/awesome/dir"/>
+    <to uri="mock:results"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: azure-storage-blob://camelazure/container1
+      parameters:
+        accountName: yourAccountName
+        accessKey: yourAccessKey
+        fileDir: /var/to/awesome/dir
+    steps:
+      - to:
+          uri: mock:results
+----
+====
+
+=== Delete After Read
+
+The consumer supports automatic deletion of blobs after they have been 
successfully processed. This is useful when you want to ensure that blobs are 
only processed once.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("azure-storage-blob://camelazure/container1?deleteAfterRead=true&accessKey=RAW(yourAccessKey)")
+    .log("Processing blob: ${header.CamelAzureStorageBlobBlobName}")
+    .to("direct:processBlob");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from 
uri="azure-storage-blob://camelazure/container1?deleteAfterRead=true&amp;accessKey=RAW(yourAccessKey)"/>
+  <log message="Processing blob: ${header.CamelAzureStorageBlobBlobName}"/>
+  <to uri="direct:processBlob"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: azure-storage-blob://camelazure/container1
+      parameters:
+        deleteAfterRead: true
+        accessKey: "RAW(yourAccessKey)"
+      steps:
+        - log:
+            message: "Processing blob: ${header.CamelAzureStorageBlobBlobName}"
+        - to:
+            uri: direct:processBlob
+----
+====
+
+IMPORTANT: The delete operation is only performed if the Exchange is 
successfully committed. If processing fails or a rollback occurs, the blob will 
not be deleted and can be reprocessed on the next poll.
+
+NOTE: When `deleteAfterRead` is set to `false` (the default), the same blobs 
will be retrieved repeatedly in subsequent polls. In this case, you should use 
the Idempotent Consumer EIP to filter out duplicates based on the 
`CamelAzureStorageBlobBlobName` header.
+
+=== Move After Read
+
+The consumer can move blobs to a different container after successful 
processing. This is useful for archiving processed blobs or implementing a 
processing pipeline across containers.
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("azure-storage-blob://camelazure/incoming?moveAfterRead=true&destinationContainer=archive&accessKey=RAW(yourAccessKey)")
+    .log("Processing blob: ${header.CamelAzureStorageBlobBlobName}")
+    .to("direct:processBlob");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from 
uri="azure-storage-blob://camelazure/incoming?moveAfterRead=true&amp;destinationContainer=archive&amp;accessKey=RAW(yourAccessKey)"/>
+  <log message="Processing blob: ${header.CamelAzureStorageBlobBlobName}"/>
+  <to uri="direct:processBlob"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: azure-storage-blob://camelazure/incoming
+      parameters:
+        moveAfterRead: true
+        destinationContainer: archive
+        accessKey: "RAW(yourAccessKey)"
+      steps:
+        - log:
+            message: "Processing blob: ${header.CamelAzureStorageBlobBlobName}"
+        - to:
+            uri: direct:processBlob
+----
+====
+
+You can also customize the destination blob name by adding a prefix and/or 
suffix:
+
+[tabs]
+====
+Java::
++
+[source,java]
+----
+from("azure-storage-blob://camelazure/source?moveAfterRead=true&destinationContainer=archive&prefix=incoming/&removePrefixOnMove=true&destinationBlobPrefix=processed/&destinationBlobSuffix=.done&accessKey=RAW(yourAccessKey)")
+    .log("Processing: ${header.CamelAzureStorageBlobBlobName}")
+    .to("direct:processBlob");
+----
+
+XML::
++
+[source,xml]
+----
+<route>
+  <from 
uri="azure-storage-blob://camelazure/source?moveAfterRead=true&amp;destinationContainer=archive&amp;prefix=incoming/&amp;removePrefixOnMove=true&amp;destinationBlobPrefix=processed/&amp;destinationBlobSuffix=.done&amp;accessKey=RAW(yourAccessKey)"/>
+  <log message="Processing: ${header.CamelAzureStorageBlobBlobName}"/>
+  <to uri="direct:processBlob"/>
+</route>
+----
+
+YAML::
++
+[source,yaml]
+----
+- route:
+    from:
+      uri: azure-storage-blob://camelazure/source
+      parameters:
+        moveAfterRead: true
+        destinationContainer: archive
+        prefix: "incoming/"
+        removePrefixOnMove: true
+        destinationBlobPrefix: "processed/"
+        destinationBlobSuffix: ".done"
+        accessKey: "RAW(yourAccessKey)"
+      steps:
+        - log:
+            message: "Processing: ${header.CamelAzureStorageBlobBlobName}"
+        - to:
+            uri: direct:processBlob
+----
+====
+
+The move operation works as follows:
+
+1. The blob is copied to the destination container with the new name
+2. The original blob is deleted from the source container
+3. Both operations only occur after the Exchange is successfully committed
+
+The following options control the move behavior:
+
+[width="100%",cols="25%,75%",options="header",]
+|===
+|Option |Description
+|`moveAfterRead` |Enable moving blobs after successful processing
+|`destinationContainer` |Target container for moved blobs (required when 
`moveAfterRead=true`)
+|`destinationBlobPrefix` |Prefix to add to the blob name in the destination
+|`destinationBlobSuffix` |Suffix to add to the blob name in the destination
+|`removePrefixOnMove` |Remove the source prefix from the blob name before 
adding destination prefix
+|===
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
 
b/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-operations.adoc
similarity index 61%
copy from 
components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
copy to 
components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-operations.adoc
index 6c02d53d2284..8d7bc7cec7af 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-operations.adoc
@@ -1,525 +1,9 @@
-= Azure Storage Blob Service Component
-:doctitle: Azure Storage Blob Service
-:shortname: azure-storage-blob
-:artifactid: camel-azure-storage-blob
-:description: Store and retrieve blobs from Azure Storage Blob Service.
-:since: 3.3
-:supportlevel: Stable
+= Azure Storage Blob - Producer Operations
 :tabs-sync-option:
-:component-header: Both producer and consumer are supported
-//Manually maintained attributes
-:group: Azure
 
-*Since Camel {since}*
+xref:ROOT:azure-storage-blob-component.adoc[Back to Azure Storage Blob 
Component]
 
-*{component-header}*
-
-The Azure Storage Blob component is used for storing and retrieving blobs from 
https://azure.microsoft.com/services/storage/blobs/[Azure Storage Blob] Service 
using *Azure APIs v12*.
-However, in the case of versions above v12, we will see if this component can 
adopt these changes depending on how much breaking changes can result.
-
-Prerequisites
-
-You must have a valid Windows Azure Storage account. More information is 
available at
-https://docs.microsoft.com/azure/[Azure Documentation Portal].
-
-Maven users will need to add the following dependency to their `pom.xml`
-for this component:
-
-[source,xml]
-----
-<dependency>
-    <groupId>org.apache.camel</groupId>
-    <artifactId>camel-azure-storage-blob</artifactId>
-    <version>x.x.x</version>
-  <!-- use the same version as your Camel core version -->
-</dependency>
-----
-
-
-== URI Format
-
-[source,text]
-----
-azure-storage-blob://accountName[/containerName][?options]
-----
-
-In the case of a consumer, `accountName`, `containerName` are required.
-
-In the case of a producer, it depends on the operation that is being 
requested, for example, if operation is on a container level, e.b: 
createContainer, accountName and containerName are only required, but in case 
of operation being requested in blob level, e.g: getBlob, accountName, 
containerName and blobName are required.
-
-The blob will be created if it does not already exist.
-You can append query options to the URI in the following format, 
`?options=value&option2=value&...`
-
-
-// component options: START
-include::partial$component-configure-options.adoc[]
-include::partial$component-endpoint-options.adoc[]
-include::partial$component-endpoint-headers.adoc[]
-// component options: END
-
-*Required information options:*
-
-To use this component, you have multiple options to provide the required Azure 
authentication information:
-
-- By providing your own 
https://azuresdkdocs.blob.core.windows.net/$web/java/azure-storage-blob/12.0.0/com/azure/storage/blob/BlobServiceClient.html[BlobServiceClient]
 instance which can be injected into `blobServiceClient`. Note: You don't need 
to create a specific client, e.g.: BlockBlobClient, the BlobServiceClient 
represents the upper level which
-can be used to retrieve lower level clients.
-- Via Azure Identity, when specifying `credentialType=AZURE_IDENTITY` and 
providing required 
https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/identity/azure-identity#environment-variables[environment
 variables]. This enables service principal (e.g. app registration) 
authentication with secret/certificate as well as username password. Note that 
this is the default authentication strategy.
-- Via shared storage account key, when specifying 
`credentialType=SHARED_ACCOUNT_KEY` and providing `accountName` and `accessKey` 
for your Azure account, this is the simplest way to get started. The accessKey 
can be generated through your Azure portal.
-- Via shared storage account key, when specifying 
`credentialType=SHARED_KEY_CREDENTIAL` and providing a 
https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/apidocs/com/azure/storage/common/StorageSharedKeyCredential.html[StorageSharedKeyCredential]
 instance which can be injected into `credentials` option.
-- Via Azure SAS, when specifying `credentialType=AZURE_SAS` and providing a 
SAS Token parameter through the `sasToken` parameter.
-
-== Usage
-
-For example, to download a blob content from the block blob `hello.txt`
-located on the `container1` in the `camelazure` storage account, use the 
following snippet:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/container1?blobName=hello.txt&credentialType=SHARED_ACCOUNT_KEY&accessKey=RAW(yourAccessKey)")
-    .to("file://blobdirectory");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;credentialType=SHARED_ACCOUNT_KEY&amp;accessKey=RAW(yourAccessKey)"/>
-    <to uri="file://blobdirectory"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/container1
-      parameters:
-        blobName: hello.txt
-        credentialType: SHARED_ACCOUNT_KEY
-        accessKey: RAW(yourAccessKey)
-    steps:
-      - to:
-          uri: file://blobdirectory
-----
-====
-
-=== Advanced Azure Storage Blob configuration
-
-If your Camel Application is running behind a firewall or if you need to
-have more control over the `BlobServiceClient` instance configuration, you can
-create your own instance:
-
-._Java-only: programmatic BlobServiceClient setup_
-
-[source,java]
-----
-StorageSharedKeyCredential credential = new 
StorageSharedKeyCredential("yourAccountName", "yourAccessKey");
-String uri = String.format("https://%s.blob.core.windows.net";, 
"yourAccountName");
-
-BlobServiceClient client = new BlobServiceClientBuilder()
-                          .endpoint(uri)
-                          .credential(credential)
-                          .buildClient();
-// This is camel context
-context.getRegistry().bind("client", client);
-----
-
-Then refer to this instance in your Camel `azure-storage-blob` component 
configuration:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://cameldev/container1?blobName=myblob&serviceClient=#client")
-    .to("mock:result");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from 
uri="azure-storage-blob://cameldev/container1?blobName=myblob&amp;serviceClient=#client"/>
-    <to uri="mock:result"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://cameldev/container1
-      parameters:
-        blobName: myblob
-        serviceClient: "#client"
-    steps:
-      - to:
-          uri: mock:result
-----
-====
-
-=== Automatic detection of BlobServiceClient client in registry
-
-The component is capable of detecting the presence of an BlobServiceClient 
bean into the registry.
-If it's the only instance of that type, it will be used as the client, and you 
won't have to define it as uri parameter, like the example above.
-This may be really useful for smarter configuration of the endpoint.
-
-=== Azure Storage Blob Producer operations
-
-Camel Azure Storage Blob component provides a wide range of operations on the 
producer side:
-
-*Operations on the service level*
-
-For these operations, `accountName` is *required*.
-[width="100%",cols="10%,90%",options="header",]
-|===
-|Operation |Description
-|`listBlobContainers`  |Get the content of the blob. You can restrict the 
output of this operation to a blob range.
-|`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.
-|`findBlobsByTags` | Returns a list of blobs across the storage account whose 
index tags match the SQL-like filter expression provided via the 
`CamelAzureStorageBlobTagFilter` header or the message body. Optionally honours 
`CamelAzureStorageBlobMaxResultsPerPage` and `CamelAzureStorageBlobTimeout`. 
The result body is a `List<TaggedBlobItem>`.
-|===
-
-*Operations on the container level*
-
-For these operations, `accountName` and `containerName` are *required*.
-[width="100%",cols="10%,90%",options="header",]
-|===
-|Operation |Description
-|`createBlobContainer` | Create a new container within a storage account. If a 
container with the same name already exists, the producer will ignore it.
-|`deleteBlobContainer` | Delete the specified container in the storage 
account. If the container doesn't exist, the operation fails.
-|`listBlobs`| Returns a list of blobs in this container, with folder 
structures flattened.
-|`listBlobVersions`| Returns a list of blobs and their versions in this 
container. Each `BlobItem` in the result carries its own `versionId` and 
`isCurrentVersion` flag, allowing the full version history of every blob to be 
inspected. Requires versioning to be enabled on the storage account. Honours 
the same `prefix`, `regex` and `maxResultsPerPage` filters as `listBlobs`.
-|===
-
-*Operations on the blob level*
-
-For these operations, `accountName`, `containerName` and `blobName` are 
*required*.
-[width="100%",cols="10%,10%,80%",options="header",]
-|===
-|Operation |Blob Type|Description
-|`getBlob`  |Common|Get the content of the blob. You can restrict the output 
of this operation to a blob range.
-|`deleteBlob`  |Common|Delete a blob.
-|`downloadBlobToFile` |Common|Download the entire blob into a file specified 
by the path. The file will be created and must not exist, if the file already 
exists a `FileAlreadyExistsException` will be thrown.
-|`downloadLink`  |Common| Generate the download link for the specified blob 
using shared access signatures (SAS). This by default only limits to 1hour of 
allowed access. However, you can override the default expiration duration 
through the headers.
-|`uploadBlockBlob` |BlockBlob|Creates a new block blob, or updates the content 
of an existing block blob. Updating an existing block blob overwrites any 
existing metadata on the blob. Partial updates are not supported with PutBlob; 
the content of the existing blob is overwritten with the new content. Note: For 
larger files, use `uploadBlockBlobChunked`.
-|`uploadBlockBlobChunked` |BlockBlob|Creates or updates a block blob with 
support for large files (up to several GB). Uses chunked parallel uploads for 
memory efficiency. Accepts File, Path, WrappedFile, or InputStream as body. 
Configure `blockSize` (default: 4MB) and `maxConcurrency` (default: auto) for 
performance tuning. Recommended for files larger than 256MB.
-|`stageBlockBlobList`|`BlockBlob`|Uploads the specified block to the block 
blob's "staging area" to be later committed by a call to commitBlobBlockList. 
However, in case header `CamelAzureStorageBlobCommitBlobBlockListLater` or 
config `commitBlockListLater` is set to false, this will commit the blocks 
immediately after staging the blocks.
-|`commitBlobBlockList`|`BlockBlob`|Write a blob by specifying the list of 
block IDs that are to make up the blob. To be written as part
-of a blob, a block must have been successfully written to the server in a 
prior `stageBlockBlobList` operation. You can
-call `commitBlobBlockList` to update a blob by uploading only those blocks 
that have changed, then committing the new
-and existing blocks together. Any blocks not specified in the block list and 
permanently deleted.
-|`getBlobBlockList`  |`BlockBlob`|Returns the list of blocks that have been 
uploaded as part of a block blob using the specified blocklist filter.
-|`createAppendBlob` |`AppendBlob`|Creates a 0-length append blob. Call 
commitAppendBlo`b operation to append data to an append blob.
-|`commitAppendBlob` |`AppendBlob`|Commits a new block of data to the end of 
the existing append blob. In case of header 
`CamelAzureStorageBlobCreateAppendBlob` or config `createAppendBlob` is set to 
true, it will attempt to create the appendBlob through internal call to 
`createAppendBlob` operation first before committing.
-|`createPageBlob`|`PageBlob`|Creates a page blob of the specified length. Call 
`uploadPageBlob` operation to upload data to a page blob.
-|`uploadPageBlob`|`PageBlob`|Write one or more pages to the page blob. The 
size must be a multiple of 512. In case of header 
`CamelAzureStorageBlobCreatePageBlob` or config `createPageBlob` is set to 
true, it will attempt to create the appendBlob through internal call to 
`createPageBlob` operation first before uploading.
-|`resizePageBlob`|`PageBlob`| Resizes the page blob to the specified size, 
which must be a multiple of 512.
-|`clearPageBlob`|`PageBlob`| Free the specified pages from the page blob. The 
size of the range must be a multiple of 512.
-|`getPageBlobRanges`|`PageBlob`|Returns the list of valid page ranges for a 
page blob or snapshot of a page blob.
-|`copyBlob`|`Common`|Copy a blob from one container to another one, even from 
different accounts.
-|`createBlobSnapshot`|`Common`|Creates a read-only snapshot of a blob. The 
snapshot ID is returned in the `CamelAzureStorageBlobSnapshotId` header.
-|`setBlobTags`|`Common`|Sets user-defined index tags on a blob. Tags are 
key-value pairs that can be used to filter and query blobs across containers. 
Tags can be provided via the `CamelAzureStorageBlobTags` header or as the 
message body (`Map<String, String>`).
-|`getBlobTags`|`Common`|Retrieves user-defined index tags from a blob. The 
tags are returned as the message body (`Map<String, String>`) and also set in 
the `CamelAzureStorageBlobTags` header.
-|`setBlobLegalHold`|`Common`|Sets a legal hold on a blob. The legal hold flag 
(`Boolean`) is provided via the `CamelAzureStorageBlobLegalHold` header or the 
message body. While a legal hold is set, the blob cannot be modified or deleted 
until the hold is explicitly cleared by calling the operation again with 
`false`.
-|`setBlobImmutabilityPolicy`|`Common`|Sets a time-based immutability policy on 
a blob. The policy expiry time (`OffsetDateTime`) is read from the 
`CamelAzureStorageBlobImmutabilityPolicyExpiryTime` header and the policy mode 
(`BlobImmutabilityPolicyMode`, defaults to `UNLOCKED`) from 
`CamelAzureStorageBlobImmutabilityPolicyMode`. A pre-built 
`BlobImmutabilityPolicy` may also be supplied via the message body or 
`CamelAzureStorageBlobImmutabilityPolicy` header.
-|`undeleteBlob`|`Common`|Restores the contents and metadata of a soft-deleted 
blob and any associated soft-deleted snapshots. Soft delete must be enabled on 
the storage account for this operation to succeed.
-|`setBlobTier`|`Common`|Sets the access tier of an existing blob. The target 
tier (`AccessTier` such as `HOT`, `COOL`, `COLD`, or `ARCHIVE`) is read from 
the `CamelAzureStorageBlobAccessTier` header or the message body. When 
rehydrating a blob from `ARCHIVE`, the optional 
`CamelAzureStorageBlobRehydratePriority` header (`RehydratePriority`, 
`STANDARD` or `HIGH`) controls the rehydration priority.
-|===
-
-Refer to the example section in this page to learn how to use these operations 
into your camel application.
-
-== Examples
-
-=== Consumer Examples
-
-To consume a blob into a file using the file component, this can be done like 
this:
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey")
-    .to("file://blobdirectory");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;accountName=yourAccountName&amp;accessKey=yourAccessKey"/>
-    <to uri="file://blobdirectory"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/container1
-      parameters:
-        blobName: hello.txt
-        accountName: yourAccountName
-        accessKey: yourAccessKey
-    steps:
-      - to:
-          uri: file://blobdirectory
-----
-====
-
-However, you can also write to file directly without using the file component, 
you will need to specify `fileDir` folder path to save your blob in your 
machine.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir")
-    .to("mock:results");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from 
uri="azure-storage-blob://camelazure/container1?blobName=hello.txt&amp;accountName=yourAccountName&amp;accessKey=yourAccessKey&amp;fileDir=/var/to/awesome/dir"/>
-    <to uri="mock:results"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/container1
-      parameters:
-        blobName: hello.txt
-        accountName: yourAccountName
-        accessKey: yourAccessKey
-        fileDir: /var/to/awesome/dir
-    steps:
-      - to:
-          uri: mock:results
-----
-====
-
-Also, the component supports batch consumer, hence you can consume multiple 
blobs with only specifying the container name, the consumer will
-return multiple exchanges depending on the number of the blobs in the 
container. Example:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/container1?accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir")
-    .to("mock:results");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-    <from 
uri="azure-storage-blob://camelazure/container1?accountName=yourAccountName&amp;accessKey=yourAccessKey&amp;fileDir=/var/to/awesome/dir"/>
-    <to uri="mock:results"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/container1
-      parameters:
-        accountName: yourAccountName
-        accessKey: yourAccessKey
-        fileDir: /var/to/awesome/dir
-    steps:
-      - to:
-          uri: mock:results
-----
-====
-
-==== Delete After Read
-
-The consumer supports automatic deletion of blobs after they have been 
successfully processed. This is useful when you want to ensure that blobs are 
only processed once.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/container1?deleteAfterRead=true&accessKey=RAW(yourAccessKey)")
-    .log("Processing blob: ${header.CamelAzureStorageBlobBlobName}")
-    .to("direct:processBlob");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from 
uri="azure-storage-blob://camelazure/container1?deleteAfterRead=true&amp;accessKey=RAW(yourAccessKey)"/>
-  <log message="Processing blob: ${header.CamelAzureStorageBlobBlobName}"/>
-  <to uri="direct:processBlob"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/container1
-      parameters:
-        deleteAfterRead: true
-        accessKey: "RAW(yourAccessKey)"
-      steps:
-        - log:
-            message: "Processing blob: ${header.CamelAzureStorageBlobBlobName}"
-        - to:
-            uri: direct:processBlob
-----
-====
-
-IMPORTANT: The delete operation is only performed if the Exchange is 
successfully committed. If processing fails or a rollback occurs, the blob will 
not be deleted and can be reprocessed on the next poll.
-
-NOTE: When `deleteAfterRead` is set to `false` (the default), the same blobs 
will be retrieved repeatedly in subsequent polls. In this case, you should use 
the Idempotent Consumer EIP to filter out duplicates based on the 
`CamelAzureStorageBlobBlobName` header.
-
-==== Move After Read
-
-The consumer can move blobs to a different container after successful 
processing. This is useful for archiving processed blobs or implementing a 
processing pipeline across containers.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/incoming?moveAfterRead=true&destinationContainer=archive&accessKey=RAW(yourAccessKey)")
-    .log("Processing blob: ${header.CamelAzureStorageBlobBlobName}")
-    .to("direct:processBlob");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from 
uri="azure-storage-blob://camelazure/incoming?moveAfterRead=true&amp;destinationContainer=archive&amp;accessKey=RAW(yourAccessKey)"/>
-  <log message="Processing blob: ${header.CamelAzureStorageBlobBlobName}"/>
-  <to uri="direct:processBlob"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/incoming
-      parameters:
-        moveAfterRead: true
-        destinationContainer: archive
-        accessKey: "RAW(yourAccessKey)"
-      steps:
-        - log:
-            message: "Processing blob: ${header.CamelAzureStorageBlobBlobName}"
-        - to:
-            uri: direct:processBlob
-----
-====
-
-You can also customize the destination blob name by adding a prefix and/or 
suffix:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("azure-storage-blob://camelazure/source?moveAfterRead=true&destinationContainer=archive&prefix=incoming/&removePrefixOnMove=true&destinationBlobPrefix=processed/&destinationBlobSuffix=.done&accessKey=RAW(yourAccessKey)")
-    .log("Processing: ${header.CamelAzureStorageBlobBlobName}")
-    .to("direct:processBlob");
-----
-
-XML::
-+
-[source,xml]
-----
-<route>
-  <from 
uri="azure-storage-blob://camelazure/source?moveAfterRead=true&amp;destinationContainer=archive&amp;prefix=incoming/&amp;removePrefixOnMove=true&amp;destinationBlobPrefix=processed/&amp;destinationBlobSuffix=.done&amp;accessKey=RAW(yourAccessKey)"/>
-  <log message="Processing: ${header.CamelAzureStorageBlobBlobName}"/>
-  <to uri="direct:processBlob"/>
-</route>
-----
-
-YAML::
-+
-[source,yaml]
-----
-- route:
-    from:
-      uri: azure-storage-blob://camelazure/source
-      parameters:
-        moveAfterRead: true
-        destinationContainer: archive
-        prefix: "incoming/"
-        removePrefixOnMove: true
-        destinationBlobPrefix: "processed/"
-        destinationBlobSuffix: ".done"
-        accessKey: "RAW(yourAccessKey)"
-      steps:
-        - log:
-            message: "Processing: ${header.CamelAzureStorageBlobBlobName}"
-        - to:
-            uri: direct:processBlob
-----
-====
-
-The move operation works as follows:
-
-1. The blob is copied to the destination container with the new name
-2. The original blob is deleted from the source container
-3. Both operations only occur after the Exchange is successfully committed
-
-The following options control the move behavior:
-
-[width="100%",cols="25%,75%",options="header",]
-|===
-|Option |Description
-|`moveAfterRead` |Enable moving blobs after successful processing
-|`destinationContainer` |Target container for moved blobs (required when 
`moveAfterRead=true`)
-|`destinationBlobPrefix` |Prefix to add to the blob name in the destination
-|`destinationBlobSuffix` |Suffix to add to the blob name in the destination
-|`removePrefixOnMove` |Remove the source prefix from the blob name before 
adding destination prefix
-|===
-
-=== Producer Operations Examples
+== Producer Operations Examples
 - `listBlobContainers`:
 
 NOTE: The `CamelAzureStorageBlobListBlobContainersOptions` header requires a 
`ListBlobContainersOptions` object, which must be set from a bean or processor.
@@ -1468,7 +952,7 @@ YAML::
 ----
 ====
 
-=== Reading a specific blob snapshot
+== Reading a specific blob snapshot
 
 The `getBlob`, `downloadBlobToFile` and `downloadLink` operations can target a 
specific snapshot by setting the
 `snapshotId` URI parameter or the `CamelAzureStorageBlobSnapshotId` exchange 
header. When set, the read is scoped
@@ -1522,7 +1006,7 @@ YAML::
 ----
 ====
 
-=== Reading a specific blob version
+== Reading a specific blob version
 
 When blob versioning is enabled on the storage account, the `getBlob`, 
`downloadBlobToFile` and `downloadLink`
 operations can target a specific version by setting the `versionId` URI 
parameter or the
@@ -1849,7 +1333,7 @@ from("direct:rehydrate")
     .to("mock:result");
 ----
 
-=== Blob modification during download (ConditionNotMet)
+== Blob modification during download (ConditionNotMet)
 
 When downloading a blob via streaming (the `getBlob` operation or the consumer 
without `fileDir`), the Azure SDK reads the blob in chunks.
 On the first chunk it captures the blob's ETag and uses it as an `if-match` 
condition on subsequent chunk requests.
@@ -1865,7 +1349,7 @@ Workarounds:
 * Use blob versioning — read from a specific version via the `versionId` 
option or the `CamelAzureStorageBlobVersionId` header.
 * Avoid modifying blobs while they are being consumed.
 
-=== SAS Token generation example
+== SAS Token generation example
 
 SAS Blob Container tokens can be generated programmatically or via Azure UI. 
To generate the token with Java code, the following can be done:
 
@@ -1936,20 +1420,3 @@ YAML::
               credentialType: AZURE_SAS
 ----
 ====
-
-== Important Development Notes
-
-All integration tests use https://www.testcontainers.org/[Testcontainers] and 
run by default.
-Obtaining of Azure accessKey and accountName is needed to be able to run all 
integration tests using Azure services.
-In addition to the mocked unit tests, you *will need to run the integration 
tests
-with every change you make or even client upgrade as the Azure client can 
break things even on minor versions upgrade.*
-To run the integration tests, on this component directory, run the following 
maven command:
-
-[source,bash]
-----
-mvn verify -DaccountName=myacc -DaccessKey=mykey 
-DcredentialType=SHARED_ACCOUNT_KEY
-----
-
-Whereby `accountName` is your Azure account name and `accessKey` is the access 
key being generated from Azure portal.
-
-
diff --git a/docs/components/modules/others/nav.adoc 
b/docs/components/modules/others/nav.adoc
index e8ea5aefaa88..d9f6b5052929 100644
--- a/docs/components/modules/others/nav.adoc
+++ b/docs/components/modules/others/nav.adoc
@@ -4,6 +4,8 @@
 * xref:others:index.adoc[Miscellaneous Components]
 ** xref:attachments.adoc[Attachments]
 *** xref:azure-schema-registry.adoc[Azure Schema Registry]
+** xref:azure-storage-blob-consumer.adoc[Azure Storage Blob - Consumer 
Examples]
+** xref:azure-storage-blob-operations.adoc[Azure Storage Blob - Producer 
Operations]
 ** xref:camel-yaml-dsl-validator-maven-plugin.adoc[Camel YAML DSL Validator 
Maven Plugin]
 ** xref:cli-connector.adoc[CLI Connector]
 ** xref:cli-debug.adoc[CLI Debug]
diff --git 
a/docs/components/modules/others/pages/azure-storage-blob-consumer.adoc 
b/docs/components/modules/others/pages/azure-storage-blob-consumer.adoc
new file mode 120000
index 000000000000..6f430bda17db
--- /dev/null
+++ b/docs/components/modules/others/pages/azure-storage-blob-consumer.adoc
@@ -0,0 +1 @@
+../../../../../components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-consumer.adoc
\ No newline at end of file
diff --git 
a/docs/components/modules/others/pages/azure-storage-blob-operations.adoc 
b/docs/components/modules/others/pages/azure-storage-blob-operations.adoc
new file mode 120000
index 000000000000..b8c2b8eddd08
--- /dev/null
+++ b/docs/components/modules/others/pages/azure-storage-blob-operations.adoc
@@ -0,0 +1 @@
+../../../../../components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-operations.adoc
\ No newline at end of file

Reply via email to