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

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


The following commit(s) were added to refs/heads/main by this push:
     new 291784c71a0d CAMEL-23339: camel-azure-storage-blob - Add support for 
immutability policy and legal hold operations (#22826)
291784c71a0d is described below

commit 291784c71a0d76b3bcb0d1035bb23fde41103aa4
Author: Andrea Cosentino <[email protected]>
AuthorDate: Wed Apr 29 13:50:07 2026 +0200

    CAMEL-23339: camel-azure-storage-blob - Add support for immutability policy 
and legal hold operations (#22826)
    
    Expose Azure Blob Storage immutability policies and legal holds through
    two new producer operations on the camel-azure-storage-blob component.
    Both features are required for compliance and quarantine workflows
    where blobs must remain unmodified during processing.
    
    - BlobOperationsDefinition: new setBlobLegalHold and 
setBlobImmutabilityPolicy
    - BlobConstants: new BLOB_LEGAL_HOLD, BLOB_IMMUTABILITY_POLICY,
      BLOB_IMMUTABILITY_POLICY_EXPIRY_TIME and BLOB_IMMUTABILITY_POLICY_MODE
      headers
    - BlobExchangeHeaders: readers and writers for the new headers
    - BlobConfigurationOptionsProxy: resolves the new options from headers
    - BlobClientWrapper: setLegalHold and setImmutabilityPolicy delegating
      to BlobClientBase.setLegalHoldWithResponse / 
setImmutabilityPolicyWithResponse
    - BlobOperations: setBlobLegalHold reads the flag from the dedicated
      header or message body; setBlobImmutabilityPolicy accepts a pre-built
      BlobImmutabilityPolicy via body/header or builds one from the expiry
      time / mode headers (defaulting to UNLOCKED)
    - BlobProducer: dispatches the two new operations
    - Unit tests covering header- and body-driven inputs, mode defaulting
      and missing-input validation
    - Documentation update with operation table entries and usage examples
    
    Signed-off-by: Andrea Cosentino <[email protected]>
    Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
---
 .../catalog/components/azure-storage-blob.json     |   8 +-
 .../azure/storage/blob/azure-storage-blob.json     |   8 +-
 .../main/docs/azure-storage-blob-component.adoc    |  33 +++++
 .../blob/BlobConfigurationOptionsProxy.java        |  18 +++
 .../azure/storage/blob/BlobConstants.java          |  21 ++++
 .../azure/storage/blob/BlobExchangeHeaders.java    |  33 +++++
 .../storage/blob/BlobOperationsDefinition.java     |  16 ++-
 .../component/azure/storage/blob/BlobProducer.java |   6 +
 .../storage/blob/client/BlobClientWrapper.java     |  15 +++
 .../storage/blob/operations/BlobOperations.java    |  82 +++++++++++++
 .../blob/operations/BlobOperationsTest.java        | 133 +++++++++++++++++++++
 .../endpoint/dsl/BlobEndpointBuilderFactory.java   |  63 ++++++++++
 12 files changed, 431 insertions(+), 5 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
index 34546924c3df..f9decbae71fa 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/azure-storage-blob.json
@@ -77,7 +77,7 @@
     "sourceBlobAccessKey": { "index": 50, "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, "security": "secret", "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Source Blob Access Key: 
for copyblob operation, sadly,  [...]
   },
   "headers": {
-    "CamelAzureStorageBlobOperation": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": 
"org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition", 
"enum": [ "listBlobContainers", "findBlobsByTags", "createBlobContainer", 
"deleteBlobContainer", "listBlobs", "getBlob", "deleteBlob", 
"downloadBlobToFile", "downloadLink", "uploadBlockBlob", 
"uploadBlockBlobChunked", "stageBlockBlobList", "commitBlobBlock [...]
+    "CamelAzureStorageBlobOperation": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": 
"org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition", 
"enum": [ "listBlobContainers", "findBlobsByTags", "createBlobContainer", 
"deleteBlobContainer", "listBlobs", "getBlob", "deleteBlob", 
"downloadBlobToFile", "downloadLink", "uploadBlockBlob", 
"uploadBlockBlobChunked", "stageBlockBlobList", "commitBlobBlock [...]
     "CamelAzureStorageBlobHttpHeaders": { "index": 1, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "BlobHttpHeaders", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "(uploadBlockBlob, 
commitBlobBlockList, createAppendBlob, createPageBlob) Additional parameters 
for a set of operations.", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#BLOB_HTTP_HEA [...]
     "CamelAzureStorageBlobETag": { "index": 2, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The E Tag of the blob", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#E_TAG" },
     "CamelAzureStorageBlobCreationTime": { "index": 3, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "OffsetDateTime", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Creation time of the 
blob.", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#CREATION_TIME" },
@@ -150,7 +150,11 @@
     "CamelAzureStorageBlobVersionId": { "index": 70, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The blob version identifier. On read 
operations (getBlob, downloadBlobToFile, downloadLink) it can be provided as 
input to target a specific blob version when versioning is enabled on the 
storage account. On the consumer side it is  [...]
     "CamelAzureStorageBlobIsCurrentVersion": { "index": 71, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Flag indicating whether this is the 
current version of the blob.", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#BLOB_IS_CURRENT_VERSION"
 },
     "CamelAzureStorageBlobTags": { "index": 72, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Map<String,String>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "(producer) (setBlobTags) 
The tags to set on the blob as key-value pairs. (consumer) The tags retrieved 
from the blob.", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#BLOB_TAGS" },
-    "CamelAzureStorageBlobTagFilter": { "index": 73, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "(findBlobsByTags) A SQL-like expression 
that filters blobs across the storage account based on their index tags, for 
example Environment = 'Production' AND Status = 'Active'.", "constantName": 
"org.apache.camel.component.a [...]
+    "CamelAzureStorageBlobTagFilter": { "index": 73, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "(findBlobsByTags) A SQL-like expression 
that filters blobs across the storage account based on their index tags, for 
example Environment = 'Production' AND Status = 'Active'.", "constantName": 
"org.apache.camel.component.a [...]
+    "CamelAzureStorageBlobLegalHold": { "index": 74, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "(producer) (setBlobLegalHold) The legal 
hold status to set on the blob. When set to true the blob is protected from 
modification and deletion until the hold is cleared by setting the value to 
false. (consumer) The legal hold status [...]
+    "CamelAzureStorageBlobImmutabilityPolicy": { "index": 75, "kind": 
"header", "displayName": "", "group": "producer", "label": "producer", 
"required": false, "javaType": 
"com.azure.storage.blob.models.BlobImmutabilityPolicy", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"(setBlobImmutabilityPolicy) A pre-built BlobImmutabilityPolicy object that 
overrides the policy expiry time and mode headers when present.", 
"constantName": "org.apach [...]
+    "CamelAzureStorageBlobImmutabilityPolicyExpiryTime": { "index": 76, 
"kind": "header", "displayName": "", "group": "producer", "label": "producer", 
"required": false, "javaType": "java.time.OffsetDateTime", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"(setBlobImmutabilityPolicy) The expiry time of the time-based retention 
policy. Required unless a pre-built BlobImmutabilityPolicy is provided via the 
body or the CamelAzureStorageBlobI [...]
+    "CamelAzureStorageBlobImmutabilityPolicyMode": { "index": 77, "kind": 
"header", "displayName": "", "group": "producer", "label": "producer", 
"required": false, "javaType": 
"com.azure.storage.blob.models.BlobImmutabilityPolicyMode", "enum": [ 
"Mutable", "Unlocked", "Locked" ], "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": 
"(setBlobImmutabilityPolicy) The mode of the immutability policy: UNLOCKED 
(default, can be modified or deleted), L [...]
   },
   "properties": {
     "accountName": { "index": 0, "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" },
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
 
b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
index 34546924c3df..f9decbae71fa 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
@@ -77,7 +77,7 @@
     "sourceBlobAccessKey": { "index": 50, "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, "security": "secret", "configurationClass": 
"org.apache.camel.component.azure.storage.blob.BlobConfiguration", 
"configurationField": "configuration", "description": "Source Blob Access Key: 
for copyblob operation, sadly,  [...]
   },
   "headers": {
-    "CamelAzureStorageBlobOperation": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": 
"org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition", 
"enum": [ "listBlobContainers", "findBlobsByTags", "createBlobContainer", 
"deleteBlobContainer", "listBlobs", "getBlob", "deleteBlob", 
"downloadBlobToFile", "downloadLink", "uploadBlockBlob", 
"uploadBlockBlobChunked", "stageBlockBlobList", "commitBlobBlock [...]
+    "CamelAzureStorageBlobOperation": { "index": 0, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": 
"org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition", 
"enum": [ "listBlobContainers", "findBlobsByTags", "createBlobContainer", 
"deleteBlobContainer", "listBlobs", "getBlob", "deleteBlob", 
"downloadBlobToFile", "downloadLink", "uploadBlockBlob", 
"uploadBlockBlobChunked", "stageBlockBlobList", "commitBlobBlock [...]
     "CamelAzureStorageBlobHttpHeaders": { "index": 1, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "BlobHttpHeaders", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "(uploadBlockBlob, 
commitBlobBlockList, createAppendBlob, createPageBlob) Additional parameters 
for a set of operations.", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#BLOB_HTTP_HEA [...]
     "CamelAzureStorageBlobETag": { "index": 2, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The E Tag of the blob", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#E_TAG" },
     "CamelAzureStorageBlobCreationTime": { "index": 3, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "OffsetDateTime", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Creation time of the 
blob.", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#CREATION_TIME" },
@@ -150,7 +150,11 @@
     "CamelAzureStorageBlobVersionId": { "index": 70, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The blob version identifier. On read 
operations (getBlob, downloadBlobToFile, downloadLink) it can be provided as 
input to target a specific blob version when versioning is enabled on the 
storage account. On the consumer side it is  [...]
     "CamelAzureStorageBlobIsCurrentVersion": { "index": 71, "kind": "header", 
"displayName": "", "group": "consumer", "label": "consumer", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "Flag indicating whether this is the 
current version of the blob.", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#BLOB_IS_CURRENT_VERSION"
 },
     "CamelAzureStorageBlobTags": { "index": 72, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Map<String,String>", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "(producer) (setBlobTags) 
The tags to set on the blob as key-value pairs. (consumer) The tags retrieved 
from the blob.", "constantName": 
"org.apache.camel.component.azure.storage.blob.BlobConstants#BLOB_TAGS" },
-    "CamelAzureStorageBlobTagFilter": { "index": 73, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "(findBlobsByTags) A SQL-like expression 
that filters blobs across the storage account based on their index tags, for 
example Environment = 'Production' AND Status = 'Active'.", "constantName": 
"org.apache.camel.component.a [...]
+    "CamelAzureStorageBlobTagFilter": { "index": 73, "kind": "header", 
"displayName": "", "group": "producer", "label": "producer", "required": false, 
"javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "(findBlobsByTags) A SQL-like expression 
that filters blobs across the storage account based on their index tags, for 
example Environment = 'Production' AND Status = 'Active'.", "constantName": 
"org.apache.camel.component.a [...]
+    "CamelAzureStorageBlobLegalHold": { "index": 74, "kind": "header", 
"displayName": "", "group": "common", "label": "", "required": false, 
"javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "(producer) (setBlobLegalHold) The legal 
hold status to set on the blob. When set to true the blob is protected from 
modification and deletion until the hold is cleared by setting the value to 
false. (consumer) The legal hold status [...]
+    "CamelAzureStorageBlobImmutabilityPolicy": { "index": 75, "kind": 
"header", "displayName": "", "group": "producer", "label": "producer", 
"required": false, "javaType": 
"com.azure.storage.blob.models.BlobImmutabilityPolicy", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"(setBlobImmutabilityPolicy) A pre-built BlobImmutabilityPolicy object that 
overrides the policy expiry time and mode headers when present.", 
"constantName": "org.apach [...]
+    "CamelAzureStorageBlobImmutabilityPolicyExpiryTime": { "index": 76, 
"kind": "header", "displayName": "", "group": "producer", "label": "producer", 
"required": false, "javaType": "java.time.OffsetDateTime", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"(setBlobImmutabilityPolicy) The expiry time of the time-based retention 
policy. Required unless a pre-built BlobImmutabilityPolicy is provided via the 
body or the CamelAzureStorageBlobI [...]
+    "CamelAzureStorageBlobImmutabilityPolicyMode": { "index": 77, "kind": 
"header", "displayName": "", "group": "producer", "label": "producer", 
"required": false, "javaType": 
"com.azure.storage.blob.models.BlobImmutabilityPolicyMode", "enum": [ 
"Mutable", "Unlocked", "Locked" ], "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": 
"(setBlobImmutabilityPolicy) The mode of the immutability policy: UNLOCKED 
(default, can be modified or deleted), L [...]
   },
   "properties": {
     "accountName": { "index": 0, "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" },
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 ca2693ab6950..452b6f1d14b5 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
@@ -168,6 +168,8 @@ and existing blocks together. Any blocks not specified in 
the block list and per
 |`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.
 |===
 
 Refer to the example section in this page to learn how to use these operations 
into your camel application.
@@ -793,6 +795,37 @@ from("direct:findBlobsByTags")
   .to("mock:result");
 
--------------------------------------------------------------------------------
 
+- `setBlobLegalHold`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+// place a legal hold on the blob (e.g. for compliance / quarantine workflows)
+from("direct:setLegalHold")
+  .setHeader(BlobConstants.BLOB_LEGAL_HOLD, constant(true))
+  
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=setBlobLegalHold&serviceClient=#client")
+  .to("mock:result");
+
+// clear the legal hold once the workflow is complete
+from("direct:clearLegalHold")
+  .setHeader(BlobConstants.BLOB_LEGAL_HOLD, constant(false))
+  
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=setBlobLegalHold&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `setBlobImmutabilityPolicy`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+// apply a 7-day unlocked time-based retention policy (can be modified or 
deleted)
+from("direct:setImmutabilityPolicy")
+  .setHeader(BlobConstants.BLOB_IMMUTABILITY_POLICY_EXPIRY_TIME, 
constant(OffsetDateTime.now().plusDays(7)))
+  .setHeader(BlobConstants.BLOB_IMMUTABILITY_POLICY_MODE, 
constant(BlobImmutabilityPolicyMode.UNLOCKED))
+  
.to("azure-storage-blob://camelazure/container1?blobName=hello.txt&operation=setBlobImmutabilityPolicy&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
 === 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:
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxy.java
 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxy.java
index 427d2715a3ed..b13829fe0b25 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxy.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxy.java
@@ -25,6 +25,8 @@ import java.util.function.Supplier;
 import com.azure.core.util.Context;
 import com.azure.storage.blob.models.AccessTier;
 import com.azure.storage.blob.models.BlobHttpHeaders;
+import com.azure.storage.blob.models.BlobImmutabilityPolicy;
+import com.azure.storage.blob.models.BlobImmutabilityPolicyMode;
 import com.azure.storage.blob.models.BlobListDetails;
 import com.azure.storage.blob.models.BlobRange;
 import com.azure.storage.blob.models.BlobRequestConditions;
@@ -287,6 +289,22 @@ public class BlobConfigurationOptionsProxy {
         return BlobExchangeHeaders.getBlobTagFilterFromHeaders(exchange);
     }
 
+    public Boolean getBlobLegalHold(final Exchange exchange) {
+        return BlobExchangeHeaders.getBlobLegalHoldFromHeaders(exchange);
+    }
+
+    public BlobImmutabilityPolicy getBlobImmutabilityPolicy(final Exchange 
exchange) {
+        return 
BlobExchangeHeaders.getBlobImmutabilityPolicyFromHeaders(exchange);
+    }
+
+    public OffsetDateTime getBlobImmutabilityPolicyExpiryTime(final Exchange 
exchange) {
+        return 
BlobExchangeHeaders.getBlobImmutabilityPolicyExpiryTimeFromHeaders(exchange);
+    }
+
+    public BlobImmutabilityPolicyMode getBlobImmutabilityPolicyMode(final 
Exchange exchange) {
+        return 
BlobExchangeHeaders.getBlobImmutabilityPolicyModeFromHeaders(exchange);
+    }
+
     public BlobConfiguration getConfiguration() {
         return configuration;
     }
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 70889bdbc083..47fe9e15f0fe 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
@@ -306,6 +306,27 @@ public final class BlobConstants {
                             + " index tags, for example `\"Environment\" = 
'Production' AND \"Status\" = 'Active'`.",
               javaType = "String")
     public static final String BLOB_TAG_FILTER = HEADER_PREFIX + "TagFilter";
+    @Metadata(description = "(producer) (setBlobLegalHold) The legal hold 
status to set on the blob. When set to true the blob is"
+                            + " protected from modification and deletion until 
the hold is cleared by setting the value to false.\n"
+                            + "(consumer) The legal hold status returned by 
the setBlobLegalHold operation.",
+              javaType = "Boolean")
+    public static final String BLOB_LEGAL_HOLD = HEADER_PREFIX + "LegalHold";
+    @Metadata(label = "producer",
+              description = "(setBlobImmutabilityPolicy) A pre-built 
`BlobImmutabilityPolicy` object that overrides the policy"
+                            + " expiry time and mode headers when present.",
+              javaType = 
"com.azure.storage.blob.models.BlobImmutabilityPolicy")
+    public static final String BLOB_IMMUTABILITY_POLICY = HEADER_PREFIX + 
"ImmutabilityPolicy";
+    @Metadata(label = "producer",
+              description = "(setBlobImmutabilityPolicy) The expiry time of 
the time-based retention policy. Required unless a"
+                            + " pre-built `BlobImmutabilityPolicy` is provided 
via the body or the"
+                            + " `CamelAzureStorageBlobImmutabilityPolicy` 
header.",
+              javaType = "java.time.OffsetDateTime")
+    public static final String BLOB_IMMUTABILITY_POLICY_EXPIRY_TIME = 
HEADER_PREFIX + "ImmutabilityPolicyExpiryTime";
+    @Metadata(label = "producer",
+              description = "(setBlobImmutabilityPolicy) The mode of the 
immutability policy: `UNLOCKED` (default, can be"
+                            + " modified or deleted), `LOCKED` (cannot be 
modified or shortened, only extended), or `MUTABLE`.",
+              javaType = 
"com.azure.storage.blob.models.BlobImmutabilityPolicyMode")
+    public static final String BLOB_IMMUTABILITY_POLICY_MODE = HEADER_PREFIX + 
"ImmutabilityPolicyMode";
 
     private BlobConstants() {
     }
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobExchangeHeaders.java
 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobExchangeHeaders.java
index d851ac8011b2..c1b0abc838eb 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobExchangeHeaders.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobExchangeHeaders.java
@@ -28,6 +28,8 @@ import com.azure.storage.blob.models.AppendBlobItem;
 import com.azure.storage.blob.models.ArchiveStatus;
 import com.azure.storage.blob.models.BlobDownloadHeaders;
 import com.azure.storage.blob.models.BlobHttpHeaders;
+import com.azure.storage.blob.models.BlobImmutabilityPolicy;
+import com.azure.storage.blob.models.BlobImmutabilityPolicyMode;
 import com.azure.storage.blob.models.BlobListDetails;
 import com.azure.storage.blob.models.BlobProperties;
 import com.azure.storage.blob.models.BlobRequestConditions;
@@ -511,8 +513,39 @@ public class BlobExchangeHeaders {
         return getObjectFromHeaders(exchange, BlobConstants.BLOB_TAG_FILTER, 
String.class);
     }
 
+    public static Boolean getBlobLegalHoldFromHeaders(final Exchange exchange) 
{
+        return getObjectFromHeaders(exchange, BlobConstants.BLOB_LEGAL_HOLD, 
Boolean.class);
+    }
+
+    public static BlobImmutabilityPolicy 
getBlobImmutabilityPolicyFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, 
BlobConstants.BLOB_IMMUTABILITY_POLICY, BlobImmutabilityPolicy.class);
+    }
+
+    public static OffsetDateTime 
getBlobImmutabilityPolicyExpiryTimeFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, 
BlobConstants.BLOB_IMMUTABILITY_POLICY_EXPIRY_TIME, OffsetDateTime.class);
+    }
+
+    public static BlobImmutabilityPolicyMode 
getBlobImmutabilityPolicyModeFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, 
BlobConstants.BLOB_IMMUTABILITY_POLICY_MODE, BlobImmutabilityPolicyMode.class);
+    }
+
     public BlobExchangeHeaders blobTags(final Map<String, String> tags) {
         headers.put(BlobConstants.BLOB_TAGS, tags);
         return this;
     }
+
+    public BlobExchangeHeaders blobLegalHold(final Boolean legalHold) {
+        headers.put(BlobConstants.BLOB_LEGAL_HOLD, legalHold);
+        return this;
+    }
+
+    public BlobExchangeHeaders blobImmutabilityPolicyExpiryTime(final 
OffsetDateTime expiryTime) {
+        headers.put(BlobConstants.BLOB_IMMUTABILITY_POLICY_EXPIRY_TIME, 
expiryTime);
+        return this;
+    }
+
+    public BlobExchangeHeaders blobImmutabilityPolicyMode(final 
BlobImmutabilityPolicyMode policyMode) {
+        headers.put(BlobConstants.BLOB_IMMUTABILITY_POLICY_MODE, policyMode);
+        return this;
+    }
 }
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 c7a3e79ef356..60e953936d5b 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
@@ -155,5 +155,19 @@ public enum BlobOperationsDefinition {
     /**
      * Retrieves user-defined index tags from a blob.
      */
-    getBlobTags
+    getBlobTags,
+    /**
+     * Sets a legal hold on a blob. Legal holds prevent blob modification and 
deletion until the hold is explicitly
+     * cleared. The legal hold flag is read from the {@code 
CamelAzureStorageBlobLegalHold} header or the message body
+     * (Boolean).
+     */
+    setBlobLegalHold,
+    /**
+     * Sets a time-based immutability policy on a blob. The policy expiry time 
is read from the
+     * {@code CamelAzureStorageBlobImmutabilityPolicyExpiryTime} header 
(OffsetDateTime) and the policy mode from the
+     * {@code CamelAzureStorageBlobImmutabilityPolicyMode} header 
(BlobImmutabilityPolicyMode, defaults to UNLOCKED). A
+     * pre-built {@code BlobImmutabilityPolicy} can also be passed via the 
message body or the
+     * {@code CamelAzureStorageBlobImmutabilityPolicy} header.
+     */
+    setBlobImmutabilityPolicy
 }
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 0514f5f22ca0..26f6fd65a6a0 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
@@ -141,6 +141,12 @@ public class BlobProducer extends DefaultProducer {
             case getBlobTags:
                 setResponse(exchange, 
getBlobOperations(exchange).getBlobTags(exchange));
                 break;
+            case setBlobLegalHold:
+                setResponse(exchange, 
getBlobOperations(exchange).setBlobLegalHold(exchange));
+                break;
+            case setBlobImmutabilityPolicy:
+                setResponse(exchange, 
getBlobOperations(exchange).setBlobImmutabilityPolicy(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 cd33adf3a391..94d6541fb636 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
@@ -40,6 +40,8 @@ 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.BlobImmutabilityPolicy;
+import com.azure.storage.blob.models.BlobLegalHoldResult;
 import com.azure.storage.blob.models.BlobProperties;
 import com.azure.storage.blob.models.BlobRange;
 import com.azure.storage.blob.models.BlobRequestConditions;
@@ -382,6 +384,19 @@ public class BlobClientWrapper {
         return client.getTagsWithResponse(options, timeout, Context.NONE);
     }
 
+    public Response<BlobLegalHoldResult> setLegalHold(
+            final boolean legalHold,
+            final Duration timeout) {
+        return client.setLegalHoldWithResponse(legalHold, timeout, 
Context.NONE);
+    }
+
+    public Response<BlobImmutabilityPolicy> setImmutabilityPolicy(
+            final BlobImmutabilityPolicy policy,
+            final BlobRequestConditions requestConditions,
+            final Duration timeout) {
+        return client.setImmutabilityPolicyWithResponse(policy, 
requestConditions, timeout, Context.NONE);
+    }
+
     public BlobLeaseClient getLeaseClient() {
         return new BlobLeaseClientBuilder().blobClient(client).buildClient();
     }
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 005045f6176c..eb8367774843 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
@@ -35,6 +35,9 @@ import com.azure.storage.blob.models.AccessTier;
 import com.azure.storage.blob.models.AppendBlobItem;
 import com.azure.storage.blob.models.BlobDownloadHeaders;
 import com.azure.storage.blob.models.BlobHttpHeaders;
+import com.azure.storage.blob.models.BlobImmutabilityPolicy;
+import com.azure.storage.blob.models.BlobImmutabilityPolicyMode;
+import com.azure.storage.blob.models.BlobLegalHoldResult;
 import com.azure.storage.blob.models.BlobProperties;
 import com.azure.storage.blob.models.BlobRange;
 import com.azure.storage.blob.models.BlobRequestConditions;
@@ -661,6 +664,85 @@ public class BlobOperations {
         return BlobOperationResponse.create(tags, exchangeHeaders.toMap());
     }
 
+    public BlobOperationResponse setBlobLegalHold(final Exchange exchange) {
+        ObjectHelper.notNull(exchange, MISSING_EXCHANGE);
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Setting legal hold on blob [{}] from exchange [{}]...", 
configurationProxy.getBlobName(exchange),
+                    exchange);
+        }
+
+        Boolean legalHold = configurationProxy.getBlobLegalHold(exchange);
+        if (legalHold == null) {
+            legalHold = exchange.getIn().getBody(Boolean.class);
+        }
+        if (legalHold == null) {
+            throw new IllegalArgumentException(
+                    "Legal hold flag must be specified either as the message 
body (Boolean) or via the "
+                                               + BlobConstants.BLOB_LEGAL_HOLD 
+ " header.");
+        }
+
+        final BlobCommonRequestOptions commonRequestOptions = 
getCommonRequestOptions(exchange);
+
+        final Response<BlobLegalHoldResult> response = 
client.setLegalHold(legalHold, commonRequestOptions.getTimeout());
+
+        final boolean hasLegalHold = response.getValue() != null && 
response.getValue().hasLegalHold();
+        final BlobExchangeHeaders exchangeHeaders = 
BlobExchangeHeaders.create()
+                .blobLegalHold(hasLegalHold)
+                .httpHeaders(response.getHeaders());
+
+        return BlobOperationResponse.create(hasLegalHold, 
exchangeHeaders.toMap());
+    }
+
+    public BlobOperationResponse setBlobImmutabilityPolicy(final Exchange 
exchange) {
+        ObjectHelper.notNull(exchange, MISSING_EXCHANGE);
+
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("Setting immutability policy on blob [{}] from exchange 
[{}]...",
+                    configurationProxy.getBlobName(exchange), exchange);
+        }
+
+        BlobImmutabilityPolicy policy = 
configurationProxy.getBlobImmutabilityPolicy(exchange);
+        if (policy == null) {
+            final Object body = exchange.getIn().getBody();
+            if (body instanceof BlobImmutabilityPolicy) {
+                policy = (BlobImmutabilityPolicy) body;
+            }
+        }
+        if (policy == null) {
+            final OffsetDateTime expiryTime = 
configurationProxy.getBlobImmutabilityPolicyExpiryTime(exchange);
+            if (expiryTime == null) {
+                throw new IllegalArgumentException(
+                        "Immutability policy expiry time must be specified via 
the "
+                                                   + 
BlobConstants.BLOB_IMMUTABILITY_POLICY_EXPIRY_TIME
+                                                   + " header, or a pre-built 
BlobImmutabilityPolicy must be provided via the message body or "
+                                                   + 
BlobConstants.BLOB_IMMUTABILITY_POLICY + " header.");
+            }
+            BlobImmutabilityPolicyMode policyMode = 
configurationProxy.getBlobImmutabilityPolicyMode(exchange);
+            if (policyMode == null) {
+                policyMode = BlobImmutabilityPolicyMode.UNLOCKED;
+            }
+            policy = new 
BlobImmutabilityPolicy().setExpiryTime(expiryTime).setPolicyMode(policyMode);
+        }
+
+        final BlobCommonRequestOptions commonRequestOptions = 
getCommonRequestOptions(exchange);
+
+        final Response<BlobImmutabilityPolicy> response = 
client.setImmutabilityPolicy(
+                policy,
+                commonRequestOptions.getBlobRequestConditions(),
+                commonRequestOptions.getTimeout());
+
+        final BlobImmutabilityPolicy result = response.getValue();
+        final BlobExchangeHeaders exchangeHeaders = 
BlobExchangeHeaders.create()
+                .httpHeaders(response.getHeaders());
+        if (result != null) {
+            
exchangeHeaders.blobImmutabilityPolicyExpiryTime(result.getExpiryTime())
+                    .blobImmutabilityPolicyMode(result.getPolicyMode());
+        }
+
+        return BlobOperationResponse.create(result, exchangeHeaders.toMap());
+    }
+
     private DownloadRetryOptions getDownloadRetryOptions(final 
BlobConfigurationOptionsProxy configurationProxy) {
         return new 
DownloadRetryOptions().setMaxRetryRequests(configurationProxy.getMaxRetryRequests());
     }
diff --git 
a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationsTest.java
 
b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationsTest.java
index 0744ed6e7a09..50e5ec8d0d46 100644
--- 
a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationsTest.java
+++ 
b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationsTest.java
@@ -30,6 +30,9 @@ import java.util.Map;
 import com.azure.core.http.HttpHeaders;
 import com.azure.core.http.rest.ResponseBase;
 import com.azure.storage.blob.models.BlobDownloadHeaders;
+import com.azure.storage.blob.models.BlobImmutabilityPolicy;
+import com.azure.storage.blob.models.BlobImmutabilityPolicyMode;
+import com.azure.storage.blob.models.BlobLegalHoldResult;
 import com.azure.storage.blob.models.BlobProperties;
 import com.azure.storage.blob.models.BlockBlobItem;
 import com.azure.storage.blob.specialized.BlobClientBase;
@@ -50,6 +53,7 @@ import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -58,6 +62,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -388,6 +393,134 @@ class BlobOperationsTest extends CamelTestSupport {
                 .get("x-test-header").getValue());
     }
 
+    @Test
+    void testSetBlobLegalHoldFromHeader() {
+        final HttpHeaders httpHeaders = new HttpHeaders().set("x-test-header", 
"111");
+        final BlobLegalHoldResult legalHoldResult = 
mock(BlobLegalHoldResult.class);
+        when(legalHoldResult.hasLegalHold()).thenReturn(true);
+
+        when(client.setLegalHold(eq(true), any()))
+                .thenReturn(new ResponseBase<>(null, 200, httpHeaders, 
legalHoldResult, null));
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setHeader(BlobConstants.BLOB_LEGAL_HOLD, true);
+
+        final BlobOperations operations = new BlobOperations(configuration, 
client);
+        final BlobOperationResponse response = 
operations.setBlobLegalHold(exchange);
+
+        assertNotNull(response);
+        assertTrue((boolean) response.getBody());
+        assertEquals(true, 
response.getHeaders().get(BlobConstants.BLOB_LEGAL_HOLD));
+        assertEquals("111", ((HttpHeaders) 
response.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS))
+                .get("x-test-header").getValue());
+    }
+
+    @Test
+    void testSetBlobLegalHoldFromBody() {
+        final HttpHeaders httpHeaders = new HttpHeaders().set("x-test-header", 
"222");
+        final BlobLegalHoldResult legalHoldResult = 
mock(BlobLegalHoldResult.class);
+        when(legalHoldResult.hasLegalHold()).thenReturn(false);
+
+        when(client.setLegalHold(eq(false), any()))
+                .thenReturn(new ResponseBase<>(null, 200, httpHeaders, 
legalHoldResult, null));
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(false);
+
+        final BlobOperations operations = new BlobOperations(configuration, 
client);
+        final BlobOperationResponse response = 
operations.setBlobLegalHold(exchange);
+
+        assertNotNull(response);
+        assertFalse((boolean) response.getBody());
+        assertEquals(false, 
response.getHeaders().get(BlobConstants.BLOB_LEGAL_HOLD));
+    }
+
+    @Test
+    void testSetBlobLegalHoldWithNoFlagThrows() {
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody("not-a-boolean");
+
+        final BlobOperations operations = new BlobOperations(configuration, 
client);
+        assertThrows(IllegalArgumentException.class, () -> 
operations.setBlobLegalHold(exchange));
+    }
+
+    @Test
+    void testSetBlobImmutabilityPolicyFromHeaders() {
+        final OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(7);
+        final BlobImmutabilityPolicy persistedPolicy
+                = new 
BlobImmutabilityPolicy().setExpiryTime(expiryTime).setPolicyMode(BlobImmutabilityPolicyMode.LOCKED);
+        final HttpHeaders httpHeaders = new HttpHeaders().set("x-test-header", 
"333");
+
+        when(client.setImmutabilityPolicy(any(), any(), any()))
+                .thenReturn(new ResponseBase<>(null, 200, httpHeaders, 
persistedPolicy, null));
+
+        final Exchange exchange = new DefaultExchange(context);
+        
exchange.getIn().setHeader(BlobConstants.BLOB_IMMUTABILITY_POLICY_EXPIRY_TIME, 
expiryTime);
+        
exchange.getIn().setHeader(BlobConstants.BLOB_IMMUTABILITY_POLICY_MODE, 
BlobImmutabilityPolicyMode.LOCKED);
+
+        final BlobOperations operations = new BlobOperations(configuration, 
client);
+        final BlobOperationResponse response = 
operations.setBlobImmutabilityPolicy(exchange);
+
+        assertNotNull(response);
+        final BlobImmutabilityPolicy result = (BlobImmutabilityPolicy) 
response.getBody();
+        assertNotNull(result);
+        assertEquals(expiryTime, result.getExpiryTime());
+        assertEquals(BlobImmutabilityPolicyMode.LOCKED, 
result.getPolicyMode());
+        assertEquals(expiryTime, 
response.getHeaders().get(BlobConstants.BLOB_IMMUTABILITY_POLICY_EXPIRY_TIME));
+        assertEquals(BlobImmutabilityPolicyMode.LOCKED,
+                
response.getHeaders().get(BlobConstants.BLOB_IMMUTABILITY_POLICY_MODE));
+    }
+
+    @Test
+    void testSetBlobImmutabilityPolicyDefaultsToUnlocked() {
+        final OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
+        final BlobImmutabilityPolicy persistedPolicy
+                = new 
BlobImmutabilityPolicy().setExpiryTime(expiryTime).setPolicyMode(BlobImmutabilityPolicyMode.UNLOCKED);
+        final HttpHeaders httpHeaders = new HttpHeaders();
+
+        when(client.setImmutabilityPolicy(any(), any(), any()))
+                .thenReturn(new ResponseBase<>(null, 200, httpHeaders, 
persistedPolicy, null));
+
+        final Exchange exchange = new DefaultExchange(context);
+        
exchange.getIn().setHeader(BlobConstants.BLOB_IMMUTABILITY_POLICY_EXPIRY_TIME, 
expiryTime);
+
+        final BlobOperations operations = new BlobOperations(configuration, 
client);
+        final BlobOperationResponse response = 
operations.setBlobImmutabilityPolicy(exchange);
+
+        assertNotNull(response);
+        assertEquals(BlobImmutabilityPolicyMode.UNLOCKED,
+                ((BlobImmutabilityPolicy) response.getBody()).getPolicyMode());
+    }
+
+    @Test
+    void testSetBlobImmutabilityPolicyFromBody() {
+        final OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(3);
+        final BlobImmutabilityPolicy bodyPolicy
+                = new 
BlobImmutabilityPolicy().setExpiryTime(expiryTime).setPolicyMode(BlobImmutabilityPolicyMode.UNLOCKED);
+        final HttpHeaders httpHeaders = new HttpHeaders();
+
+        when(client.setImmutabilityPolicy(eq(bodyPolicy), any(), any()))
+                .thenReturn(new ResponseBase<>(null, 200, httpHeaders, 
bodyPolicy, null));
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(bodyPolicy);
+
+        final BlobOperations operations = new BlobOperations(configuration, 
client);
+        final BlobOperationResponse response = 
operations.setBlobImmutabilityPolicy(exchange);
+
+        assertNotNull(response);
+        assertEquals(expiryTime, ((BlobImmutabilityPolicy) 
response.getBody()).getExpiryTime());
+        verify(client, times(1)).setImmutabilityPolicy(eq(bodyPolicy), any(), 
any());
+    }
+
+    @Test
+    void testSetBlobImmutabilityPolicyWithoutExpiryThrows() {
+        final Exchange exchange = new DefaultExchange(context);
+
+        final BlobOperations operations = new BlobOperations(configuration, 
client);
+        assertThrows(IllegalArgumentException.class, () -> 
operations.setBlobImmutabilityPolicy(exchange));
+    }
+
     @Test
     void testCreateBlobSnapshot() {
         final String snapshotId = "2026-04-15T10:00:00.0000000Z";
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
index ff5f6b0dfd2f..ee315bd99902 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/BlobEndpointBuilderFactory.java
@@ -4452,6 +4452,69 @@ public interface BlobEndpointBuilderFactory {
         public String azureStorageBlobTagFilter() {
             return "CamelAzureStorageBlobTagFilter";
         }
+        /**
+         * (producer) (setBlobLegalHold) The legal hold status to set on the
+         * blob. When set to true the blob is protected from modification and
+         * deletion until the hold is cleared by setting the value to false.
+         * (consumer) The legal hold status returned by the setBlobLegalHold
+         * operation.
+         * 
+         * The option is a: {@code Boolean} type.
+         * 
+         * Group: common
+         * 
+         * @return the name of the header {@code AzureStorageBlobLegalHold}.
+         */
+        public String azureStorageBlobLegalHold() {
+            return "CamelAzureStorageBlobLegalHold";
+        }
+        /**
+         * (setBlobImmutabilityPolicy) A pre-built BlobImmutabilityPolicy 
object
+         * that overrides the policy expiry time and mode headers when present.
+         * 
+         * The option is a: {@code
+         * com.azure.storage.blob.models.BlobImmutabilityPolicy} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code
+         * AzureStorageBlobImmutabilityPolicy}.
+         */
+        public String azureStorageBlobImmutabilityPolicy() {
+            return "CamelAzureStorageBlobImmutabilityPolicy";
+        }
+        /**
+         * (setBlobImmutabilityPolicy) The expiry time of the time-based
+         * retention policy. Required unless a pre-built BlobImmutabilityPolicy
+         * is provided via the body or the
+         * CamelAzureStorageBlobImmutabilityPolicy header.
+         * 
+         * The option is a: {@code java.time.OffsetDateTime} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code
+         * AzureStorageBlobImmutabilityPolicyExpiryTime}.
+         */
+        public String azureStorageBlobImmutabilityPolicyExpiryTime() {
+            return "CamelAzureStorageBlobImmutabilityPolicyExpiryTime";
+        }
+        /**
+         * (setBlobImmutabilityPolicy) The mode of the immutability policy:
+         * UNLOCKED (default, can be modified or deleted), LOCKED (cannot be
+         * modified or shortened, only extended), or MUTABLE.
+         * 
+         * The option is a: {@code
+         * com.azure.storage.blob.models.BlobImmutabilityPolicyMode} type.
+         * 
+         * Group: producer
+         * 
+         * @return the name of the header {@code
+         * AzureStorageBlobImmutabilityPolicyMode}.
+         */
+        public String azureStorageBlobImmutabilityPolicyMode() {
+            return "CamelAzureStorageBlobImmutabilityPolicyMode";
+        }
     }
     static BlobEndpointBuilder endpointBuilder(String componentName, String 
path) {
         class BlobEndpointBuilderImpl extends AbstractEndpointBuilder 
implements BlobEndpointBuilder, AdvancedBlobEndpointBuilder {

Reply via email to