You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2021/03/10 06:47:13 UTC

[camel] branch master updated (992cfde -> ee304f4)

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

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


    from 992cfde  Sync deps
     new b2f9b1b  CAMEL-16321 - Have a middle folder for azure components
     new 42e0110  CAMEL-16321 - Have a middle folder for azure components
     new 2af9bab  CAMEL-16321 - Have a middle folder for azure components
     new 040663e  CAMEL-16321 - Have a middle folder for azure components
     new ee304f4  CAMEL-16321 - Have a middle folder for azure components

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 components/{ => camel-azure}/camel-azure-eventhubs/pom.xml |  2 +-
 .../azure/eventhubs/EventHubsComponentConfigurer.java      |  0
 .../azure/eventhubs/EventHubsEndpointConfigurer.java       |  0
 .../azure/eventhubs/EventHubsEndpointUriFactory.java       |  0
 .../services/org/apache/camel/component.properties         |  0
 .../services/org/apache/camel/component/azure-eventhubs    |  0
 .../org/apache/camel/configurer/azure-eventhubs-component  |  0
 .../org/apache/camel/configurer/azure-eventhubs-endpoint   |  0
 .../org/apache/camel/urifactory/azure-eventhubs-endpoint   |  0
 .../camel/component/azure/eventhubs/azure-eventhubs.json   |  0
 .../src/main/docs/azure-eventhubs-component.adoc           |  0
 .../component/azure/eventhubs/EventHubsComponent.java      |  0
 .../component/azure/eventhubs/EventHubsConfiguration.java  |  0
 .../eventhubs/EventHubsConfigurationOptionsProxy.java      |  0
 .../component/azure/eventhubs/EventHubsConstants.java      |  0
 .../camel/component/azure/eventhubs/EventHubsConsumer.java |  0
 .../camel/component/azure/eventhubs/EventHubsEndpoint.java |  0
 .../camel/component/azure/eventhubs/EventHubsProducer.java |  0
 .../azure/eventhubs/client/EventHubsClientFactory.java     |  0
 .../eventhubs/operations/EventHubsProducerOperations.java  |  0
 .../component/azure/eventhubs/EventHubsComponentTest.java  |  0
 .../component/azure/eventhubs/EventHubsConsumerIT.java     |  0
 .../component/azure/eventhubs/EventHubsProducerIT.java     |  0
 .../camel/component/azure/eventhubs/EventProcessorIT.java  |  0
 .../component/azure/eventhubs/EventProcessorTest.java      |  0
 .../apache/camel/component/azure/eventhubs/TestUtils.java  |  0
 .../operations/EventHubsProducerOperationsIT.java          |  0
 .../src/test/resources/log4j2.properties                   |  0
 .../{ => camel-azure}/camel-azure-storage-blob/pom.xml     |  2 +-
 .../azure/storage/blob/BlobComponentConfigurer.java        |  0
 .../azure/storage/blob/BlobEndpointConfigurer.java         |  0
 .../azure/storage/blob/BlobEndpointUriFactory.java         |  0
 .../services/org/apache/camel/component.properties         |  0
 .../services/org/apache/camel/component/azure-storage-blob |  0
 .../apache/camel/configurer/azure-storage-blob-component   |  0
 .../apache/camel/configurer/azure-storage-blob-endpoint    |  0
 .../apache/camel/urifactory/azure-storage-blob-endpoint    |  0
 .../component/azure/storage/blob/azure-storage-blob.json   |  0
 .../src/main/docs/azure-storage-blob-component.adoc        |  0
 .../src/main/docs/azure-summary.adoc                       |  0
 .../camel/component/azure/storage/blob/BlobBlock.java      |  0
 .../azure/storage/blob/BlobCommonRequestOptions.java       |  0
 .../camel/component/azure/storage/blob/BlobComponent.java  |  0
 .../component/azure/storage/blob/BlobConfiguration.java    |  0
 .../azure/storage/blob/BlobConfigurationOptionsProxy.java  |  0
 .../camel/component/azure/storage/blob/BlobConstants.java  |  0
 .../camel/component/azure/storage/blob/BlobConsumer.java   |  0
 .../camel/component/azure/storage/blob/BlobEndpoint.java   |  0
 .../component/azure/storage/blob/BlobExchangeHeaders.java  |  0
 .../azure/storage/blob/BlobOperationsDefinition.java       |  0
 .../camel/component/azure/storage/blob/BlobProducer.java   |  0
 .../component/azure/storage/blob/BlobStreamAndLength.java  |  0
 .../camel/component/azure/storage/blob/BlobType.java       |  0
 .../camel/component/azure/storage/blob/BlobUtils.java      |  0
 .../azure/storage/blob/client/BlobClientFactory.java       |  0
 .../azure/storage/blob/client/BlobClientWrapper.java       |  0
 .../storage/blob/client/BlobContainerClientWrapper.java    |  0
 .../storage/blob/client/BlobServiceClientWrapper.java      |  0
 .../storage/blob/operations/BlobContainerOperations.java   |  0
 .../storage/blob/operations/BlobOperationResponse.java     |  0
 .../azure/storage/blob/operations/BlobOperations.java      |  0
 .../storage/blob/operations/BlobServiceOperations.java     |  0
 .../component/azure/storage/blob/BlobComponentTest.java    |  0
 .../storage/blob/BlobConfigurationOptionsProxyTest.java    |  0
 .../camel/component/azure/storage/blob/BlobTestUtils.java  |  0
 .../component/azure/storage/blob/integration/BaseIT.java   |  0
 .../azure/storage/blob/integration/BlobConsumerITTest.java |  0
 .../blob/integration/BlobContainerOperationsITTest.java    |  0
 .../storage/blob/integration/BlobOperationsITTest.java     |  0
 .../azure/storage/blob/integration/BlobProducerITTest.java |  0
 .../blob/operations/BlobContainerOperationsTest.java       |  0
 .../azure/storage/blob/operations/BlobOperationsTest.java  |  0
 .../src/test/resources/azurite.properties                  |  0
 .../src/test/resources/log4j2.properties                   |  0
 .../src/test/resources/upload_test_file                    |  0
 .../{ => camel-azure}/camel-azure-storage-datalake/pom.xml |  2 +-
 .../storage/datalake/DataLakeComponentConfigurer.java      |  0
 .../azure/storage/datalake/DataLakeEndpointConfigurer.java |  0
 .../azure/storage/datalake/DataLakeEndpointUriFactory.java |  0
 .../services/org/apache/camel/component.properties         |  0
 .../org/apache/camel/component/azure-storage-datalake      |  0
 .../camel/configurer/azure-storage-datalake-component      |  0
 .../camel/configurer/azure-storage-datalake-endpoint       |  0
 .../camel/urifactory/azure-storage-datalake-endpoint       |  0
 .../azure/storage/datalake/azure-storage-datalake.json     |  0
 .../src/main/docs/azure-storage-datalake-component.adoc    |  0
 .../azure/storage/datalake/DataLakeComponent.java          |  0
 .../azure/storage/datalake/DataLakeConfiguration.java      |  0
 .../datalake/DataLakeConfigurationOptionsProxy.java        |  0
 .../azure/storage/datalake/DataLakeConstants.java          |  0
 .../component/azure/storage/datalake/DataLakeConsumer.java |  0
 .../component/azure/storage/datalake/DataLakeEndpoint.java |  0
 .../azure/storage/datalake/DataLakeExchangeHeaders.java    |  0
 .../storage/datalake/DataLakeOperationsDefinition.java     |  0
 .../component/azure/storage/datalake/DataLakeProducer.java |  0
 .../component/azure/storage/datalake/DataLakeUtils.java    |  0
 .../azure/storage/datalake/FileCommonRequestOptions.java   |  0
 .../azure/storage/datalake/FileStreamAndLength.java        |  0
 .../storage/datalake/client/DataLakeClientFactory.java     |  0
 .../datalake/client/DataLakeDirectoryClientWrapper.java    |  0
 .../storage/datalake/client/DataLakeFileClientWrapper.java |  0
 .../datalake/client/DataLakeFileSystemClientWrapper.java   |  0
 .../datalake/client/DataLakeServiceClientWrapper.java      |  0
 .../datalake/operations/DataLakeDirectoryOperations.java   |  0
 .../datalake/operations/DataLakeFileOperations.java        |  0
 .../datalake/operations/DataLakeFileSystemOperations.java  |  0
 .../datalake/operations/DataLakeOperationResponse.java     |  0
 .../datalake/operations/DataLakeServiceOperations.java     |  0
 .../storage/datalake/component/DataLakeComponentTest.java  |  0
 .../azure/storage/datalake/integration/BaseIT.java         |  0
 .../storage/datalake/integration/DataLakeConsumerIT.java   |  0
 .../datalake/integration/DataLakeFileOperationIT.java      |  0
 .../integration/DataLakeFileSystemOperationIT.java         |  0
 .../storage/datalake/integration/DataLakeProducerIT.java   |  0
 .../operations/DataLakeDirectoryOperationTest.java         |  0
 .../datalake/operations/DataLakeFileOperationTest.java     |  0
 .../operations/DataLakeFileSystemOperationTest.java        |  0
 .../src/test/resources/log4j2.properties                   |  0
 .../{ => camel-azure}/camel-azure-storage-queue/pom.xml    |  2 +-
 .../azure/storage/queue/QueueComponentConfigurer.java      |  0
 .../azure/storage/queue/QueueEndpointConfigurer.java       |  0
 .../azure/storage/queue/QueueEndpointUriFactory.java       |  0
 .../services/org/apache/camel/component.properties         |  0
 .../org/apache/camel/component/azure-storage-queue         |  0
 .../apache/camel/configurer/azure-storage-queue-component  |  0
 .../apache/camel/configurer/azure-storage-queue-endpoint   |  0
 .../apache/camel/urifactory/azure-storage-queue-endpoint   |  0
 .../component/azure/storage/queue/azure-storage-queue.json |  0
 .../src/main/docs/azure-storage-queue-component.adoc       |  0
 .../component/azure/storage/queue/QueueComponent.java      |  0
 .../component/azure/storage/queue/QueueConfiguration.java  |  0
 .../storage/queue/QueueConfigurationOptionsProxy.java      |  0
 .../component/azure/storage/queue/QueueConstants.java      |  0
 .../camel/component/azure/storage/queue/QueueConsumer.java |  0
 .../camel/component/azure/storage/queue/QueueEndpoint.java |  0
 .../azure/storage/queue/QueueExchangeHeaders.java          |  0
 .../azure/storage/queue/QueueOperationDefinition.java      |  0
 .../camel/component/azure/storage/queue/QueueProducer.java |  0
 .../azure/storage/queue/client/QueueClientFactory.java     |  0
 .../azure/storage/queue/client/QueueClientWrapper.java     |  0
 .../storage/queue/client/QueueServiceClientWrapper.java    |  0
 .../storage/queue/operations/QueueOperationResponse.java   |  0
 .../azure/storage/queue/operations/QueueOperations.java    |  0
 .../storage/queue/operations/QueueServiceOperations.java   |  0
 .../component/azure/storage/queue/QueueComponentTest.java  |  0
 .../storage/queue/QueueConfigurationOptionsProxyTest.java  |  0
 .../component/azure/storage/queue/QueueConsumerIT.java     |  0
 .../component/azure/storage/queue/QueueProducerIT.java     |  0
 .../component/azure/storage/queue/QueueTestUtils.java      |  0
 .../azure/storage/queue/operations/QueueOperationsIT.java  |  0
 .../storage/queue/operations/QueueOperationsTest.java      |  0
 .../storage/queue/operations/QueueServiceOperationsIT.java |  0
 .../src/test/resources/log4j2.properties                   |  0
 components/{camel-fhir => camel-azure}/pom.xml             | 14 ++++++++------
 components/pom.xml                                         |  5 +----
 .../modules/ROOT/pages/azure-eventhubs-component.adoc      |  2 +-
 .../modules/ROOT/pages/azure-storage-blob-component.adoc   |  2 +-
 .../ROOT/pages/azure-storage-datalake-component.adoc       |  2 +-
 .../modules/ROOT/pages/azure-storage-queue-component.adoc  |  2 +-
 docs/components/modules/ROOT/pages/azure-summary.adoc      |  2 +-
 .../apache/camel/maven/packaging/PrepareCatalogMojo.java   |  5 +++++
 161 files changed, 23 insertions(+), 19 deletions(-)
 rename components/{ => camel-azure}/camel-azure-eventhubs/pom.xml (98%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentConfigurer.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointConfigurer.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointUriFactory.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component.properties (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component/azure-eventhubs (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-component (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-endpoint (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-eventhubs-endpoint (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/generated/resources/org/apache/camel/component/azure/eventhubs/azure-eventhubs.json (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/docs/azure-eventhubs-component.adoc (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsComponent.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfiguration.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfigurationOptionsProxy.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConstants.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumer.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpoint.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsProducer.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/client/EventHubsClientFactory.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumerIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsProducerIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/TestUtils.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperationsIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-eventhubs/src/test/resources/log4j2.properties (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/pom.xml (98%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component.properties (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component/azure-storage-blob (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-component (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-endpoint (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-storage-blob-endpoint (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/docs/azure-summary.adoc (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobBlock.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobCommonRequestOptions.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxy.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConstants.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConsumer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobExchangeHeaders.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobOperationsDefinition.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobProducer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobStreamAndLength.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobType.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobUtils.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientWrapper.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobContainerClientWrapper.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobServiceClientWrapper.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationResponse.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobServiceOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobComponentTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxyTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobTestUtils.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BaseIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobConsumerITTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobContainerOperationsITTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobOperationsITTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobProducerITTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperationsTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationsTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/resources/azurite.properties (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/resources/log4j2.properties (100%)
 rename components/{ => camel-azure}/camel-azure-storage-blob/src/test/resources/upload_test_file (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/pom.xml (99%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/generated/java/org/apache/camel/component/azure/storage/datalake/DataLakeComponentConfigurer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/generated/java/org/apache/camel/component/azure/storage/datalake/DataLakeEndpointConfigurer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/generated/java/org/apache/camel/component/azure/storage/datalake/DataLakeEndpointUriFactory.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/generated/resources/META-INF/services/org/apache/camel/component.properties (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/generated/resources/META-INF/services/org/apache/camel/component/azure-storage-datalake (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-datalake-component (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-datalake-endpoint (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-storage-datalake-endpoint (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/generated/resources/org/apache/camel/component/azure/storage/datalake/azure-storage-datalake.json (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/docs/azure-storage-datalake-component.adoc (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeComponent.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeConfiguration.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeConfigurationOptionsProxy.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeConstants.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeConsumer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeEndpoint.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeExchangeHeaders.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeOperationsDefinition.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeProducer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/DataLakeUtils.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/FileCommonRequestOptions.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/FileStreamAndLength.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/client/DataLakeClientFactory.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/client/DataLakeDirectoryClientWrapper.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/client/DataLakeFileClientWrapper.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/client/DataLakeFileSystemClientWrapper.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/client/DataLakeServiceClientWrapper.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/operations/DataLakeDirectoryOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/operations/DataLakeFileOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/operations/DataLakeFileSystemOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/operations/DataLakeOperationResponse.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/operations/DataLakeServiceOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/java/org/apache/camel/component/azure/storage/datalake/component/DataLakeComponentTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/java/org/apache/camel/component/azure/storage/datalake/integration/BaseIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/java/org/apache/camel/component/azure/storage/datalake/integration/DataLakeConsumerIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/java/org/apache/camel/component/azure/storage/datalake/integration/DataLakeFileOperationIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/java/org/apache/camel/component/azure/storage/datalake/integration/DataLakeFileSystemOperationIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/java/org/apache/camel/component/azure/storage/datalake/integration/DataLakeProducerIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/java/org/apache/camel/component/azure/storage/datalake/operations/DataLakeDirectoryOperationTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/java/org/apache/camel/component/azure/storage/datalake/operations/DataLakeFileOperationTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/java/org/apache/camel/component/azure/storage/datalake/operations/DataLakeFileSystemOperationTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-datalake/src/test/resources/log4j2.properties (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/pom.xml (98%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/generated/java/org/apache/camel/component/azure/storage/queue/QueueComponentConfigurer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/generated/java/org/apache/camel/component/azure/storage/queue/QueueEndpointConfigurer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/generated/java/org/apache/camel/component/azure/storage/queue/QueueEndpointUriFactory.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/generated/resources/META-INF/services/org/apache/camel/component.properties (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/generated/resources/META-INF/services/org/apache/camel/component/azure-storage-queue (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-queue-component (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-queue-endpoint (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-storage-queue-endpoint (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/generated/resources/org/apache/camel/component/azure/storage/queue/azure-storage-queue.json (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/docs/azure-storage-queue-component.adoc (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/QueueComponent.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/QueueConfiguration.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/QueueConfigurationOptionsProxy.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/QueueConstants.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/QueueConsumer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/QueueEndpoint.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/QueueExchangeHeaders.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/QueueOperationDefinition.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/QueueProducer.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/client/QueueClientFactory.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/client/QueueClientWrapper.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/client/QueueServiceClientWrapper.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/operations/QueueOperationResponse.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/operations/QueueOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/main/java/org/apache/camel/component/azure/storage/queue/operations/QueueServiceOperations.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/test/java/org/apache/camel/component/azure/storage/queue/QueueComponentTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/test/java/org/apache/camel/component/azure/storage/queue/QueueConfigurationOptionsProxyTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/test/java/org/apache/camel/component/azure/storage/queue/QueueConsumerIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/test/java/org/apache/camel/component/azure/storage/queue/QueueProducerIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/test/java/org/apache/camel/component/azure/storage/queue/QueueTestUtils.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/test/java/org/apache/camel/component/azure/storage/queue/operations/QueueOperationsIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/test/java/org/apache/camel/component/azure/storage/queue/operations/QueueOperationsTest.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/test/java/org/apache/camel/component/azure/storage/queue/operations/QueueServiceOperationsIT.java (100%)
 rename components/{ => camel-azure}/camel-azure-storage-queue/src/test/resources/log4j2.properties (100%)
 copy components/{camel-fhir => camel-azure}/pom.xml (79%)


[camel] 04/05: CAMEL-16321 - Have a middle folder for azure components

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 040663e438d7800d5897eaebe3827491e7b8b65c
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Wed Mar 10 07:39:45 2021 +0100

    CAMEL-16321 - Have a middle folder for azure components
---
 components/pom.xml | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/components/pom.xml b/components/pom.xml
index 89adb71..a795d3e 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -108,10 +108,7 @@
         <module>camel-avro</module>
         <module>camel-avro-rpc</module>
         <module>camel-aws</module>
-        <module>camel-azure-storage-blob</module>
-        <module>camel-azure-storage-datalake</module>
-        <module>camel-azure-storage-queue</module>
-        <module>camel-azure-eventhubs</module>
+        <module>camel-azure</module>
         <module>camel-barcode</module>
         <module>camel-base64</module>
         <module>camel-bean-validator</module>


[camel] 05/05: CAMEL-16321 - Have a middle folder for azure components

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ee304f459f5ce693c71d2eaa5a1f9694ec08a2e0
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Wed Mar 10 07:43:59 2021 +0100

    CAMEL-16321 - Have a middle folder for azure components
---
 docs/components/modules/ROOT/pages/azure-eventhubs-component.adoc    | 2 +-
 docs/components/modules/ROOT/pages/azure-storage-blob-component.adoc | 2 +-
 .../modules/ROOT/pages/azure-storage-datalake-component.adoc         | 2 +-
 .../components/modules/ROOT/pages/azure-storage-queue-component.adoc | 2 +-
 docs/components/modules/ROOT/pages/azure-summary.adoc                | 2 +-
 .../java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java    | 5 +++--
 6 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/docs/components/modules/ROOT/pages/azure-eventhubs-component.adoc b/docs/components/modules/ROOT/pages/azure-eventhubs-component.adoc
index ab5678c..f3912c9 100644
--- a/docs/components/modules/ROOT/pages/azure-eventhubs-component.adoc
+++ b/docs/components/modules/ROOT/pages/azure-eventhubs-component.adoc
@@ -1,7 +1,7 @@
 [[azure-eventhubs-component]]
 = Azure Event Hubs Component
 //THIS FILE IS COPIED: EDIT THE SOURCE FILE:
-:page-source: components/camel-azure-eventhubs/src/main/docs/azure-eventhubs-component.adoc
+:page-source: components/camel-azure/camel-azure-eventhubs/src/main/docs/azure-eventhubs-component.adoc
 :docTitle: Azure Event Hubs
 :artifactId: camel-azure-eventhubs
 :description: The azure-eventhubs component that integrates Azure Event Hubs using AMQP protocol. Azure EventHubs is a highly scalable publish-subscribe service that can ingest millions of events per second and stream them to multiple consumers.
diff --git a/docs/components/modules/ROOT/pages/azure-storage-blob-component.adoc b/docs/components/modules/ROOT/pages/azure-storage-blob-component.adoc
index c0649dd..3f3c7a4 100644
--- a/docs/components/modules/ROOT/pages/azure-storage-blob-component.adoc
+++ b/docs/components/modules/ROOT/pages/azure-storage-blob-component.adoc
@@ -1,7 +1,7 @@
 [[azure-storage-blob-component]]
 = Azure Storage Blob Service Component
 //THIS FILE IS COPIED: EDIT THE SOURCE FILE:
-:page-source: components/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
+:page-source: components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
 :docTitle: Azure Storage Blob Service
 :artifactId: camel-azure-storage-blob
 :description: Store and retrieve blobs from Azure Storage Blob Service using SDK v12.
diff --git a/docs/components/modules/ROOT/pages/azure-storage-datalake-component.adoc b/docs/components/modules/ROOT/pages/azure-storage-datalake-component.adoc
index a453f96..135b43f 100644
--- a/docs/components/modules/ROOT/pages/azure-storage-datalake-component.adoc
+++ b/docs/components/modules/ROOT/pages/azure-storage-datalake-component.adoc
@@ -1,7 +1,7 @@
 [[azure-storage-datalake-component]]
 = Azure storage datalake service Component
 //THIS FILE IS COPIED: EDIT THE SOURCE FILE:
-:page-source: components/camel-azure-storage-datalake/src/main/docs/azure-storage-datalake-component.adoc
+:page-source: components/camel-azure/camel-azure-storage-datalake/src/main/docs/azure-storage-datalake-component.adoc
 :docTitle: Azure storage datalake service
 :artifactId: camel-azure-storage-datalake
 :description: Camel Azure Datalake Gen2 Component
diff --git a/docs/components/modules/ROOT/pages/azure-storage-queue-component.adoc b/docs/components/modules/ROOT/pages/azure-storage-queue-component.adoc
index a8e3af8..efcc57e 100644
--- a/docs/components/modules/ROOT/pages/azure-storage-queue-component.adoc
+++ b/docs/components/modules/ROOT/pages/azure-storage-queue-component.adoc
@@ -1,7 +1,7 @@
 [[azure-storage-queue-component]]
 = Azure Storage Queue Service Component
 //THIS FILE IS COPIED: EDIT THE SOURCE FILE:
-:page-source: components/camel-azure-storage-queue/src/main/docs/azure-storage-queue-component.adoc
+:page-source: components/camel-azure/camel-azure-storage-queue/src/main/docs/azure-storage-queue-component.adoc
 :docTitle: Azure Storage Queue Service
 :artifactId: camel-azure-storage-queue
 :description: The azure-storage-queue component is used for storing and retrieving the messages to/from Azure Storage Queue using Azure SDK v12.
diff --git a/docs/components/modules/ROOT/pages/azure-summary.adoc b/docs/components/modules/ROOT/pages/azure-summary.adoc
index 18f33ff..70c650b 100644
--- a/docs/components/modules/ROOT/pages/azure-summary.adoc
+++ b/docs/components/modules/ROOT/pages/azure-summary.adoc
@@ -1,7 +1,7 @@
 [[Azure-CamelComponentsforMicrosoftAzureServices]]
 = Camel Components for Microsoft Azure Services
 //THIS FILE IS COPIED: EDIT THE SOURCE FILE:
-:page-source: components/camel-azure-storage-blob/src/main/docs/azure-summary.adoc
+:page-source: components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-summary.adoc
 //attributes written by hand, not generated
 :docTitle: Azure
 
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
index 82d9465..ec0cb5b 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
@@ -1167,8 +1167,9 @@ public class PrepareCatalogMojo extends AbstractMojo {
             case "camel-infinispan":
                 return Arrays.asList(dir.resolve("camel-infinispan"), dir.resolve("camel-infinispan-embedded"));
             case "camel-azure":
-                return Arrays.asList(dir.resolve("camel-azure-eventhubs"), dir.resolve("camel-azure-storage-blob"), dir.resolve("camel-azure-storage-datalake"),
-                dir.resolve("camel-azure-storage-queue"));
+                return Arrays.asList(dir.resolve("camel-azure-eventhubs"), dir.resolve("camel-azure-storage-blob"),
+                        dir.resolve("camel-azure-storage-datalake"),
+                        dir.resolve("camel-azure-storage-queue"));
             case "camel-aws":
                 return Arrays.asList(dir.resolve("camel-aws2-athena"), dir.resolve("camel-aws2-cw"),
                         dir.resolve("camel-aws2-ddb"), dir.resolve("camel-aws2-ec2"),


[camel] 03/05: CAMEL-16321 - Have a middle folder for azure components

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 2af9bab2319a661cad967d40d70d24fbebc1803d
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Wed Mar 10 07:38:46 2021 +0100

    CAMEL-16321 - Have a middle folder for azure components
---
 .../camel-azure/camel-azure-eventhubs/pom.xml      | 125 ++++
 .../eventhubs/EventHubsComponentConfigurer.java    | 182 ++++++
 .../eventhubs/EventHubsEndpointConfigurer.java     | 178 ++++++
 .../eventhubs/EventHubsEndpointUriFactory.java     |  89 +++
 .../services/org/apache/camel/component.properties |   7 +
 .../org/apache/camel/component/azure-eventhubs     |   2 +
 .../camel/configurer/azure-eventhubs-component     |   2 +
 .../camel/configurer/azure-eventhubs-endpoint      |   2 +
 .../camel/urifactory/azure-eventhubs-endpoint      |   2 +
 .../component/azure/eventhubs/azure-eventhubs.json |  72 +++
 .../src/main/docs/azure-eventhubs-component.adoc   | 254 ++++++++
 .../azure/eventhubs/EventHubsComponent.java        | 130 ++++
 .../azure/eventhubs/EventHubsConfiguration.java    | 337 ++++++++++
 .../EventHubsConfigurationOptionsProxy.java        |  60 ++
 .../azure/eventhubs/EventHubsConstants.java        |  31 +
 .../azure/eventhubs/EventHubsConsumer.java         | 160 +++++
 .../azure/eventhubs/EventHubsEndpoint.java         |  70 +++
 .../azure/eventhubs/EventHubsProducer.java         |  77 +++
 .../eventhubs/client/EventHubsClientFactory.java   | 144 +++++
 .../operations/EventHubsProducerOperations.java    | 152 +++++
 .../azure/eventhubs/EventHubsComponentTest.java    | 132 ++++
 .../azure/eventhubs/EventHubsConsumerIT.java       | 146 +++++
 .../azure/eventhubs/EventHubsProducerIT.java       | 139 ++++
 .../azure/eventhubs/EventProcessorIT.java          | 110 ++++
 .../azure/eventhubs/EventProcessorTest.java        |  57 ++
 .../camel/component/azure/eventhubs/TestUtils.java |  60 ++
 .../operations/EventHubsProducerOperationsIT.java  | 188 ++++++
 .../src/test/resources/log4j2.properties           |  27 +
 .../camel-azure/camel-azure-storage-blob/pom.xml   | 116 ++++
 .../storage/blob/BlobComponentConfigurer.java      | 200 ++++++
 .../azure/storage/blob/BlobEndpointConfigurer.java | 202 ++++++
 .../azure/storage/blob/BlobEndpointUriFactory.java |  94 +++
 .../services/org/apache/camel/component.properties |   7 +
 .../org/apache/camel/component/azure-storage-blob  |   2 +
 .../camel/configurer/azure-storage-blob-component  |   2 +
 .../camel/configurer/azure-storage-blob-endpoint   |   2 +
 .../camel/urifactory/azure-storage-blob-endpoint   |   2 +
 .../azure/storage/blob/azure-storage-blob.json     |  87 +++
 .../main/docs/azure-storage-blob-component.adoc    | 697 +++++++++++++++++++++
 .../src/main/docs/azure-summary.adoc               |  15 +
 .../component/azure/storage/blob/BlobBlock.java    |  56 ++
 .../storage/blob/BlobCommonRequestOptions.java     |  73 +++
 .../azure/storage/blob/BlobComponent.java          | 131 ++++
 .../azure/storage/blob/BlobConfiguration.java      | 403 ++++++++++++
 .../blob/BlobConfigurationOptionsProxy.java        | 216 +++++++
 .../azure/storage/blob/BlobConstants.java          |  87 +++
 .../component/azure/storage/blob/BlobConsumer.java | 171 +++++
 .../component/azure/storage/blob/BlobEndpoint.java | 110 ++++
 .../azure/storage/blob/BlobExchangeHeaders.java    | 438 +++++++++++++
 .../storage/blob/BlobOperationsDefinition.java     | 122 ++++
 .../component/azure/storage/blob/BlobProducer.java | 169 +++++
 .../azure/storage/blob/BlobStreamAndLength.java    |  78 +++
 .../component/azure/storage/blob/BlobType.java     |  30 +
 .../component/azure/storage/blob/BlobUtils.java    |  55 ++
 .../storage/blob/client/BlobClientFactory.java     |  60 ++
 .../storage/blob/client/BlobClientWrapper.java     | 204 ++++++
 .../blob/client/BlobContainerClientWrapper.java    |  60 ++
 .../blob/client/BlobServiceClientWrapper.java      |  48 ++
 .../blob/operations/BlobContainerOperations.java   |  81 +++
 .../blob/operations/BlobOperationResponse.java     |  54 ++
 .../storage/blob/operations/BlobOperations.java    | 468 ++++++++++++++
 .../blob/operations/BlobServiceOperations.java     |  49 ++
 .../azure/storage/blob/BlobComponentTest.java      | 134 ++++
 .../blob/BlobConfigurationOptionsProxyTest.java    | 114 ++++
 .../azure/storage/blob/BlobTestUtils.java          |  44 ++
 .../azure/storage/blob/integration/BaseIT.java     |  85 +++
 .../blob/integration/BlobConsumerITTest.java       | 242 +++++++
 .../integration/BlobContainerOperationsITTest.java |  89 +++
 .../blob/integration/BlobOperationsITTest.java     | 422 +++++++++++++
 .../blob/integration/BlobProducerITTest.java       | 218 +++++++
 .../operations/BlobContainerOperationsTest.java    | 175 ++++++
 .../blob/operations/BlobOperationsTest.java        | 179 ++++++
 .../src/test/resources/azurite.properties          |  20 +
 .../src/test/resources/log4j2.properties           |  27 +
 .../src/test/resources/upload_test_file            |   1 +
 .../camel-azure-storage-datalake/pom.xml           | 144 +++++
 .../datalake/DataLakeComponentConfigurer.java      | 229 +++++++
 .../datalake/DataLakeEndpointConfigurer.java       | 231 +++++++
 .../datalake/DataLakeEndpointUriFactory.java       |  97 +++
 .../services/org/apache/camel/component.properties |   7 +
 .../apache/camel/component/azure-storage-datalake  |   2 +
 .../configurer/azure-storage-datalake-component    |   2 +
 .../configurer/azure-storage-datalake-endpoint     |   2 +
 .../urifactory/azure-storage-datalake-endpoint     |   2 +
 .../storage/datalake/azure-storage-datalake.json   |  97 +++
 .../docs/azure-storage-datalake-component.adoc     | 553 ++++++++++++++++
 .../azure/storage/datalake/DataLakeComponent.java  | 112 ++++
 .../storage/datalake/DataLakeConfiguration.java    | 356 +++++++++++
 .../DataLakeConfigurationOptionsProxy.java         | 267 ++++++++
 .../azure/storage/datalake/DataLakeConstants.java  |  86 +++
 .../azure/storage/datalake/DataLakeConsumer.java   | 165 +++++
 .../azure/storage/datalake/DataLakeEndpoint.java   |  97 +++
 .../storage/datalake/DataLakeExchangeHeaders.java  | 414 ++++++++++++
 .../datalake/DataLakeOperationsDefinition.java     |  35 ++
 .../azure/storage/datalake/DataLakeProducer.java   | 172 +++++
 .../azure/storage/datalake/DataLakeUtils.java      |  48 ++
 .../storage/datalake/FileCommonRequestOptions.java |  78 +++
 .../storage/datalake/FileStreamAndLength.java      |  78 +++
 .../datalake/client/DataLakeClientFactory.java     |  94 +++
 .../client/DataLakeDirectoryClientWrapper.java     |  56 ++
 .../datalake/client/DataLakeFileClientWrapper.java | 133 ++++
 .../client/DataLakeFileSystemClientWrapper.java    |  70 +++
 .../client/DataLakeServiceClientWrapper.java       |  47 ++
 .../operations/DataLakeDirectoryOperations.java    |  69 ++
 .../operations/DataLakeFileOperations.java         | 240 +++++++
 .../operations/DataLakeFileSystemOperations.java   |  85 +++
 .../operations/DataLakeOperationResponse.java      |  53 ++
 .../operations/DataLakeServiceOperations.java      |  42 ++
 .../datalake/component/DataLakeComponentTest.java  |  86 +++
 .../azure/storage/datalake/integration/BaseIT.java |  94 +++
 .../datalake/integration/DataLakeConsumerIT.java   | 224 +++++++
 .../integration/DataLakeFileOperationIT.java       | 135 ++++
 .../integration/DataLakeFileSystemOperationIT.java |  81 +++
 .../datalake/integration/DataLakeProducerIT.java   | 113 ++++
 .../operations/DataLakeDirectoryOperationTest.java |  81 +++
 .../operations/DataLakeFileOperationTest.java      | 110 ++++
 .../DataLakeFileSystemOperationTest.java           | 172 +++++
 .../src/test/resources/log4j2.properties           |  27 +
 .../camel-azure/camel-azure-storage-queue/pom.xml  | 109 ++++
 .../storage/queue/QueueComponentConfigurer.java    | 134 ++++
 .../storage/queue/QueueEndpointConfigurer.java     | 130 ++++
 .../storage/queue/QueueEndpointUriFactory.java     |  81 +++
 .../services/org/apache/camel/component.properties |   7 +
 .../org/apache/camel/component/azure-storage-queue |   2 +
 .../camel/configurer/azure-storage-queue-component |   2 +
 .../camel/configurer/azure-storage-queue-endpoint  |   2 +
 .../camel/urifactory/azure-storage-queue-endpoint  |   2 +
 .../azure/storage/queue/azure-storage-queue.json   |  62 ++
 .../main/docs/azure-storage-queue-component.adoc   | 412 ++++++++++++
 .../azure/storage/queue/QueueComponent.java        | 129 ++++
 .../azure/storage/queue/QueueConfiguration.java    | 246 ++++++++
 .../queue/QueueConfigurationOptionsProxy.java      |  94 +++
 .../azure/storage/queue/QueueConstants.java        |  42 ++
 .../azure/storage/queue/QueueConsumer.java         | 184 ++++++
 .../azure/storage/queue/QueueEndpoint.java         |  84 +++
 .../azure/storage/queue/QueueExchangeHeaders.java  | 140 +++++
 .../storage/queue/QueueOperationDefinition.java    |  31 +
 .../azure/storage/queue/QueueProducer.java         | 115 ++++
 .../storage/queue/client/QueueClientFactory.java   |  59 ++
 .../storage/queue/client/QueueClientWrapper.java   |  77 +++
 .../queue/client/QueueServiceClientWrapper.java    |  49 ++
 .../queue/operations/QueueOperationResponse.java   |  54 ++
 .../storage/queue/operations/QueueOperations.java  | 209 ++++++
 .../queue/operations/QueueServiceOperations.java   |  52 ++
 .../azure/storage/queue/QueueComponentTest.java    | 117 ++++
 .../queue/QueueConfigurationOptionsProxyTest.java  |  55 ++
 .../azure/storage/queue/QueueConsumerIT.java       | 113 ++++
 .../azure/storage/queue/QueueProducerIT.java       | 216 +++++++
 .../azure/storage/queue/QueueTestUtils.java        |  53 ++
 .../queue/operations/QueueOperationsIT.java        | 251 ++++++++
 .../queue/operations/QueueOperationsTest.java      | 117 ++++
 .../queue/operations/QueueServiceOperationsIT.java |  99 +++
 .../src/test/resources/log4j2.properties           |  27 +
 components/camel-azure/pom.xml                     |  42 ++
 154 files changed, 18158 insertions(+)

diff --git a/components/camel-azure/camel-azure-eventhubs/pom.xml b/components/camel-azure/camel-azure-eventhubs/pom.xml
new file mode 100644
index 0000000..d85540d
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/pom.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-azure-parent</artifactId>
+        <version>3.9.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-azure-eventhubs</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Camel :: Azure Event Hubs</name>
+    <description>Camel Azure Event Hubs Component</description>
+
+    <properties>
+      <camel.osgi.import.pkg>
+        !org.apache.camel.component.azure.eventhubs*,
+        reactor*;version="[3,4)",
+        ${camel.osgi.import.defaults},
+        *
+      </camel.osgi.import.pkg>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+
+        <!-- azure sdk -->
+        <dependency>
+            <groupId>com.azure</groupId>
+            <artifactId>azure-messaging-eventhubs</artifactId>
+            <version>${azure-eventhubs-java-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.azure</groupId>
+            <artifactId>azure-messaging-eventhubs-checkpointstore-blob</artifactId>
+            <version>${azure-eventhubs-checkpointstore-blob-version}</version>
+        </dependency>
+
+        <!-- extras -->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <!-- for testing -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${commons-lang3-version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <profiles>
+        <profile>
+            <id>fullTests</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <version>${maven-surefire-plugin-version}</version>
+                        <executions>
+                            <execution>
+                                <phase>integration-test</phase>
+                                <goals>
+                                    <goal>test</goal>
+                                </goals>
+                                <configuration>
+                                    <excludes>
+                                        <exclude>none</exclude>
+                                    </excludes>
+                                    <includes>
+                                        <include>**/*IT</include>
+                                    </includes>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/components/camel-azure/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentConfigurer.java b/components/camel-azure/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentConfigurer.java
new file mode 100644
index 0000000..47175fc
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentConfigurer.java
@@ -0,0 +1,182 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class EventHubsComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    private org.apache.camel.component.azure.eventhubs.EventHubsConfiguration getOrCreateConfiguration(EventHubsComponent target) {
+        if (target.getConfiguration() == null) {
+            target.setConfiguration(new org.apache.camel.component.azure.eventhubs.EventHubsConfiguration());
+        }
+        return target.getConfiguration();
+    }
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        EventHubsComponent target = (EventHubsComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "amqpretryoptions":
+        case "amqpRetryOptions": getOrCreateConfiguration(target).setAmqpRetryOptions(property(camelContext, com.azure.core.amqp.AmqpRetryOptions.class, value)); return true;
+        case "amqptransporttype":
+        case "amqpTransportType": getOrCreateConfiguration(target).setAmqpTransportType(property(camelContext, com.azure.core.amqp.AmqpTransportType.class, value)); return true;
+        case "autodiscoverclient":
+        case "autoDiscoverClient": getOrCreateConfiguration(target).setAutoDiscoverClient(property(camelContext, boolean.class, value)); return true;
+        case "autowiredenabled":
+        case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true;
+        case "blobaccesskey":
+        case "blobAccessKey": getOrCreateConfiguration(target).setBlobAccessKey(property(camelContext, java.lang.String.class, value)); return true;
+        case "blobaccountname":
+        case "blobAccountName": getOrCreateConfiguration(target).setBlobAccountName(property(camelContext, java.lang.String.class, value)); return true;
+        case "blobcontainername":
+        case "blobContainerName": getOrCreateConfiguration(target).setBlobContainerName(property(camelContext, java.lang.String.class, value)); return true;
+        case "blobstoragesharedkeycredential":
+        case "blobStorageSharedKeyCredential": getOrCreateConfiguration(target).setBlobStorageSharedKeyCredential(property(camelContext, com.azure.storage.common.StorageSharedKeyCredential.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "checkpointstore":
+        case "checkpointStore": getOrCreateConfiguration(target).setCheckpointStore(property(camelContext, com.azure.messaging.eventhubs.CheckpointStore.class, value)); return true;
+        case "configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.azure.eventhubs.EventHubsConfiguration.class, value)); return true;
+        case "connectionstring":
+        case "connectionString": getOrCreateConfiguration(target).setConnectionString(property(camelContext, java.lang.String.class, value)); return true;
+        case "consumergroupname":
+        case "consumerGroupName": getOrCreateConfiguration(target).setConsumerGroupName(property(camelContext, java.lang.String.class, value)); return true;
+        case "eventposition":
+        case "eventPosition": getOrCreateConfiguration(target).setEventPosition(property(camelContext, java.util.Map.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        case "partitionid":
+        case "partitionId": getOrCreateConfiguration(target).setPartitionId(property(camelContext, java.lang.String.class, value)); return true;
+        case "partitionkey":
+        case "partitionKey": getOrCreateConfiguration(target).setPartitionKey(property(camelContext, java.lang.String.class, value)); return true;
+        case "prefetchcount":
+        case "prefetchCount": getOrCreateConfiguration(target).setPrefetchCount(property(camelContext, int.class, value)); return true;
+        case "producerasyncclient":
+        case "producerAsyncClient": getOrCreateConfiguration(target).setProducerAsyncClient(property(camelContext, com.azure.messaging.eventhubs.EventHubProducerAsyncClient.class, value)); return true;
+        case "sharedaccesskey":
+        case "sharedAccessKey": getOrCreateConfiguration(target).setSharedAccessKey(property(camelContext, java.lang.String.class, value)); return true;
+        case "sharedaccessname":
+        case "sharedAccessName": getOrCreateConfiguration(target).setSharedAccessName(property(camelContext, java.lang.String.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "amqpretryoptions":
+        case "amqpRetryOptions": return com.azure.core.amqp.AmqpRetryOptions.class;
+        case "amqptransporttype":
+        case "amqpTransportType": return com.azure.core.amqp.AmqpTransportType.class;
+        case "autodiscoverclient":
+        case "autoDiscoverClient": return boolean.class;
+        case "autowiredenabled":
+        case "autowiredEnabled": return boolean.class;
+        case "blobaccesskey":
+        case "blobAccessKey": return java.lang.String.class;
+        case "blobaccountname":
+        case "blobAccountName": return java.lang.String.class;
+        case "blobcontainername":
+        case "blobContainerName": return java.lang.String.class;
+        case "blobstoragesharedkeycredential":
+        case "blobStorageSharedKeyCredential": return com.azure.storage.common.StorageSharedKeyCredential.class;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return boolean.class;
+        case "checkpointstore":
+        case "checkpointStore": return com.azure.messaging.eventhubs.CheckpointStore.class;
+        case "configuration": return org.apache.camel.component.azure.eventhubs.EventHubsConfiguration.class;
+        case "connectionstring":
+        case "connectionString": return java.lang.String.class;
+        case "consumergroupname":
+        case "consumerGroupName": return java.lang.String.class;
+        case "eventposition":
+        case "eventPosition": return java.util.Map.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        case "partitionid":
+        case "partitionId": return java.lang.String.class;
+        case "partitionkey":
+        case "partitionKey": return java.lang.String.class;
+        case "prefetchcount":
+        case "prefetchCount": return int.class;
+        case "producerasyncclient":
+        case "producerAsyncClient": return com.azure.messaging.eventhubs.EventHubProducerAsyncClient.class;
+        case "sharedaccesskey":
+        case "sharedAccessKey": return java.lang.String.class;
+        case "sharedaccessname":
+        case "sharedAccessName": return java.lang.String.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        EventHubsComponent target = (EventHubsComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "amqpretryoptions":
+        case "amqpRetryOptions": return getOrCreateConfiguration(target).getAmqpRetryOptions();
+        case "amqptransporttype":
+        case "amqpTransportType": return getOrCreateConfiguration(target).getAmqpTransportType();
+        case "autodiscoverclient":
+        case "autoDiscoverClient": return getOrCreateConfiguration(target).isAutoDiscoverClient();
+        case "autowiredenabled":
+        case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "blobaccesskey":
+        case "blobAccessKey": return getOrCreateConfiguration(target).getBlobAccessKey();
+        case "blobaccountname":
+        case "blobAccountName": return getOrCreateConfiguration(target).getBlobAccountName();
+        case "blobcontainername":
+        case "blobContainerName": return getOrCreateConfiguration(target).getBlobContainerName();
+        case "blobstoragesharedkeycredential":
+        case "blobStorageSharedKeyCredential": return getOrCreateConfiguration(target).getBlobStorageSharedKeyCredential();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "checkpointstore":
+        case "checkpointStore": return getOrCreateConfiguration(target).getCheckpointStore();
+        case "configuration": return target.getConfiguration();
+        case "connectionstring":
+        case "connectionString": return getOrCreateConfiguration(target).getConnectionString();
+        case "consumergroupname":
+        case "consumerGroupName": return getOrCreateConfiguration(target).getConsumerGroupName();
+        case "eventposition":
+        case "eventPosition": return getOrCreateConfiguration(target).getEventPosition();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        case "partitionid":
+        case "partitionId": return getOrCreateConfiguration(target).getPartitionId();
+        case "partitionkey":
+        case "partitionKey": return getOrCreateConfiguration(target).getPartitionKey();
+        case "prefetchcount":
+        case "prefetchCount": return getOrCreateConfiguration(target).getPrefetchCount();
+        case "producerasyncclient":
+        case "producerAsyncClient": return getOrCreateConfiguration(target).getProducerAsyncClient();
+        case "sharedaccesskey":
+        case "sharedAccessKey": return getOrCreateConfiguration(target).getSharedAccessKey();
+        case "sharedaccessname":
+        case "sharedAccessName": return getOrCreateConfiguration(target).getSharedAccessName();
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "eventposition":
+        case "eventPosition": return com.azure.messaging.eventhubs.models.EventPosition.class;
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-azure/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointConfigurer.java b/components/camel-azure/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointConfigurer.java
new file mode 100644
index 0000000..b57289f
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointConfigurer.java
@@ -0,0 +1,178 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class EventHubsEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        EventHubsEndpoint target = (EventHubsEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "amqpretryoptions":
+        case "amqpRetryOptions": target.getConfiguration().setAmqpRetryOptions(property(camelContext, com.azure.core.amqp.AmqpRetryOptions.class, value)); return true;
+        case "amqptransporttype":
+        case "amqpTransportType": target.getConfiguration().setAmqpTransportType(property(camelContext, com.azure.core.amqp.AmqpTransportType.class, value)); return true;
+        case "autodiscoverclient":
+        case "autoDiscoverClient": target.getConfiguration().setAutoDiscoverClient(property(camelContext, boolean.class, value)); return true;
+        case "blobaccesskey":
+        case "blobAccessKey": target.getConfiguration().setBlobAccessKey(property(camelContext, java.lang.String.class, value)); return true;
+        case "blobaccountname":
+        case "blobAccountName": target.getConfiguration().setBlobAccountName(property(camelContext, java.lang.String.class, value)); return true;
+        case "blobcontainername":
+        case "blobContainerName": target.getConfiguration().setBlobContainerName(property(camelContext, java.lang.String.class, value)); return true;
+        case "blobstoragesharedkeycredential":
+        case "blobStorageSharedKeyCredential": target.getConfiguration().setBlobStorageSharedKeyCredential(property(camelContext, com.azure.storage.common.StorageSharedKeyCredential.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "checkpointstore":
+        case "checkpointStore": target.getConfiguration().setCheckpointStore(property(camelContext, com.azure.messaging.eventhubs.CheckpointStore.class, value)); return true;
+        case "connectionstring":
+        case "connectionString": target.getConfiguration().setConnectionString(property(camelContext, java.lang.String.class, value)); return true;
+        case "consumergroupname":
+        case "consumerGroupName": target.getConfiguration().setConsumerGroupName(property(camelContext, java.lang.String.class, value)); return true;
+        case "eventposition":
+        case "eventPosition": target.getConfiguration().setEventPosition(property(camelContext, java.util.Map.class, value)); return true;
+        case "exceptionhandler":
+        case "exceptionHandler": target.setExceptionHandler(property(camelContext, org.apache.camel.spi.ExceptionHandler.class, value)); return true;
+        case "exchangepattern":
+        case "exchangePattern": target.setExchangePattern(property(camelContext, org.apache.camel.ExchangePattern.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        case "partitionid":
+        case "partitionId": target.getConfiguration().setPartitionId(property(camelContext, java.lang.String.class, value)); return true;
+        case "partitionkey":
+        case "partitionKey": target.getConfiguration().setPartitionKey(property(camelContext, java.lang.String.class, value)); return true;
+        case "prefetchcount":
+        case "prefetchCount": target.getConfiguration().setPrefetchCount(property(camelContext, int.class, value)); return true;
+        case "producerasyncclient":
+        case "producerAsyncClient": target.getConfiguration().setProducerAsyncClient(property(camelContext, com.azure.messaging.eventhubs.EventHubProducerAsyncClient.class, value)); return true;
+        case "sharedaccesskey":
+        case "sharedAccessKey": target.getConfiguration().setSharedAccessKey(property(camelContext, java.lang.String.class, value)); return true;
+        case "sharedaccessname":
+        case "sharedAccessName": target.getConfiguration().setSharedAccessName(property(camelContext, java.lang.String.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "amqpretryoptions":
+        case "amqpRetryOptions": return com.azure.core.amqp.AmqpRetryOptions.class;
+        case "amqptransporttype":
+        case "amqpTransportType": return com.azure.core.amqp.AmqpTransportType.class;
+        case "autodiscoverclient":
+        case "autoDiscoverClient": return boolean.class;
+        case "blobaccesskey":
+        case "blobAccessKey": return java.lang.String.class;
+        case "blobaccountname":
+        case "blobAccountName": return java.lang.String.class;
+        case "blobcontainername":
+        case "blobContainerName": return java.lang.String.class;
+        case "blobstoragesharedkeycredential":
+        case "blobStorageSharedKeyCredential": return com.azure.storage.common.StorageSharedKeyCredential.class;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return boolean.class;
+        case "checkpointstore":
+        case "checkpointStore": return com.azure.messaging.eventhubs.CheckpointStore.class;
+        case "connectionstring":
+        case "connectionString": return java.lang.String.class;
+        case "consumergroupname":
+        case "consumerGroupName": return java.lang.String.class;
+        case "eventposition":
+        case "eventPosition": return java.util.Map.class;
+        case "exceptionhandler":
+        case "exceptionHandler": return org.apache.camel.spi.ExceptionHandler.class;
+        case "exchangepattern":
+        case "exchangePattern": return org.apache.camel.ExchangePattern.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        case "partitionid":
+        case "partitionId": return java.lang.String.class;
+        case "partitionkey":
+        case "partitionKey": return java.lang.String.class;
+        case "prefetchcount":
+        case "prefetchCount": return int.class;
+        case "producerasyncclient":
+        case "producerAsyncClient": return com.azure.messaging.eventhubs.EventHubProducerAsyncClient.class;
+        case "sharedaccesskey":
+        case "sharedAccessKey": return java.lang.String.class;
+        case "sharedaccessname":
+        case "sharedAccessName": return java.lang.String.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        EventHubsEndpoint target = (EventHubsEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "amqpretryoptions":
+        case "amqpRetryOptions": return target.getConfiguration().getAmqpRetryOptions();
+        case "amqptransporttype":
+        case "amqpTransportType": return target.getConfiguration().getAmqpTransportType();
+        case "autodiscoverclient":
+        case "autoDiscoverClient": return target.getConfiguration().isAutoDiscoverClient();
+        case "blobaccesskey":
+        case "blobAccessKey": return target.getConfiguration().getBlobAccessKey();
+        case "blobaccountname":
+        case "blobAccountName": return target.getConfiguration().getBlobAccountName();
+        case "blobcontainername":
+        case "blobContainerName": return target.getConfiguration().getBlobContainerName();
+        case "blobstoragesharedkeycredential":
+        case "blobStorageSharedKeyCredential": return target.getConfiguration().getBlobStorageSharedKeyCredential();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "checkpointstore":
+        case "checkpointStore": return target.getConfiguration().getCheckpointStore();
+        case "connectionstring":
+        case "connectionString": return target.getConfiguration().getConnectionString();
+        case "consumergroupname":
+        case "consumerGroupName": return target.getConfiguration().getConsumerGroupName();
+        case "eventposition":
+        case "eventPosition": return target.getConfiguration().getEventPosition();
+        case "exceptionhandler":
+        case "exceptionHandler": return target.getExceptionHandler();
+        case "exchangepattern":
+        case "exchangePattern": return target.getExchangePattern();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        case "partitionid":
+        case "partitionId": return target.getConfiguration().getPartitionId();
+        case "partitionkey":
+        case "partitionKey": return target.getConfiguration().getPartitionKey();
+        case "prefetchcount":
+        case "prefetchCount": return target.getConfiguration().getPrefetchCount();
+        case "producerasyncclient":
+        case "producerAsyncClient": return target.getConfiguration().getProducerAsyncClient();
+        case "sharedaccesskey":
+        case "sharedAccessKey": return target.getConfiguration().getSharedAccessKey();
+        case "sharedaccessname":
+        case "sharedAccessName": return target.getConfiguration().getSharedAccessName();
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "eventposition":
+        case "eventPosition": return com.azure.messaging.eventhubs.models.EventPosition.class;
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-azure/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointUriFactory.java b/components/camel-azure/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointUriFactory.java
new file mode 100644
index 0000000..272f4ab
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointUriFactory.java
@@ -0,0 +1,89 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.spi.EndpointUriFactory;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+public class EventHubsEndpointUriFactory extends org.apache.camel.support.component.EndpointUriFactorySupport implements EndpointUriFactory {
+
+    private static final String BASE = ":namespace/eventHubName";
+
+    private static final Set<String> PROPERTY_NAMES;
+    private static final Set<String> SECRET_PROPERTY_NAMES;
+    static {
+        Set<String> props = new HashSet<>(23);
+        props.add("blobStorageSharedKeyCredential");
+        props.add("connectionString");
+        props.add("autoDiscoverClient");
+        props.add("prefetchCount");
+        props.add("sharedAccessKey");
+        props.add("sharedAccessName");
+        props.add("partitionId");
+        props.add("checkpointStore");
+        props.add("exchangePattern");
+        props.add("amqpTransportType");
+        props.add("consumerGroupName");
+        props.add("eventPosition");
+        props.add("lazyStartProducer");
+        props.add("blobAccountName");
+        props.add("bridgeErrorHandler");
+        props.add("producerAsyncClient");
+        props.add("partitionKey");
+        props.add("namespace");
+        props.add("amqpRetryOptions");
+        props.add("blobContainerName");
+        props.add("eventHubName");
+        props.add("exceptionHandler");
+        props.add("blobAccessKey");
+        PROPERTY_NAMES = Collections.unmodifiableSet(props);
+        Set<String> secretProps = new HashSet<>(4);
+        secretProps.add("blobStorageSharedKeyCredential");
+        secretProps.add("connectionString");
+        secretProps.add("sharedAccessKey");
+        secretProps.add("blobAccessKey");
+        SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps);
+    }
+
+    @Override
+    public boolean isEnabled(String scheme) {
+        return "azure-eventhubs".equals(scheme);
+    }
+
+    @Override
+    public String buildUri(String scheme, Map<String, Object> properties, boolean encode) throws URISyntaxException {
+        String syntax = scheme + BASE;
+        String uri = syntax;
+
+        Map<String, Object> copy = new HashMap<>(properties);
+
+        uri = buildPathParameter(syntax, uri, "namespace", null, false, copy);
+        uri = buildPathParameter(syntax, uri, "eventHubName", null, false, copy);
+        uri = buildQueryParameters(uri, copy, encode);
+        return uri;
+    }
+
+    @Override
+    public Set<String> propertyNames() {
+        return PROPERTY_NAMES;
+    }
+
+    @Override
+    public Set<String> secretPropertyNames() {
+        return SECRET_PROPERTY_NAMES;
+    }
+
+    @Override
+    public boolean isLenientProperties() {
+        return false;
+    }
+}
+
diff --git a/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component.properties b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component.properties
new file mode 100644
index 0000000..ee00325
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+components=azure-eventhubs
+groupId=org.apache.camel
+artifactId=camel-azure-eventhubs
+version=3.9.0-SNAPSHOT
+projectName=Camel :: Azure Event Hubs
+projectDescription=Camel Azure Event Hubs Component
diff --git a/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component/azure-eventhubs b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component/azure-eventhubs
new file mode 100644
index 0000000..bf24c2f
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component/azure-eventhubs
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.azure.eventhubs.EventHubsComponent
diff --git a/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-component b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-component
new file mode 100644
index 0000000..927b28a
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-component
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.azure.eventhubs.EventHubsComponentConfigurer
diff --git a/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-endpoint b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-endpoint
new file mode 100644
index 0000000..d500a7e
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.azure.eventhubs.EventHubsEndpointConfigurer
diff --git a/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-eventhubs-endpoint b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-eventhubs-endpoint
new file mode 100644
index 0000000..e865df1
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-eventhubs-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.azure.eventhubs.EventHubsEndpointUriFactory
diff --git a/components/camel-azure/camel-azure-eventhubs/src/generated/resources/org/apache/camel/component/azure/eventhubs/azure-eventhubs.json b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/org/apache/camel/component/azure/eventhubs/azure-eventhubs.json
new file mode 100644
index 0000000..3822400
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/generated/resources/org/apache/camel/component/azure/eventhubs/azure-eventhubs.json
@@ -0,0 +1,72 @@
+{
+  "component": {
+    "kind": "component",
+    "name": "azure-eventhubs",
+    "title": "Azure Event Hubs",
+    "description": "The azure-eventhubs component that integrates Azure Event Hubs using AMQP protocol. Azure EventHubs is a highly scalable publish-subscribe service that can ingest millions of events per second and stream them to multiple consumers.",
+    "deprecated": false,
+    "firstVersion": "3.5.0",
+    "label": "cloud,messaging",
+    "javaType": "org.apache.camel.component.azure.eventhubs.EventHubsComponent",
+    "supportLevel": "Stable",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-azure-eventhubs",
+    "version": "3.9.0-SNAPSHOT",
+    "scheme": "azure-eventhubs",
+    "extendsScheme": "",
+    "syntax": "azure-eventhubs:namespace\/eventHubName",
+    "async": false,
+    "api": false,
+    "consumerOnly": false,
+    "producerOnly": false,
+    "lenientProperties": false
+  },
+  "componentProperties": {
+    "amqpRetryOptions": { "kind": "property", "displayName": "Amqp Retry Options", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "com.azure.core.amqp.AmqpRetryOptions", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the retry policy for EventHubAsyncClient. If not specified, the default r [...]
+    "amqpTransportType": { "kind": "property", "displayName": "Amqp Transport Type", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "com.azure.core.amqp.AmqpTransportType", "enum": [ "Amqp", "AmqpWebSockets" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "AMQP", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the tran [...]
+    "autoDiscoverClient": { "kind": "property", "displayName": "Auto Discover Client", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Setting the autoDiscoverClient mechanism, if true, the component will look for a [...]
+    "configuration": { "kind": "property", "displayName": "Configuration", "group": "common", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "deprecated": false, "autowired": false, "secret": false, "description": "The component configurations" },
+    "blobAccessKey": { "kind": "property", "displayName": "Blob Access Key", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets access key for the associated azure acco [...]
+    "blobAccountName": { "kind": "property", "displayName": "Blob Account Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for a [...]
+    "blobContainerName": { "kind": "property", "displayName": "Blob Container Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets the blob container that shall b [...]
+    "blobStorageSharedKeyCredential": { "kind": "property", "displayName": "Blob Storage Shared Key Credential", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "com.azure.storage.common.StorageSharedKeyCredential", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default  [...]
+    "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a me [...]
+    "checkpointStore": { "kind": "property", "displayName": "Checkpoint Store", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "com.azure.messaging.eventhubs.CheckpointStore", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "BlobCheckpointStore", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the CheckpointStore the  [...]
+    "consumerGroupName": { "kind": "property", "displayName": "Consumer Group Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "$Default", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the name of the consumer group this consumer is associated  [...]
+    "eventPosition": { "kind": "property", "displayName": "Event Position", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, com.azure.messaging.eventhubs.models.EventPosition>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the map containing the event  [...]
+    "prefetchCount": { "kind": "property", "displayName": "Prefetch Count", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 500, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the count used by the receiver to control the number of events the Event Hub consumer w [...]
+    "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during star [...]
+    "partitionId": { "kind": "property", "displayName": "Partition Id", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the identifier of the Event Hub partition that the events will be sent to. If the identifier is not  [...]
+    "partitionKey": { "kind": "property", "displayName": "Partition Key", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to ma [...]
+    "producerAsyncClient": { "kind": "property", "displayName": "Producer Async Client", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "com.azure.messaging.eventhubs.EventHubProducerAsyncClient", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the EventHubProducerAsyncClient.An asynchr [...]
+    "autowiredEnabled": { "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which t [...]
+    "connectionString": { "kind": "property", "displayName": "Connection String", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply t [...]
+    "sharedAccessKey": { "kind": "property", "displayName": "Shared Access Key", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "The generated value for the SharedAccessName" },
+    "sharedAccessName": { "kind": "property", "displayName": "Shared Access Name", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "The name you chose for your EventHubs SAS keys" }
+  },
+  "properties": {
+    "namespace": { "kind": "path", "displayName": "Namespace", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "EventHubs namespace created in Azure Portal" },
+    "eventHubName": { "kind": "path", "displayName": "Event Hub Name", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "EventHubs name under a specific namcespace" },
+    "amqpRetryOptions": { "kind": "parameter", "displayName": "Amqp Retry Options", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "com.azure.core.amqp.AmqpRetryOptions", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the retry policy for EventHubAsyncClient. If not specified, the default  [...]
+    "amqpTransportType": { "kind": "parameter", "displayName": "Amqp Transport Type", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "com.azure.core.amqp.AmqpTransportType", "enum": [ "Amqp", "AmqpWebSockets" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "AMQP", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the tra [...]
+    "autoDiscoverClient": { "kind": "parameter", "displayName": "Auto Discover Client", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Setting the autoDiscoverClient mechanism, if true, the component will look for  [...]
+    "blobAccessKey": { "kind": "parameter", "displayName": "Blob Access Key", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets access key for the associated azure acc [...]
+    "blobAccountName": { "kind": "parameter", "displayName": "Blob Account Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for  [...]
+    "blobContainerName": { "kind": "parameter", "displayName": "Blob Container Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets the blob container that shall  [...]
+    "blobStorageSharedKeyCredential": { "kind": "parameter", "displayName": "Blob Storage Shared Key Credential", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "com.azure.storage.common.StorageSharedKeyCredential", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default [...]
+    "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a m [...]
+    "checkpointStore": { "kind": "parameter", "displayName": "Checkpoint Store", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "com.azure.messaging.eventhubs.CheckpointStore", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "BlobCheckpointStore", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the CheckpointStore the [...]
+    "consumerGroupName": { "kind": "parameter", "displayName": "Consumer Group Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "$Default", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the name of the consumer group this consumer is associated [...]
+    "eventPosition": { "kind": "parameter", "displayName": "Event Position", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, com.azure.messaging.eventhubs.models.EventPosition>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the map containing the event [...]
+    "prefetchCount": { "kind": "parameter", "displayName": "Prefetch Count", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 500, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the count used by the receiver to control the number of events the Event Hub consumer  [...]
+    "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the con [...]
+    "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during sta [...]
+    "partitionId": { "kind": "parameter", "displayName": "Partition Id", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the identifier of the Event Hub partition that the events will be sent to. If the identifier is not [...]
+    "partitionKey": { "kind": "parameter", "displayName": "Partition Key", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to m [...]
+    "producerAsyncClient": { "kind": "parameter", "displayName": "Producer Async Client", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "com.azure.messaging.eventhubs.EventHubProducerAsyncClient", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the EventHubProducerAsyncClient.An asynch [...]
+    "connectionString": { "kind": "parameter", "displayName": "Connection String", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply  [...]
+    "sharedAccessKey": { "kind": "parameter", "displayName": "Shared Access Key", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "The generated value for the SharedAccessName" },
+    "sharedAccessName": { "kind": "parameter", "displayName": "Shared Access Name", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "The name you chose for your EventHubs SAS keys" }
+  }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/docs/azure-eventhubs-component.adoc b/components/camel-azure/camel-azure-eventhubs/src/main/docs/azure-eventhubs-component.adoc
new file mode 100644
index 0000000..13cd941
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/docs/azure-eventhubs-component.adoc
@@ -0,0 +1,254 @@
+[[azure-eventhubs-component]]
+= Azure Event Hubs Component
+:docTitle: Azure Event Hubs
+:artifactId: camel-azure-eventhubs
+:description: The azure-eventhubs component that integrates Azure Event Hubs using AMQP protocol. Azure EventHubs is a highly scalable publish-subscribe service that can ingest millions of events per second and stream them to multiple consumers.
+:since: 3.5
+:supportLevel: Stable
+:component-header: Both producer and consumer are supported
+include::{cq-version}@camel-quarkus:ROOT:partial$reference/components/azure-eventhubs.adoc[opts=optional]
+//Manually maintained attributes
+:group: Azure
+
+*Since Camel {since}*
+
+*{component-header}*
+
+The Azure Event Hubs used to integrate https://azure.microsoft.com/en-us/services/event-hubs/[Azure Event Hubs] using https://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol[AMQP protocol].
+Azure EventHubs is a highly scalable publish-subscribe service that can ingest millions of events per second and stream them to multiple consumers.
+
+NOTE: Besides AMQP protocol support, Event Hubs as well supports Kafka and HTTPS protocols. Therefore, you can use as well xref:components::kafka-component.adoc[Camel Kafka] component to produce and consume to Azure Event Hubs. You can lean more https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-quickstart-kafka-enabled-event-hubs[here].
+
+
+Prerequisites
+
+You must have a valid Windows Azure Event Hubs 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-eventhubs</artifactId>
+    <version>x.x.x</version>
+  <!-- use the same version as your Camel core version -->
+</dependency>
+------------------------------------------------------------
+
+== URI Format
+
+[source,text]
+------------------------------
+azure-eventhubs://[namespace/eventHubName][?options]
+------------------------------
+
+In case you supply the `connectionString`, `namespace` and `eventHubName` are not required as these options already included
+in the `connectionString`
+
+For example in order consume event from EventHub, use the following snippet:
+[source,java]
+--------------------------------------------------------------------------------
+from("azure-eventhubs:/camel/camelHub?sharedAccessName=SASaccountName&sharedAccessKey=SASaccessKey&blobAccountName=accountName&blobAccessKey=accessKey&blobContainerName=containerName").
+to("file://queuedirectory");
+--------------------------------------------------------------------------------
+
+== URI Options
+
+// endpoint options: START
+The Azure Event Hubs endpoint is configured using URI syntax:
+
+----
+azure-eventhubs:namespace/eventHubName
+----
+
+with the following path and query parameters:
+
+=== Path Parameters (2 parameters):
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *namespace* | EventHubs namespace created in Azure Portal |  | String
+| *eventHubName* | EventHubs name under a specific namcespace |  | String
+|===
+
+
+=== Query Parameters (21 parameters):
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *amqpRetryOptions* (common) | Sets the retry policy for EventHubAsyncClient. If not specified, the default retry options are used. |  | AmqpRetryOptions
+| *amqpTransportType* (common) | Sets the transport type by which all the communication with Azure Event Hubs occurs. Default value is AmqpTransportType#AMQP. There are 2 enums and the value can be one of: Amqp, AmqpWebSockets | AMQP | AmqpTransportType
+| *autoDiscoverClient* (common) | Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry automatically otherwise it will skip that checking. | true | boolean
+| *blobAccessKey* (consumer) | In case you chose the default BlobCheckpointStore, this sets access key for the associated azure account name to be used for authentication with azure blob services |  | String
+| *blobAccountName* (consumer) | In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for authentication with azure blob services. |  | String
+| *blobContainerName* (consumer) | In case you chose the default BlobCheckpointStore, this sets the blob container that shall be used by the BlobCheckpointStore to store the checkpoint offsets |  | String
+| *blobStorageSharedKeyCredential* (consumer) | In case you chose the default BlobCheckpointStore, StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication information |  | StorageSharedKeyCredential
+| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
+| *checkpointStore* (consumer) | Sets the CheckpointStore the EventProcessorClient will use for storing partition ownership and checkpoint information. Users can, optionally, provide their own implementation of CheckpointStore which will store ownership and checkpoint information. By default it set to use com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore which stores all checkpoint offsets into Azure Blob Storage | BlobCheckpointStore | CheckpointStore
+| *consumerGroupName* (consumer) | Sets the name of the consumer group this consumer is associated with. Events are read in the context of this group. The name of the consumer group that is created by default is {link #DEFAULT_CONSUMER_GROUP_NAME $Default}. | $Default | String
+| *eventPosition* (consumer) | Sets the map containing the event position to use for each partition if a checkpoint for the partition does not exist in CheckpointStore. This map is keyed off of the partition id. If there is no checkpoint in CheckpointStore and there is no entry in this map, the processing of the partition will start from {link EventPosition#latest() latest} position. |  | Map
+| *prefetchCount* (consumer) | Sets the count used by the receiver to control the number of events the Event Hub consumer will actively receive and queue locally without regard to whether a receive operation is currently active. | 500 | int
+| *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
+| *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
+| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
+| *partitionId* (producer) | Sets the identifier of the Event Hub partition that the events will be sent to. If the identifier is not specified, the Event Hubs service will be responsible for routing events that are sent to an available partition. |  | String
+| *partitionKey* (producer) | Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to map this key to a specific partition. The selection of a partition is stable for a given partition hashing key. Should any other batches of events be sent using the same exact partition hashing key, the Event Hubs service will route them all to the same partition. This should be specified only when there is a need to group events by partition, but there is fl [...]
+| *producerAsyncClient* (producer) | Sets the EventHubProducerAsyncClient.An asynchronous producer responsible for transmitting EventData to a specific Event Hub, grouped together in batches. Depending on the options specified when creating an \{linkEventDataBatch}, the events may be automatically routed to an available partition or specific to a partition. Use by this component to produce the data in camel producer. |  | EventHubProducerAsyncClient
+| *connectionString* (security) | Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply the connection string for your eventHub. The connection string for EventHubs already include all the necessary information to connection to your EventHub. To learn on how to generate the connection string, take a look at this documentation: \https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string |  | String
+| *sharedAccessKey* (security) | The generated value for the SharedAccessName |  | String
+| *sharedAccessName* (security) | The name you chose for your EventHubs SAS keys |  | String
+|===
+// endpoint options: END
+
+// component options: START
+The Azure Event Hubs component supports 21 options, which are listed below.
+
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *amqpRetryOptions* (common) | Sets the retry policy for EventHubAsyncClient. If not specified, the default retry options are used. |  | AmqpRetryOptions
+| *amqpTransportType* (common) | Sets the transport type by which all the communication with Azure Event Hubs occurs. Default value is AmqpTransportType#AMQP. There are 2 enums and the value can be one of: Amqp, AmqpWebSockets | AMQP | AmqpTransportType
+| *autoDiscoverClient* (common) | Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry automatically otherwise it will skip that checking. | true | boolean
+| *configuration* (common) | The component configurations |  | EventHubsConfiguration
+| *blobAccessKey* (consumer) | In case you chose the default BlobCheckpointStore, this sets access key for the associated azure account name to be used for authentication with azure blob services |  | String
+| *blobAccountName* (consumer) | In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for authentication with azure blob services. |  | String
+| *blobContainerName* (consumer) | In case you chose the default BlobCheckpointStore, this sets the blob container that shall be used by the BlobCheckpointStore to store the checkpoint offsets |  | String
+| *blobStorageSharedKeyCredential* (consumer) | In case you chose the default BlobCheckpointStore, StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication information |  | StorageSharedKeyCredential
+| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
+| *checkpointStore* (consumer) | Sets the CheckpointStore the EventProcessorClient will use for storing partition ownership and checkpoint information. Users can, optionally, provide their own implementation of CheckpointStore which will store ownership and checkpoint information. By default it set to use com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore which stores all checkpoint offsets into Azure Blob Storage | BlobCheckpointStore | CheckpointStore
+| *consumerGroupName* (consumer) | Sets the name of the consumer group this consumer is associated with. Events are read in the context of this group. The name of the consumer group that is created by default is {link #DEFAULT_CONSUMER_GROUP_NAME $Default}. | $Default | String
+| *eventPosition* (consumer) | Sets the map containing the event position to use for each partition if a checkpoint for the partition does not exist in CheckpointStore. This map is keyed off of the partition id. If there is no checkpoint in CheckpointStore and there is no entry in this map, the processing of the partition will start from {link EventPosition#latest() latest} position. |  | Map
+| *prefetchCount* (consumer) | Sets the count used by the receiver to control the number of events the Event Hub consumer will actively receive and queue locally without regard to whether a receive operation is currently active. | 500 | int
+| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
+| *partitionId* (producer) | Sets the identifier of the Event Hub partition that the events will be sent to. If the identifier is not specified, the Event Hubs service will be responsible for routing events that are sent to an available partition. |  | String
+| *partitionKey* (producer) | Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to map this key to a specific partition. The selection of a partition is stable for a given partition hashing key. Should any other batches of events be sent using the same exact partition hashing key, the Event Hubs service will route them all to the same partition. This should be specified only when there is a need to group events by partition, but there is fl [...]
+| *producerAsyncClient* (producer) | Sets the EventHubProducerAsyncClient.An asynchronous producer responsible for transmitting EventData to a specific Event Hub, grouped together in batches. Depending on the options specified when creating an \{linkEventDataBatch}, the events may be automatically routed to an available partition or specific to a partition. Use by this component to produce the data in camel producer. |  | EventHubProducerAsyncClient
+| *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which then gets configured on the component. This can be used for automatic configuring JDBC data sources, JMS connection factories, AWS Clients, etc. | true | boolean
+| *connectionString* (security) | Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply the connection string for your eventHub. The connection string for EventHubs already include all the necessary information to connection to your EventHub. To learn on how to generate the connection string, take a look at this documentation: \https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string |  | String
+| *sharedAccessKey* (security) | The generated value for the SharedAccessName |  | String
+| *sharedAccessName* (security) | The name you chose for your EventHubs SAS keys |  | String
+|===
+// component options: END
+
+
+== Authentication Information
+
+To use this component, you have 3 options in order to provide the required Azure authentication information:
+
+- Provide `sharedAccessName` and `sharedAccessKey` for your Azure Event Hubs account. The sharedAccessKey can
+be generated through your Event Hubs Azure portal.
+- Provide `connectionString` string, if you provide the connection string, you don't supply `namespace`, `eventHubName`, `sharedAccessKey` and `sharedAccessName`
+as these data already included in the `connectionString`, therefore is the simplest option to get started. Learn more https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string[here] on how to generate the connection string.
+- Provide a https://docs.microsoft.com/en-us/java/api/com.azure.messaging.eventhubs.eventhubproducerasyncclient?view=azure-java-stable[EventHubProducerAsyncClient] instance which can be
+provided into `producerAsyncClient`. However, this is *only possible for camel producer*, for the camel consumer, is not possible to inject the client due to some design constrain by the `EventProcessorClient`.
+
+
+== Checkpoint Store Information
+A checkpoint store stores and retrieves partition ownership information and checkpoint details for each partition in a given consumer group of an event hub instance. Users are not meant to implement an CheckpointStore.
+Users are expected to choose existing implementations of this interface, instantiate it, and pass it to the component through `checkpointStore` option.
+Users are not expected to use any of the methods on a checkpoint store, these are used internally by the client.
+
+Having said that, if the user does not pass any `CheckpointStore` implementation, the component will fallback to use https://docs.microsoft.com/en-us/javascript/api/@azure/eventhubs-checkpointstore-blob/blobcheckpointstore?view=azure-node-latest[`BlobCheckpointStore`] to store the checkpoint info in Azure Blob Storage account.
+If you chose to use the default `BlobCheckpointStore`, you will need to supply the following options:
+
+- `blobAccountName`: It sets Azure account name to be used for authentication with azure blob services.
+- `blobAccessKey` : It sets access key for the associated azure account name to be used for authentication with azure blob services.
+- `blobContainerName` : It sets the blob container that shall be used by the BlobCheckpointStore to store the checkpoint offsets.
+
+
+== Async Consumer and Producer
+
+This component implements the async Consumer and producer.
+
+This allows camel route to consume and produce events asynchronously without blocking any threads.
+
+
+== Usage
+
+=== Message headers evaluated by the component producer
+[width="100%",cols="10%,10%,10%,70%",options="header",]
+|=======================================================================
+|Header |Variable Name |Type |Description
+
+|`CamelAzureEventHubsPartitionKey`| `EventHubsConstants.PARTITION_KEY`|`String`| Overrides the hashing key to be provided for the batch of events, which instructs the Event Hubs service to map this key to a specific partition.
+|`CamelAzureEventHubsPartitionId`| `EventHubsConstants.PARTITION_ID`|`String`| Overrides the identifier of the Event Hub partition that the {link EventData events} will be sent to.
+|=======================================================================
+
+
+=== Message headers set by the component consumer
+[width="100%",cols="10%,10%,10%,70%",options="header",]
+|=======================================================================
+|Header |Variable Name |Type |Description
+
+|`CamelAzureEventHubsPartitionKey`| `EventHubsConstants.PARTITION_KEY`|`String`| It sets the partition hashing key if it was set when originally publishing the event. If it exists, this value was used to compute a hash to select a partition to send the message to. This is only present on a received {@link EventData}.
+|`CamelAzureEventHubsPartitionId`| `EventHubsConstants.PARTITION_ID`|`String`| It sets the partition id of the Event Hub.
+|`CamelAzureEventHubsOffset`| `EventHubsConstants.OFFSET`|`Long`| It sets the offset of the event when it was received from the associated Event Hub partition. This is only present on a received {@link EventData}.
+|`CamelAzureEventHubsEnqueuedTime`| `EventHubsConstants.ENQUEUED_TIME`|`Instant`| It sets the instant, in UTC, of when the event was enqueued in the Event Hub partition. This is only present on a received {@link EventData}.
+|`CamelAzureEventHubsSequenceNumber`| `EventHubsConstants.SEQUENCE_NUMBER`|`Long`| It sets the sequence number assigned to the event when it was enqueued in the associated Event Hub partition. This is unique for every message received in the Event Hub partition. This is only present on a received {@link EventData}.
+|=======================================================================
+
+=== Message body type
+The component's producer expects the data in the message body to be in `byte[]`. This allows the user to utilize Camel TypeConverter to marshal/unmarshal data with ease.
+The same goes as well for the component's consumer, it will set the encoded data as `byte[]` in the message body.
+
+
+=== Automatic detection of EventHubProducerAsyncClient client in registry
+
+The component is capable of detecting the presence of an EventHubProducerAsyncClient bean into the registry.
+If it's the only instance of that type it will be used as 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.
+
+=== Consumer Example
+The example below will unmarshal the events that was originally produced in JSON:
+```
+from("azure-eventhubs:?connectionString=RAW({{connectionString}})"&blobContainerName=containerTest&eventPosition=#eventPosition"
+    +"&blobAccountName={{blobAccountName}}&blobAccessKey=RAW({{blobAccessKey}})")
+.unmarshal().json(JsonLibrary.Jackson)
+.to(result);
+```
+
+=== Producer Example
+The example below will send events as String to EventHubs:
+```
+from("direct:start")
+.process(exchange -> {
+        exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
+        exchange.getIn().setBody("test event");
+})
+.to("azure-eventhubs:?connectionString=RAW({{connectionString}})"
+```
+
+Also, the component supports as well *aggregation* of messages by sending events as *iterable* of either Exchanges/Messages or normal data (e.g: list of Strings). For example:
+```
+from("direct:start")
+.process(exchange -> {
+        final List<String> messages = new LinkedList<>();
+        messages.add("Test String Message 1");
+        messages.add("Test String Message 2");
+
+        exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
+        exchange.getIn().setBody(messages);
+})
+.to("azure-eventhubs:?connectionString=RAW({{connectionString}})"
+```
+
+=== Development Notes (Important)
+When developing on this component, you will need to obtain your Azure accessKey in order to run the integration tests. 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:
+----
+mvn verify -PfullTests -DconnectionString=string -DblobAccountName=blob -DblobAccessKey=key
+----
+Whereby `blobAccountName` is your Azure account name and `blobAccessKey` is the access key being generated from Azure portal and `connectionString` is the eventHub connection string.
+
+
+include::camel-spring-boot::page$azure-eventhubs-starter.adoc[]
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsComponent.java b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsComponent.java
new file mode 100644
index 0000000..d87ce3a
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsComponent.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
+import org.apache.camel.Endpoint;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.annotations.Component;
+import org.apache.camel.support.DefaultComponent;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Azure EventHubs component
+ */
+@Component("azure-eventhubs")
+public class EventHubsComponent extends DefaultComponent {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EventHubsComponent.class);
+
+    @Metadata
+    private EventHubsConfiguration configuration = new EventHubsConfiguration();
+
+    public EventHubsComponent() {
+    }
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+
+        final EventHubsConfiguration configuration
+                = this.configuration != null ? this.configuration.copy() : new EventHubsConfiguration();
+
+        final EventHubsEndpoint endpoint = new EventHubsEndpoint(uri, this, configuration);
+        setProperties(endpoint, parameters);
+
+        if (configuration.isAutoDiscoverClient()) {
+            checkAndSetRegistryClient(configuration::setProducerAsyncClient, configuration::getProducerAsyncClient,
+                    EventHubProducerAsyncClient.class);
+        }
+
+        // if we don't have client nor connectionString, we check for params
+        if (areAzureClientsNotSet(configuration) && ObjectHelper.isEmpty(configuration.getConnectionString())) {
+            checkAndSetNamespaceAndHubName(configuration, remaining);
+            validateConfigurations(configuration);
+        }
+
+        return endpoint;
+    }
+
+    /**
+     * The component configurations
+     */
+    public EventHubsConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(EventHubsConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    private <C> void checkAndSetRegistryClient(
+            final Consumer<C> setClientFn, final Supplier<C> getClientFn, final Class<C> clientType) {
+        if (ObjectHelper.isEmpty(getClientFn.get())) {
+            final Set<C> clients = getCamelContext().getRegistry().findByType(clientType);
+            if (clients.size() == 1) {
+                setClientFn.accept(clients.stream().findFirst().get());
+            } else if (clients.size() > 1) {
+                LOG.info(String.format("More than one %s instance in the registry, make sure to have only one instance",
+                        clientType.getSimpleName()));
+            } else {
+                LOG.info(String.format("No %s instance in the registry", clientType.getSimpleName()));
+            }
+        } else {
+            LOG.info(String.format("%s instance is already set at endpoint level: skipping the check in the registry",
+                    clientType.getSimpleName()));
+        }
+    }
+
+    private void validateConfigurations(final EventHubsConfiguration configuration) {
+        if (!isAccessKeyAndAccessNameSet(configuration)) {
+            throw new IllegalArgumentException(
+                    "Azure EventHubs SharedAccessName/SharedAccessKey, ConsumerAsyncClient/ProducerAsyncClient "
+                                               + "or connectionString must be specified.");
+        }
+    }
+
+    private boolean isAccessKeyAndAccessNameSet(final EventHubsConfiguration configuration) {
+        return ObjectHelper.isNotEmpty(configuration.getSharedAccessName())
+                && ObjectHelper.isNotEmpty(configuration.getSharedAccessKey());
+    }
+
+    private boolean areAzureClientsNotSet(final EventHubsConfiguration configuration) {
+        return ObjectHelper.isEmpty(configuration.getProducerAsyncClient());
+    }
+
+    private void checkAndSetNamespaceAndHubName(final EventHubsConfiguration configuration, final String remaining) {
+        // only set if clients are empty and remaining exists
+        if (ObjectHelper.isEmpty(remaining)) {
+            throw new IllegalArgumentException("ConnectionString, AzureClients or Namespace and EventHub name must be set");
+        }
+
+        final String[] parts = remaining.split("/");
+
+        if (parts.length < 2) {
+            throw new IllegalArgumentException("ConnectionString, AzureClients or Namespace and EventHub name must be set");
+        }
+        configuration.setNamespace(parts[0]);
+        configuration.setEventHubName(parts[1]);
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfiguration.java b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfiguration.java
new file mode 100644
index 0000000..526c609
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfiguration.java
@@ -0,0 +1,337 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.azure.core.amqp.AmqpRetryOptions;
+import com.azure.core.amqp.AmqpTransportType;
+import com.azure.messaging.eventhubs.CheckpointStore;
+import com.azure.messaging.eventhubs.EventData;
+import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
+import com.azure.messaging.eventhubs.EventProcessorClient;
+import com.azure.messaging.eventhubs.models.EventPosition;
+import com.azure.storage.common.StorageSharedKeyCredential;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.spi.UriPath;
+
+@UriParams
+public class EventHubsConfiguration implements Cloneable {
+
+    @UriPath
+    private String namespace;
+    @UriPath
+    private String eventHubName;
+    @UriParam(label = "security")
+    private String sharedAccessName;
+    @UriParam(label = "security", secret = true)
+    private String sharedAccessKey;
+    @UriParam(label = "security", secret = true)
+    private String connectionString;
+    @UriParam(label = "common", defaultValue = "AMQP")
+    private AmqpTransportType amqpTransportType = AmqpTransportType.AMQP;
+    @UriParam(label = "common")
+    private AmqpRetryOptions amqpRetryOptions;
+    @UriParam(label = "common", defaultValue = "true")
+    private boolean autoDiscoverClient = true;
+    @UriParam(label = "consumer", defaultValue = "$Default")
+    private String consumerGroupName = "$Default";
+    @UriParam(label = "consumer", defaultValue = "500")
+    private int prefetchCount = 500;
+    @UriParam(label = "consumer", defaultValue = "BlobCheckpointStore")
+    private CheckpointStore checkpointStore;
+    @UriParam(label = "consumer")
+    private String blobAccountName;
+    @UriParam(label = "consumer", secret = true)
+    private String blobAccessKey;
+    @UriParam(label = "consumer")
+    private String blobContainerName;
+    @UriParam(label = "consumer", secret = true)
+    private StorageSharedKeyCredential blobStorageSharedKeyCredential;
+    @UriParam(label = "consumer")
+    private Map<String, EventPosition> eventPosition = new HashMap<>();
+    @UriParam(label = "producer")
+    private EventHubProducerAsyncClient producerAsyncClient;
+    @UriParam(label = "producer")
+    private String partitionKey;
+    @UriParam(label = "producer")
+    private String partitionId;
+
+    /**
+     * EventHubs namespace created in Azure Portal
+     */
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public void setNamespace(String namespace) {
+        this.namespace = namespace;
+    }
+
+    /**
+     * EventHubs name under a specific namcespace
+     */
+    public String getEventHubName() {
+        return eventHubName;
+    }
+
+    public void setEventHubName(String eventHubName) {
+        this.eventHubName = eventHubName;
+    }
+
+    /**
+     * The name you chose for your EventHubs SAS keys
+     */
+    public String getSharedAccessName() {
+        return sharedAccessName;
+    }
+
+    public void setSharedAccessName(String sharedAccessName) {
+        this.sharedAccessName = sharedAccessName;
+    }
+
+    /**
+     * The generated value for the SharedAccessName
+     */
+    public String getSharedAccessKey() {
+        return sharedAccessKey;
+    }
+
+    public void setSharedAccessKey(String sharedAccessKey) {
+        this.sharedAccessKey = sharedAccessKey;
+    }
+
+    /**
+     * Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply the connection
+     * string for your eventHub. The connection string for EventHubs already include all the necessary information to
+     * connection to your EventHub. To learn on how to generate the connection string, take a look at this
+     * documentation: https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string
+     */
+    public String getConnectionString() {
+        return connectionString;
+    }
+
+    public void setConnectionString(String connectionString) {
+        this.connectionString = connectionString;
+    }
+
+    /**
+     * Sets the transport type by which all the communication with Azure Event Hubs occurs. Default value is
+     * {@link AmqpTransportType#AMQP}.
+     */
+    public AmqpTransportType getAmqpTransportType() {
+        return amqpTransportType;
+    }
+
+    public void setAmqpTransportType(AmqpTransportType amqpTransportType) {
+        this.amqpTransportType = amqpTransportType;
+    }
+
+    /**
+     * Sets the retry policy for {@link EventHubAsyncClient}. If not specified, the default retry options are used.
+     */
+    public AmqpRetryOptions getAmqpRetryOptions() {
+        return amqpRetryOptions;
+    }
+
+    public void setAmqpRetryOptions(AmqpRetryOptions amqpRetryOptions) {
+        this.amqpRetryOptions = amqpRetryOptions;
+    }
+
+    /**
+     * Sets the name of the consumer group this consumer is associated with. Events are read in the context of this
+     * group. The name of the consumer group that is created by default is {@link #DEFAULT_CONSUMER_GROUP_NAME
+     * "$Default"}.
+     */
+    public String getConsumerGroupName() {
+        return consumerGroupName;
+    }
+
+    public void setConsumerGroupName(String consumerGroupName) {
+        this.consumerGroupName = consumerGroupName;
+    }
+
+    /**
+     * Sets the count used by the receiver to control the number of events the Event Hub consumer will actively receive
+     * and queue locally without regard to whether a receive operation is currently active.
+     */
+    public int getPrefetchCount() {
+        return prefetchCount;
+    }
+
+    public void setPrefetchCount(int prefetchCount) {
+        this.prefetchCount = prefetchCount;
+    }
+
+    /**
+     * Sets the {@link EventHubProducerAsyncClient}.An asynchronous producer responsible for transmitting
+     * {@link EventData} to a specific Event Hub, grouped together in batches. Depending on the
+     * {@link CreateBatchOptions options} specified when creating an {@linkEventDataBatch}, the events may be
+     * automatically routed to an available partition or specific to a partition. Use by this component to produce the
+     * data in camel producer.
+     */
+    public EventHubProducerAsyncClient getProducerAsyncClient() {
+        return producerAsyncClient;
+    }
+
+    public void setProducerAsyncClient(EventHubProducerAsyncClient producerAsyncClient) {
+        this.producerAsyncClient = producerAsyncClient;
+    }
+
+    /**
+     * Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry
+     * automatically otherwise it will skip that checking.
+     */
+    public boolean isAutoDiscoverClient() {
+        return autoDiscoverClient;
+    }
+
+    public void setAutoDiscoverClient(boolean autoDiscoverClient) {
+        this.autoDiscoverClient = autoDiscoverClient;
+    }
+
+    /**
+     * Sets the identifier of the Event Hub partition that the {@link EventData events} will be sent to. If the
+     * identifier is not specified, the Event Hubs service will be responsible for routing events that are sent to an
+     * available partition.
+     */
+    public String getPartitionId() {
+        return partitionId;
+    }
+
+    public void setPartitionId(String partitionId) {
+        this.partitionId = partitionId;
+    }
+
+    /**
+     * Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to map this key
+     * to a specific partition.
+     *
+     * The selection of a partition is stable for a given partition hashing key. Should any other batches of events be
+     * sent using the same exact partition hashing key, the Event Hubs service will route them all to the same
+     * partition.
+     *
+     * This should be specified only when there is a need to group events by partition, but there is flexibility into
+     * which partition they are routed. If ensuring that a batch of events is sent only to a specific partition, it is
+     * recommended that the {@link #setPartitionId(String) identifier of the position be specified directly} when
+     * sending the batch.
+     */
+    public String getPartitionKey() {
+        return partitionKey;
+    }
+
+    public void setPartitionKey(String partitionKey) {
+        this.partitionKey = partitionKey;
+    }
+
+    /**
+     * Sets the {@link CheckpointStore} the {@link EventProcessorClient} will use for storing partition ownership and
+     * checkpoint information.
+     *
+     * <p>
+     * Users can, optionally, provide their own implementation of {@link CheckpointStore} which will store ownership and
+     * checkpoint information.
+     * </p>
+     *
+     * By default it set to use {@link com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore} which
+     * stores all checkpoint offsets into Azure Blob Storage
+     */
+    public CheckpointStore getCheckpointStore() {
+        return checkpointStore;
+    }
+
+    public void setCheckpointStore(CheckpointStore checkpointStore) {
+        this.checkpointStore = checkpointStore;
+    }
+
+    /**
+     * In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for authentication
+     * with azure blob services.
+     */
+    public String getBlobAccountName() {
+        return blobAccountName;
+    }
+
+    public void setBlobAccountName(String blobAccountName) {
+        this.blobAccountName = blobAccountName;
+    }
+
+    /**
+     * In case you chose the default BlobCheckpointStore, this sets access key for the associated azure account name to
+     * be used for authentication with azure blob services
+     */
+    public String getBlobAccessKey() {
+        return blobAccessKey;
+    }
+
+    public void setBlobAccessKey(String blobAccessKey) {
+        this.blobAccessKey = blobAccessKey;
+    }
+
+    /**
+     * In case you chose the default BlobCheckpointStore, this sets the blob container that shall be used by the
+     * BlobCheckpointStore to store the checkpoint offsets
+     */
+    public String getBlobContainerName() {
+        return blobContainerName;
+    }
+
+    public void setBlobContainerName(String blobContainerName) {
+        this.blobContainerName = blobContainerName;
+    }
+
+    /**
+     * In case you chose the default BlobCheckpointStore, StorageSharedKeyCredential can be injected to create the azure
+     * client, this holds the important authentication information
+     */
+    public StorageSharedKeyCredential getBlobStorageSharedKeyCredential() {
+        return blobStorageSharedKeyCredential;
+    }
+
+    public void setBlobStorageSharedKeyCredential(StorageSharedKeyCredential blobStorageSharedKeyCredential) {
+        this.blobStorageSharedKeyCredential = blobStorageSharedKeyCredential;
+    }
+
+    /**
+     * Sets the map containing the event position to use for each partition if a checkpoint for the partition does not
+     * exist in {@link CheckpointStore}. This map is keyed off of the partition id. If there is no checkpoint in
+     * {@link CheckpointStore} and there is no entry in this map, the processing of the partition will start from
+     * {@link EventPosition#latest() latest} position.
+     */
+    public Map<String, EventPosition> getEventPosition() {
+        return eventPosition;
+    }
+
+    public void setEventPosition(Map<String, EventPosition> eventPosition) {
+        this.eventPosition = eventPosition;
+    }
+
+    // *************************************************
+    //
+    // *************************************************
+
+    public EventHubsConfiguration copy() {
+        try {
+            return (EventHubsConfiguration) super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeCamelException(e);
+        }
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfigurationOptionsProxy.java b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfigurationOptionsProxy.java
new file mode 100644
index 0000000..05091b0
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfigurationOptionsProxy.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.util.function.Supplier;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * A proxy class for {@link EventHubsConfiguration} and {@link EventHubsConstants}. Ideally this is responsible to
+ * obtain the correct configurations options either from configs or exchange headers
+ */
+public class EventHubsConfigurationOptionsProxy {
+
+    private final EventHubsConfiguration configuration;
+
+    public EventHubsConfigurationOptionsProxy(final EventHubsConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    private static <T> T getObjectFromHeaders(final Exchange exchange, final String headerName, final Class<T> classType) {
+        return exchange.getIn().getHeader(headerName, classType);
+    }
+
+    public String getPartitionKey(final Exchange exchange) {
+        return getOption(exchange, EventHubsConstants.PARTITION_KEY, configuration::getPartitionKey, String.class);
+    }
+
+    public String getPartitionId(final Exchange exchange) {
+        return getOption(exchange, EventHubsConstants.PARTITION_ID, configuration::getPartitionId, String.class);
+    }
+
+    public EventHubsConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    private <R> R getOption(
+            final Exchange exchange, final String headerName, final Supplier<R> fallbackFn, final Class<R> type) {
+        // we first try to look if our value in exchange otherwise fallback to fallbackFn which could be either a function or constant
+        return ObjectHelper.isEmpty(exchange) || ObjectHelper.isEmpty(getObjectFromHeaders(exchange, headerName, type))
+                ? fallbackFn.get()
+                : getObjectFromHeaders(exchange, headerName, type);
+    }
+
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConstants.java b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConstants.java
new file mode 100644
index 0000000..f0b24ea
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConstants.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+public final class EventHubsConstants {
+    private static final String HEADER_PREFIX = "CamelAzureEventHubs";
+    // common headers, set by consumer and evaluated by producer
+    public static final String PARTITION_KEY = HEADER_PREFIX + "PartitionKey";
+    public static final String PARTITION_ID = HEADER_PREFIX + "PartitionId";
+    // headers set by the consumer only
+    public static final String OFFSET = HEADER_PREFIX + "Offset";
+    public static final String ENQUEUED_TIME = HEADER_PREFIX + "EnqueuedTime";
+    public static final String SEQUENCE_NUMBER = HEADER_PREFIX + "SequenceNumber";
+
+    private EventHubsConstants() {
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumer.java b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumer.java
new file mode 100644
index 0000000..56ccee6
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumer.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import com.azure.messaging.eventhubs.EventProcessorClient;
+import com.azure.messaging.eventhubs.models.ErrorContext;
+import com.azure.messaging.eventhubs.models.EventContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExtendedExchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
+import org.apache.camel.spi.Synchronization;
+import org.apache.camel.support.DefaultConsumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EventHubsConsumer extends DefaultConsumer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EventHubsConsumer.class);
+
+    // we use the EventProcessorClient as recommended by Azure docs to consume from all partitions
+    private EventProcessorClient processorClient;
+
+    public EventHubsConsumer(final EventHubsEndpoint endpoint, final Processor processor) {
+        super(endpoint, processor);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        // create the client
+        processorClient = EventHubsClientFactory.createEventProcessorClient(getConfiguration(),
+                this::onEventListener, this::onErrorListener);
+
+        // start the client but we will rely on the Azure Client Scheduler for thread management
+        processorClient.start();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        if (processorClient != null) {
+            // shutdown the client
+            processorClient.stop();
+        }
+
+        // shutdown camel consumer
+        super.doStop();
+    }
+
+    public EventHubsConfiguration getConfiguration() {
+        return getEndpoint().getConfiguration();
+    }
+
+    @Override
+    public EventHubsEndpoint getEndpoint() {
+        return (EventHubsEndpoint) super.getEndpoint();
+    }
+
+    private Exchange createAzureEventHubExchange(final EventContext eventContext) {
+        final Exchange exchange = createExchange(true);
+        final Message message = exchange.getIn();
+
+        // set body as byte[] and let camel typeConverters do the job to convert
+        message.setBody(eventContext.getEventData().getBody());
+        // set headers
+        message.setHeader(EventHubsConstants.PARTITION_ID, eventContext.getPartitionContext().getPartitionId());
+        message.setHeader(EventHubsConstants.PARTITION_KEY, eventContext.getEventData().getPartitionKey());
+        message.setHeader(EventHubsConstants.OFFSET, eventContext.getEventData().getOffset());
+        message.setHeader(EventHubsConstants.ENQUEUED_TIME, eventContext.getEventData().getEnqueuedTime());
+        message.setHeader(EventHubsConstants.SEQUENCE_NUMBER, eventContext.getEventData().getSequenceNumber());
+
+        return exchange;
+    }
+
+    private Exchange createAzureEventHubExchange(final ErrorContext errorContext) {
+        final Exchange exchange = createExchange(true);
+        final Message message = exchange.getIn();
+
+        // set headers
+        message.setHeader(EventHubsConstants.PARTITION_ID, errorContext.getPartitionContext().getPartitionId());
+
+        // set exception
+        exchange.setException(errorContext.getThrowable());
+
+        return exchange;
+    }
+
+    private void onEventListener(final EventContext eventContext) {
+        final Exchange exchange = createAzureEventHubExchange(eventContext);
+
+        // add exchange callback
+        exchange.adapt(ExtendedExchange.class).addOnCompletion(new Synchronization() {
+            @Override
+            public void onComplete(Exchange exchange) {
+                // we update the consumer offsets
+                processCommit(exchange, eventContext);
+            }
+
+            @Override
+            public void onFailure(Exchange exchange) {
+                // we do nothing here
+                processRollback(exchange);
+            }
+        });
+        // send message to next processor in the route
+        getAsyncProcessor().process(exchange, doneSync -> LOG.trace("Processing exchange [{}] done.", exchange));
+    }
+
+    private void onErrorListener(final ErrorContext errorContext) {
+        final Exchange exchange = createAzureEventHubExchange(errorContext);
+
+        // log exception if an exception occurred and was not handled
+        if (exchange.getException() != null) {
+            getExceptionHandler().handleException("Error processing exchange", exchange,
+                    exchange.getException());
+        }
+    }
+
+    /**
+     * Strategy to commit the offset after message being processed successfully.
+     *
+     * @param exchange the exchange
+     */
+    private void processCommit(final Exchange exchange, final EventContext eventContext) {
+        try {
+            eventContext.updateCheckpoint();
+        } catch (Exception ex) {
+            getExceptionHandler().handleException("Error occurred during updating the checkpoint. This exception is ignored.",
+                    exchange, ex);
+        }
+    }
+
+    /**
+     * Strategy when processing the exchange failed.
+     *
+     * @param exchange the exchange
+     */
+    private void processRollback(Exchange exchange) {
+        final Exception cause = exchange.getException();
+        if (cause != null) {
+            getExceptionHandler().handleException("Error during processing exchange.", exchange, cause);
+        }
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpoint.java b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpoint.java
new file mode 100644
index 0000000..b9010e8
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpoint.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import org.apache.camel.Category;
+import org.apache.camel.Component;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.support.DefaultEndpoint;
+
+/**
+ * The azure-eventhubs component that integrates Azure Event Hubs using AMQP protocol. Azure EventHubs is a highly
+ * scalable publish-subscribe service that can ingest millions of events per second and stream them to multiple
+ * consumers.
+ */
+@UriEndpoint(firstVersion = "3.5.0", scheme = "azure-eventhubs", title = "Azure Event Hubs",
+             syntax = "azure-eventhubs:namespace/eventHubName", category = {
+                     Category.CLOUD, Category.MESSAGING })
+public class EventHubsEndpoint extends DefaultEndpoint {
+
+    @UriParam
+    private EventHubsConfiguration configuration;
+
+    public EventHubsEndpoint(final String uri, final Component component, final EventHubsConfiguration configuration) {
+        super(uri, component);
+        this.configuration = configuration;
+    }
+
+    @Override
+    public Producer createProducer() throws Exception {
+        return new EventHubsProducer(this);
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) throws Exception {
+        final Consumer eventHubConsumer = new EventHubsConsumer(this, processor);
+        configureConsumer(eventHubConsumer);
+
+        return eventHubConsumer;
+    }
+
+    /**
+     * The component configurations
+     */
+    public EventHubsConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(EventHubsConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsProducer.java b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsProducer.java
new file mode 100644
index 0000000..1164156
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsProducer.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
+import org.apache.camel.component.azure.eventhubs.operations.EventHubsProducerOperations;
+import org.apache.camel.support.DefaultAsyncProducer;
+
+public class EventHubsProducer extends DefaultAsyncProducer {
+
+    private EventHubProducerAsyncClient producerAsyncClient;
+    private EventHubsProducerOperations producerOperations;
+
+    public EventHubsProducer(final Endpoint endpoint) {
+        super(endpoint);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        // create the client
+        producerAsyncClient = EventHubsClientFactory.createEventHubProducerAsyncClient(getEndpoint().getConfiguration());
+
+        // create our operations
+        producerOperations = new EventHubsProducerOperations(producerAsyncClient, getConfiguration());
+    }
+
+    @Override
+    public boolean process(Exchange exchange, AsyncCallback callback) {
+        try {
+            return producerOperations.sendEvents(exchange, callback);
+        } catch (Exception e) {
+            exchange.setException(e);
+            callback.done(true);
+            return true;
+        }
+
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        if (producerAsyncClient != null) {
+            // shutdown async client
+            producerAsyncClient.close();
+        }
+
+        super.doStop();
+    }
+
+    @Override
+    public EventHubsEndpoint getEndpoint() {
+        return (EventHubsEndpoint) super.getEndpoint();
+    }
+
+    public EventHubsConfiguration getConfiguration() {
+        return getEndpoint().getConfiguration();
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/client/EventHubsClientFactory.java b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/client/EventHubsClientFactory.java
new file mode 100644
index 0000000..89f1c6c
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/client/EventHubsClientFactory.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs.client;
+
+import java.util.Locale;
+import java.util.function.Consumer;
+
+import com.azure.messaging.eventhubs.CheckpointStore;
+import com.azure.messaging.eventhubs.EventHubClientBuilder;
+import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
+import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
+import com.azure.messaging.eventhubs.EventProcessorClient;
+import com.azure.messaging.eventhubs.EventProcessorClientBuilder;
+import com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore;
+import com.azure.messaging.eventhubs.models.ErrorContext;
+import com.azure.messaging.eventhubs.models.EventContext;
+import com.azure.storage.blob.BlobContainerAsyncClient;
+import com.azure.storage.blob.BlobContainerClientBuilder;
+import com.azure.storage.common.StorageSharedKeyCredential;
+import org.apache.camel.component.azure.eventhubs.EventHubsConfiguration;
+import org.apache.camel.util.ObjectHelper;
+
+public final class EventHubsClientFactory {
+
+    private static final String SERVICE_URI_SEGMENT = "servicebus.windows.net";
+    private static final String BLOB_SERVICE_URI_SEGMENT = ".blob.core.windows.net";
+
+    private EventHubsClientFactory() {
+    }
+
+    public static EventHubProducerAsyncClient createEventHubProducerAsyncClient(final EventHubsConfiguration configuration) {
+        return new EventHubClientBuilder()
+                .connectionString(buildConnectionString(configuration))
+                .transportType(configuration.getAmqpTransportType())
+                .retry(configuration.getAmqpRetryOptions())
+                .buildAsyncProducerClient();
+    }
+
+    public static EventHubConsumerAsyncClient createEventHubConsumerAsyncClient(final EventHubsConfiguration configuration) {
+        return new EventHubClientBuilder()
+                .connectionString(buildConnectionString(configuration))
+                .consumerGroup(configuration.getConsumerGroupName())
+                .prefetchCount(configuration.getPrefetchCount())
+                .transportType(configuration.getAmqpTransportType())
+                .retry(configuration.getAmqpRetryOptions())
+                .buildAsyncConsumerClient();
+    }
+
+    public static EventProcessorClient createEventProcessorClient(
+            final EventHubsConfiguration configuration, final Consumer<EventContext> processEvent,
+            final Consumer<ErrorContext> processError) {
+        return new EventProcessorClientBuilder()
+                .initialPartitionEventPosition(configuration.getEventPosition())
+                .connectionString(buildConnectionString(configuration))
+                .checkpointStore(createCheckpointStore(configuration))
+                .consumerGroup(configuration.getConsumerGroupName())
+                .retry(configuration.getAmqpRetryOptions())
+                .transportType(configuration.getAmqpTransportType())
+                .processError(processError)
+                .processEvent(processEvent)
+                .buildEventProcessorClient();
+
+    }
+
+    // public for testing purposes
+    public static BlobContainerAsyncClient createBlobContainerClient(final EventHubsConfiguration configuration) {
+        return new BlobContainerClientBuilder()
+                .endpoint(buildAzureEndpointUri(configuration))
+                .containerName(configuration.getBlobContainerName())
+                .credential(getCredentialForClient(configuration))
+                .buildAsyncClient();
+    }
+
+    private static CheckpointStore createCheckpointStore(final EventHubsConfiguration configuration) {
+        if (ObjectHelper.isNotEmpty(configuration.getCheckpointStore())) {
+            return configuration.getCheckpointStore();
+        }
+        // so we have no checkpoint store, we fallback to default BlobCheckpointStore
+        // first we check if we have all required params for BlobCheckpointStore
+        if (ObjectHelper.isEmpty(configuration.getBlobContainerName())
+                || !isCredentialsSet(configuration)) {
+            throw new IllegalArgumentException(
+                    "Since there is no provided CheckpointStore, you will need to set blobAccountName, blobAccessName"
+                                               + " or blobContainerName in order to use the default BlobCheckpointStore");
+        }
+
+        // second build the BlobContainerAsyncClient
+        return new BlobCheckpointStore(createBlobContainerClient(configuration));
+    }
+
+    private static boolean isCredentialsSet(final EventHubsConfiguration configuration) {
+        if (ObjectHelper.isNotEmpty(configuration.getBlobStorageSharedKeyCredential())) {
+            return true;
+        }
+
+        return ObjectHelper.isNotEmpty(configuration.getBlobAccessKey())
+                && ObjectHelper.isNotEmpty(configuration.getBlobAccountName());
+    }
+
+    private static String buildConnectionString(final EventHubsConfiguration configuration) {
+        if (ObjectHelper.isNotEmpty(configuration.getConnectionString())) {
+            return configuration.getConnectionString();
+        }
+
+        return String.format(Locale.ROOT, "Endpoint=sb://%s.%s/;SharedAccessKeyName=%s;SharedAccessKey=%s;EntityPath=%s",
+                configuration.getNamespace(), SERVICE_URI_SEGMENT, configuration.getSharedAccessName(),
+                configuration.getSharedAccessKey(),
+                configuration.getEventHubName());
+    }
+
+    private static String buildAzureEndpointUri(final EventHubsConfiguration configuration) {
+        return String.format(Locale.ROOT, "https://%s" + BLOB_SERVICE_URI_SEGMENT, getAccountName(configuration));
+    }
+
+    private static StorageSharedKeyCredential getCredentialForClient(final EventHubsConfiguration configuration) {
+        final StorageSharedKeyCredential storageSharedKeyCredential = configuration.getBlobStorageSharedKeyCredential();
+
+        if (storageSharedKeyCredential != null) {
+            return storageSharedKeyCredential;
+        }
+
+        return new StorageSharedKeyCredential(configuration.getBlobAccountName(), configuration.getBlobAccessKey());
+    }
+
+    private static String getAccountName(final EventHubsConfiguration configuration) {
+        return ObjectHelper.isNotEmpty(configuration.getBlobStorageSharedKeyCredential())
+                ? configuration.getBlobStorageSharedKeyCredential().getAccountName()
+                : configuration.getBlobAccountName();
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperations.java b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperations.java
new file mode 100644
index 0000000..4037ba2
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperations.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs.operations;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.azure.messaging.eventhubs.EventData;
+import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
+import com.azure.messaging.eventhubs.models.SendOptions;
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.TypeConverter;
+import org.apache.camel.component.azure.eventhubs.EventHubsConfiguration;
+import org.apache.camel.component.azure.eventhubs.EventHubsConfigurationOptionsProxy;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import reactor.core.publisher.Mono;
+
+public class EventHubsProducerOperations {
+
+    private static final Logger LOG = LoggerFactory.getLogger(EventHubsProducerOperations.class);
+
+    private final EventHubProducerAsyncClient producerAsyncClient;
+    private final EventHubsConfigurationOptionsProxy configurationOptionsProxy;
+
+    public EventHubsProducerOperations(final EventHubProducerAsyncClient producerAsyncClient,
+                                       final EventHubsConfiguration configuration) {
+        ObjectHelper.notNull(producerAsyncClient, "client cannot be null");
+
+        this.producerAsyncClient = producerAsyncClient;
+        configurationOptionsProxy = new EventHubsConfigurationOptionsProxy(configuration);
+    }
+
+    public boolean sendEvents(final Exchange exchange, final AsyncCallback callback) {
+        ObjectHelper.notNull(exchange, "exchange cannot be null");
+        ObjectHelper.notNull(callback, "callback cannot be null");
+
+        final SendOptions sendOptions = createSendOptions(configurationOptionsProxy.getPartitionKey(exchange),
+                configurationOptionsProxy.getPartitionId(exchange));
+        final Iterable<EventData> eventData = createEventData(exchange);
+
+        return sendAsyncEvents(eventData, sendOptions, exchange, callback);
+    }
+
+    private boolean sendAsyncEvents(
+            final Iterable<EventData> eventData, final SendOptions sendOptions, final Exchange exchange,
+            final AsyncCallback asyncCallback) {
+        sendAsyncEventsWithSuitableMethod(eventData, sendOptions)
+                .subscribe(unused -> LOG.debug("Processed one event..."), error -> {
+                    // error but we continue
+                    LOG.debug("Error processing async exchange with error:" + error.getMessage());
+                    exchange.setException(error);
+                    asyncCallback.done(false);
+                }, () -> {
+                    // we are done from everything, so mark it as sync done
+                    LOG.debug("All events with exchange have been sent successfully.");
+                    asyncCallback.done(false);
+                });
+
+        return false;
+    }
+
+    private Mono<Void> sendAsyncEventsWithSuitableMethod(final Iterable<EventData> eventData, final SendOptions sendOptions) {
+        if (ObjectHelper.isEmpty(sendOptions)) {
+            return producerAsyncClient.send(eventData);
+        }
+
+        return producerAsyncClient.send(eventData, sendOptions);
+    }
+
+    private SendOptions createSendOptions(final String partitionKey, final String partitionId) {
+        // if both are set, we don't want that
+        if (ObjectHelper.isNotEmpty(partitionKey) && ObjectHelper.isNotEmpty(partitionId)) {
+            throw new IllegalArgumentException("Both partitionKey and partitionId are set. Only one or the other can be set.");
+        }
+        // if both are not set, we return null and let EventHubs handle the partition assigning
+        if (ObjectHelper.isEmpty(partitionKey) && ObjectHelper.isEmpty(partitionId)) {
+            return null;
+        }
+
+        return new SendOptions()
+                .setPartitionId(partitionId)
+                .setPartitionKey(partitionKey);
+    }
+
+    @SuppressWarnings("unchecked")
+    private Iterable<EventData> createEventData(final Exchange exchange) {
+        // check if our exchange is list or contain some values
+        if (exchange.getIn().getBody() instanceof Iterable) {
+            return createEventDataFromIterable((Iterable<Object>) exchange.getIn().getBody(),
+                    exchange.getContext().getTypeConverter());
+        }
+
+        // we have only a single event here
+        return Collections.singletonList(createEventDataFromExchange(exchange));
+    }
+
+    private Iterable<EventData> createEventDataFromIterable(final Iterable<Object> inputData, final TypeConverter converter) {
+        final List<EventData> finalEventData = new LinkedList<>();
+
+        inputData.forEach(data -> {
+            if (data instanceof Exchange) {
+                finalEventData.add(createEventDataFromExchange((Exchange) data));
+            } else if (data instanceof Message) {
+                finalEventData.add(createEventDataFromMessage((Message) data));
+            } else {
+                finalEventData.add(createEventDataFromObject(data, converter));
+            }
+        });
+
+        return finalEventData;
+    }
+
+    private EventData createEventDataFromExchange(final Exchange exchange) {
+        return createEventDataFromMessage(exchange.getIn());
+    }
+
+    private EventData createEventDataFromMessage(final Message message) {
+        return createEventDataFromObject(message.getBody(), message.getExchange().getContext().getTypeConverter());
+    }
+
+    private EventData createEventDataFromObject(final Object inputData, final TypeConverter converter) {
+        final byte[] data = converter.convertTo(byte[].class, inputData);
+
+        if (ObjectHelper.isEmpty(data)) {
+            throw new IllegalArgumentException(
+                    String.format("Cannot convert message body %s to byte[]. You will need "
+                                  + "to make sure the data encoded in byte[] or add a Camel TypeConverter to convert the data to byte[]",
+                            inputData));
+        }
+
+        return new EventData(data);
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentTest.java b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentTest.java
new file mode 100644
index 0000000..6ffdbb0
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
+import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
+import org.apache.camel.ResolveEndpointFailedException;
+import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class EventHubsComponentTest extends CamelTestSupport {
+
+    @Test
+    public void testCreateEndpointWithNoEventHubsNameOrNameSpace() throws Exception {
+        ResolveEndpointFailedException exception = assertThrows(ResolveEndpointFailedException.class,
+                () -> context.getEndpoint("azure-eventhubs:?sharedAccessKey=string&sharedAccessName=name"));
+
+        assertTrue(
+                exception.getMessage().contains("ConnectionString, AzureClients or Namespace and EventHub name must be set"));
+
+        ResolveEndpointFailedException exception2 = assertThrows(ResolveEndpointFailedException.class,
+                () -> context.getEndpoint("azure-eventhubs:name?sharedAccessKey=string&sharedAccessName=name"));
+
+        assertTrue(
+                exception2.getMessage().contains("ConnectionString, AzureClients or Namespace and EventHub name must be set"));
+    }
+
+    @Test
+    public void testCreateEndpointWithNoSuppliedClientsOrKeysOrConnectionString() {
+        final String expectedErrorMessage
+                = "Azure EventHubs SharedAccessName/SharedAccessKey, ConsumerAsyncClient/ProducerAsyncClient "
+                  + "or connectionString must be specified";
+
+        // first case: with no client or key or connectionstring
+        assertTrue(getErrorMessage("azure-eventhubs:name/hubName?").contains(expectedErrorMessage));
+
+        // second case: connectionString set
+        assertNotNull(context.getEndpoint("azure-eventhubs:?connectionString=string"));
+
+        // third case: either access key or access name set
+        assertTrue(getErrorMessage("azure-eventhubs:name/hubName?sharedAccessName=test").contains(expectedErrorMessage));
+        assertTrue(getErrorMessage("azure-eventhubs:name/hubName?sharedAccessKey=test").contains(expectedErrorMessage));
+        assertNotNull(context.getEndpoint("azure-eventhubs:name/hubName?sharedAccessName=test&sharedAccessKey=test"));
+
+        // forth case: with client set
+        final EventHubsConfiguration configuration = new EventHubsConfiguration();
+        configuration.setNamespace("test");
+        configuration.setConsumerGroupName("testGroup");
+        configuration.setSharedAccessKey("dummyKey");
+        configuration.setSharedAccessName("dummyUser");
+
+        final EventHubProducerAsyncClient producerAsyncClient
+                = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
+
+        context.getRegistry().bind("producerClient", producerAsyncClient);
+
+        assertNotNull(context
+                .getEndpoint("azure-eventhubs:name/hubName?autoDiscoverClient=false&producerAsyncClient=#producerClient"));
+    }
+
+    @Test
+    public void testClientAutoDiscovery() {
+        final EventHubsConfiguration configuration = new EventHubsConfiguration();
+        configuration.setNamespace("test");
+        configuration.setConsumerGroupName("testGroup");
+        configuration.setSharedAccessKey("dummyKey");
+        configuration.setSharedAccessName("dummyUser");
+
+        final EventHubConsumerAsyncClient consumerAsyncClient
+                = EventHubsClientFactory.createEventHubConsumerAsyncClient(configuration);
+        final EventHubConsumerAsyncClient consumerAsyncClient2
+                = EventHubsClientFactory.createEventHubConsumerAsyncClient(configuration);
+        final EventHubProducerAsyncClient producerAsyncClient
+                = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
+
+        // we dont allow more than one instance
+        context.getRegistry().bind("consumerClient", consumerAsyncClient);
+        context.getRegistry().bind("consumerClient2", consumerAsyncClient2);
+
+        assertThrows(ResolveEndpointFailedException.class, () -> context.getEndpoint("azure-eventhubs:name/hubName"));
+
+        context.getRegistry().bind("producerClient", producerAsyncClient);
+
+        final EventHubsEndpoint endpoint = (EventHubsEndpoint) context.getEndpoint("azure-eventhubs:name/hubName");
+
+        assertEquals(producerAsyncClient, endpoint.getConfiguration().getProducerAsyncClient());
+    }
+
+    @Test
+    public void testCreateEndpointWithConfig() {
+        final String uri = "azure-eventhubs:namespace/hubName?sharedAccessName=DummyAccessKeyName"
+                           + "&sharedAccessKey=DummyKey"
+                           + "&consumerGroupName=testConsumer&prefetchCount=100";
+
+        final EventHubsEndpoint endpoint = (EventHubsEndpoint) context.getEndpoint(uri);
+
+        assertEquals("namespace", endpoint.getConfiguration().getNamespace());
+        assertEquals("hubName", endpoint.getConfiguration().getEventHubName());
+        assertEquals("testConsumer", endpoint.getConfiguration().getConsumerGroupName());
+        assertEquals("DummyAccessKeyName", endpoint.getConfiguration().getSharedAccessName());
+        assertEquals("DummyKey", endpoint.getConfiguration().getSharedAccessKey());
+        assertEquals(100, endpoint.getConfiguration().getPrefetchCount());
+        assertTrue(endpoint.getConfiguration().isAutoDiscoverClient());
+    }
+
+    private String getErrorMessage(final String uri) {
+        ResolveEndpointFailedException exception
+                = assertThrows(ResolveEndpointFailedException.class, () -> context.getEndpoint(uri));
+        return exception.getMessage();
+    }
+
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumerIT.java b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumerIT.java
new file mode 100644
index 0000000..88f04cb
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumerIT.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+
+import com.azure.messaging.eventhubs.EventData;
+import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
+import com.azure.messaging.eventhubs.models.EventPosition;
+import com.azure.messaging.eventhubs.models.SendOptions;
+import com.azure.storage.blob.BlobContainerAsyncClient;
+import org.apache.camel.CamelContext;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class EventHubsConsumerIT extends CamelTestSupport {
+
+    @EndpointInject("mock:result")
+    private MockEndpoint result;
+
+    private String containerName;
+    private BlobContainerAsyncClient containerAsyncClient;
+    private EventHubsConfiguration configuration;
+
+    @BeforeAll
+    public void prepare() throws Exception {
+        containerName = RandomStringUtils.randomAlphabetic(5).toLowerCase();
+
+        final Properties properties = TestUtils.loadAzureAccessFromJvmEnv();
+
+        configuration = new EventHubsConfiguration();
+        configuration.setBlobAccessKey(properties.getProperty(TestUtils.BLOB_ACCESS_KEY));
+        configuration.setBlobAccountName(properties.getProperty(TestUtils.BLOB_ACCOUNT_NAME));
+        configuration.setBlobContainerName(containerName);
+        configuration.setConnectionString(properties.getProperty(TestUtils.CONNECTION_STRING));
+
+        containerAsyncClient = EventHubsClientFactory.createBlobContainerClient(configuration);
+
+        // create test container
+        containerAsyncClient.create().block();
+    }
+
+    @Test
+    public void testConsumerEvents() throws InterruptedException {
+        // send test data
+        final EventHubProducerAsyncClient producerAsyncClient
+                = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
+
+        final String messageBody = RandomStringUtils.randomAlphabetic(30);
+        final String messageKey = RandomStringUtils.randomAlphabetic(5);
+
+        producerAsyncClient
+                .send(Collections.singletonList(new EventData(messageBody)), new SendOptions().setPartitionKey(messageKey))
+                .block();
+
+        result.expectedMinimumMessageCount(1);
+        result.setAssertPeriod(20000);
+
+        final List<Exchange> exchanges = result.getExchanges();
+        result.assertIsSatisfied();
+
+        // now we check our messages
+        final Exchange returnedMessage = exchanges.stream()
+                .filter(Objects::nonNull)
+                .filter(exchange -> exchange.getMessage().getHeader(EventHubsConstants.PARTITION_KEY)
+                                    != null
+                        && exchange.getMessage().getHeader(EventHubsConstants.PARTITION_KEY).equals(messageKey))
+                .findFirst()
+                .orElse(null);
+
+        assertNotNull(returnedMessage);
+
+        assertEquals(messageKey, returnedMessage.getMessage().getHeader(EventHubsConstants.PARTITION_KEY));
+
+        assertNotNull(returnedMessage.getMessage().getBody());
+        assertNotNull(returnedMessage.getMessage().getHeader(EventHubsConstants.PARTITION_ID));
+        assertNotNull(returnedMessage.getMessage().getHeader(EventHubsConstants.SEQUENCE_NUMBER));
+        assertNotNull(returnedMessage.getMessage().getHeader(EventHubsConstants.OFFSET));
+        assertNotNull(returnedMessage.getMessage().getHeader(EventHubsConstants.ENQUEUED_TIME));
+    }
+
+    @AfterAll
+    public void tearDown() {
+        // delete testing container
+        containerAsyncClient.delete().block();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("azure-eventhubs:?"
+                     + "connectionString=RAW({{connectionString}})"
+                     + "&blobContainerName=" + containerName + "&eventPosition=#eventPosition"
+                     + "&blobAccountName={{blobAccountName}}&blobAccessKey=RAW({{blobAccessKey}})")
+                             .to(result);
+
+            }
+        };
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        final Map<String, EventPosition> positionMap = new HashMap<>();
+        positionMap.put("0", EventPosition.earliest());
+        positionMap.put("1", EventPosition.earliest());
+
+        CamelContext context = super.createCamelContext();
+        context.getRegistry().bind("eventPosition", positionMap);
+
+        return context;
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsProducerIT.java b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsProducerIT.java
new file mode 100644
index 0000000..30e6a32
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsProducerIT.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.util.Properties;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.azure.messaging.eventhubs.EventHubClientBuilder;
+import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
+import com.azure.messaging.eventhubs.models.EventPosition;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class EventHubsProducerIT extends CamelTestSupport {
+
+    @EndpointInject
+    private ProducerTemplate template;
+
+    @EndpointInject("mock:result")
+    private MockEndpoint result;
+
+    private EventHubConsumerAsyncClient consumerAsyncClient;
+
+    @BeforeAll
+    public void prepare() throws Exception {
+        final Properties properties = TestUtils.loadAzureAccessFromJvmEnv();
+
+        final EventHubsConfiguration configuration = new EventHubsConfiguration();
+        configuration.setConnectionString(properties.getProperty(TestUtils.CONNECTION_STRING));
+        configuration.setConsumerGroupName(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME);
+
+        consumerAsyncClient = EventHubsClientFactory.createEventHubConsumerAsyncClient(configuration);
+    }
+
+    @Test
+    public void testSendEventWithSpecificPartition() throws InterruptedException {
+
+        final String messageBody = RandomStringUtils.randomAlphabetic(30);
+        final String firstPartition = "0";
+
+        final AtomicBoolean eventExists = new AtomicBoolean();
+
+        final CompletableFuture<Exchange> resultAsync = template.asyncSend("direct:sendAsync", exchange -> {
+            exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
+            exchange.getIn().setBody(messageBody);
+        });
+
+        resultAsync.whenComplete((exchange, throwable) -> {
+            // we sent our exchange, let's check it out
+            final Boolean eventFlag = consumerAsyncClient.receiveFromPartition(firstPartition, EventPosition.earliest())
+                    .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
+                            && partitionEvent.getData().getBodyAsString()
+                                    .contains(messageBody))
+                    .block();
+
+            if (eventFlag == null) {
+                eventExists.set(false);
+            }
+
+            eventExists.set(eventFlag);
+        });
+
+        result.expectedMinimumMessageCount(1);
+        result.setAssertPeriod(20000);
+        result.assertIsSatisfied();
+
+        assertTrue(eventExists.get());
+    }
+
+    @Test
+    public void testSendingNonValidData() throws InterruptedException {
+
+        final String messageBody = RandomStringUtils.randomAlphabetic(30);
+        final String firstPartition = "0";
+
+        final AtomicReference<Exchange> resultExchange = new AtomicReference<>();
+
+        final CompletableFuture<Exchange> resultAsync = template.asyncSend("direct:sendAsync", exchange -> {
+            exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
+            exchange.getIn().setHeader(EventHubsConstants.PARTITION_KEY, "testKey");
+            exchange.getIn().setBody(messageBody);
+        });
+
+        resultAsync.whenComplete((exchange, throwable) -> resultExchange.set(exchange));
+
+        result.setAssertPeriod(100);
+        result.assertIsSatisfied();
+
+        assertNotNull(resultExchange.get());
+        assertNotNull(resultExchange.get().getException());
+    }
+
+    @AfterAll
+    public void tearDown() {
+        consumerAsyncClient.close();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:sendAsync")
+                        .to("azure-eventhubs:?connectionString=RAW({{connectionString}})")
+                        .to(result);
+            }
+        };
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorIT.java b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorIT.java
new file mode 100644
index 0000000..f0273a0
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorIT.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+
+import com.azure.messaging.eventhubs.EventData;
+import com.azure.messaging.eventhubs.EventHubClientBuilder;
+import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
+import com.azure.messaging.eventhubs.EventProcessorClient;
+import com.azure.messaging.eventhubs.models.ErrorContext;
+import com.azure.messaging.eventhubs.models.EventContext;
+import com.azure.messaging.eventhubs.models.EventPosition;
+import com.azure.messaging.eventhubs.models.SendOptions;
+import com.azure.storage.blob.BlobContainerAsyncClient;
+import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public class EventProcessorIT {
+
+    private EventHubsConfiguration configuration;
+    private BlobContainerAsyncClient containerAsyncClient;
+
+    @BeforeAll
+    public void prepare() throws Exception {
+        final Properties properties = TestUtils.loadAzureAccessFromJvmEnv();
+        final String containerName = RandomStringUtils.randomAlphabetic(5).toLowerCase();
+
+        configuration = new EventHubsConfiguration();
+        configuration.setConnectionString(properties.getProperty("connectionString"));
+        configuration.setConsumerGroupName(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME);
+        configuration.setBlobAccessKey(properties.getProperty("blobAccessKey"));
+        configuration.setBlobAccountName(properties.getProperty("blobAccountName"));
+
+        Map<String, EventPosition> positionMap = new HashMap<>();
+        positionMap.put("0", EventPosition.earliest());
+
+        configuration.setEventPosition(positionMap);
+        configuration.setBlobContainerName(containerName);
+
+        containerAsyncClient = EventHubsClientFactory.createBlobContainerClient(configuration);
+
+        // create test container
+        containerAsyncClient.create().block();
+    }
+
+    @Test
+    public void testEventProcessingWithBlobCheckpointStore() {
+        final AtomicBoolean doneAsync = new AtomicBoolean();
+        final EventHubProducerAsyncClient producerAsyncClient
+                = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
+        final Consumer<EventContext> onEvent = eventContext -> {
+            final String body = eventContext.getEventData().getBodyAsString();
+            if (eventContext.getPartitionContext().getPartitionId().equals("0")
+                    && body.contains("Testing Event Consumer With BlobStore")) {
+                assertTrue(true);
+                doneAsync.set(true);
+            }
+        };
+        final Consumer<ErrorContext> onError = errorContext -> {
+        };
+        final EventProcessorClient processorClient
+                = EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError);
+
+        processorClient.start();
+
+        producerAsyncClient.send(Collections.singletonList(new EventData("Testing Event Consumer With BlobStore")),
+                new SendOptions().setPartitionId("0")).block();
+
+        Awaitility.await()
+                .timeout(30, TimeUnit.SECONDS)
+                .untilTrue(doneAsync);
+
+        processorClient.stop();
+        producerAsyncClient.close();
+    }
+
+    @AfterAll
+    public void tearDown() {
+        containerAsyncClient.delete().block();
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorTest.java b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorTest.java
new file mode 100644
index 0000000..9b4ba1f
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.util.function.Consumer;
+
+import com.azure.messaging.eventhubs.models.ErrorContext;
+import com.azure.messaging.eventhubs.models.EventContext;
+import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class EventProcessorTest {
+
+    @Test
+    public void testCreateEventProcessorWithNonValidOptions() {
+        final EventHubsConfiguration configuration = new EventHubsConfiguration();
+        final Consumer<EventContext> onEvent = event -> {
+        };
+        final Consumer<ErrorContext> onError = error -> {
+        };
+
+        assertThrows(IllegalArgumentException.class,
+                () -> EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
+
+        configuration.setBlobContainerName("testContainer");
+        assertThrows(IllegalArgumentException.class,
+                () -> EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
+
+        configuration.setBlobAccountName("testAcc");
+        assertThrows(IllegalArgumentException.class,
+                () -> EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
+
+        configuration.setBlobAccessKey("testAccess");
+        assertNotNull(EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
+
+        configuration.setBlobContainerName(null);
+        assertThrows(IllegalArgumentException.class,
+                () -> EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/TestUtils.java b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/TestUtils.java
new file mode 100644
index 0000000..0d6f6df
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/TestUtils.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Objects;
+import java.util.Properties;
+
+public final class TestUtils {
+
+    public static final String CONNECTION_STRING = "connectionString";
+    public static final String BLOB_ACCOUNT_NAME = "blobAccountName";
+    public static final String BLOB_ACCESS_KEY = "blobAccessKey";
+
+    private TestUtils() {
+    }
+
+    public static Properties loadAzurePropertiesFile() throws IOException {
+        final Properties properties = new Properties();
+        final String fileName = "azure_key.properties";
+
+        final InputStream inputStream = Objects.requireNonNull(TestUtils.class.getClassLoader().getResourceAsStream(fileName));
+
+        properties.load(inputStream);
+
+        return properties;
+    }
+
+    public static Properties loadAzureAccessFromJvmEnv() throws Exception {
+        final Properties properties = new Properties();
+        if (System.getProperty(CONNECTION_STRING) == null
+                || System.getProperty(BLOB_ACCOUNT_NAME) == null
+                || System.getProperty(BLOB_ACCESS_KEY) == null) {
+            throw new Exception(
+                    "Make sure to supply azure eventHubs connectionString, e.g:  mvn verify -PfullTests -DconnectionString=string"
+                                + " -DblobAccountName=blob -DblobAccessKey=key");
+        }
+        properties.setProperty(CONNECTION_STRING, System.getProperty(CONNECTION_STRING));
+        properties.setProperty(BLOB_ACCOUNT_NAME, System.getProperty(BLOB_ACCOUNT_NAME));
+        properties.setProperty(BLOB_ACCESS_KEY, System.getProperty(BLOB_ACCESS_KEY));
+
+        return properties;
+    }
+
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperationsIT.java b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperationsIT.java
new file mode 100644
index 0000000..e5d7960
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperationsIT.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.eventhubs.operations;
+
+import java.time.Duration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import com.azure.messaging.eventhubs.EventHubClientBuilder;
+import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
+import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
+import com.azure.messaging.eventhubs.models.EventPosition;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.azure.eventhubs.EventHubsConfiguration;
+import org.apache.camel.component.azure.eventhubs.EventHubsConstants;
+import org.apache.camel.component.azure.eventhubs.TestUtils;
+import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+class EventHubsProducerOperationsIT extends CamelTestSupport {
+
+    private EventHubsConfiguration configuration;
+    private EventHubProducerAsyncClient producerAsyncClient;
+    private EventHubConsumerAsyncClient consumerAsyncClient;
+
+    @BeforeAll
+    public void prepare() throws Exception {
+        final Properties properties = TestUtils.loadAzureAccessFromJvmEnv();
+
+        configuration = new EventHubsConfiguration();
+        configuration.setConnectionString(properties.getProperty("connectionString"));
+        configuration.setConsumerGroupName(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME);
+
+        producerAsyncClient = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
+        consumerAsyncClient = EventHubsClientFactory.createEventHubConsumerAsyncClient(configuration);
+    }
+
+    @Test
+    public void testSendEventWithSpecificPartition() {
+        final EventHubsProducerOperations operations = new EventHubsProducerOperations(producerAsyncClient, configuration);
+        final String firstPartition = producerAsyncClient.getPartitionIds().blockLast();
+        final Exchange exchange = new DefaultExchange(context);
+
+        exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
+        exchange.getIn().setBody("test should be in firstPartition");
+
+        operations.sendEvents(exchange, doneSync -> {
+        });
+
+        Awaitility.await()
+                .atMost(30, TimeUnit.SECONDS)
+                .pollDelay(Duration.ofSeconds(2))
+                .pollInterval(Duration.ofSeconds(2))
+                .until(() -> {
+                    final Boolean eventExists = consumerAsyncClient
+                            .receiveFromPartition(firstPartition, EventPosition.earliest())
+                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
+                                    && partitionEvent.getData().getBodyAsString()
+                                            .contains("test should be in firstPartition"))
+                            .block();
+
+                    if (eventExists == null) {
+                        return false;
+                    }
+
+                    return eventExists;
+                });
+    }
+
+    @Test
+    public void testIterableExchangesSendEventsWithSpecificPartition() {
+        final EventHubsProducerOperations operations = new EventHubsProducerOperations(producerAsyncClient, configuration);
+        final String firstPartition = producerAsyncClient.getPartitionIds().blockLast();
+
+        final Exchange exchange1 = new DefaultExchange(context);
+        final Exchange exchange2 = new DefaultExchange(context);
+
+        exchange1.getIn().setBody("Exchange Message 1");
+        exchange2.getIn().setBody("Exchange Message 2");
+
+        final List<Exchange> exchanges = new LinkedList<>();
+        exchanges.add(exchange1);
+        exchanges.add(exchange2);
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(exchanges);
+
+        operations.sendEvents(exchange, doneSync -> {
+        });
+
+        Awaitility.await()
+                .atMost(40, TimeUnit.SECONDS)
+                .pollDelay(Duration.ofSeconds(2))
+                .pollInterval(Duration.ofSeconds(2))
+                .until(() -> {
+                    final Boolean event1Exists = consumerAsyncClient
+                            .receiveFromPartition(firstPartition, EventPosition.earliest())
+                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
+                                    && partitionEvent.getData().getBodyAsString()
+                                            .contains("Exchange Message 1"))
+                            .block();
+
+                    final Boolean event2Exists = consumerAsyncClient
+                            .receiveFromPartition(firstPartition, EventPosition.earliest())
+                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
+                                    && partitionEvent.getData().getBodyAsString()
+                                            .contains("Exchange Message 2"))
+                            .block();
+
+                    if (event1Exists == null || event2Exists == null) {
+                        return false;
+                    }
+
+                    return event1Exists && event2Exists;
+                });
+    }
+
+    @Test
+    public void testIterableStringSendEventsWithSpecificPartition() {
+        final EventHubsProducerOperations operations = new EventHubsProducerOperations(producerAsyncClient, configuration);
+        final String firstPartition = producerAsyncClient.getPartitionIds().blockLast();
+
+        final List<String> messages = new LinkedList<>();
+        messages.add("Test String Message 1");
+        messages.add("Test String Message 2");
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(messages);
+
+        operations.sendEvents(exchange, doneSync -> {
+        });
+
+        Awaitility.await()
+                .atMost(40, TimeUnit.SECONDS)
+                .pollDelay(Duration.ofSeconds(2))
+                .pollInterval(Duration.ofSeconds(2))
+                .until(() -> {
+                    final Boolean event1Exists = consumerAsyncClient
+                            .receiveFromPartition(firstPartition, EventPosition.earliest())
+                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
+                                    && partitionEvent.getData().getBodyAsString()
+                                            .contains("Test String Message 1"))
+                            .block();
+
+                    final Boolean event2Exists = consumerAsyncClient
+                            .receiveFromPartition(firstPartition, EventPosition.earliest())
+                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
+                                    && partitionEvent.getData().getBodyAsString()
+                                            .contains("Test String Message 2"))
+                            .block();
+
+                    if (event1Exists == null || event2Exists == null) {
+                        return false;
+                    }
+
+                    return event1Exists && event2Exists;
+                });
+    }
+
+    @AfterAll
+    public void tearDown() {
+        producerAsyncClient.close();
+        consumerAsyncClient.close();
+    }
+}
diff --git a/components/camel-azure/camel-azure-eventhubs/src/test/resources/log4j2.properties b/components/camel-azure/camel-azure-eventhubs/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..5ec8843
--- /dev/null
+++ b/components/camel-azure/camel-azure-eventhubs/src/test/resources/log4j2.properties
@@ -0,0 +1,27 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-eventhubs-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
\ No newline at end of file
diff --git a/components/camel-azure/camel-azure-storage-blob/pom.xml b/components/camel-azure/camel-azure-storage-blob/pom.xml
new file mode 100644
index 0000000..b3a338f
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-azure-parent</artifactId>
+        <version>3.9.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-azure-storage-blob</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Camel :: Azure Storage Blob</name>
+    <description>Camel Azure Blob Storage Service Component</description>
+
+    <properties>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+
+        <!-- azure sdk -->
+        <dependency>
+            <groupId>com.azure</groupId>
+            <artifactId>azure-storage-blob</artifactId>
+            <version>${azure-storage-blob-java-sdk12-version}</version>
+        </dependency>
+
+        <!-- extras -->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <!-- for testing -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${commons-lang3-version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testcontainers</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>${testcontainers-version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- test infra -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-azure-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-azure-storage-blob</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
new file mode 100644
index 0000000..7100ed3
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
@@ -0,0 +1,200 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class BlobComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    private org.apache.camel.component.azure.storage.blob.BlobConfiguration getOrCreateConfiguration(BlobComponent target) {
+        if (target.getConfiguration() == null) {
+            target.setConfiguration(new org.apache.camel.component.azure.storage.blob.BlobConfiguration());
+        }
+        return target.getConfiguration();
+    }
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        BlobComponent target = (BlobComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "accesskey":
+        case "accessKey": getOrCreateConfiguration(target).setAccessKey(property(camelContext, java.lang.String.class, value)); return true;
+        case "autodiscoverclient":
+        case "autoDiscoverClient": getOrCreateConfiguration(target).setAutoDiscoverClient(property(camelContext, boolean.class, value)); return true;
+        case "autowiredenabled":
+        case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true;
+        case "blobname":
+        case "blobName": getOrCreateConfiguration(target).setBlobName(property(camelContext, java.lang.String.class, value)); return true;
+        case "bloboffset":
+        case "blobOffset": getOrCreateConfiguration(target).setBlobOffset(property(camelContext, long.class, value)); return true;
+        case "blobsequencenumber":
+        case "blobSequenceNumber": getOrCreateConfiguration(target).setBlobSequenceNumber(property(camelContext, java.lang.Long.class, value)); return true;
+        case "blobtype":
+        case "blobType": getOrCreateConfiguration(target).setBlobType(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobType.class, value)); return true;
+        case "blocklisttype":
+        case "blockListType": getOrCreateConfiguration(target).setBlockListType(property(camelContext, com.azure.storage.blob.models.BlockListType.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "closestreamafterread":
+        case "closeStreamAfterRead": getOrCreateConfiguration(target).setCloseStreamAfterRead(property(camelContext, boolean.class, value)); return true;
+        case "closestreamafterwrite":
+        case "closeStreamAfterWrite": getOrCreateConfiguration(target).setCloseStreamAfterWrite(property(camelContext, boolean.class, value)); return true;
+        case "commitblocklistlater":
+        case "commitBlockListLater": getOrCreateConfiguration(target).setCommitBlockListLater(property(camelContext, boolean.class, value)); return true;
+        case "configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobConfiguration.class, value)); return true;
+        case "createappendblob":
+        case "createAppendBlob": getOrCreateConfiguration(target).setCreateAppendBlob(property(camelContext, boolean.class, value)); return true;
+        case "createpageblob":
+        case "createPageBlob": getOrCreateConfiguration(target).setCreatePageBlob(property(camelContext, boolean.class, value)); return true;
+        case "credentials": getOrCreateConfiguration(target).setCredentials(property(camelContext, com.azure.storage.common.StorageSharedKeyCredential.class, value)); return true;
+        case "datacount":
+        case "dataCount": getOrCreateConfiguration(target).setDataCount(property(camelContext, java.lang.Long.class, value)); return true;
+        case "downloadlinkexpiration":
+        case "downloadLinkExpiration": getOrCreateConfiguration(target).setDownloadLinkExpiration(property(camelContext, java.lang.Long.class, value)); return true;
+        case "filedir":
+        case "fileDir": getOrCreateConfiguration(target).setFileDir(property(camelContext, java.lang.String.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        case "maxresultsperpage":
+        case "maxResultsPerPage": getOrCreateConfiguration(target).setMaxResultsPerPage(property(camelContext, java.lang.Integer.class, value)); return true;
+        case "maxretryrequests":
+        case "maxRetryRequests": getOrCreateConfiguration(target).setMaxRetryRequests(property(camelContext, int.class, value)); return true;
+        case "operation": getOrCreateConfiguration(target).setOperation(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition.class, value)); return true;
+        case "pageblobsize":
+        case "pageBlobSize": getOrCreateConfiguration(target).setPageBlobSize(property(camelContext, java.lang.Long.class, value)); return true;
+        case "prefix": getOrCreateConfiguration(target).setPrefix(property(camelContext, java.lang.String.class, value)); return true;
+        case "regex": getOrCreateConfiguration(target).setRegex(property(camelContext, java.lang.String.class, value)); return true;
+        case "serviceclient":
+        case "serviceClient": getOrCreateConfiguration(target).setServiceClient(property(camelContext, com.azure.storage.blob.BlobServiceClient.class, value)); return true;
+        case "timeout": getOrCreateConfiguration(target).setTimeout(property(camelContext, java.time.Duration.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "accesskey":
+        case "accessKey": return java.lang.String.class;
+        case "autodiscoverclient":
+        case "autoDiscoverClient": return boolean.class;
+        case "autowiredenabled":
+        case "autowiredEnabled": return boolean.class;
+        case "blobname":
+        case "blobName": return java.lang.String.class;
+        case "bloboffset":
+        case "blobOffset": return long.class;
+        case "blobsequencenumber":
+        case "blobSequenceNumber": return java.lang.Long.class;
+        case "blobtype":
+        case "blobType": return org.apache.camel.component.azure.storage.blob.BlobType.class;
+        case "blocklisttype":
+        case "blockListType": return com.azure.storage.blob.models.BlockListType.class;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return boolean.class;
+        case "closestreamafterread":
+        case "closeStreamAfterRead": return boolean.class;
+        case "closestreamafterwrite":
+        case "closeStreamAfterWrite": return boolean.class;
+        case "commitblocklistlater":
+        case "commitBlockListLater": return boolean.class;
+        case "configuration": return org.apache.camel.component.azure.storage.blob.BlobConfiguration.class;
+        case "createappendblob":
+        case "createAppendBlob": return boolean.class;
+        case "createpageblob":
+        case "createPageBlob": return boolean.class;
+        case "credentials": return com.azure.storage.common.StorageSharedKeyCredential.class;
+        case "datacount":
+        case "dataCount": return java.lang.Long.class;
+        case "downloadlinkexpiration":
+        case "downloadLinkExpiration": return java.lang.Long.class;
+        case "filedir":
+        case "fileDir": return java.lang.String.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        case "maxresultsperpage":
+        case "maxResultsPerPage": return java.lang.Integer.class;
+        case "maxretryrequests":
+        case "maxRetryRequests": return int.class;
+        case "operation": return org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition.class;
+        case "pageblobsize":
+        case "pageBlobSize": return java.lang.Long.class;
+        case "prefix": return java.lang.String.class;
+        case "regex": return java.lang.String.class;
+        case "serviceclient":
+        case "serviceClient": return com.azure.storage.blob.BlobServiceClient.class;
+        case "timeout": return java.time.Duration.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        BlobComponent target = (BlobComponent) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "accesskey":
+        case "accessKey": return getOrCreateConfiguration(target).getAccessKey();
+        case "autodiscoverclient":
+        case "autoDiscoverClient": return getOrCreateConfiguration(target).isAutoDiscoverClient();
+        case "autowiredenabled":
+        case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "blobname":
+        case "blobName": return getOrCreateConfiguration(target).getBlobName();
+        case "bloboffset":
+        case "blobOffset": return getOrCreateConfiguration(target).getBlobOffset();
+        case "blobsequencenumber":
+        case "blobSequenceNumber": return getOrCreateConfiguration(target).getBlobSequenceNumber();
+        case "blobtype":
+        case "blobType": return getOrCreateConfiguration(target).getBlobType();
+        case "blocklisttype":
+        case "blockListType": return getOrCreateConfiguration(target).getBlockListType();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "closestreamafterread":
+        case "closeStreamAfterRead": return getOrCreateConfiguration(target).isCloseStreamAfterRead();
+        case "closestreamafterwrite":
+        case "closeStreamAfterWrite": return getOrCreateConfiguration(target).isCloseStreamAfterWrite();
+        case "commitblocklistlater":
+        case "commitBlockListLater": return getOrCreateConfiguration(target).isCommitBlockListLater();
+        case "configuration": return target.getConfiguration();
+        case "createappendblob":
+        case "createAppendBlob": return getOrCreateConfiguration(target).isCreateAppendBlob();
+        case "createpageblob":
+        case "createPageBlob": return getOrCreateConfiguration(target).isCreatePageBlob();
+        case "credentials": return getOrCreateConfiguration(target).getCredentials();
+        case "datacount":
+        case "dataCount": return getOrCreateConfiguration(target).getDataCount();
+        case "downloadlinkexpiration":
+        case "downloadLinkExpiration": return getOrCreateConfiguration(target).getDownloadLinkExpiration();
+        case "filedir":
+        case "fileDir": return getOrCreateConfiguration(target).getFileDir();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        case "maxresultsperpage":
+        case "maxResultsPerPage": return getOrCreateConfiguration(target).getMaxResultsPerPage();
+        case "maxretryrequests":
+        case "maxRetryRequests": return getOrCreateConfiguration(target).getMaxRetryRequests();
+        case "operation": return getOrCreateConfiguration(target).getOperation();
+        case "pageblobsize":
+        case "pageBlobSize": return getOrCreateConfiguration(target).getPageBlobSize();
+        case "prefix": return getOrCreateConfiguration(target).getPrefix();
+        case "regex": return getOrCreateConfiguration(target).getRegex();
+        case "serviceclient":
+        case "serviceClient": return getOrCreateConfiguration(target).getServiceClient();
+        case "timeout": return getOrCreateConfiguration(target).getTimeout();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
new file mode 100644
index 0000000..78990ee
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
@@ -0,0 +1,202 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
+import org.apache.camel.spi.PropertyConfigurerGetter;
+import org.apache.camel.spi.ConfigurerStrategy;
+import org.apache.camel.spi.GeneratedPropertyConfigurer;
+import org.apache.camel.util.CaseInsensitiveMap;
+import org.apache.camel.support.component.PropertyConfigurerSupport;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@SuppressWarnings("unchecked")
+public class BlobEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
+
+    @Override
+    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
+        BlobEndpoint target = (BlobEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "accesskey":
+        case "accessKey": target.getConfiguration().setAccessKey(property(camelContext, java.lang.String.class, value)); return true;
+        case "autodiscoverclient":
+        case "autoDiscoverClient": target.getConfiguration().setAutoDiscoverClient(property(camelContext, boolean.class, value)); return true;
+        case "blobname":
+        case "blobName": target.getConfiguration().setBlobName(property(camelContext, java.lang.String.class, value)); return true;
+        case "bloboffset":
+        case "blobOffset": target.getConfiguration().setBlobOffset(property(camelContext, long.class, value)); return true;
+        case "blobsequencenumber":
+        case "blobSequenceNumber": target.getConfiguration().setBlobSequenceNumber(property(camelContext, java.lang.Long.class, value)); return true;
+        case "blobserviceclient":
+        case "blobServiceClient": target.setBlobServiceClient(property(camelContext, com.azure.storage.blob.BlobServiceClient.class, value)); return true;
+        case "blobtype":
+        case "blobType": target.getConfiguration().setBlobType(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobType.class, value)); return true;
+        case "blocklisttype":
+        case "blockListType": target.getConfiguration().setBlockListType(property(camelContext, com.azure.storage.blob.models.BlockListType.class, value)); return true;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "closestreamafterread":
+        case "closeStreamAfterRead": target.getConfiguration().setCloseStreamAfterRead(property(camelContext, boolean.class, value)); return true;
+        case "closestreamafterwrite":
+        case "closeStreamAfterWrite": target.getConfiguration().setCloseStreamAfterWrite(property(camelContext, boolean.class, value)); return true;
+        case "commitblocklistlater":
+        case "commitBlockListLater": target.getConfiguration().setCommitBlockListLater(property(camelContext, boolean.class, value)); return true;
+        case "createappendblob":
+        case "createAppendBlob": target.getConfiguration().setCreateAppendBlob(property(camelContext, boolean.class, value)); return true;
+        case "createpageblob":
+        case "createPageBlob": target.getConfiguration().setCreatePageBlob(property(camelContext, boolean.class, value)); return true;
+        case "credentials": target.getConfiguration().setCredentials(property(camelContext, com.azure.storage.common.StorageSharedKeyCredential.class, value)); return true;
+        case "datacount":
+        case "dataCount": target.getConfiguration().setDataCount(property(camelContext, java.lang.Long.class, value)); return true;
+        case "downloadlinkexpiration":
+        case "downloadLinkExpiration": target.getConfiguration().setDownloadLinkExpiration(property(camelContext, java.lang.Long.class, value)); return true;
+        case "exceptionhandler":
+        case "exceptionHandler": target.setExceptionHandler(property(camelContext, org.apache.camel.spi.ExceptionHandler.class, value)); return true;
+        case "exchangepattern":
+        case "exchangePattern": target.setExchangePattern(property(camelContext, org.apache.camel.ExchangePattern.class, value)); return true;
+        case "filedir":
+        case "fileDir": target.getConfiguration().setFileDir(property(camelContext, java.lang.String.class, value)); return true;
+        case "lazystartproducer":
+        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        case "maxresultsperpage":
+        case "maxResultsPerPage": target.getConfiguration().setMaxResultsPerPage(property(camelContext, java.lang.Integer.class, value)); return true;
+        case "maxretryrequests":
+        case "maxRetryRequests": target.getConfiguration().setMaxRetryRequests(property(camelContext, int.class, value)); return true;
+        case "operation": target.getConfiguration().setOperation(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition.class, value)); return true;
+        case "pageblobsize":
+        case "pageBlobSize": target.getConfiguration().setPageBlobSize(property(camelContext, java.lang.Long.class, value)); return true;
+        case "prefix": target.getConfiguration().setPrefix(property(camelContext, java.lang.String.class, value)); return true;
+        case "regex": target.getConfiguration().setRegex(property(camelContext, java.lang.String.class, value)); return true;
+        case "serviceclient":
+        case "serviceClient": target.getConfiguration().setServiceClient(property(camelContext, com.azure.storage.blob.BlobServiceClient.class, value)); return true;
+        case "timeout": target.getConfiguration().setTimeout(property(camelContext, java.time.Duration.class, value)); return true;
+        default: return false;
+        }
+    }
+
+    @Override
+    public Class<?> getOptionType(String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "accesskey":
+        case "accessKey": return java.lang.String.class;
+        case "autodiscoverclient":
+        case "autoDiscoverClient": return boolean.class;
+        case "blobname":
+        case "blobName": return java.lang.String.class;
+        case "bloboffset":
+        case "blobOffset": return long.class;
+        case "blobsequencenumber":
+        case "blobSequenceNumber": return java.lang.Long.class;
+        case "blobserviceclient":
+        case "blobServiceClient": return com.azure.storage.blob.BlobServiceClient.class;
+        case "blobtype":
+        case "blobType": return org.apache.camel.component.azure.storage.blob.BlobType.class;
+        case "blocklisttype":
+        case "blockListType": return com.azure.storage.blob.models.BlockListType.class;
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return boolean.class;
+        case "closestreamafterread":
+        case "closeStreamAfterRead": return boolean.class;
+        case "closestreamafterwrite":
+        case "closeStreamAfterWrite": return boolean.class;
+        case "commitblocklistlater":
+        case "commitBlockListLater": return boolean.class;
+        case "createappendblob":
+        case "createAppendBlob": return boolean.class;
+        case "createpageblob":
+        case "createPageBlob": return boolean.class;
+        case "credentials": return com.azure.storage.common.StorageSharedKeyCredential.class;
+        case "datacount":
+        case "dataCount": return java.lang.Long.class;
+        case "downloadlinkexpiration":
+        case "downloadLinkExpiration": return java.lang.Long.class;
+        case "exceptionhandler":
+        case "exceptionHandler": return org.apache.camel.spi.ExceptionHandler.class;
+        case "exchangepattern":
+        case "exchangePattern": return org.apache.camel.ExchangePattern.class;
+        case "filedir":
+        case "fileDir": return java.lang.String.class;
+        case "lazystartproducer":
+        case "lazyStartProducer": return boolean.class;
+        case "maxresultsperpage":
+        case "maxResultsPerPage": return java.lang.Integer.class;
+        case "maxretryrequests":
+        case "maxRetryRequests": return int.class;
+        case "operation": return org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition.class;
+        case "pageblobsize":
+        case "pageBlobSize": return java.lang.Long.class;
+        case "prefix": return java.lang.String.class;
+        case "regex": return java.lang.String.class;
+        case "serviceclient":
+        case "serviceClient": return com.azure.storage.blob.BlobServiceClient.class;
+        case "timeout": return java.time.Duration.class;
+        default: return null;
+        }
+    }
+
+    @Override
+    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
+        BlobEndpoint target = (BlobEndpoint) obj;
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "accesskey":
+        case "accessKey": return target.getConfiguration().getAccessKey();
+        case "autodiscoverclient":
+        case "autoDiscoverClient": return target.getConfiguration().isAutoDiscoverClient();
+        case "blobname":
+        case "blobName": return target.getConfiguration().getBlobName();
+        case "bloboffset":
+        case "blobOffset": return target.getConfiguration().getBlobOffset();
+        case "blobsequencenumber":
+        case "blobSequenceNumber": return target.getConfiguration().getBlobSequenceNumber();
+        case "blobserviceclient":
+        case "blobServiceClient": return target.getBlobServiceClient();
+        case "blobtype":
+        case "blobType": return target.getConfiguration().getBlobType();
+        case "blocklisttype":
+        case "blockListType": return target.getConfiguration().getBlockListType();
+        case "bridgeerrorhandler":
+        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "closestreamafterread":
+        case "closeStreamAfterRead": return target.getConfiguration().isCloseStreamAfterRead();
+        case "closestreamafterwrite":
+        case "closeStreamAfterWrite": return target.getConfiguration().isCloseStreamAfterWrite();
+        case "commitblocklistlater":
+        case "commitBlockListLater": return target.getConfiguration().isCommitBlockListLater();
+        case "createappendblob":
+        case "createAppendBlob": return target.getConfiguration().isCreateAppendBlob();
+        case "createpageblob":
+        case "createPageBlob": return target.getConfiguration().isCreatePageBlob();
+        case "credentials": return target.getConfiguration().getCredentials();
+        case "datacount":
+        case "dataCount": return target.getConfiguration().getDataCount();
+        case "downloadlinkexpiration":
+        case "downloadLinkExpiration": return target.getConfiguration().getDownloadLinkExpiration();
+        case "exceptionhandler":
+        case "exceptionHandler": return target.getExceptionHandler();
+        case "exchangepattern":
+        case "exchangePattern": return target.getExchangePattern();
+        case "filedir":
+        case "fileDir": return target.getConfiguration().getFileDir();
+        case "lazystartproducer":
+        case "lazyStartProducer": return target.isLazyStartProducer();
+        case "maxresultsperpage":
+        case "maxResultsPerPage": return target.getConfiguration().getMaxResultsPerPage();
+        case "maxretryrequests":
+        case "maxRetryRequests": return target.getConfiguration().getMaxRetryRequests();
+        case "operation": return target.getConfiguration().getOperation();
+        case "pageblobsize":
+        case "pageBlobSize": return target.getConfiguration().getPageBlobSize();
+        case "prefix": return target.getConfiguration().getPrefix();
+        case "regex": return target.getConfiguration().getRegex();
+        case "serviceclient":
+        case "serviceClient": return target.getConfiguration().getServiceClient();
+        case "timeout": return target.getConfiguration().getTimeout();
+        default: return null;
+        }
+    }
+}
+
diff --git a/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
new file mode 100644
index 0000000..3bc4ecc
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
@@ -0,0 +1,94 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.spi.EndpointUriFactory;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+public class BlobEndpointUriFactory extends org.apache.camel.support.component.EndpointUriFactorySupport implements EndpointUriFactory {
+
+    private static final String BASE = ":accountName/containerName";
+
+    private static final Set<String> PROPERTY_NAMES;
+    private static final Set<String> SECRET_PROPERTY_NAMES;
+    static {
+        Set<String> props = new HashSet<>(31);
+        props.add("blobName");
+        props.add("accountName");
+        props.add("credentials");
+        props.add("prefix");
+        props.add("createPageBlob");
+        props.add("blobOffset");
+        props.add("timeout");
+        props.add("dataCount");
+        props.add("blobServiceClient");
+        props.add("maxRetryRequests");
+        props.add("bridgeErrorHandler");
+        props.add("containerName");
+        props.add("closeStreamAfterRead");
+        props.add("closeStreamAfterWrite");
+        props.add("autoDiscoverClient");
+        props.add("maxResultsPerPage");
+        props.add("downloadLinkExpiration");
+        props.add("exchangePattern");
+        props.add("blockListType");
+        props.add("createAppendBlob");
+        props.add("regex");
+        props.add("lazyStartProducer");
+        props.add("blobSequenceNumber");
+        props.add("accessKey");
+        props.add("commitBlockListLater");
+        props.add("serviceClient");
+        props.add("fileDir");
+        props.add("blobType");
+        props.add("pageBlobSize");
+        props.add("exceptionHandler");
+        props.add("operation");
+        PROPERTY_NAMES = Collections.unmodifiableSet(props);
+        Set<String> secretProps = new HashSet<>(1);
+        secretProps.add("accessKey");
+        SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps);
+    }
+
+    @Override
+    public boolean isEnabled(String scheme) {
+        return "azure-storage-blob".equals(scheme);
+    }
+
+    @Override
+    public String buildUri(String scheme, Map<String, Object> properties, boolean encode) throws URISyntaxException {
+        String syntax = scheme + BASE;
+        String uri = syntax;
+
+        Map<String, Object> copy = new HashMap<>(properties);
+
+        uri = buildPathParameter(syntax, uri, "accountName", null, false, copy);
+        uri = buildPathParameter(syntax, uri, "containerName", null, false, copy);
+        uri = buildQueryParameters(uri, copy, encode);
+        return uri;
+    }
+
+    @Override
+    public Set<String> propertyNames() {
+        return PROPERTY_NAMES;
+    }
+
+    @Override
+    public Set<String> secretPropertyNames() {
+        return SECRET_PROPERTY_NAMES;
+    }
+
+    @Override
+    public boolean isLenientProperties() {
+        return false;
+    }
+}
+
diff --git a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component.properties b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component.properties
new file mode 100644
index 0000000..68ceed4
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+components=azure-storage-blob
+groupId=org.apache.camel
+artifactId=camel-azure-storage-blob
+version=3.9.0-SNAPSHOT
+projectName=Camel :: Azure Storage Blob
+projectDescription=Camel Azure Blob Storage Service Component
diff --git a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component/azure-storage-blob b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component/azure-storage-blob
new file mode 100644
index 0000000..cf117de
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component/azure-storage-blob
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.azure.storage.blob.BlobComponent
diff --git a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-component b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-component
new file mode 100644
index 0000000..cc4ee61
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-component
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.azure.storage.blob.BlobComponentConfigurer
diff --git a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-endpoint b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-endpoint
new file mode 100644
index 0000000..e8f26cb
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.azure.storage.blob.BlobEndpointConfigurer
diff --git a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-storage-blob-endpoint b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-storage-blob-endpoint
new file mode 100644
index 0000000..cd307b4
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-storage-blob-endpoint
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.component.azure.storage.blob.BlobEndpointUriFactory
diff --git a/components/camel-azure/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
new file mode 100644
index 0000000..1a50cca
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
@@ -0,0 +1,87 @@
+{
+  "component": {
+    "kind": "component",
+    "name": "azure-storage-blob",
+    "title": "Azure Storage Blob Service",
+    "description": "Store and retrieve blobs from Azure Storage Blob Service using SDK v12.",
+    "deprecated": false,
+    "firstVersion": "3.3.0",
+    "label": "cloud,file",
+    "javaType": "org.apache.camel.component.azure.storage.blob.BlobComponent",
+    "supportLevel": "Stable",
+    "groupId": "org.apache.camel",
+    "artifactId": "camel-azure-storage-blob",
+    "version": "3.9.0-SNAPSHOT",
+    "scheme": "azure-storage-blob",
+    "extendsScheme": "",
+    "syntax": "azure-storage-blob:accountName\/containerName",
+    "async": false,
+    "api": false,
+    "consumerOnly": false,
+    "producerOnly": false,
+    "lenientProperties": false
+  },
+  "componentProperties": {
+    "autoDiscoverClient": { "kind": "property", "displayName": "Auto Discover Client", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Setting the autoDiscoverClient mechanism, if true, the component will look for a c [...]
+    "blobName": { "kind": "property", "displayName": "Blob Name", "group": "common", "label": "common", "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": "The blob name, to consume specific blob from a container. However on producer, is only required for the operations on [...]
+    "blobOffset": { "kind": "property", "displayName": "Blob Offset", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Set the blob offset for the upload or download operations, default is 0" },
+    "blobType": { "kind": "property", "displayName": "Blob Type", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobType", "enum": [ "blockblob", "appendblob", "pageblob" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "blockblob", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description":  [...]
+    "closeStreamAfterRead": { "kind": "property", "displayName": "Close Stream After Read", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Close the stream after read or keep it open, default is true" },
+    "configuration": { "kind": "property", "displayName": "Configuration", "group": "common", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "deprecated": false, "autowired": false, "secret": false, "description": "The component configurations" },
+    "credentials": { "kind": "property", "displayName": "Credentials", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.common.StorageSharedKeyCredential", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "StorageSharedKeyCredential can be injected to create the azure client, this holds t [...]
+    "dataCount": { "kind": "property", "displayName": "Data Count", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "How many bytes to include in the range. Must be greater than or equal to 0 if specified." },
+    "fileDir": { "kind": "property", "displayName": "File Dir", "group": "common", "label": "common", "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": "The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer" },
+    "maxResultsPerPage": { "kind": "property", "displayName": "Max Results Per Page", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the requ [...]
+    "maxRetryRequests": { "kind": "property", "displayName": "Max Retry Requests", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum number of additional HTTP Get requests that will be made while reading  [...]
+    "prefix": { "kind": "property", "displayName": "Prefix", "group": "common", "label": "common", "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": "Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs." },
+    "regex": { "kind": "property", "displayName": "Regex", "group": "common", "label": "common", "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": "Filters the results to return only blobs whose names match the specified regular expression. May be null to return all if bo [...]
+    "serviceClient": { "kind": "property", "displayName": "Service Client", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.blob.BlobServiceClient", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Client to a storage account. This client does not hold any state about a particular stora [...]
+    "timeout": { "kind": "property", "displayName": "Timeout", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "java.time.Duration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "An optional timeout value beyond which a RuntimeException will be raised." },
+    "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a me [...]
+    "blobSequenceNumber": { "kind": "property", "displayName": "Blob Sequence Number", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "0", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "A user-controlled value that you can use to track requests. The value of [...]
+    "blockListType": { "kind": "property", "displayName": "Block List Type", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "com.azure.storage.blob.models.BlockListType", "enum": [ "committed", "uncommitted", "all" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "COMMITTED", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description":  [...]
+    "closeStreamAfterWrite": { "kind": "property", "displayName": "Close Stream After Write", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Close the stream after write or keep it open, default is true" },
+    "commitBlockListLater": { "kind": "property", "displayName": "Commit Block List Later", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the staged blocks will not be committed directly." },
+    "createAppendBlob": { "kind": "property", "displayName": "Create Append Blob", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the append blocks will be created when committing append blocks." },
+    "createPageBlob": { "kind": "property", "displayName": "Create Page Blob", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the page blob will be created when uploading page blob." },
+    "downloadLinkExpiration": { "kind": "property", "displayName": "Download Link Expiration", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Override the default expiration (millis) of URL download link." },
+    "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during star [...]
+    "operation": { "kind": "property", "displayName": "Operation", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition", "enum": [ "listBlobContainers", "createBlobContainer", "deleteBlobContainer", "listBlobs", "getBlob", "deleteBlob", "downloadBlobToFile", "downloadLink", "uploadBlockBlob", "stageBlockBlobList", "commitBlobBlockList", "getBlobBlockList", "createAppendBlob", "c [...]
+    "pageBlobSize": { "kind": "property", "displayName": "Page Blob Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "512", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum size for the page blob, up to 8 TB. The page blob size must  [...]
+    "autowiredEnabled": { "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which t [...]
+    "accessKey": { "kind": "property", "displayName": "Access Key", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Access key for the associated azure account name to be used for authentication with azure blob services" }
+  },
+  "properties": {
+    "accountName": { "kind": "path", "displayName": "Account Name", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Azure account name to be used for authentication with azure blob services" },
+    "containerName": { "kind": "path", "displayName": "Container 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": "The blob container name" },
+    "autoDiscoverClient": { "kind": "parameter", "displayName": "Auto Discover Client", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Setting the autoDiscoverClient mechanism, if true, the component will look for a  [...]
+    "blobName": { "kind": "parameter", "displayName": "Blob Name", "group": "common", "label": "common", "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": "The blob name, to consume specific blob from a container. However on producer, is only required for the operations o [...]
+    "blobOffset": { "kind": "parameter", "displayName": "Blob Offset", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Set the blob offset for the upload or download operations, default is 0" },
+    "blobServiceClient": { "kind": "parameter", "displayName": "Blob Service Client", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.blob.BlobServiceClient", "deprecated": false, "autowired": false, "secret": false, "description": "Client to a storage account. This client does not hold any state about a particular storage account but is instead a convenient way of sending off appropriate requests to the resource on the service. It may  [...]
+    "blobType": { "kind": "parameter", "displayName": "Blob Type", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobType", "enum": [ "blockblob", "appendblob", "pageblob" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "blockblob", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": [...]
+    "closeStreamAfterRead": { "kind": "parameter", "displayName": "Close Stream After Read", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Close the stream after read or keep it open, default is true" },
+    "credentials": { "kind": "parameter", "displayName": "Credentials", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.common.StorageSharedKeyCredential", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "StorageSharedKeyCredential can be injected to create the azure client, this holds  [...]
+    "dataCount": { "kind": "parameter", "displayName": "Data Count", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "How many bytes to include in the range. Must be greater than or equal to 0 if specified." },
+    "fileDir": { "kind": "parameter", "displayName": "File Dir", "group": "common", "label": "common", "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": "The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer" },
+    "maxResultsPerPage": { "kind": "parameter", "displayName": "Max Results Per Page", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the req [...]
+    "maxRetryRequests": { "kind": "parameter", "displayName": "Max Retry Requests", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum number of additional HTTP Get requests that will be made while reading [...]
+    "prefix": { "kind": "parameter", "displayName": "Prefix", "group": "common", "label": "common", "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": "Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs." },
+    "regex": { "kind": "parameter", "displayName": "Regex", "group": "common", "label": "common", "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": "Filters the results to return only blobs whose names match the specified regular expression. May be null to return all if b [...]
+    "serviceClient": { "kind": "parameter", "displayName": "Service Client", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.blob.BlobServiceClient", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Client to a storage account. This client does not hold any state about a particular stor [...]
+    "timeout": { "kind": "parameter", "displayName": "Timeout", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "java.time.Duration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "An optional timeout value beyond which a RuntimeException will be raised." },
+    "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a m [...]
+    "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the con [...]
+    "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
+    "blobSequenceNumber": { "kind": "parameter", "displayName": "Blob Sequence Number", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "0", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "A user-controlled value that you can use to track requests. The value o [...]
+    "blockListType": { "kind": "parameter", "displayName": "Block List Type", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "com.azure.storage.blob.models.BlockListType", "enum": [ "committed", "uncommitted", "all" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "COMMITTED", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": [...]
+    "closeStreamAfterWrite": { "kind": "parameter", "displayName": "Close Stream After Write", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Close the stream after write or keep it open, default is true" },
+    "commitBlockListLater": { "kind": "parameter", "displayName": "Commit Block List Later", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the staged blocks will not be committed directly." },
+    "createAppendBlob": { "kind": "parameter", "displayName": "Create Append Blob", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the append blocks will be created when committing append blo [...]
+    "createPageBlob": { "kind": "parameter", "displayName": "Create Page Blob", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the page blob will be created when uploading page blob." },
+    "downloadLinkExpiration": { "kind": "parameter", "displayName": "Download Link Expiration", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Override the default expiration (millis) of URL download link." },
+    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during sta [...]
+    "operation": { "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition", "enum": [ "listBlobContainers", "createBlobContainer", "deleteBlobContainer", "listBlobs", "getBlob", "deleteBlob", "downloadBlobToFile", "downloadLink", "uploadBlockBlob", "stageBlockBlobList", "commitBlobBlockList", "getBlobBlockList", "createAppendBlob", " [...]
+    "pageBlobSize": { "kind": "parameter", "displayName": "Page Blob Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "512", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum size for the page blob, up to 8 TB. The page blob size must [...]
+    "accessKey": { "kind": "parameter", "displayName": "Access Key", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Access key for the associated azure account name to be used for authentication with azure blob services" }
+  }
+}
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
new file mode 100644
index 0000000..abf081e
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
@@ -0,0 +1,697 @@
+[[azure-storage-blob-component]]
+= Azure Storage Blob Service Component
+:docTitle: Azure Storage Blob Service
+:artifactId: camel-azure-storage-blob
+:description: Store and retrieve blobs from Azure Storage Blob Service using SDK v12.
+:since: 3.3
+:supportLevel: Stable
+:component-header: Both producer and consumer are supported
+include::{cq-version}@camel-quarkus:ROOT:partial$reference/components/azure-storage-blob.adoc[opts=optional]
+//Manually maintained attributes
+:group: Azure
+
+*Since Camel {since}*
+
+*{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 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 case of consumer, accountName, containerName are required. In case of producer, it depends on the operation that 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&...
+
+For example in order to download a blob content from the block blob `hello.txt`
+located on the `container1` in the `camelazure` storage account, use the following snippet:
+
+[source,java]
+--------------------------------------------------------------------------------
+from("azure-storage-blob:/camelazure/container1?blobName=hello.txt&accessKey=yourAccessKey").
+to("file://blobdirectory");
+--------------------------------------------------------------------------------
+
+
+
+== URI Options
+
+
+// component options: START
+The Azure Storage Blob Service component supports 28 options, which are listed below.
+
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *autoDiscoverClient* (common) | Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry automatically otherwise it will skip that checking. | true | boolean
+| *blobName* (common) | The blob name, to consume specific blob from a container. However on producer, is only required for the operations on the blob level |  | String
+| *blobOffset* (common) | Set the blob offset for the upload or download operations, default is 0 | 0 | long
+| *blobType* (common) | The blob type in order to initiate the appropriate settings for each blob type. There are 3 enums and the value can be one of: blockblob, appendblob, pageblob | blockblob | BlobType
+| *closeStreamAfterRead* (common) | Close the stream after read or keep it open, default is true | true | boolean
+| *configuration* (common) | The component configurations |  | BlobConfiguration
+| *credentials* (common) | StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication information |  | StorageSharedKeyCredential
+| *dataCount* (common) | How many bytes to include in the range. Must be greater than or equal to 0 if specified. |  | Long
+| *fileDir* (common) | The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer |  | String
+| *maxResultsPerPage* (common) | Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not specify maxResultsPerPage or specifies a value greater than 5,000, the server will return up to 5,000 items. |  | Integer
+| *maxRetryRequests* (common) | Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a response body. | 0 | int
+| *prefix* (common) | Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs. |  | String
+| *regex* (common) | Filters the results to return only blobs whose names match the specified regular expression. May be null to return all if both prefix and regex are set, regex takes the priority and prefix is ignored. |  | String
+| *serviceClient* (common) | Client to a storage account. This client does not hold any state about a particular storage account but is instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used to construct URLs to blobs and containers. This client contains operations on a service account. Operations on a container are available on BlobContainerClient through BlobServiceClient#getBlobContainerClient(String), and operations on a blob  [...]
+| *timeout* (common) | An optional timeout value beyond which a RuntimeException will be raised. |  | Duration
+| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
+| *blobSequenceNumber* (producer) | A user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 263 - 1.The default value is 0. | 0 | Long
+| *blockListType* (producer) | Specifies which type of blocks to return. There are 3 enums and the value can be one of: committed, uncommitted, all | COMMITTED | BlockListType
+| *closeStreamAfterWrite* (producer) | Close the stream after write or keep it open, default is true | true | boolean
+| *commitBlockListLater* (producer) | When is set to true, the staged blocks will not be committed directly. | true | boolean
+| *createAppendBlob* (producer) | When is set to true, the append blocks will be created when committing append blocks. | true | boolean
+| *createPageBlob* (producer) | When is set to true, the page blob will be created when uploading page blob. | true | boolean
+| *downloadLinkExpiration* (producer) | Override the default expiration (millis) of URL download link. |  | Long
+| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
+| *operation* (producer) | The blob operation that can be used with this component on the producer. There are 19 enums and the value can be one of: listBlobContainers, createBlobContainer, deleteBlobContainer, listBlobs, getBlob, deleteBlob, downloadBlobToFile, downloadLink, uploadBlockBlob, stageBlockBlobList, commitBlobBlockList, getBlobBlockList, createAppendBlob, commitAppendBlob, createPageBlob, uploadPageBlob, resizePageBlob, clearPageBlob, getPageBlobRanges | listBlobContainers |  [...]
+| *pageBlobSize* (producer) | Specifies the maximum size for the page blob, up to 8 TB. The page blob size must be aligned to a 512-byte boundary. | 512 | Long
+| *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which then gets configured on the component. This can be used for automatic configuring JDBC data sources, JMS connection factories, AWS Clients, etc. | true | boolean
+| *accessKey* (security) | Access key for the associated azure account name to be used for authentication with azure blob services |  | String
+|===
+// component options: END
+
+// endpoint options: START
+The Azure Storage Blob Service endpoint is configured using URI syntax:
+
+----
+azure-storage-blob:accountName/containerName
+----
+
+with the following path and query parameters:
+
+=== Path Parameters (2 parameters):
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *accountName* | Azure account name to be used for authentication with azure blob services |  | String
+| *containerName* | The blob container name |  | String
+|===
+
+
+=== Query Parameters (29 parameters):
+
+
+[width="100%",cols="2,5,^1,2",options="header"]
+|===
+| Name | Description | Default | Type
+| *autoDiscoverClient* (common) | Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry automatically otherwise it will skip that checking. | true | boolean
+| *blobName* (common) | The blob name, to consume specific blob from a container. However on producer, is only required for the operations on the blob level |  | String
+| *blobOffset* (common) | Set the blob offset for the upload or download operations, default is 0 | 0 | long
+| *blobServiceClient* (common) | Client to a storage account. This client does not hold any state about a particular storage account but is instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used to construct URLs to blobs and containers. This client contains operations on a service account. Operations on a container are available on BlobContainerClient through getBlobContainerClient(String), and operations on a blob are available  [...]
+| *blobType* (common) | The blob type in order to initiate the appropriate settings for each blob type. There are 3 enums and the value can be one of: blockblob, appendblob, pageblob | blockblob | BlobType
+| *closeStreamAfterRead* (common) | Close the stream after read or keep it open, default is true | true | boolean
+| *credentials* (common) | StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication information |  | StorageSharedKeyCredential
+| *dataCount* (common) | How many bytes to include in the range. Must be greater than or equal to 0 if specified. |  | Long
+| *fileDir* (common) | The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer |  | String
+| *maxResultsPerPage* (common) | Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not specify maxResultsPerPage or specifies a value greater than 5,000, the server will return up to 5,000 items. |  | Integer
+| *maxRetryRequests* (common) | Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a response body. | 0 | int
+| *prefix* (common) | Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs. |  | String
+| *regex* (common) | Filters the results to return only blobs whose names match the specified regular expression. May be null to return all if both prefix and regex are set, regex takes the priority and prefix is ignored. |  | String
+| *serviceClient* (common) | Client to a storage account. This client does not hold any state about a particular storage account but is instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used to construct URLs to blobs and containers. This client contains operations on a service account. Operations on a container are available on BlobContainerClient through BlobServiceClient#getBlobContainerClient(String), and operations on a blob  [...]
+| *timeout* (common) | An optional timeout value beyond which a RuntimeException will be raised. |  | Duration
+| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
+| *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
+| *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
+| *blobSequenceNumber* (producer) | A user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 263 - 1.The default value is 0. | 0 | Long
+| *blockListType* (producer) | Specifies which type of blocks to return. There are 3 enums and the value can be one of: committed, uncommitted, all | COMMITTED | BlockListType
+| *closeStreamAfterWrite* (producer) | Close the stream after write or keep it open, default is true | true | boolean
+| *commitBlockListLater* (producer) | When is set to true, the staged blocks will not be committed directly. | true | boolean
+| *createAppendBlob* (producer) | When is set to true, the append blocks will be created when committing append blocks. | true | boolean
+| *createPageBlob* (producer) | When is set to true, the page blob will be created when uploading page blob. | true | boolean
+| *downloadLinkExpiration* (producer) | Override the default expiration (millis) of URL download link. |  | Long
+| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
+| *operation* (producer) | The blob operation that can be used with this component on the producer. There are 19 enums and the value can be one of: listBlobContainers, createBlobContainer, deleteBlobContainer, listBlobs, getBlob, deleteBlob, downloadBlobToFile, downloadLink, uploadBlockBlob, stageBlockBlobList, commitBlobBlockList, getBlobBlockList, createAppendBlob, commitAppendBlob, createPageBlob, uploadPageBlob, resizePageBlob, clearPageBlob, getPageBlobRanges | listBlobContainers |  [...]
+| *pageBlobSize* (producer) | Specifies the maximum size for the page blob, up to 8 TB. The page blob size must be aligned to a 512-byte boundary. | 512 | Long
+| *accessKey* (security) | Access key for the associated azure account name to be used for authentication with azure blob services |  | String
+|===
+// endpoint options: END
+
+*Required information options:*
+
+To use this component, you have 3 options in order to provide the required Azure authentication information:
+
+- Provide `accountName` and `accessKey` for your Azure account, this is the simplest way to get started. The accessKey can
+be generated through your Azure portal.
+- Provide a https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/apidocs/com/azure/storage/common/StorageSharedKeyCredential.html[StorageSharedKeyCredential] instance which can be
+provided into `credentials` option.
+- Provide a 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
+provided 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.
+
+
+== Batch Consumer
+
+This component implements the Batch Consumer.
+
+This allows you for instance to know how many messages exists in this
+batch and for instance let the Aggregator
+aggregate this number of messages.
+
+
+== Usage
+
+=== Message headers evaluated by the component producer
+[width="100%",cols="10%,10%,10%,10%,60%",options="header",]
+|=======================================================================
+|Header |Variable Name |Type |Operations |Description
+
+|`CamelAzureStorageBlobTimeout` |`BlobConstants.TIMEOUT`|`Duration`|All|An optional timeout value beyond which a {@link RuntimeException} will be raised.
+|`CamelAzureStorageBlobMetadata`|`BlobConstants.METADATA`|`Map<String,String>`|Operations related to container and blob| Metadata to associate with the container or blob.
+|`CamelAzureStorageBlobPublicAccessType`|`BlobConstants.PUBLIC_ACCESS_TYPE`|`PublicAccessType`|`createContainer`|Specifies how the data in this container is available to the public. Pass `null` for no public access.
+|`CamelAzureStorageBlobRequestCondition`|`BlobConstants.BLOB_REQUEST_CONDITION`|`BlobRequestConditions`|Operations related to container and blob|This contains values which will restrict the successful operation of a variety of requests to the conditions present. These conditions are entirely optional.
+|`CamelAzureStorageBlobListDetails`|`BlobConstants.BLOB_LIST_DETAILS`|`BlobListDetails`|`listBlobs`|The details for listing specific blobs
+|`CamelAzureStorageBlobPrefix`|`BlobConstants.PREFIX`|`String`|`listBlobs`,`getBlob`|Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs.
+|`CamelAzureStorageBlobMaxResultsPerPage`|`BlobConstants.MAX_RESULTS_PER_PAGE`|`Integer`|`listBlobs`| Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not specify maxResultsPerPage or specifies a value greater than 5,000, the server will return up to 5,000 items.
+|`CamelAzureStorageBlobListBlobOptions`|`BlobConstants.LIST_BLOB_OPTIONS`|`ListBlobsOptions`|`listBlobs`|Defines options available to configure the behavior of a call to listBlobsFlatSegment on a {@link BlobContainerClient} object.
+|`CamelAzureStorageBlobHttpHeaders`|`BlobConstants.BLOB_HTTP_HEADERS`|`BlobHttpHeaders`|`uploadBlockBlob`, `commitBlobBlockList`, `createAppendBlob`, `createPageBlob`|  Additional parameters for a set of operations.
+|`CamelAzureStorageBlobAccessTier`|`BlobConstants.ACCESS_TIER`|`AccessTier`|`uploadBlockBlob`, `commitBlobBlockList`| Defines values for AccessTier.
+|`CamelAzureStorageBlobContentMD5`|`BlobConstants.CONTENT_MD5`|`byte[]`|Most operations related to upload blob|An MD5 hash of the block content. This hash is used to verify the integrity of the block during transport. When this header is specified, the storage service compares the hash of the content that has arrived with this header value. Note that this MD5 hash is not stored with the blob. If the two hashes do not match, the operation will fail.
+|`CamelAzureStorageBlobPageBlobRange`|`BlobConstants.PAGE_BLOB_RANGE`|`PageRange`|Operations related to page blob| A {@link PageRange} object. Given that pages must be aligned with 512-byte boundaries, the start offset must be a modulus of 512 and the end offset must be a modulus of 512 - 1. Examples of valid byte ranges are 0-511, 512-1023, etc.
+|`CamelAzureStorageBlobCommitBlobBlockListLater`|`BlobConstants.COMMIT_BLOCK_LIST_LATER`|`boolean`|`stageBlockBlobList`| When is set to `true`, the staged blocks will not be committed directly.
+|`CamelAzureStorageBlobCreateAppendBlob`|`BlobConstants.CREATE_APPEND_BLOB`|`boolean`|`commitAppendBlob`| When is set to `true`, the append blocks will be created when committing append blocks.
+|`CamelAzureStorageBlobCreatePageBlob`|`BlobConstants.CREATE_PAGE_BLOB`|`boolean`|`uploadPageBlob`| When is set to `true`, the page blob will be created when uploading page blob.
+|`CamelAzureStorageBlobBlockListType`|`BlobConstants.BLOCK_LIST_TYPE`|`BlockListType`|`getBlobBlockList`| Specifies which type of blocks to return.
+|`CamelAzureStorageBlobPageBlobSize`|`BlobConstants.PAGE_BLOB_SIZE`|`Long`|`createPageBlob`, `resizePageBlob`| Specifies the maximum size for the page blob, up to 8 TB. The page blob size must be aligned to a 512-byte boundary.
+|`CamelAzureStorageBlobSequenceNumber`|`BlobConstants.BLOB_SEQUENCE_NUMBER`|`Long`|`createPageBlob`|A user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1.The default value is 0.
+|`CamelAzureStorageBlobDeleteSnapshotsOptionType`|`BlobConstants.DELETE_SNAPSHOT_OPTION_TYPE`|`DeleteSnapshotsOptionType`|`deleteBlob`| Specifies the behavior for deleting the snapshots on this blob. {@code Include} will delete the base blob and all snapshots. {@code Only} will delete only the snapshots. If a snapshot is being deleted, you must pass null.
+|`CamelAzureStorageBlobListBlobContainersOptions`|`BlobConstants.LIST_BLOB_CONTAINERS_OPTIONS`|`ListBlobContainersOptions`|`listBlobContainers`| A {@link ListBlobContainersOptions} which specifies what data should be returned by the service.
+|`CamelAzureStorageBlobParallelTransferOptions`|`BlobConstants.PARALLEL_TRANSFER_OPTIONS`|`ParallelTransferOptions`|`downloadBlobToFile`| {@link ParallelTransferOptions} to use to download to file. Number of parallel transfers parameter is ignored.
+|`CamelAzureStorageBlobFileDir`|`BlobConstants.FILE_DIR`|`String`|`downloadBlobToFile`|The file directory where the downloaded blobs will be saved to.
+|`CamelAzureStorageBlobDownloadLinkExpiration`|`BlobConstants.DOWNLOAD_LINK_EXPIRATION`|`Long`|`downloadLink`| Override the default expiration (millis) of URL download link.
+|`CamelAzureStorageBlobBlobName`|`BlobConstants.BLOB_NAME`|`String`|Operations related to blob| Override/set the blob name on the exchange headers.
+|`CamelAzureStorageBlobContainerName`|`BlobConstants.BLOB_CONTAINER_NAME`|`String`|Operations related to container and blob|Override/set the container name on the exchange headers.
+|`CamelAzureStorageBlobOperation`|`BlobConstants.BLOB_OPERATION`|`BlobOperationsDefinition`|All|Specify the producer operation to execute, please see the doc on this page related to producer operation.
+|`CamelAzureStorageBlobRegex`|`BlobConstants.REGEX`|`String`|`listBlobs`,`getBlob`|Filters the results to return only blobs whose names match the specified regular expression. May be null to return all. If both prefix and regex are set, regex takes the priority and prefix is ignored.
+|=======================================================================
+
+=== Message headers set by either component producer or consumer
+[width="100%",cols="10%,10%,10%,70%",options="header",]
+|=======================================================================
+|Header |Variable Name |Type |Description
+
+|`CamelAzureStorageBlobAccessTier`|`BlobConstants.ACCESS_TIER`|`AccessTier`| Access tier of the blob.
+|`CamelAzureStorageBlobAccessTierChangeTime`|`BlobConstants.ACCESS_TIER_CHANGE_TIME`|`OffsetDateTime`| Datetime when the access tier of the blob last changed.
+|`CamelAzureStorageBlobArchiveStatus`|`BlobConstants.ARCHIVE_STATUS`|`ArchiveStatus`|Archive status of the blob.
+|`CamelAzureStorageBlobCreationTime`|`BlobConstants.CREATION_TIME`|`OffsetDateTime`|Creation time of the blob.
+|`CamelAzureStorageBlobSequenceNumber`|`BlobConstants.BLOB_SEQUENCE_NUMBER`|`Long`|The current sequence number for a page blob.
+|`CamelAzureStorageBlobBlobSize`|`BlobConstants.BLOB_SIZE`|`long`|The size of the blob.
+|`CamelAzureStorageBlobBlobType`|`BlobConstants.BLOB_TYPE`|`BlobType`|The type of the blob.
+|`CamelAzureStorageBlobCacheControl`|`BlobConstants.CACHE_CONTROL`|`String`|Cache control specified for the blob.
+|`CamelAzureStorageBlobCommittedBlockCount`|`BlobConstants.COMMITTED_BLOCK_COUNT`|`Integer`|  Number of blocks committed to an append blob
+|`CamelAzureStorageBlobContentDisposition`|`BlobConstants.CONTENT_DISPOSITION`|`String`|Content disposition specified for the blob.
+|`CamelAzureStorageBlobContentEncoding`|`BlobConstants.CONTENT_ENCODING`|`String`|Content encoding specified for the blob.
+|`CamelAzureStorageBlobContentLanguage`|`BlobConstants.CONTENT_LANGUAGE`|`String`|Content language specified for the blob.
+|`CamelAzureStorageBlobContentMd5`|`BlobConstants.CONTENT_MD5`|`byte[]`|Content MD5 specified for the blob.
+|`CamelAzureStorageBlobContentType`|`BlobConstants.CONTENT_TYPE`|`String`|Content type specified for the blob.
+|`CamelAzureStorageBlobCopyCompletionTime`|`BlobConstants.COPY_COMPILATION_TIME`|`OffsetDateTime`|Datetime when the last copy operation on the blob completed.
+|`CamelAzureStorageBlobCopyDestinationSnapshot`|`BlobConstants.COPY_DESTINATION_SNAPSHOT`|`String`|Snapshot identifier of the last incremental copy snapshot for the blob.
+|`CamelAzureStorageBlobCopyId`|`BlobConstants.COPY_ID`|`String`|Identifier of the last copy operation performed on the blob.
+|`CamelAzureStorageBlobCopyProgress`|`BlobConstants.COPY_PROGRESS`|`String`|Progress of the last copy operation performed on the blob.
+|`CamelAzureStorageBlobCopySource`|`BlobConstants.COPY_SOURCE`|`String`|Source of the last copy operation performed on the blob.
+|`CamelAzureStorageBlobCopyStatus`|`BlobConstants.COPY_STATUS`|`CopyStatusType`|Status of the last copy operation performed on the blob.
+|`CamelAzureStorageBlobCopyStatusDescription` | `BlobConstants.COPY_STATUS_DESCRIPTION`|`String`|Description of the last copy operation on the blob.
+|`CamelAzureStorageBlobETag`|`BlobConstants.E_TAG`|`String`| The E Tag of the blob
+|`CamelAzureStorageBlobIsAccessTierInferred`|`BlobConstants.IS_ACCESS_TIER_INFRRRED`|`boolean`| Flag indicating if the access tier of the blob was inferred from properties of the blob.
+|`CamelAzureStorageBlobIsIncrementalCopy`|`BlobConstants.IS_INCREMENTAL_COPY`|`boolean`|Flag indicating if the blob was incrementally copied.
+|`CamelAzureStorageBlobIsServerEncrypted`|`BlobConstants.IS_SERVER_ENCRYPTED`|`boolean`|Flag indicating if the blob's content is encrypted on the server.
+|`CamelAzureStorageBlobLastModified`|`BlobConstants.LAST_MODIFIED`|`OffsetDateTime`|Datetime when the blob was last modified.
+|`CamelAzureStorageBlobLeaseDuration`|`BlobConstants.LEASE_DURATION`|`LeaseDurationType`|Type of lease on the blob.
+|`CamelAzureStorageBlobLeaseState`|`BlobConstants.LEASE_STATE`|`LeaseStateType`|State of the lease on the blob.
+|`CamelAzureStorageBlobLeaseStatus`|`BlobConstants.LEASE_STATUS`|`LeaseStatusType`|Status of the lease on the blob.
+|`CamelAzureStorageBlobMetadata`|`BlobConstants.METADATA`|`Map<String, String>`| Additional metadata associated with the blob.
+|`CamelAzureStorageBlobAppendOffset`|`BlobConstants.APPEND_OFFSET`|`String`| The offset at which the block was committed to the block blob.
+|`CamelAzureStorageBlobFileName`|`BlobConstants.FILE_NAME`|`String`|The downloaded filename from the operation `downloadBlobToFile`.
+|`CamelAzureStorageBlobDownloadLink`|`BlobConstants.DOWNLOAD_LINK`|`String`|The download link generated by `downloadLink` operation.
+|`CamelAzureStorageBlobRawHttpHeaders`|`BlobConstants.RAW_HTTP_HEADERS`|`HttpHeaders`|Returns non-parsed httpHeaders that can be used by the user.
+|=======================================================================
+
+=== 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:
+[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:
+
+[source,java]
+-----------------------------------------------------------------------
+from("azure-storage-blob://cameldev/container1?blobName=myblob&serviceClient=#client")
+.to("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 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 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.
+|===
+
+*Operations on the container level*
+
+For these operations, `accountName` and `containerName` are *required*.
+[width="100%",cols="10%,90%",options="header",]
+|===
+|Operation |Description
+|`createBlobContainer` | Creates a new container within a storage account. If a container with the same name already exists, the producer will ignore it.
+|`deleteBlobContainer` | Deletes 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.
+|===
+
+*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|Downloads 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 {@link FileAlreadyExistsException} will be thrown.
+|`downloadLink`  |Common| Generates the download link for the specified blob using shared access signatures (SAS). This by default only limit 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.
+|`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`|Writes a blob by specifying the list of block IDs that are to make up the blob. In order 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 block list 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 data to a page blob.
+|`uploadPageBlob`|`PageBlob`|Writes one or more pages to the page blob. The write 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`| Frees 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.
+|===
+
+Refer to the example section in this page to learn how to use these operations into your camel application.
+
+=== Consumer Examples
+To consume a blob into a file using file component, this can be done like this:
+[source,java]
+--------------------------------------------------------------------------------
+from("azure-storage-blob:/camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey").
+to("file://blobdirectory");
+--------------------------------------------------------------------------------
+
+However, you can also write to file directly without using the file component, you will need to specify `fileDir` folder path in order to save your blob in your machine.
+[source,java]
+--------------------------------------------------------------------------------
+from("azure-storage-blob:/camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir").
+to("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:
+[source,java]
+--------------------------------------------------------------------------------
+from("azure-storage-blob:/camelazure/container1?accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir").
+to("mock:results");
+--------------------------------------------------------------------------------
+
+
+
+=== Producer Operations Examples
+- `listBlobContainers`:
+
+[source,java]
+--------------------------------------------------------------------------------
+from("direct:start")
+  .process(exchange -> {
+    // set the header you want the producer to evaluate, refer to the previous
+    // section to learn about the headers that can be set
+    // e.g:
+    exchange.getIn().setHeader(BlobConstants.LIST_BLOB_CONTAINERS_OPTIONS, new ListBlobContainersOptions().setMaxResultsPerPage(10));
+  })
+  .to("azure-storage-blob:/camelazure?operation=listBlobContainers&client&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `createBlobContainer`:
+
+[source,java]
+--------------------------------------------------------------------------------
+from("direct:start")
+  .process(exchange -> {
+    // set the header you want the producer to evaluate, refer to the previous
+    // section to learn about the headers that can be set
+    // e.g:
+    exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "newContainerName");
+  })
+  .to("azure-storage-blob:/camelazure/container1?operation=createBlobContainer&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `deleteBlobContainer`:
+
+[source,java]
+--------------------------------------------------------------------------------
+from("direct:start")
+  .process(exchange -> {
+    // set the header you want the producer to evaluate, refer to the previous
+    // section to learn about the headers that can be set
+    // e.g:
+    exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "overridenName");
+  })
+  .to("azure-storage-blob:/camelazure/container1?operation=deleteBlobContainer&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `listBlobs`:
+
+[source,java]
+--------------------------------------------------------------------------------
+from("direct:start")
+  .process(exchange -> {
+    // set the header you want the producer to evaluate, refer to the previous
+    // section to learn about the headers that can be set
+    // e.g:
+    exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "overridenName");
+  })
+  .to("azure-storage-blob:/camelazure/container1?operation=listBlobs&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+
+- `getBlob`:
+
+We can either set an `outputStream` in the exchange body and write the data to it. E.g:
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+    // set the header you want the producer to evaluate, refer to the previous
+    // section to learn about the headers that can be set
+    // e.g:
+    exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "overridenName");
+
+    // set our body
+    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 proceeded further downstream:
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=getBlob&serviceClient=#client")
+  .process(exchange -> {
+      InputStream inputStream = exchange.getMessage().getBody(InputStream.class);
+      // We use Apache common IO for simplicity, but you are free to do whatever dealing
+      // with inputStream
+      System.out.println(IOUtils.toString(inputStream, StandardCharsets.UTF_8.name()));
+  })
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `deleteBlob`:
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+    // set the header you want the producer to evaluate, refer to the previous
+    // section to learn about the headers that can be set
+    // e.g:
+    exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "overridenName");
+  })
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=deleteBlob&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `downloadBlobToFile`:
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+    // set the header you want the producer to evaluate, refer to the previous
+    // section to learn about the headers that can be set
+    // e.g:
+    exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "overridenName");
+  })
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=downloadBlobToFile&fileDir=/var/mydir&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `downloadLink`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=downloadLink&serviceClient=#client")
+  .process(exchange -> {
+      String link = exchange.getMessage().getHeader(BlobConstants.DOWNLOAD_LINK, String.class);
+      System.out.println("My link " + link);
+  })
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `uploadBlockBlob`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+    // set the header you want the producer to evaluate, refer to the previous
+    // section to learn about the headers that can be set
+    // e.g:
+    exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "overridenName");
+    exchange.getIn().setBody("Block Blob");
+  })
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=uploadBlockBlob&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `stageBlockBlobList`
+
+[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`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+      // We assume here you have the knowledge of these blocks you want to commit
+      final List<Block> blocksIds = new LinkedList<>();
+      blocksIds.add(new Block().setName("id-1"));
+      blocksIds.add(new Block().setName("id-2"));
+      blocksIds.add(new Block().setName("id-3"));
+
+      exchange.getIn().setBody(blocksIds);
+  })
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=commitBlockBlobList&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `getBlobBlockList`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=getBlobBlockList&serviceClient=#client")
+  .log("${body}")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+
+- `createAppendBlob`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=createAppendBlob&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `commitAppendBlob`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+    final String data = "Hello world from my awesome tests!";
+    final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+
+    exchange.getIn().setBody(dataStream);
+
+    // of course you can set whatever headers you like, refer to the headers section to learn more
+  })
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=commitAppendBlob&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `createPageBlob`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=createPageBlob&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `uploadPageBlob`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+    byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
+    new Random().nextBytes(dataBytes);
+    final InputStream dataStream = new ByteArrayInputStream(dataBytes);
+    final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
+
+    exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
+    exchange.getIn().setBody(dataStream);
+  })
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=uploadPageBlob&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `resizePageBlob`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+    final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
+
+    exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
+  })
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=resizePageBlob&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `clearPageBlob`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+    final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
+
+    exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
+  })
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=clearPageBlob&serviceClient=#client")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+- `getPageBlobRanges`
+
+[source,java]
+--------------------------------------------------------------------------------
+
+from("direct:start")
+  .process(exchange -> {
+    final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
+
+    exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
+  })
+  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=getPageBlobRanges&serviceClient=#client")
+  .log("${body}")
+  .to("mock:result");
+--------------------------------------------------------------------------------
+
+
+=== Development Notes (Important)
+All integration tests use [Testcontainers](https://www.testcontainers.org/) 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:
+----
+mvn verify -PfullTests -DaccountName=myacc -DaccessKey=mykey
+----
+Whereby `accountName` is your Azure account name and `accessKey` is the access key being generated from Azure portal.
+
+
+include::camel-spring-boot::page$azure-storage-blob-starter.adoc[]
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-summary.adoc b/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-summary.adoc
new file mode 100644
index 0000000..a20afe8
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/docs/azure-summary.adoc
@@ -0,0 +1,15 @@
+[[Azure-CamelComponentsforMicrosoftAzureServices]]
+= Camel Components for Microsoft Azure Services
+//attributes written by hand, not generated
+:docTitle: Azure
+
+The Camel Components for https://azure.microsoft.com/[Microsoft Azure Services]
+provide connectivity to Azure services from Camel.
+
+== {docTitle} components
+
+See the following for usage of each component:
+
+indexDescriptionList::[attributes='group={docTitle}',descAttribute=description]
+
+include::camel-spring-boot::page$azure-starter.adoc[]
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobBlock.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobBlock.java
new file mode 100644
index 0000000..e079a51
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobBlock.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.UUID;
+
+import com.azure.core.util.Base64Util;
+import com.azure.storage.blob.models.Block;
+
+public final class BlobBlock {
+    private final InputStream blockStream;
+    private final Block blockEntry;
+
+    private BlobBlock(Block blockEntry, InputStream blockStream) {
+        this.blockStream = blockStream;
+        this.blockEntry = blockEntry;
+    }
+
+    public static BlobBlock createBlobBlock(final InputStream inputStream) throws IOException {
+        return createBlobBlock(Base64Util.encodeToString(UUID.randomUUID().toString().getBytes()), inputStream);
+    }
+
+    public static BlobBlock createBlobBlock(final String blockId, final InputStream inputStream) throws IOException {
+        return createBlobBlock(blockId, BlobUtils.getInputStreamLength(inputStream), inputStream);
+    }
+
+    public static BlobBlock createBlobBlock(final String blockId, final long size, final InputStream inputStream) {
+        final Block block = new Block().setName(blockId).setSizeLong(size);
+
+        return new BlobBlock(block, inputStream);
+    }
+
+    public InputStream getBlockStream() {
+        return blockStream;
+    }
+
+    public Block getBlockEntry() {
+        return blockEntry;
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobCommonRequestOptions.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobCommonRequestOptions.java
new file mode 100644
index 0000000..84de6c6
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobCommonRequestOptions.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.time.Duration;
+import java.util.Map;
+
+import com.azure.storage.blob.models.AccessTier;
+import com.azure.storage.blob.models.BlobHttpHeaders;
+import com.azure.storage.blob.models.BlobRequestConditions;
+
+public class BlobCommonRequestOptions {
+
+    private final BlobHttpHeaders blobHttpHeaders;
+    private final Map<String, String> metadata;
+    private final AccessTier accessTier;
+    private final BlobRequestConditions blobRequestConditions;
+    private final byte[] contentMD5;
+    private final Duration timeout;
+
+    public BlobCommonRequestOptions(BlobHttpHeaders blobHttpHeaders, Map<String, String> metadata, AccessTier accessTier,
+                                    BlobRequestConditions blobRequestConditions, byte[] contentMD5, Duration timeout) {
+        this.blobHttpHeaders = blobHttpHeaders;
+        this.metadata = metadata;
+        this.accessTier = accessTier;
+        this.blobRequestConditions = blobRequestConditions;
+        this.contentMD5 = contentMD5;
+        this.timeout = timeout;
+    }
+
+    public BlobHttpHeaders getBlobHttpHeaders() {
+        return blobHttpHeaders;
+    }
+
+    public Map<String, String> getMetadata() {
+        return metadata;
+    }
+
+    public AccessTier getAccessTier() {
+        return accessTier;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T extends BlobRequestConditions> T getBlobRequestConditions() {
+        return blobRequestConditions == null ? null : (T) blobRequestConditions;
+    }
+
+    public byte[] getContentMD5() {
+        return contentMD5;
+    }
+
+    public Duration getTimeout() {
+        return timeout;
+    }
+
+    public String leaseId() {
+        return blobRequestConditions != null ? blobRequestConditions.getLeaseId() : null;
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java
new file mode 100644
index 0000000..75e1e9d
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.util.Map;
+import java.util.Set;
+
+import com.azure.storage.blob.BlobServiceClient;
+import com.azure.storage.common.StorageSharedKeyCredential;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.annotations.Component;
+import org.apache.camel.support.DefaultComponent;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Azure Blob Storage component using azure java sdk v12.x
+ */
+@Component("azure-storage-blob")
+public class BlobComponent extends DefaultComponent {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BlobComponent.class);
+
+    @Metadata
+    private BlobConfiguration configuration = new BlobConfiguration();
+
+    public BlobComponent() {
+    }
+
+    public BlobComponent(final CamelContext camelContext) {
+        super(camelContext);
+    }
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+
+        if (remaining == null || remaining.trim().length() == 0) {
+            throw new IllegalArgumentException("At least the account name must be specified.");
+        }
+
+        final BlobConfiguration config = this.configuration != null
+                ? this.configuration.copy()
+                : new BlobConfiguration();
+
+        final String[] parts = remaining.split("/");
+
+        // only account name is being set
+        config.setAccountName(parts[0]);
+
+        // also container name is being set
+        if (parts.length > 1) {
+            config.setContainerName(parts[1]);
+        }
+
+        final BlobEndpoint endpoint = new BlobEndpoint(uri, this, config);
+        setProperties(endpoint, parameters);
+
+        if (config.isAutoDiscoverClient()) {
+            checkAndSetRegistryClient(config);
+        }
+
+        checkCredentials(config);
+        validateConfigurations(config);
+
+        return endpoint;
+    }
+
+    /**
+     * The component configurations
+     */
+    public BlobConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(BlobConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    private void checkCredentials(final BlobConfiguration configuration) {
+        final BlobServiceClient client = configuration.getServiceClient();
+
+        // if no azureBlobClient is provided fallback to credentials
+        if (client == null) {
+            Set<StorageSharedKeyCredential> storageSharedKeyCredentials
+                    = getCamelContext().getRegistry().findByType(StorageSharedKeyCredential.class);
+            if (storageSharedKeyCredentials.size() == 1) {
+                configuration.setCredentials(storageSharedKeyCredentials.stream().findFirst().get());
+            }
+        }
+    }
+
+    private void checkAndSetRegistryClient(final BlobConfiguration configuration) {
+        if (ObjectHelper.isEmpty(configuration.getServiceClient())) {
+            final Set<BlobServiceClient> clients = getCamelContext().getRegistry().findByType(BlobServiceClient.class);
+            if (clients.size() == 1) {
+                configuration.setServiceClient(clients.stream().findFirst().get());
+            } else if (clients.size() > 1) {
+                LOG.info("More than one BlobServiceClient instance in the registry, make sure to have only one instance");
+            } else {
+                LOG.info("No BlobServiceClient instance in the registry");
+            }
+        } else {
+            LOG.info("BlobServiceClient instance is already set at endpoint level: skipping the check in the registry");
+        }
+    }
+
+    private void validateConfigurations(final BlobConfiguration configuration) {
+        if (configuration.getServiceClient() == null
+                && configuration.getAccessKey() == null
+                && configuration.getCredentials() == null) {
+            throw new IllegalArgumentException("Azure Storage accessKey or BlobServiceClient must be specified.");
+        }
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
new file mode 100644
index 0000000..b87e19a
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
@@ -0,0 +1,403 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.time.Duration;
+
+import com.azure.storage.blob.BlobClient;
+import com.azure.storage.blob.BlobContainerClient;
+import com.azure.storage.blob.BlobServiceClient;
+import com.azure.storage.blob.models.BlockListType;
+import com.azure.storage.common.StorageSharedKeyCredential;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.spi.UriPath;
+
+@UriParams
+public class BlobConfiguration implements Cloneable {
+
+    @UriPath
+    private String accountName;
+    @UriPath
+    private String containerName;
+    @UriParam
+    private StorageSharedKeyCredential credentials;
+    @UriParam
+    private BlobServiceClient serviceClient;
+    @UriParam(label = "security", secret = true)
+    private String accessKey;
+    @UriParam(label = "producer",
+              enums = "listBlobContainers,createBlobContainer,deleteBlobContainer,listBlobs,getBlob,deleteBlob,downloadBlobToFile,downloadLink,"
+                      + "uploadBlockBlob,stageBlockBlobList,commitBlobBlockList,getBlobBlockList,createAppendBlob,commitAppendBlob,createPageBlob,uploadPageBlob,resizePageBlob,"
+                      + "clearPageBlob,getPageBlobRanges",
+              defaultValue = "listBlobContainers")
+    private BlobOperationsDefinition operation = BlobOperationsDefinition.listBlobContainers;
+    @UriParam(label = "common")
+    private String blobName;
+    @UriParam(label = "common", enums = "blockblob,appendblob,pageblob", defaultValue = "blockblob")
+    private BlobType blobType = BlobType.blockblob;
+    @UriParam(label = "common")
+    private String fileDir;
+    @UriParam(label = "common", defaultValue = "0")
+    private long blobOffset;
+    @UriParam(label = "common")
+    private Long dataCount;
+    @UriParam(label = "common")
+    private Duration timeout;
+    @UriParam(label = "common")
+    private String prefix;
+    @UriParam(label = "common")
+    private Integer maxResultsPerPage;
+    @UriParam(label = "common", defaultValue = "0")
+    private int maxRetryRequests;
+    @UriParam(label = "common", defaultValue = "true")
+    private boolean autoDiscoverClient = true;
+    @UriParam(defaultValue = "true")
+    private boolean closeStreamAfterRead = true;
+    @UriParam(label = "producer", defaultValue = "true")
+    private boolean closeStreamAfterWrite = true;
+    @UriParam(label = "producer")
+    private Long downloadLinkExpiration;
+    @UriParam(label = "producer", defaultValue = "true")
+    private boolean commitBlockListLater = true;
+    @UriParam(label = "producer", defaultValue = "true")
+    private boolean createAppendBlob = true;
+    @UriParam(label = "producer", defaultValue = "true")
+    private boolean createPageBlob = true;
+    @UriParam(label = "producer", defaultValue = "0")
+    private Long blobSequenceNumber;
+    @UriParam(label = "producer", defaultValue = "512")
+    private Long pageBlobSize = BlobConstants.PAGE_BLOB_DEFAULT_SIZE;
+    @UriParam(label = "producer", defaultValue = "COMMITTED")
+    private BlockListType blockListType = BlockListType.COMMITTED;
+    @UriParam(label = "common")
+    private String regex;
+
+    /**
+     * Azure account name to be used for authentication with azure blob services
+     */
+    public String getAccountName() {
+        return accountName;
+    }
+
+    public void setAccountName(String accountName) {
+        this.accountName = accountName;
+    }
+
+    /**
+     * The blob container name
+     */
+    public String getContainerName() {
+        return containerName;
+    }
+
+    public void setContainerName(String containerName) {
+        this.containerName = containerName;
+    }
+
+    /**
+     * StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication
+     * information
+     */
+    public StorageSharedKeyCredential getCredentials() {
+        return credentials;
+    }
+
+    public void setCredentials(StorageSharedKeyCredential credentials) {
+        this.credentials = credentials;
+    }
+
+    /**
+     * Client to a storage account. This client does not hold any state about a particular storage account but is
+     * instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used
+     * to construct URLs to blobs and containers.
+     *
+     * This client contains operations on a service account. Operations on a container are available on
+     * {@link BlobContainerClient} through {@link BlobServiceClient#getBlobContainerClient(String)}, and operations on a
+     * blob are available on {@link BlobClient} through {@link BlobContainerClient#getBlobClient(String)}.
+     */
+    public BlobServiceClient getServiceClient() {
+        return serviceClient;
+    }
+
+    public void setServiceClient(BlobServiceClient serviceClient) {
+        this.serviceClient = serviceClient;
+    }
+
+    /**
+     * Access key for the associated azure account name to be used for authentication with azure blob services
+     */
+    public String getAccessKey() {
+        return accessKey;
+    }
+
+    public void setAccessKey(String accessKey) {
+        this.accessKey = accessKey;
+    }
+
+    /**
+     * The blob operation that can be used with this component on the producer
+     */
+    public BlobOperationsDefinition getOperation() {
+        return operation;
+    }
+
+    public void setOperation(BlobOperationsDefinition operation) {
+        this.operation = operation;
+    }
+
+    /**
+     * The blob name, to consume specific blob from a container. However on producer, is only required for the
+     * operations on the blob level
+     */
+    public String getBlobName() {
+        return blobName;
+    }
+
+    public void setBlobName(String blobName) {
+        this.blobName = blobName;
+    }
+
+    /**
+     * The blob type in order to initiate the appropriate settings for each blob type
+     */
+    public BlobType getBlobType() {
+        return blobType;
+    }
+
+    public void setBlobType(BlobType blobType) {
+        this.blobType = blobType;
+    }
+
+    /**
+     * The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer
+     */
+    public String getFileDir() {
+        return fileDir;
+    }
+
+    public void setFileDir(String fileDir) {
+        this.fileDir = fileDir;
+    }
+
+    /**
+     * Set the blob offset for the upload or download operations, default is 0
+     */
+    public long getBlobOffset() {
+        return blobOffset;
+    }
+
+    public void setBlobOffset(long blobOffset) {
+        this.blobOffset = blobOffset;
+    }
+
+    /**
+     * How many bytes to include in the range. Must be greater than or equal to 0 if specified.
+     */
+    public Long getDataCount() {
+        return dataCount;
+    }
+
+    public void setDataCount(Long dataCount) {
+        this.dataCount = dataCount;
+    }
+
+    /**
+     * Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a
+     * response body.
+     */
+    public int getMaxRetryRequests() {
+        return maxRetryRequests;
+    }
+
+    public void setMaxRetryRequests(int maxRetryRequests) {
+        this.maxRetryRequests = maxRetryRequests;
+    }
+
+    /**
+     * An optional timeout value beyond which a {@link RuntimeException} will be raised.
+     */
+    public Duration getTimeout() {
+        return timeout;
+    }
+
+    public void setTimeout(Duration timeout) {
+        this.timeout = timeout;
+    }
+
+    /**
+     * Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all
+     * blobs.
+     */
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public void setPrefix(String prefix) {
+        this.prefix = prefix;
+    }
+
+    /**
+     * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not
+     * specify maxResultsPerPage or specifies a value greater than 5,000, the server will return up to 5,000 items.
+     */
+    public Integer getMaxResultsPerPage() {
+        return maxResultsPerPage;
+    }
+
+    public void setMaxResultsPerPage(Integer maxResultsPerPage) {
+        this.maxResultsPerPage = maxResultsPerPage;
+    }
+
+    /**
+     * Close the stream after read or keep it open, default is true
+     */
+    public boolean isCloseStreamAfterRead() {
+        return closeStreamAfterRead;
+    }
+
+    public void setCloseStreamAfterRead(boolean closeStreamAfterRead) {
+        this.closeStreamAfterRead = closeStreamAfterRead;
+    }
+
+    /**
+     * Close the stream after write or keep it open, default is true
+     */
+    public boolean isCloseStreamAfterWrite() {
+        return closeStreamAfterWrite;
+    }
+
+    public void setCloseStreamAfterWrite(boolean closeStreamAfterWrite) {
+        this.closeStreamAfterWrite = closeStreamAfterWrite;
+    }
+
+    /**
+     * Specifies the maximum size for the page blob, up to 8 TB. The page blob size must be aligned to a 512-byte
+     * boundary.
+     */
+    public Long getPageBlobSize() {
+        return pageBlobSize;
+    }
+
+    public void setPageBlobSize(Long pageBlobSize) {
+        this.pageBlobSize = pageBlobSize;
+    }
+
+    /**
+     * Override the default expiration (millis) of URL download link.
+     */
+    public Long getDownloadLinkExpiration() {
+        return downloadLinkExpiration;
+    }
+
+    public void setDownloadLinkExpiration(Long downloadLinkExpiration) {
+        this.downloadLinkExpiration = downloadLinkExpiration;
+    }
+
+    /**
+     * When is set to `true`, the staged blocks will not be committed directly.
+     */
+    public boolean isCommitBlockListLater() {
+        return commitBlockListLater;
+    }
+
+    public void setCommitBlockListLater(boolean commitBlockListLater) {
+        this.commitBlockListLater = commitBlockListLater;
+    }
+
+    /**
+     * When is set to `true`, the append blocks will be created when committing append blocks.
+     */
+    public boolean isCreateAppendBlob() {
+        return createAppendBlob;
+    }
+
+    public void setCreateAppendBlob(boolean createAppendBlob) {
+        this.createAppendBlob = createAppendBlob;
+    }
+
+    /**
+     * When is set to `true`, the page blob will be created when uploading page blob.
+     */
+    public boolean isCreatePageBlob() {
+        return createPageBlob;
+    }
+
+    public void setCreatePageBlob(boolean createPageBlob) {
+        this.createPageBlob = createPageBlob;
+    }
+
+    /**
+     * A user-controlled value that you can use to track requests. The value of the sequence number must be between 0
+     * and 2^63 - 1.The default value is 0.
+     */
+    public Long getBlobSequenceNumber() {
+        return blobSequenceNumber;
+    }
+
+    public void setBlobSequenceNumber(Long blobSequenceNumber) {
+        this.blobSequenceNumber = blobSequenceNumber;
+    }
+
+    /**
+     * Specifies which type of blocks to return.
+     */
+    public BlockListType getBlockListType() {
+        return blockListType;
+    }
+
+    public void setBlockListType(BlockListType blockListType) {
+        this.blockListType = blockListType;
+    }
+
+    /**
+     * Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry
+     * automatically otherwise it will skip that checking.
+     */
+    public boolean isAutoDiscoverClient() {
+        return autoDiscoverClient;
+    }
+
+    public void setAutoDiscoverClient(boolean autoDiscoverClient) {
+        this.autoDiscoverClient = autoDiscoverClient;
+    }
+
+    /**
+     * Filters the results to return only blobs whose names match the specified regular expression. May be null to
+     * return all if both prefix and regex are set, regex takes the priority and prefix is ignored.
+     */
+    public String getRegex() {
+        return regex;
+    }
+
+    public void setRegex(String regex) {
+        this.regex = regex;
+    }
+
+    // *************************************************
+    //
+    // *************************************************
+
+    public BlobConfiguration copy() {
+        try {
+            return (BlobConfiguration) super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeCamelException(e);
+        }
+    }
+}
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
new file mode 100644
index 0000000..76edf24
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxy.java
@@ -0,0 +1,216 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.time.Duration;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import com.azure.storage.blob.models.AccessTier;
+import com.azure.storage.blob.models.BlobHttpHeaders;
+import com.azure.storage.blob.models.BlobListDetails;
+import com.azure.storage.blob.models.BlobRange;
+import com.azure.storage.blob.models.BlobRequestConditions;
+import com.azure.storage.blob.models.BlockListType;
+import com.azure.storage.blob.models.DeleteSnapshotsOptionType;
+import com.azure.storage.blob.models.ListBlobContainersOptions;
+import com.azure.storage.blob.models.ListBlobsOptions;
+import com.azure.storage.blob.models.PageRange;
+import com.azure.storage.blob.models.ParallelTransferOptions;
+import com.azure.storage.blob.models.PublicAccessType;
+import org.apache.camel.Exchange;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * A proxy class for {@link BlobConfigurationOptionsProxy} and {@link BlobExchangeHeaders}. Ideally this is responsible
+ * to obtain the correct configurations options either from configs or exchange headers
+ */
+public class BlobConfigurationOptionsProxy {
+
+    private final BlobConfiguration configuration;
+
+    public BlobConfigurationOptionsProxy(final BlobConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    public ListBlobContainersOptions getListBlobContainersOptions(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getListBlobContainersOptionsFromHeaders, () -> null, exchange);
+    }
+
+    public Duration getTimeout(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getTimeoutFromHeaders, configuration::getTimeout, exchange);
+    }
+
+    public ListBlobsOptions getListBlobsOptions(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getListBlobsOptionsFromHeaders, () -> null, exchange);
+    }
+
+    public BlobListDetails getBlobListDetails(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getBlobListDetailsFromHeaders, () -> null, exchange);
+    }
+
+    public String getPrefix(final Exchange exchange) {
+        //if regex is set, prefix will not take effect
+        if (ObjectHelper.isNotEmpty(getRegex(exchange))) {
+            return null;
+        }
+        return getOption(BlobExchangeHeaders::getPrefixFromHeaders, configuration::getPrefix, exchange);
+    }
+
+    public String getRegex(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getRegexFromHeaders, configuration::getRegex, exchange);
+    }
+
+    public Integer getMaxResultsPerPage(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getMaxResultsPerPageFromHeaders, configuration::getMaxResultsPerPage, exchange);
+    }
+
+    public ListBlobsOptions getListBlobOptions(final Exchange exchange) {
+        ListBlobsOptions blobsOptions = getListBlobsOptions(exchange);
+
+        if (blobsOptions == null) {
+            blobsOptions = new ListBlobsOptions();
+        }
+
+        if (!ObjectHelper.isEmpty(blobsOptions)) {
+            return blobsOptions;
+        } else {
+            blobsOptions = new ListBlobsOptions();
+        }
+
+        final BlobListDetails blobListDetails = getBlobListDetails(exchange);
+        final String prefix = getPrefix(exchange);
+        final Integer maxResultsPerPage = getMaxResultsPerPage(exchange);
+
+        blobsOptions.setDetails(blobListDetails);
+        blobsOptions.setMaxResultsPerPage(maxResultsPerPage);
+        blobsOptions.setPrefix(prefix);
+
+        return blobsOptions;
+    }
+
+    public Map<String, String> getMetadata(final Exchange exchange) {
+        return BlobExchangeHeaders.getMetadataFromHeaders(exchange);
+    }
+
+    public PublicAccessType getPublicAccessType(final Exchange exchange) {
+        return BlobExchangeHeaders.getPublicAccessTypeFromHeaders(exchange);
+    }
+
+    public BlobRequestConditions getBlobRequestConditions(final Exchange exchange) {
+        return BlobExchangeHeaders.getBlobRequestConditionsFromHeaders(exchange);
+    }
+
+    public PageRange getPageRange(final Exchange exchange) {
+        return BlobExchangeHeaders.getPageRangeFromHeaders(exchange);
+    }
+
+    public BlobRange getBlobRange(final Exchange exchange) {
+        if (configuration.getBlobType() == BlobType.pageblob) {
+            final PageRange pageRange = getPageRange(exchange);
+            if (pageRange != null) {
+                final long blobOffset = pageRange.getStart();
+                final long dataCount = pageRange.getEnd() - pageRange.getStart();
+
+                return new BlobRange(blobOffset, dataCount);
+            }
+        }
+        return new BlobRange(configuration.getBlobOffset(), configuration.getDataCount());
+    }
+
+    public BlobHttpHeaders getBlobHttpHeaders(final Exchange exchange) {
+        return BlobExchangeHeaders.getBlobHttpHeadersFromHeaders(exchange);
+    }
+
+    public AccessTier getAccessTier(final Exchange exchange) {
+        return BlobExchangeHeaders.getAccessTierFromHeaders(exchange);
+    }
+
+    public byte[] getContentMd5(final Exchange exchange) {
+        return BlobExchangeHeaders.getContentMd5FromHeaders(exchange);
+    }
+
+    public String getFileDir(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getFileDirFromHeaders, configuration::getFileDir, exchange);
+    }
+
+    public ParallelTransferOptions getParallelTransferOptions(final Exchange exchange) {
+        return BlobExchangeHeaders.getParallelTransferOptionsFromHeaders(exchange);
+    }
+
+    public DeleteSnapshotsOptionType getDeleteSnapshotsOptionType(final Exchange exchange) {
+        return BlobExchangeHeaders.getDeleteSnapshotsOptionTypeFromHeaders(exchange);
+    }
+
+    public Long getDownloadLinkExpiration(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getDownloadLinkExpirationFromHeaders, configuration::getDownloadLinkExpiration,
+                exchange);
+    }
+
+    public boolean isCommitBlockListLater(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getCommitBlockListFlagFromHeaders, configuration::isCommitBlockListLater,
+                exchange);
+    }
+
+    public BlockListType getBlockListType(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getBlockListTypeFromHeaders, configuration::getBlockListType, exchange);
+    }
+
+    public boolean isCreateAppendBlob(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getCreateAppendBlobFlagFromHeaders, configuration::isCreateAppendBlob, exchange);
+    }
+
+    public Long getPageBlobSize(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getPageBlobSize, configuration::getPageBlobSize, exchange);
+    }
+
+    public Long getBlobSequenceNumber(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getBlobSequenceNumberFromHeaders, configuration::getBlobSequenceNumber, exchange);
+    }
+
+    public boolean isCreatePageBlob(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getCreatePageBlobFlagFromHeaders, configuration::isCreatePageBlob, exchange);
+    }
+
+    public String getBlobName(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getBlobNameFromHeaders, configuration::getBlobName, exchange);
+    }
+
+    public String getContainerName(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getBlobContainerNameFromHeaders, configuration::getContainerName, exchange);
+    }
+
+    public BlobOperationsDefinition getOperation(final Exchange exchange) {
+        return getOption(BlobExchangeHeaders::getBlobOperationsDefinitionFromHeaders, configuration::getOperation, exchange);
+    }
+
+    public int getMaxRetryRequests() {
+        return configuration.getMaxRetryRequests();
+    }
+
+    public BlobConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    private <R> R getOption(final Function<Exchange, R> exchangeFn, final Supplier<R> fallbackFn, final Exchange exchange) {
+        // we first try to look if our value in exchange otherwise fallback to fallbackFn which could be either a function or constant
+        return ObjectHelper.isEmpty(exchange) || ObjectHelper.isEmpty(exchangeFn.apply(exchange))
+                ? fallbackFn.get()
+                : exchangeFn.apply(exchange);
+    }
+}
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
new file mode 100644
index 0000000..b2426c7
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConstants.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+public final class BlobConstants {
+    // constants
+    public static final Long PAGE_BLOB_DEFAULT_SIZE = 512L;
+    private static final String HEADER_PREFIX = "CamelAzureStorageBlob";
+    // header names
+    public static final String BLOB_OPERATION = HEADER_PREFIX + "Operation";
+    public static final String BLOB_HTTP_HEADERS = HEADER_PREFIX + "HttpHeaders";
+    public static final String E_TAG = HEADER_PREFIX + "ETag";
+    public static final String CREATION_TIME = HEADER_PREFIX + "CreationTime";
+    public static final String LAST_MODIFIED = HEADER_PREFIX + "LastModified";
+    public static final String CONTENT_TYPE = HEADER_PREFIX + "ContentType";
+    public static final String CONTENT_MD5 = HEADER_PREFIX + "ContentMD5";
+    public static final String CONTENT_ENCODING = HEADER_PREFIX + "ContentEncoding";
+    public static final String CONTENT_DISPOSITION = HEADER_PREFIX + "ContentDisposition";
+    public static final String CONTENT_LANGUAGE = HEADER_PREFIX + "ContentLanguage";
+    public static final String CACHE_CONTROL = HEADER_PREFIX + "CacheControl";
+    public static final String BLOB_SIZE = HEADER_PREFIX + "BlobSize";
+    public static final String BLOB_SEQUENCE_NUMBER = HEADER_PREFIX + "SequenceNumber";
+    public static final String BLOB_TYPE = HEADER_PREFIX + "BlobType";
+    public static final String LEASE_STATUS = HEADER_PREFIX + "LeaseStatus";
+    public static final String LEASE_STATE = HEADER_PREFIX + "LeaseState";
+    public static final String LEASE_DURATION = HEADER_PREFIX + "LeaseDuration";
+    public static final String COPY_ID = HEADER_PREFIX + "CopyId";
+    public static final String COPY_STATUS = HEADER_PREFIX + "CopyStatus";
+    public static final String COPY_SOURCE = HEADER_PREFIX + "CopySource";
+    public static final String COPY_PROGRESS = HEADER_PREFIX + "CopyProgress";
+    public static final String COPY_COMPILATION_TIME = HEADER_PREFIX + "CopyCompletionTime";
+    public static final String COPY_STATUS_DESCRIPTION = HEADER_PREFIX + "CopyStatusDescription";
+    public static final String COPY_DESTINATION_SNAPSHOT = HEADER_PREFIX + "CopyDestinationSnapshot";
+    public static final String IS_SERVER_ENCRYPTED = HEADER_PREFIX + "IsServerEncrypted";
+    public static final String IS_INCREMENTAL_COPY = HEADER_PREFIX + "IsIncrementalCopy";
+    public static final String ACCESS_TIER = HEADER_PREFIX + "AccessTier";
+    public static final String IS_ACCESS_TIER_INFRRRED = HEADER_PREFIX + "IsAccessTierInferred";
+    public static final String ARCHIVE_STATUS = HEADER_PREFIX + "ArchiveStatus";
+    public static final String ENCRYPTION_KEY_SHA_256 = HEADER_PREFIX + "EncryptionKeySha256";
+    public static final String ENCRYPTION_SCOPE = HEADER_PREFIX + "EncryptionScope";
+    public static final String ACCESS_TIER_CHANGE_TIME = HEADER_PREFIX + "accessTierChangeTime";
+    public static final String METADATA = HEADER_PREFIX + "Metadata";
+    public static final String COMMITTED_BLOCK_COUNT = HEADER_PREFIX + "CommittedBlockCount";
+    public static final String APPEND_OFFSET = HEADER_PREFIX + "AppendOffset";
+    public static final String RAW_HTTP_HEADERS = HEADER_PREFIX + "RawHttpHeaders";
+    public static final String FILE_NAME = HEADER_PREFIX + "FileName";
+    public static final String DOWNLOAD_LINK = HEADER_PREFIX + "DownloadLink";
+    // headers to be retrieved
+    public static final String LIST_BLOB_OPTIONS = HEADER_PREFIX + "ListBlobOptions";
+    public static final String BLOB_LIST_DETAILS = HEADER_PREFIX + "ListDetails";
+    public static final String PREFIX = HEADER_PREFIX + "Prefix";
+    public static final String REGEX = HEADER_PREFIX + "Regex";
+    public static final String MAX_RESULTS_PER_PAGE = HEADER_PREFIX + "MaxResultsPerPage";
+    public static final String TIMEOUT = HEADER_PREFIX + "Timeout";
+    public static final String PUBLIC_ACCESS_TYPE = HEADER_PREFIX + "PublicAccessType";
+    public static final String BLOB_REQUEST_CONDITION = HEADER_PREFIX + "RequestCondition";
+    public static final String BLOB_CONTAINER_NAME = HEADER_PREFIX + "BlobContainerName";
+    public static final String BLOB_NAME = HEADER_PREFIX + "BlobName";
+    public static final String FILE_DIR = HEADER_PREFIX + "FileDir";
+    public static final String PAGE_BLOB_RANGE = HEADER_PREFIX + "PageBlobRange";
+    public static final String PAGE_BLOB_SIZE = HEADER_PREFIX + "PageBlobSize";
+    public static final String COMMIT_BLOCK_LIST_LATER = HEADER_PREFIX + "CommitBlobBlockListLater";
+    public static final String BLOCK_LIST_TYPE = HEADER_PREFIX + "BlockListType";
+    public static final String CREATE_APPEND_BLOB = HEADER_PREFIX + "CreateAppendBlob";
+    public static final String CREATE_PAGE_BLOB = HEADER_PREFIX + "CreatePageBlob";
+    public static final String DELETE_SNAPSHOT_OPTION_TYPE = HEADER_PREFIX + "DeleteSnapshotsOptionType";
+    public static final String LIST_BLOB_CONTAINERS_OPTIONS = HEADER_PREFIX + "ListBlobContainersOptions";
+    public static final String PARALLEL_TRANSFER_OPTIONS = HEADER_PREFIX + "ParallelTransferOptions";
+    public static final String DOWNLOAD_LINK_EXPIRATION = HEADER_PREFIX + "DownloadLinkExpiration";
+
+    private BlobConstants() {
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConsumer.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConsumer.java
new file mode 100644
index 0000000..00e9490
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConsumer.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+import com.azure.storage.blob.BlobContainerClient;
+import com.azure.storage.blob.models.BlobItem;
+import com.azure.storage.blob.models.BlobStorageException;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExtendedExchange;
+import org.apache.camel.Processor;
+import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
+import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
+import org.apache.camel.component.azure.storage.blob.operations.BlobContainerOperations;
+import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
+import org.apache.camel.component.azure.storage.blob.operations.BlobOperations;
+import org.apache.camel.spi.Synchronization;
+import org.apache.camel.support.ScheduledBatchPollingConsumer;
+import org.apache.camel.util.CastUtils;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BlobConsumer extends ScheduledBatchPollingConsumer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BlobConsumer.class);
+
+    public BlobConsumer(final BlobEndpoint endpoint, final Processor processor) {
+        super(endpoint, processor);
+    }
+
+    @Override
+    protected int poll() throws Exception {
+        final String containerName = getEndpoint().getConfiguration().getContainerName();
+        final String blobName = getEndpoint().getConfiguration().getBlobName();
+        final BlobContainerClient blobContainerClient
+                = getEndpoint().getBlobServiceClient().getBlobContainerClient(containerName);
+
+        Queue<Exchange> exchanges;
+
+        try {
+            if (ObjectHelper.isNotEmpty(blobName)) {
+                // here we have a blob which means we just download a single blob
+                final Exchange exchange = createExchangeFromBlob(blobName, blobContainerClient);
+                exchanges = new LinkedList<>();
+                exchanges.add(exchange);
+            } else {
+                // download multiple blobs since we only have no blobName set
+                exchanges = createBatchExchangesFromContainer(blobContainerClient);
+            }
+            return processBatch(CastUtils.cast(exchanges));
+        } catch (BlobStorageException ex) {
+            if (404 == ex.getStatusCode()) {
+                return 0;
+            } else {
+                throw ex;
+            }
+        }
+    }
+
+    private Exchange createExchangeFromBlob(final String blobName, final BlobContainerClient blobContainerClient)
+            throws IOException {
+        final BlobClientWrapper clientWrapper
+                = new BlobClientWrapper(blobContainerClient.getBlobClient(blobName));
+        final BlobOperations operations = new BlobOperations(getEndpoint().getConfiguration(), clientWrapper);
+        final Exchange exchange = createExchange(true);
+
+        BlobOperationResponse response;
+        if (!ObjectHelper.isEmpty(getEndpoint().getConfiguration().getFileDir())) {
+            // if we have a fileDir set, we download our content
+            response = operations.downloadBlobToFile(exchange);
+        } else {
+            // otherwise, we rely on the outputstream/inputstream
+            response = operations.getBlob(exchange);
+        }
+
+        getEndpoint().setResponseOnExchange(response, exchange);
+
+        exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
+        return exchange;
+    }
+
+    @SuppressWarnings("unchecked")
+    private Queue<Exchange> createBatchExchangesFromContainer(final BlobContainerClient blobContainerClient)
+            throws IOException {
+        final BlobContainerClientWrapper containerClientWrapper = new BlobContainerClientWrapper(blobContainerClient);
+        final BlobContainerOperations containerOperations
+                = new BlobContainerOperations(getEndpoint().getConfiguration(), containerClientWrapper);
+
+        final List<BlobItem> blobs = (List<BlobItem>) containerOperations.listBlobs(null).getBody();
+
+        final Queue<Exchange> exchanges = new LinkedList<>();
+
+        for (BlobItem blobItem : blobs) {
+            exchanges.add(createExchangeFromBlob(blobItem.getName(), blobContainerClient));
+        }
+        return exchanges;
+    }
+
+    @Override
+    public BlobEndpoint getEndpoint() {
+        return (BlobEndpoint) super.getEndpoint();
+    }
+
+    @Override
+    public int processBatch(Queue<Object> exchanges) {
+        final int total = exchanges.size();
+
+        for (int index = 0; index < total && isBatchAllowed(); index++) {
+            // only loop if we are started (allowed to run)
+            final Exchange exchange = ObjectHelper.cast(Exchange.class, exchanges.poll());
+
+            // add current index and total as properties
+            exchange.setProperty(Exchange.BATCH_INDEX, index);
+            exchange.setProperty(Exchange.BATCH_SIZE, total);
+            exchange.setProperty(Exchange.BATCH_COMPLETE, index == total - 1);
+
+            // update pending number of exchanges
+            pendingExchanges = total - index - 1;
+
+            // add on completion to handle after work when the exchange is done
+            exchange.adapt(ExtendedExchange.class).addOnCompletion(new Synchronization() {
+                @Override
+                public void onComplete(Exchange exchange) {
+                    LOG.trace("Complected from processing all exchanges...");
+                }
+
+                @Override
+                public void onFailure(Exchange exchange) {
+                    processRollback(exchange);
+                }
+            });
+
+            LOG.trace("Processing exchange [{}]...", exchange);
+            getAsyncProcessor().process(exchange, doneSync -> LOG.trace("Processing exchange [{}] done.", exchange));
+        }
+        return total;
+    }
+
+    /**
+     * Strategy when processing the exchange failed.
+     *
+     * @param exchange the exchange
+     */
+    protected void processRollback(Exchange exchange) {
+        Exception cause = exchange.getException();
+        if (cause != null) {
+            LOG.warn("Exchange failed, so rolling back message status: {}", exchange, cause);
+        } else {
+            LOG.warn("Exchange failed, so rolling back message status: {}", exchange);
+        }
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java
new file mode 100644
index 0000000..e8f072f
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import com.azure.storage.blob.BlobClient;
+import com.azure.storage.blob.BlobContainerClient;
+import com.azure.storage.blob.BlobServiceClient;
+import org.apache.camel.Category;
+import org.apache.camel.Component;
+import org.apache.camel.Consumer;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.component.azure.storage.blob.client.BlobClientFactory;
+import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.support.DefaultEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Store and retrieve blobs from Azure Storage Blob Service using SDK v12.
+ */
+@UriEndpoint(firstVersion = "3.3.0", scheme = "azure-storage-blob", title = "Azure Storage Blob Service",
+             syntax = "azure-storage-blob:accountName/containerName", category = { Category.CLOUD, Category.FILE })
+public class BlobEndpoint extends DefaultEndpoint {
+
+    @UriParam
+    private BlobServiceClient blobServiceClient;
+
+    @UriParam
+    private BlobConfiguration configuration;
+
+    public BlobEndpoint(final String uri, final Component component, final BlobConfiguration configuration) {
+        super(uri, component);
+        this.configuration = configuration;
+    }
+
+    @Override
+    public Producer createProducer() {
+        return new BlobProducer(this);
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) {
+        // we need blobname as well as blob container in order to create it
+        if (ObjectHelper.isEmpty(configuration.getContainerName())) {
+            throw new IllegalArgumentException("Container name must be set.");
+        }
+        return new BlobConsumer(this, processor);
+    }
+
+    @Override
+    public void doStart() throws Exception {
+        super.doStart();
+
+        blobServiceClient = configuration.getServiceClient() != null
+                ? configuration.getServiceClient() : BlobClientFactory.createBlobServiceClient(configuration);
+    }
+
+    public void setResponseOnExchange(final BlobOperationResponse response, final Exchange exchange) {
+        final Message message = exchange.getIn();
+
+        message.setBody(response.getBody());
+        message.setHeaders(response.getHeaders());
+    }
+
+    /**
+     * The component configurations
+     */
+    public BlobConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(BlobConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    /**
+     * Client to a storage account. This client does not hold any state about a particular storage account but is
+     * instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used
+     * to construct URLs to blobs and containers.
+     *
+     * This client contains operations on a service account. Operations on a container are available on
+     * {@link BlobContainerClient} through {@link #getBlobContainerClient(String)}, and operations on a blob are
+     * available on {@link BlobClient} through {@link #getBlobContainerClient(String).getBlobClient(String)}.
+     */
+    public BlobServiceClient getBlobServiceClient() {
+        return blobServiceClient;
+    }
+
+    public void setBlobServiceClient(BlobServiceClient blobServiceClient) {
+        this.blobServiceClient = blobServiceClient;
+    }
+}
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
new file mode 100644
index 0000000..8faed08
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobExchangeHeaders.java
@@ -0,0 +1,438 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.time.Duration;
+import java.time.OffsetDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.azure.core.http.HttpHeaders;
+import com.azure.storage.blob.models.AccessTier;
+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.BlobListDetails;
+import com.azure.storage.blob.models.BlobProperties;
+import com.azure.storage.blob.models.BlobRequestConditions;
+import com.azure.storage.blob.models.BlobType;
+import com.azure.storage.blob.models.BlockBlobItem;
+import com.azure.storage.blob.models.BlockListType;
+import com.azure.storage.blob.models.CopyStatusType;
+import com.azure.storage.blob.models.DeleteSnapshotsOptionType;
+import com.azure.storage.blob.models.LeaseDurationType;
+import com.azure.storage.blob.models.LeaseStateType;
+import com.azure.storage.blob.models.LeaseStatusType;
+import com.azure.storage.blob.models.ListBlobContainersOptions;
+import com.azure.storage.blob.models.ListBlobsOptions;
+import com.azure.storage.blob.models.PageBlobItem;
+import com.azure.storage.blob.models.PageRange;
+import com.azure.storage.blob.models.ParallelTransferOptions;
+import com.azure.storage.blob.models.PublicAccessType;
+import org.apache.camel.Exchange;
+import org.apache.camel.util.ObjectHelper;
+
+public class BlobExchangeHeaders {
+
+    private final Map<String, Object> headers = new HashMap<>();
+
+    public static BlobExchangeHeaders createBlobExchangeHeadersFromBlobProperties(final BlobProperties properties) {
+        return new BlobExchangeHeaders()
+                .accessTierHeader(properties.getAccessTier())
+                .accessTierChangeTime(properties.getAccessTierChangeTime())
+                .archiveStatus(properties.getArchiveStatus())
+                .blobSequenceNumber(properties.getBlobSequenceNumber())
+                .blobSize(properties.getBlobSize())
+                .blobType(properties.getBlobType())
+                .cacheControl(properties.getCacheControl())
+                .committedBlockCount(properties.getCommittedBlockCount())
+                .contentDisposition(properties.getContentDisposition())
+                .contentEncoding(properties.getContentEncoding())
+                .contentLanguage(properties.getContentLanguage())
+                .contentMd5(properties.getContentMd5())
+                .contentType(properties.getContentType())
+                .copyCompletionTime(properties.getCopyCompletionTime())
+                .copyDestinationSnapshot(properties.getCopyDestinationSnapshot())
+                .copyId(properties.getCopyId())
+                .copyProgress(properties.getCopyProgress())
+                .copySource(properties.getCopySource())
+                .copyStatus(properties.getCopyStatus())
+                .copyStatusDescription(properties.getCopyStatusDescription())
+                .creationTime(properties.getCreationTime())
+                .encryptionKeySha256(properties.getEncryptionKeySha256())
+                .eTag(properties.getETag())
+                .isAccessTierInferred(properties.isAccessTierInferred())
+                .isIncrementalCopy(properties.isIncrementalCopy())
+                .isServerEncrypted(properties.isServerEncrypted())
+                .lastModified(properties.getLastModified())
+                .leaseDuration(properties.getLeaseDuration())
+                .leaseState(properties.getLeaseState())
+                .leaseStatus(properties.getLeaseStatus())
+                .metadata(properties.getMetadata());
+    }
+
+    public static BlobExchangeHeaders createBlobExchangeHeadersFromBlobDownloadHeaders(
+            final BlobDownloadHeaders blobDownloadHeaders) {
+        return createBlobExchangeHeadersFromBlobProperties(buildBlobProperties(blobDownloadHeaders));
+    }
+
+    public static BlobExchangeHeaders createBlobExchangeHeadersFromBlockBlobItem(final BlockBlobItem blockBlobItem) {
+        return new BlobExchangeHeaders()
+                .eTag(blockBlobItem.getETag())
+                .lastModified(blockBlobItem.getLastModified())
+                .contentMd5(blockBlobItem.getContentMd5())
+                .isServerEncrypted(blockBlobItem.isServerEncrypted())
+                .encryptionKeySha256(blockBlobItem.getEncryptionKeySha256())
+                .encryptionScope(blockBlobItem.getEncryptionScope());
+    }
+
+    public static BlobExchangeHeaders createBlobExchangeHeadersFromAppendBlobItem(final AppendBlobItem appendBlobItem) {
+        return new BlobExchangeHeaders()
+                .eTag(appendBlobItem.getETag())
+                .lastModified(appendBlobItem.getLastModified())
+                .contentMd5(appendBlobItem.getContentMd5())
+                .isServerEncrypted(appendBlobItem.isServerEncrypted())
+                .encryptionKeySha256(appendBlobItem.getEncryptionKeySha256())
+                .encryptionScope(appendBlobItem.getEncryptionScope())
+                .appendOffset(appendBlobItem.getBlobAppendOffset())
+                .committedBlockCount(appendBlobItem.getBlobCommittedBlockCount());
+    }
+
+    public static BlobExchangeHeaders createBlobExchangeHeadersFromPageBlobItem(final PageBlobItem pageBlobItem) {
+        return new BlobExchangeHeaders()
+                .eTag(pageBlobItem.getETag())
+                .lastModified(pageBlobItem.getLastModified())
+                .contentMd5(pageBlobItem.getContentMd5())
+                .isServerEncrypted(pageBlobItem.isServerEncrypted())
+                .encryptionScope(pageBlobItem.getEncryptionScope())
+                .blobSequenceNumber(pageBlobItem.getBlobSequenceNumber());
+    }
+
+    public static BlobExchangeHeaders create() {
+        return new BlobExchangeHeaders();
+    }
+
+    private static BlobProperties buildBlobProperties(final BlobDownloadHeaders hd) {
+        return new BlobProperties(
+                null, hd.getLastModified(), hd.getETag(),
+                hd.getContentLength() == null ? 0 : hd.getContentLength(), hd.getContentType(), null,
+                hd.getContentEncoding(), hd.getContentDisposition(), hd.getContentLanguage(), hd.getCacheControl(),
+                hd.getBlobSequenceNumber(), hd.getBlobType(), hd.getLeaseStatus(), hd.getLeaseState(),
+                hd.getLeaseDuration(), hd.getCopyId(), hd.getCopyStatus(), hd.getCopySource(), hd.getCopyProgress(),
+                hd.getCopyCompletionTime(), hd.getCopyStatusDescription(), hd.isServerEncrypted(),
+                null, null, null, null, null, hd.getEncryptionKeySha256(), null, hd.getMetadata(),
+                hd.getBlobCommittedBlockCount());
+    }
+
+    public static Duration getTimeoutFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.TIMEOUT, Duration.class);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static Map<String, String> getMetadataFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.METADATA, Map.class);
+    }
+
+    public static PublicAccessType getPublicAccessTypeFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.PUBLIC_ACCESS_TYPE, PublicAccessType.class);
+    }
+
+    public static BlobRequestConditions getBlobRequestConditionsFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.BLOB_REQUEST_CONDITION, BlobRequestConditions.class);
+    }
+
+    public static BlobListDetails getBlobListDetailsFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.BLOB_LIST_DETAILS, BlobListDetails.class);
+    }
+
+    public static ListBlobsOptions getListBlobsOptionsFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.LIST_BLOB_OPTIONS, ListBlobsOptions.class);
+    }
+
+    public static String getPrefixFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.PREFIX, String.class);
+    }
+
+    public static String getRegexFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.REGEX, String.class);
+    }
+
+    public static Integer getMaxResultsPerPageFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.MAX_RESULTS_PER_PAGE, Integer.class);
+    }
+
+    public static BlobHttpHeaders getBlobHttpHeadersFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.BLOB_HTTP_HEADERS, BlobHttpHeaders.class);
+    }
+
+    public static AccessTier getAccessTierFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.ACCESS_TIER, AccessTier.class);
+    }
+
+    public static byte[] getContentMd5FromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.CONTENT_MD5, byte[].class);
+    }
+
+    public static PageRange getPageRangeFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.PAGE_BLOB_RANGE, PageRange.class);
+    }
+
+    public static Boolean getCommitBlockListFlagFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.COMMIT_BLOCK_LIST_LATER, Boolean.class);
+    }
+
+    public static Boolean getCreateAppendBlobFlagFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.CREATE_APPEND_BLOB, Boolean.class);
+    }
+
+    public static Boolean getCreatePageBlobFlagFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.CREATE_PAGE_BLOB, Boolean.class);
+    }
+
+    public static BlockListType getBlockListTypeFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.BLOCK_LIST_TYPE, BlockListType.class);
+    }
+
+    public static Long getPageBlobSize(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.PAGE_BLOB_SIZE, Long.class);
+    }
+
+    public static Long getBlobSequenceNumberFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.BLOB_SEQUENCE_NUMBER, Long.class);
+    }
+
+    public static DeleteSnapshotsOptionType getDeleteSnapshotsOptionTypeFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.DELETE_SNAPSHOT_OPTION_TYPE, DeleteSnapshotsOptionType.class);
+    }
+
+    public static ListBlobContainersOptions getListBlobContainersOptionsFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.LIST_BLOB_CONTAINERS_OPTIONS, ListBlobContainersOptions.class);
+    }
+
+    public static ParallelTransferOptions getParallelTransferOptionsFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.PARALLEL_TRANSFER_OPTIONS, ParallelTransferOptions.class);
+    }
+
+    public static String getFileDirFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.FILE_DIR, String.class);
+    }
+
+    public static Long getDownloadLinkExpirationFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.DOWNLOAD_LINK_EXPIRATION, Long.class);
+    }
+
+    public static String getBlobNameFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.BLOB_NAME, String.class);
+    }
+
+    public static String getBlobContainerNameFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.BLOB_CONTAINER_NAME, String.class);
+    }
+
+    public static BlobOperationsDefinition getBlobOperationsDefinitionFromHeaders(final Exchange exchange) {
+        return getObjectFromHeaders(exchange, BlobConstants.BLOB_OPERATION, BlobOperationsDefinition.class);
+    }
+
+    private static <T> T getObjectFromHeaders(final Exchange exchange, final String headerName, final Class<T> classType) {
+        return ObjectHelper.isEmpty(exchange) ? null : exchange.getIn().getHeader(headerName, classType);
+    }
+
+    public Map<String, Object> toMap() {
+        return headers;
+    }
+
+    public BlobExchangeHeaders accessTierHeader(final AccessTier accessTier) {
+        headers.put(BlobConstants.ACCESS_TIER, accessTier);
+        return this;
+    }
+
+    public BlobExchangeHeaders accessTierChangeTime(final OffsetDateTime accessTierChangeTime) {
+        headers.put(BlobConstants.ACCESS_TIER_CHANGE_TIME, accessTierChangeTime);
+        return this;
+    }
+
+    public BlobExchangeHeaders archiveStatus(final ArchiveStatus archiveStatus) {
+        headers.put(BlobConstants.ARCHIVE_STATUS, archiveStatus);
+        return this;
+    }
+
+    public BlobExchangeHeaders creationTime(final OffsetDateTime creationTime) {
+        headers.put(BlobConstants.CREATION_TIME, creationTime);
+        return this;
+    }
+
+    public BlobExchangeHeaders blobSequenceNumber(final Long sequence) {
+        headers.put(BlobConstants.BLOB_SEQUENCE_NUMBER, sequence);
+        return this;
+    }
+
+    public BlobExchangeHeaders blobSize(final long size) {
+        headers.put(BlobConstants.BLOB_SIZE, size);
+        return this;
+    }
+
+    public BlobExchangeHeaders blobType(final BlobType blobType) {
+        headers.put(BlobConstants.BLOB_TYPE, blobType);
+        return this;
+    }
+
+    public BlobExchangeHeaders cacheControl(final String cache) {
+        headers.put(BlobConstants.CACHE_CONTROL, cache);
+        return this;
+    }
+
+    public BlobExchangeHeaders committedBlockCount(final Integer count) {
+        headers.put(BlobConstants.COMMITTED_BLOCK_COUNT, count);
+        return this;
+    }
+
+    public BlobExchangeHeaders contentDisposition(final String content) {
+        headers.put(BlobConstants.CONTENT_DISPOSITION, content);
+        return this;
+    }
+
+    public BlobExchangeHeaders contentEncoding(final String contentEncoding) {
+        headers.put(BlobConstants.CONTENT_ENCODING, contentEncoding);
+        return this;
+    }
+
+    public BlobExchangeHeaders contentLanguage(final String contentLanguageHeader) {
+        headers.put(BlobConstants.CONTENT_LANGUAGE, contentLanguageHeader);
+        return this;
+    }
+
+    public BlobExchangeHeaders contentMd5(final byte[] md5) {
+        headers.put(BlobConstants.CONTENT_MD5, md5);
+        return this;
+    }
+
+    public BlobExchangeHeaders contentType(final String type) {
+        headers.put(BlobConstants.CONTENT_TYPE, type);
+        return this;
+    }
+
+    public BlobExchangeHeaders copyCompletionTime(final OffsetDateTime offsetDateTime) {
+        headers.put(BlobConstants.COPY_COMPILATION_TIME, offsetDateTime);
+        return this;
+    }
+
+    public BlobExchangeHeaders copyDestinationSnapshot(final String copyDest) {
+        headers.put(BlobConstants.COPY_DESTINATION_SNAPSHOT, copyDest);
+        return this;
+    }
+
+    public BlobExchangeHeaders copyId(final String copyId) {
+        headers.put(BlobConstants.COPY_ID, copyId);
+        return this;
+    }
+
+    public BlobExchangeHeaders copyProgress(final String copyProg) {
+        headers.put(BlobConstants.COPY_PROGRESS, copyProg);
+        return this;
+    }
+
+    public BlobExchangeHeaders copySource(final String copySource) {
+        headers.put(BlobConstants.COPY_SOURCE, copySource);
+        return this;
+    }
+
+    public BlobExchangeHeaders copyStatus(final CopyStatusType copyStatusType) {
+        headers.put(BlobConstants.COPY_STATUS, copyStatusType);
+        return this;
+    }
+
+    public BlobExchangeHeaders copyStatusDescription(final String copyStatusDes) {
+        headers.put(BlobConstants.COPY_STATUS_DESCRIPTION, copyStatusDes);
+        return this;
+    }
+
+    public BlobExchangeHeaders encryptionKeySha256(final String encryptionKeySha256) {
+        headers.put(BlobConstants.ENCRYPTION_KEY_SHA_256, encryptionKeySha256);
+        return this;
+    }
+
+    public BlobExchangeHeaders encryptionScope(final String scope) {
+        headers.put(BlobConstants.ENCRYPTION_SCOPE, scope);
+        return this;
+    }
+
+    public BlobExchangeHeaders eTag(final String eTag) {
+        headers.put(BlobConstants.E_TAG, eTag);
+        return this;
+    }
+
+    public BlobExchangeHeaders isAccessTierInferred(final Boolean isAccess) {
+        headers.put(BlobConstants.IS_ACCESS_TIER_INFRRRED, isAccess);
+        return this;
+    }
+
+    public BlobExchangeHeaders isIncrementalCopy(final Boolean isIncr) {
+        headers.put(BlobConstants.IS_INCREMENTAL_COPY, isIncr);
+        return this;
+    }
+
+    public BlobExchangeHeaders isServerEncrypted(final Boolean isServerEncrypted) {
+        headers.put(BlobConstants.IS_SERVER_ENCRYPTED, isServerEncrypted);
+        return this;
+    }
+
+    public BlobExchangeHeaders lastModified(final OffsetDateTime offsetDateTime) {
+        headers.put(BlobConstants.LAST_MODIFIED, offsetDateTime);
+        return this;
+    }
+
+    public BlobExchangeHeaders leaseDuration(final LeaseDurationType leaseDurationType) {
+        headers.put(BlobConstants.LEASE_DURATION, leaseDurationType);
+        return this;
+    }
+
+    public BlobExchangeHeaders leaseState(final LeaseStateType leaseStateType) {
+        headers.put(BlobConstants.LEASE_STATE, leaseStateType);
+        return this;
+    }
+
+    public BlobExchangeHeaders leaseStatus(final LeaseStatusType leaseStatusType) {
+        headers.put(BlobConstants.LEASE_STATUS, leaseStatusType);
+        return this;
+    }
+
+    public BlobExchangeHeaders metadata(final Map<String, String> metadata) {
+        headers.put(BlobConstants.METADATA, metadata);
+        return this;
+    }
+
+    public BlobExchangeHeaders appendOffset(final String offset) {
+        headers.put(BlobConstants.APPEND_OFFSET, offset);
+        return this;
+    }
+
+    public BlobExchangeHeaders fileName(final String fileName) {
+        headers.put(BlobConstants.FILE_NAME, fileName);
+        return this;
+    }
+
+    public BlobExchangeHeaders downloadLink(final String downloadLink) {
+        headers.put(BlobConstants.DOWNLOAD_LINK, downloadLink);
+        return this;
+    }
+
+    public BlobExchangeHeaders httpHeaders(final HttpHeaders httpHeaders) {
+        headers.put(BlobConstants.RAW_HTTP_HEADERS, httpHeaders);
+        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
new file mode 100644
index 0000000..f94d07d
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobOperationsDefinition.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.nio.file.FileAlreadyExistsException;
+
+public enum BlobOperationsDefinition {
+    // Operations on the service level
+    //
+    /**
+     * Returns a list of containers in the storage account.
+     */
+    listBlobContainers,
+
+    // Operations on the container level
+    //
+    /**
+     * Creates a new container within a storage account. If a container with the same name already exists, the producer
+     * will ignore it.
+     */
+    createBlobContainer,
+    /**
+     * Deletes the specified container in the storage account. If the container doesn't exist the operation fails.
+     */
+    deleteBlobContainer,
+    /**
+     * Returns a list of blobs in this container, with folder structures flattened.
+     */
+    listBlobs,
+
+    // Operations on the blob level
+    //
+    /**
+     * Get the content of the blob, can be restricted to a blob range.
+     */
+    getBlob,
+    /**
+     * Delete a blob
+     */
+    deleteBlob,
+    /**
+     * Downloads 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 {@link FileAlreadyExistsException} will
+     * be thrown.
+     */
+    downloadBlobToFile,
+    /**
+     * Generates the download link for the specified blob using shared access signatures (SAS). This by default only
+     * limit to 1hour of allowed access. However, you can override the default expiration duration through the headers.
+     */
+    downloadLink,
+    /**
+     * 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.
+     */
+    uploadBlockBlob,
+    /**
+     * 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` is set to false, this
+     * will also commit the blocks.
+     */
+    stageBlockBlobList,
+    /**
+     * Writes a blob by specifying the list of block IDs that are to make up the blob. In order 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.
+     */
+    commitBlobBlockList,
+    /**
+     * Returns the list of blocks that have been uploaded as part of a block blob using the specified block list filter.
+     */
+    getBlobBlockList,
+    /**
+     * Creates a 0-length append blob. Call commitAppendBlo`b operation to append data to an append blob.
+     */
+    createAppendBlob,
+    /**
+     * Commits a new block of data to the end of the existing append blob. In case of header
+     * `CamelAzureStorageBlobAppendBlobCreated` is set to false, it will attempt to create the appendBlob through
+     * internal call to `createAppendBlob` operation.
+     */
+    commitAppendBlob,
+    /**
+     * Creates a page blob of the specified length. Call `uploadPageBlob` operation to upload data data to a page blob.
+     */
+    createPageBlob,
+    /**
+     * Writes one or more pages to the page blob. The write size must be a multiple of 512. In case of header
+     * `CamelAzureStorageBlobPageBlockCreated` is set to false, it will attempt to create the appendBlob through
+     * internal call to `createPageBlob` operation.
+     */
+    uploadPageBlob,
+    /**
+     * Resizes the page blob to the specified size (which must be a multiple of 512).
+     */
+    resizePageBlob,
+    /**
+     * Frees the specified pages from the page blob. The size of the range must be a multiple of 512.
+     */
+    clearPageBlob,
+    /**
+     * Returns the list of valid page ranges for a page blob or snapshot of a page blob.
+     */
+    getPageBlobRanges,
+}
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
new file mode 100644
index 0000000..4e7c6de
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobProducer.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
+import org.apache.camel.component.azure.storage.blob.client.BlobServiceClientWrapper;
+import org.apache.camel.component.azure.storage.blob.operations.BlobContainerOperations;
+import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
+import org.apache.camel.component.azure.storage.blob.operations.BlobOperations;
+import org.apache.camel.component.azure.storage.blob.operations.BlobServiceOperations;
+import org.apache.camel.support.DefaultProducer;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * A Producer which sends messages to the Azure Storage Blob Service
+ */
+public class BlobProducer extends DefaultProducer {
+
+    private final BlobConfiguration configuration;
+    private final BlobConfigurationOptionsProxy configurationProxy;
+    private final BlobServiceOperations blobServiceOperations;
+    private final BlobServiceClientWrapper blobServiceClientWrapper;
+
+    public BlobProducer(final Endpoint endpoint) {
+        super(endpoint);
+        this.configuration = getEndpoint().getConfiguration();
+        this.blobServiceClientWrapper = new BlobServiceClientWrapper(getEndpoint().getBlobServiceClient());
+        this.blobServiceOperations = new BlobServiceOperations(configuration, blobServiceClientWrapper);
+        this.configurationProxy = new BlobConfigurationOptionsProxy(configuration);
+    }
+
+    @Override
+    public void process(final Exchange exchange) throws Exception {
+        BlobOperationsDefinition operation = determineOperation(exchange);
+
+        if (ObjectHelper.isEmpty(operation)) {
+            operation = BlobOperationsDefinition.listBlobContainers;
+        }
+
+        switch (operation) {
+            // service operations
+            case listBlobContainers:
+                setResponse(exchange, blobServiceOperations.listBlobContainers(exchange));
+                break;
+            // container operations
+            case createBlobContainer:
+                setResponse(exchange, getContainerOperations(exchange).createContainer(exchange));
+                break;
+            case deleteBlobContainer:
+                setResponse(exchange, getContainerOperations(exchange).deleteContainer(exchange));
+                break;
+            case listBlobs:
+                setResponse(exchange, getContainerOperations(exchange).listBlobs(exchange));
+                break;
+            // blob operations
+            case getBlob:
+                setResponse(exchange, getBlobOperations(exchange).getBlob(exchange));
+                break;
+            case deleteBlob:
+                setResponse(exchange, getBlobOperations(exchange).deleteBlob(exchange));
+                break;
+            case downloadBlobToFile:
+                setResponse(exchange, getBlobOperations(exchange).downloadBlobToFile(exchange));
+                break;
+            case downloadLink:
+                setResponse(exchange, getBlobOperations(exchange).downloadLink(exchange));
+                break;
+            // block blob operations
+            case uploadBlockBlob:
+                setResponse(exchange, getBlobOperations(exchange).uploadBlockBlob(exchange));
+                break;
+            case stageBlockBlobList:
+                setResponse(exchange, getBlobOperations(exchange).stageBlockBlobList(exchange));
+                break;
+            case commitBlobBlockList:
+                setResponse(exchange, getBlobOperations(exchange).commitBlobBlockList(exchange));
+                break;
+            case getBlobBlockList:
+                setResponse(exchange, getBlobOperations(exchange).getBlobBlockList(exchange));
+                break;
+            // append blob operations
+            case createAppendBlob:
+                setResponse(exchange, getBlobOperations(exchange).createAppendBlob(exchange));
+                break;
+            case commitAppendBlob:
+                setResponse(exchange, getBlobOperations(exchange).commitAppendBlob(exchange));
+                break;
+            // page blob operations
+            case createPageBlob:
+                setResponse(exchange, getBlobOperations(exchange).createPageBlob(exchange));
+                break;
+            case uploadPageBlob:
+                setResponse(exchange, getBlobOperations(exchange).uploadPageBlob(exchange));
+                break;
+            case resizePageBlob:
+                setResponse(exchange, getBlobOperations(exchange).resizePageBlob(exchange));
+                break;
+            case clearPageBlob:
+                setResponse(exchange, getBlobOperations(exchange).clearPageBlob(exchange));
+                break;
+            case getPageBlobRanges:
+                setResponse(exchange, getBlobOperations(exchange).getPageBlobRanges(exchange));
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported operation");
+        }
+    }
+
+    private void setResponse(final Exchange exchange, final BlobOperationResponse blobOperationResponse) {
+        exchange.getMessage().setBody(blobOperationResponse.getBody());
+        exchange.getMessage().setHeaders(blobOperationResponse.getHeaders());
+    }
+
+    @Override
+    public BlobEndpoint getEndpoint() {
+        return (BlobEndpoint) super.getEndpoint();
+    }
+
+    private BlobOperationsDefinition determineOperation(final Exchange exchange) {
+        return configurationProxy.getOperation(exchange);
+    }
+
+    private BlobContainerOperations getContainerOperations(final Exchange exchange) {
+        return new BlobContainerOperations(
+                configuration, blobServiceClientWrapper.getBlobContainerClientWrapper(determineContainerName(exchange)));
+    }
+
+    private BlobOperations getBlobOperations(final Exchange exchange) {
+        final BlobClientWrapper clientWrapper
+                = blobServiceClientWrapper.getBlobContainerClientWrapper(determineContainerName(exchange))
+                        .getBlobClientWrapper(determineBlobName(exchange));
+
+        return new BlobOperations(configuration, clientWrapper);
+    }
+
+    private String determineContainerName(final Exchange exchange) {
+        final String containerName = configurationProxy.getContainerName(exchange);
+
+        if (ObjectHelper.isEmpty(containerName)) {
+            throw new IllegalArgumentException("Container name must be specified");
+        }
+        return containerName;
+    }
+
+    public String determineBlobName(final Exchange exchange) {
+        final String blobName = configurationProxy.getBlobName(exchange);
+
+        if (ObjectHelper.isEmpty(blobName)) {
+            throw new IllegalArgumentException("Blob name must be specified");
+        }
+        return blobName;
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobStreamAndLength.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobStreamAndLength.java
new file mode 100644
index 0000000..a38a604
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobStreamAndLength.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.WrappedFile;
+
+public final class BlobStreamAndLength {
+
+    private final InputStream inputStream;
+
+    private final long streamLength;
+
+    private BlobStreamAndLength(InputStream inputStream, long streamLength) {
+        this.inputStream = inputStream;
+        this.streamLength = streamLength;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static BlobStreamAndLength createBlobStreamAndLengthFromExchangeBody(final Exchange exchange) throws IOException {
+        Object body = exchange.getIn().getBody();
+
+        if (body instanceof WrappedFile) {
+            // unwrap file
+            body = ((WrappedFile) body).getFile();
+        }
+
+        if (body instanceof InputStream) {
+            return new BlobStreamAndLength((InputStream) body, BlobUtils.getInputStreamLength((InputStream) body));
+        }
+        if (body instanceof File) {
+            return new BlobStreamAndLength(new BufferedInputStream(new FileInputStream((File) body)), ((File) body).length());
+        }
+        if (body instanceof byte[]) {
+            return new BlobStreamAndLength(new ByteArrayInputStream((byte[]) body), ((byte[]) body).length);
+        }
+
+        // try as input stream
+        final InputStream inputStream
+                = exchange.getContext().getTypeConverter().tryConvertTo(InputStream.class, exchange, body);
+
+        if (inputStream == null) {
+            // fallback to string based
+            throw new IllegalArgumentException("Unsupported blob type:" + body.getClass().getName());
+        }
+
+        return new BlobStreamAndLength(inputStream, BlobUtils.getInputStreamLength(inputStream));
+    }
+
+    public InputStream getInputStream() {
+        return inputStream;
+    }
+
+    public long getStreamLength() {
+        return streamLength;
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobType.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobType.java
new file mode 100644
index 0000000..3e2b5b9
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobType.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+/**
+ * Blob Type
+ */
+// The lower case naming is done to make component URI look better
+// when a type needs to be set and make it consistent with the values
+// used by Azure SDK BlobType parse implementation which is currently not
+// directly accessible
+public enum BlobType {
+    blockblob,
+    appendblob,
+    pageblob
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobUtils.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobUtils.java
new file mode 100644
index 0000000..02ada37
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobUtils.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.commons.io.IOUtils;
+
+public final class BlobUtils {
+
+    private BlobUtils() {
+    }
+
+    public static Message getInMessage(final Exchange exchange) {
+        return ObjectHelper.isEmpty(exchange) ? null : exchange.getIn();
+    }
+
+    public static Long getInputStreamLength(final InputStream inputStream) throws IOException {
+        final long length = IOUtils.toByteArray(inputStream).length;
+        inputStream.reset();
+
+        return length;
+    }
+
+    public static String getContainerName(final BlobConfiguration configuration, final Exchange exchange) {
+        return ObjectHelper.isEmpty(BlobExchangeHeaders.getBlobContainerNameFromHeaders(exchange))
+                ? configuration.getContainerName()
+                : BlobExchangeHeaders.getBlobContainerNameFromHeaders(exchange);
+    }
+
+    public static String getBlobName(final BlobConfiguration configuration, final Exchange exchange) {
+        return ObjectHelper.isEmpty(BlobExchangeHeaders.getBlobNameFromHeaders(exchange))
+                ? configuration.getBlobName()
+                : BlobExchangeHeaders.getBlobNameFromHeaders(exchange);
+    }
+
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java
new file mode 100644
index 0000000..46f71fc
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.client;
+
+import java.util.Locale;
+
+import com.azure.storage.blob.BlobServiceClient;
+import com.azure.storage.blob.BlobServiceClientBuilder;
+import com.azure.storage.common.StorageSharedKeyCredential;
+import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
+import org.apache.camel.util.ObjectHelper;
+
+public final class BlobClientFactory {
+
+    private static final String SERVICE_URI_SEGMENT = ".blob.core.windows.net";
+
+    private BlobClientFactory() {
+    }
+
+    public static BlobServiceClient createBlobServiceClient(final BlobConfiguration configuration) {
+        return new BlobServiceClientBuilder()
+                .endpoint(buildAzureEndpointUri(configuration))
+                .credential(getCredentialForClient(configuration))
+                .buildClient();
+    }
+
+    private static String buildAzureEndpointUri(final BlobConfiguration configuration) {
+        return String.format(Locale.ROOT, "https://%s" + SERVICE_URI_SEGMENT, getAccountName(configuration));
+    }
+
+    private static StorageSharedKeyCredential getCredentialForClient(final BlobConfiguration configuration) {
+        final StorageSharedKeyCredential storageSharedKeyCredential = configuration.getCredentials();
+
+        if (storageSharedKeyCredential != null) {
+            return storageSharedKeyCredential;
+        }
+
+        return new StorageSharedKeyCredential(configuration.getAccountName(), configuration.getAccessKey());
+    }
+
+    private static String getAccountName(final BlobConfiguration configuration) {
+        return !ObjectHelper.isEmpty(configuration.getCredentials())
+                ? configuration.getCredentials().getAccountName() : configuration.getAccountName();
+    }
+
+}
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
new file mode 100644
index 0000000..8a8d548
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientWrapper.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.client;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.time.Duration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.azure.core.http.HttpHeaders;
+import com.azure.core.http.rest.Response;
+import com.azure.core.http.rest.ResponseBase;
+import com.azure.core.util.Context;
+import com.azure.storage.blob.BlobClient;
+import com.azure.storage.blob.models.AccessTier;
+import com.azure.storage.blob.models.AppendBlobItem;
+import com.azure.storage.blob.models.AppendBlobRequestConditions;
+import com.azure.storage.blob.models.BlobDownloadHeaders;
+import com.azure.storage.blob.models.BlobHttpHeaders;
+import com.azure.storage.blob.models.BlobProperties;
+import com.azure.storage.blob.models.BlobRange;
+import com.azure.storage.blob.models.BlobRequestConditions;
+import com.azure.storage.blob.models.BlockBlobItem;
+import com.azure.storage.blob.models.BlockList;
+import com.azure.storage.blob.models.BlockListType;
+import com.azure.storage.blob.models.DeleteSnapshotsOptionType;
+import com.azure.storage.blob.models.DownloadRetryOptions;
+import com.azure.storage.blob.models.PageBlobItem;
+import com.azure.storage.blob.models.PageBlobRequestConditions;
+import com.azure.storage.blob.models.PageList;
+import com.azure.storage.blob.models.PageRange;
+import com.azure.storage.blob.models.ParallelTransferOptions;
+import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
+import com.azure.storage.blob.specialized.AppendBlobClient;
+import com.azure.storage.blob.specialized.BlobInputStream;
+import com.azure.storage.blob.specialized.BlockBlobClient;
+import com.azure.storage.blob.specialized.PageBlobClient;
+import org.apache.camel.util.ObjectHelper;
+
+public class BlobClientWrapper {
+
+    private final BlobClient client;
+
+    public BlobClientWrapper(final BlobClient client) {
+        ObjectHelper.notNull(client, "client can not be null");
+
+        this.client = client;
+    }
+
+    public String getBlobName() {
+        return client.getBlobName();
+    }
+
+    public String getBlobUrl() {
+        return client.getBlobUrl();
+    }
+
+    public Response<Void> delete(
+            final DeleteSnapshotsOptionType deleteBlobSnapshotOptions,
+            final BlobRequestConditions requestConditions, final Duration timeout) {
+        return client.deleteWithResponse(deleteBlobSnapshotOptions, requestConditions, timeout, Context.NONE);
+    }
+
+    public Map<String, Object> openInputStream(final BlobRange blobRange, final BlobRequestConditions blobRequestConditions) {
+
+        final BlobInputStream blobInputStream = client.openInputStream(blobRange, blobRequestConditions);
+
+        // Hack to fold the response in order to ease the mocking in the unit tests
+        final Map<String, Object> results = new HashMap<>();
+        results.put("inputStream", blobInputStream);
+        results.put("properties", blobInputStream.getProperties());
+
+        return results;
+    }
+
+    public ResponseBase<BlobDownloadHeaders, Void> downloadWithResponse(
+            final OutputStream stream, final BlobRange range,
+            final DownloadRetryOptions options, final BlobRequestConditions requestConditions, final boolean getRangeContentMd5,
+            final Duration timeout) {
+        return client.downloadWithResponse(stream, range, options, requestConditions, getRangeContentMd5, timeout,
+                Context.NONE);
+    }
+
+    public Response<BlobProperties> downloadToFileWithResponse(
+            final String filePath, final BlobRange range,
+            final ParallelTransferOptions parallelTransferOptions, final DownloadRetryOptions downloadRetryOptions,
+            final BlobRequestConditions requestConditions,
+            final boolean rangeGetContentMd5, final Duration timeout) {
+        return client.downloadToFileWithResponse(filePath, range, parallelTransferOptions, downloadRetryOptions,
+                requestConditions, rangeGetContentMd5, timeout, Context.NONE);
+    }
+
+    public Response<BlockBlobItem> uploadBlockBlob(
+            final InputStream data, final long length, final BlobHttpHeaders headers,
+            final Map<String, String> metadata, AccessTier tier, final byte[] contentMd5,
+            final BlobRequestConditions requestConditions,
+            final Duration timeout) {
+        return getBlockBlobClient().uploadWithResponse(data, length, headers, metadata, tier, contentMd5, requestConditions,
+                timeout, Context.NONE);
+    }
+
+    public HttpHeaders stageBlockBlob(
+            final String base64BlockId, final InputStream data, final long length, final byte[] contentMd5,
+            final String leaseId, final Duration timeout) {
+        return client.getBlockBlobClient()
+                .stageBlockWithResponse(base64BlockId, data, length, contentMd5, leaseId, timeout, Context.NONE).getHeaders();
+    }
+
+    public Response<BlockBlobItem> commitBlockBlob(
+            final List<String> base64BlockIds, final BlobHttpHeaders headers,
+            final Map<String, String> metadata, final AccessTier tier, final BlobRequestConditions requestConditions,
+            final Duration timeout) {
+        return getBlockBlobClient().commitBlockListWithResponse(base64BlockIds, headers, metadata, tier, requestConditions,
+                timeout, Context.NONE);
+    }
+
+    public Response<BlockList> listBlobBlocks(final BlockListType listType, final String leaseId, final Duration timeout) {
+        return getBlockBlobClient().listBlocksWithResponse(listType, leaseId, timeout, Context.NONE);
+    }
+
+    public Response<AppendBlobItem> createAppendBlob(
+            final BlobHttpHeaders headers, final Map<String, String> metadata,
+            final BlobRequestConditions requestConditions, final Duration timeout) {
+
+        return getAppendBlobClient().createWithResponse(headers, metadata, requestConditions, timeout, Context.NONE);
+    }
+
+    public Response<AppendBlobItem> appendBlobBlock(
+            final InputStream data, final long length, final byte[] contentMd5,
+            final AppendBlobRequestConditions appendBlobRequestConditions, final Duration timeout) {
+        return getAppendBlobClient().appendBlockWithResponse(data, length, contentMd5, appendBlobRequestConditions, timeout,
+                Context.NONE);
+    }
+
+    public boolean appendBlobExists() {
+        return getAppendBlobClient().exists();
+    }
+
+    public Response<PageBlobItem> createPageBlob(
+            final long size, final Long sequenceNumber, final BlobHttpHeaders headers,
+            final Map<String, String> metadata, final BlobRequestConditions requestConditions, final Duration timeout) {
+        return getPageBlobClient().createWithResponse(size, sequenceNumber, headers, metadata, requestConditions, timeout,
+                Context.NONE);
+    }
+
+    public Response<PageBlobItem> uploadPageBlob(
+            final PageRange pageRange, final InputStream body, final byte[] contentMd5,
+            final PageBlobRequestConditions pageBlobRequestConditions, final Duration timeout) {
+        return getPageBlobClient().uploadPagesWithResponse(pageRange, body, contentMd5, pageBlobRequestConditions, timeout,
+                Context.NONE);
+    }
+
+    public Response<PageBlobItem> resizePageBlob(
+            final long size, final BlobRequestConditions requestConditions, final Duration timeout) {
+        return getPageBlobClient().resizeWithResponse(size, requestConditions, timeout, Context.NONE);
+    }
+
+    public Response<PageBlobItem> clearPagesBlob(
+            final PageRange pageRange, final PageBlobRequestConditions pageBlobRequestConditions, final Duration timeout) {
+        return getPageBlobClient().clearPagesWithResponse(pageRange, pageBlobRequestConditions, timeout, Context.NONE);
+    }
+
+    public Response<PageList> getPageBlobRanges(
+            final BlobRange blobRange, final BlobRequestConditions requestConditions,
+            final Duration timeout) {
+        return getPageBlobClient().getPageRangesWithResponse(blobRange, requestConditions, timeout, Context.NONE);
+    }
+
+    public boolean pageBlobExists() {
+        return getPageBlobClient().exists();
+    }
+
+    public String generateSas(final BlobServiceSasSignatureValues blobServiceSasSignatureValues) {
+        return client.generateSas(blobServiceSasSignatureValues);
+    }
+
+    private BlockBlobClient getBlockBlobClient() {
+        return client.getBlockBlobClient();
+    }
+
+    private AppendBlobClient getAppendBlobClient() {
+        return client.getAppendBlobClient();
+    }
+
+    private PageBlobClient getPageBlobClient() {
+        return client.getPageBlobClient();
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobContainerClientWrapper.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobContainerClientWrapper.java
new file mode 100644
index 0000000..6047d68
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobContainerClientWrapper.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.client;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.azure.core.http.HttpHeaders;
+import com.azure.core.util.Context;
+import com.azure.storage.blob.BlobContainerClient;
+import com.azure.storage.blob.models.BlobItem;
+import com.azure.storage.blob.models.BlobRequestConditions;
+import com.azure.storage.blob.models.ListBlobsOptions;
+import com.azure.storage.blob.models.PublicAccessType;
+import org.apache.camel.util.ObjectHelper;
+
+public class BlobContainerClientWrapper {
+
+    private final BlobContainerClient client;
+
+    public BlobContainerClientWrapper(final BlobContainerClient client) {
+        this.client = client;
+    }
+
+    public HttpHeaders createContainer(
+            final Map<String, String> metadata, final PublicAccessType publicAccessType, final Duration timeout) {
+        return client.createWithResponse(metadata, publicAccessType, timeout, Context.NONE).getHeaders();
+    }
+
+    public HttpHeaders deleteContainer(final BlobRequestConditions blobRequestConditions, final Duration timeout) {
+        return client.deleteWithResponse(blobRequestConditions, timeout, Context.NONE).getHeaders();
+    }
+
+    public List<BlobItem> listBlobs(final ListBlobsOptions listBlobsOptions, final Duration timeout) {
+        return client.listBlobs(listBlobsOptions, timeout).stream().collect(Collectors.toList());
+    }
+
+    public BlobClientWrapper getBlobClientWrapper(final String blobName) {
+        if (!ObjectHelper.isEmpty(blobName)) {
+            return new BlobClientWrapper(client.getBlobClient(blobName));
+        }
+        throw new IllegalArgumentException("Cannot initialize a blob since no blob name was provided.");
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobServiceClientWrapper.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobServiceClientWrapper.java
new file mode 100644
index 0000000..dd2cb3b
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobServiceClientWrapper.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.client;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.azure.storage.blob.BlobServiceClient;
+import com.azure.storage.blob.models.BlobContainerItem;
+import com.azure.storage.blob.models.ListBlobContainersOptions;
+import org.apache.camel.util.ObjectHelper;
+
+public class BlobServiceClientWrapper {
+
+    private final BlobServiceClient client;
+
+    public BlobServiceClientWrapper(final BlobServiceClient client) {
+        ObjectHelper.notNull(client, "client cannot be null");
+
+        this.client = client;
+    }
+
+    public List<BlobContainerItem> listBlobContainers(final ListBlobContainersOptions options, final Duration timeout) {
+        return client.listBlobContainers(options, timeout).stream().collect(Collectors.toList());
+    }
+
+    public BlobContainerClientWrapper getBlobContainerClientWrapper(final String containerName) {
+        if (!ObjectHelper.isEmpty(containerName)) {
+            return new BlobContainerClientWrapper(client.getBlobContainerClient(containerName));
+        }
+        throw new IllegalArgumentException("Cannot initialize a blob container since no container name was provided.");
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperations.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperations.java
new file mode 100644
index 0000000..23f4a98
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperations.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.operations;
+
+import java.time.Duration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.azure.storage.blob.models.BlobItem;
+import com.azure.storage.blob.models.BlobRequestConditions;
+import com.azure.storage.blob.models.ListBlobsOptions;
+import com.azure.storage.blob.models.PublicAccessType;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
+import org.apache.camel.component.azure.storage.blob.BlobConfigurationOptionsProxy;
+import org.apache.camel.component.azure.storage.blob.BlobExchangeHeaders;
+import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * All operations related to {@link com.azure.storage.blob.BlobContainerClient}. This is at the container level.
+ */
+public class BlobContainerOperations {
+
+    private final BlobContainerClientWrapper client;
+    private final BlobConfigurationOptionsProxy configurationProxy;
+
+    public BlobContainerOperations(final BlobConfiguration configuration, final BlobContainerClientWrapper client) {
+        ObjectHelper.notNull(client, "client cannot be null");
+        this.client = client;
+        this.configurationProxy = new BlobConfigurationOptionsProxy(configuration);
+    }
+
+    public BlobOperationResponse listBlobs(final Exchange exchange) {
+        final ListBlobsOptions listBlobOptions = configurationProxy.getListBlobOptions(exchange);
+        final Duration timeout = configurationProxy.getTimeout(exchange);
+        final String regex = configurationProxy.getRegex(exchange);
+        List<BlobItem> blobs = client.listBlobs(listBlobOptions, timeout);
+        if (ObjectHelper.isEmpty(regex)) {
+            return new BlobOperationResponse(blobs);
+        }
+        List<BlobItem> filteredBlobs = blobs.stream()
+                .filter(x -> x.getName().matches(regex))
+                .collect(Collectors.toCollection(LinkedList<BlobItem>::new));
+        return new BlobOperationResponse(filteredBlobs);
+    }
+
+    public BlobOperationResponse createContainer(final Exchange exchange) {
+        final Map<String, String> metadata = configurationProxy.getMetadata(exchange);
+        final PublicAccessType publicAccessType = configurationProxy.getPublicAccessType(exchange);
+        final Duration timeout = configurationProxy.getTimeout(exchange);
+
+        final BlobExchangeHeaders blobExchangeHeaders
+                = new BlobExchangeHeaders().httpHeaders(client.createContainer(metadata, publicAccessType, timeout));
+        return new BlobOperationResponse(true, blobExchangeHeaders.toMap());
+    }
+
+    public BlobOperationResponse deleteContainer(final Exchange exchange) {
+        final BlobRequestConditions blobRequestConditions = configurationProxy.getBlobRequestConditions(exchange);
+        final Duration timeout = configurationProxy.getTimeout(exchange);
+        final BlobExchangeHeaders blobExchangeHeaders
+                = new BlobExchangeHeaders().httpHeaders(client.deleteContainer(blobRequestConditions, timeout));
+        return new BlobOperationResponse(true, blobExchangeHeaders.toMap());
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationResponse.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationResponse.java
new file mode 100644
index 0000000..cec4675
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationResponse.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.operations;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class BlobOperationResponse {
+
+    private Object body;
+    private Map<String, Object> headers = new HashMap<>();
+
+    public BlobOperationResponse() {
+    }
+
+    public BlobOperationResponse(final Object body, final Map<String, Object> headers) {
+        this.body = body;
+        this.headers = headers;
+    }
+
+    public BlobOperationResponse(final Object body) {
+        setBody(body);
+    }
+
+    public Object getBody() {
+        return body;
+    }
+
+    public void setBody(Object body) {
+        this.body = body;
+    }
+
+    public Map<String, Object> getHeaders() {
+        return headers;
+    }
+
+    public void setHeaders(final Map<String, Object> headers) {
+        this.headers = headers;
+    }
+}
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
new file mode 100644
index 0000000..6080d8e
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperations.java
@@ -0,0 +1,468 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.operations;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.time.Duration;
+import java.time.OffsetDateTime;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import com.azure.core.http.rest.Response;
+import com.azure.core.http.rest.ResponseBase;
+import com.azure.storage.blob.BlobClient;
+import com.azure.storage.blob.models.AccessTier;
+import com.azure.storage.blob.models.AppendBlobItem;
+import com.azure.storage.blob.models.BlobDownloadHeaders;
+import com.azure.storage.blob.models.BlobHttpHeaders;
+import com.azure.storage.blob.models.BlobProperties;
+import com.azure.storage.blob.models.BlobRange;
+import com.azure.storage.blob.models.BlobRequestConditions;
+import com.azure.storage.blob.models.Block;
+import com.azure.storage.blob.models.BlockBlobItem;
+import com.azure.storage.blob.models.BlockList;
+import com.azure.storage.blob.models.BlockListType;
+import com.azure.storage.blob.models.DeleteSnapshotsOptionType;
+import com.azure.storage.blob.models.DownloadRetryOptions;
+import com.azure.storage.blob.models.PageBlobItem;
+import com.azure.storage.blob.models.PageList;
+import com.azure.storage.blob.models.PageRange;
+import com.azure.storage.blob.models.ParallelTransferOptions;
+import com.azure.storage.blob.sas.BlobSasPermission;
+import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.azure.storage.blob.BlobBlock;
+import org.apache.camel.component.azure.storage.blob.BlobCommonRequestOptions;
+import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
+import org.apache.camel.component.azure.storage.blob.BlobConfigurationOptionsProxy;
+import org.apache.camel.component.azure.storage.blob.BlobConstants;
+import org.apache.camel.component.azure.storage.blob.BlobExchangeHeaders;
+import org.apache.camel.component.azure.storage.blob.BlobStreamAndLength;
+import org.apache.camel.component.azure.storage.blob.BlobUtils;
+import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * All operations related {@link BlobClient}. This is at the blob level.
+ */
+public class BlobOperations {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BlobOperations.class);
+
+    private final BlobClientWrapper client;
+    private final BlobConfigurationOptionsProxy configurationProxy;
+
+    public BlobOperations(final BlobConfiguration configuration, final BlobClientWrapper client) {
+        ObjectHelper.notNull(client, "client can not be null.");
+
+        this.client = client;
+        this.configurationProxy = new BlobConfigurationOptionsProxy(configuration);
+    }
+
+    public BlobOperationResponse getBlob(final Exchange exchange) throws IOException {
+        LOG.trace("Getting a blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
+
+        final Message message = BlobUtils.getInMessage(exchange);
+        final OutputStream outputStream = ObjectHelper.isEmpty(message) ? null : message.getBody(OutputStream.class);
+        final BlobRange blobRange = configurationProxy.getBlobRange(exchange);
+        final BlobCommonRequestOptions blobCommonRequestOptions = getCommonRequestOptions(exchange);
+
+        if (outputStream == null) {
+            // Then we create an input stream
+            final Map<String, Object> blobInputStream
+                    = client.openInputStream(blobRange, blobCommonRequestOptions.getBlobRequestConditions());
+            final BlobExchangeHeaders blobExchangeHeaders = BlobExchangeHeaders
+                    .createBlobExchangeHeadersFromBlobProperties((BlobProperties) blobInputStream.get("properties"));
+
+            return new BlobOperationResponse(blobInputStream.get("inputStream"), blobExchangeHeaders.toMap());
+        }
+        // we have an outputStream set, so we use it
+        final DownloadRetryOptions downloadRetryOptions = getDownloadRetryOptions(configurationProxy);
+
+        try {
+            final ResponseBase<BlobDownloadHeaders, Void> response = client.downloadWithResponse(outputStream, blobRange,
+                    downloadRetryOptions, blobCommonRequestOptions.getBlobRequestConditions(),
+                    blobCommonRequestOptions.getContentMD5() != null, blobCommonRequestOptions.getTimeout());
+
+            final BlobExchangeHeaders blobExchangeHeaders
+                    = BlobExchangeHeaders.createBlobExchangeHeadersFromBlobDownloadHeaders(response.getDeserializedHeaders())
+                            .httpHeaders(response.getHeaders());
+
+            return new BlobOperationResponse(outputStream, blobExchangeHeaders.toMap());
+        } finally {
+            if (configurationProxy.getConfiguration().isCloseStreamAfterRead()) {
+                outputStream.close();
+            }
+        }
+    }
+
+    public BlobOperationResponse downloadBlobToFile(final Exchange exchange) {
+        // check for fileDir
+        final String fileDir = configurationProxy.getFileDir(exchange);
+        if (ObjectHelper.isEmpty(fileDir)) {
+            throw new IllegalArgumentException("In order to download a blob, you will need to specify the fileDir in the URI");
+        }
+
+        final File fileToDownload = new File(fileDir, client.getBlobName());
+        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
+        final BlobRange blobRange = configurationProxy.getBlobRange(exchange);
+        final ParallelTransferOptions parallelTransferOptions = configurationProxy.getParallelTransferOptions(exchange);
+        final DownloadRetryOptions downloadRetryOptions = getDownloadRetryOptions(configurationProxy);
+
+        final Response<BlobProperties> response = client.downloadToFileWithResponse(fileToDownload.toString(), blobRange,
+                parallelTransferOptions, downloadRetryOptions,
+                commonRequestOptions.getBlobRequestConditions(), commonRequestOptions.getContentMD5() != null,
+                commonRequestOptions.getTimeout());
+
+        final BlobExchangeHeaders exchangeHeaders
+                = BlobExchangeHeaders.createBlobExchangeHeadersFromBlobProperties(response.getValue())
+                        .httpHeaders(response.getHeaders())
+                        .fileName(fileToDownload.toString());
+
+        return new BlobOperationResponse(fileToDownload, exchangeHeaders.toMap());
+    }
+
+    public BlobOperationResponse deleteBlob(final Exchange exchange) {
+        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
+        final DeleteSnapshotsOptionType deleteSnapshotsOptionType = configurationProxy.getDeleteSnapshotsOptionType(exchange);
+
+        return buildResponse(client.delete(deleteSnapshotsOptionType, commonRequestOptions.getBlobRequestConditions(),
+                commonRequestOptions.getTimeout()), true);
+    }
+
+    public BlobOperationResponse downloadLink(final Exchange exchange) {
+        final OffsetDateTime offsetDateTime = OffsetDateTime.now();
+        final long defaultExpirationTime = 60L * 60L; // 1 hour
+        final BlobSasPermission sasPermission = new BlobSasPermission().setReadPermission(true); // only read access
+        final Long expirationMillis = configurationProxy.getDownloadLinkExpiration(exchange);
+
+        OffsetDateTime offsetDateTimeToSet;
+        if (expirationMillis != null) {
+            offsetDateTimeToSet = offsetDateTime.plusSeconds(expirationMillis / 1000);
+        } else {
+            offsetDateTimeToSet = offsetDateTime.plusSeconds(defaultExpirationTime);
+        }
+
+        final BlobServiceSasSignatureValues serviceSasSignatureValues
+                = new BlobServiceSasSignatureValues(offsetDateTimeToSet, sasPermission);
+        final String url = client.getBlobUrl() + "?" + client.generateSas(serviceSasSignatureValues);
+
+        final BlobExchangeHeaders headers = BlobExchangeHeaders.create().downloadLink(url);
+
+        return new BlobOperationResponse(true, headers.toMap());
+    }
+
+    public BlobOperationResponse uploadBlockBlob(final Exchange exchange) throws IOException {
+        ObjectHelper.notNull(exchange, "exchange cannot be null");
+
+        final BlobStreamAndLength blobStreamAndLength = BlobStreamAndLength.createBlobStreamAndLengthFromExchangeBody(exchange);
+        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
+
+        LOG.trace("Putting a block blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
+
+        try {
+            final Response<BlockBlobItem> response = client.uploadBlockBlob(blobStreamAndLength.getInputStream(),
+                    blobStreamAndLength.getStreamLength(), commonRequestOptions.getBlobHttpHeaders(),
+                    commonRequestOptions.getMetadata(), commonRequestOptions.getAccessTier(),
+                    commonRequestOptions.getContentMD5(), commonRequestOptions.getBlobRequestConditions(),
+                    commonRequestOptions.getTimeout());
+
+            return buildResponse(response, true);
+        } finally {
+            closeInputStreamIfNeeded(blobStreamAndLength.getInputStream());
+        }
+    }
+
+    public BlobOperationResponse stageBlockBlobList(final Exchange exchange) throws Exception {
+        ObjectHelper.notNull(exchange, "exchange cannot be null");
+
+        final Object object = exchange.getIn().getMandatoryBody();
+
+        List<BlobBlock> blobBlocks = null;
+        if (object instanceof List) {
+            // noinspection unchecked
+            blobBlocks = (List<BlobBlock>) object;
+        } else if (object instanceof BlobBlock) {
+            blobBlocks = Collections.singletonList((BlobBlock) object);
+        }
+        if (blobBlocks == null || blobBlocks.isEmpty()) {
+            throw new IllegalArgumentException("Illegal storageBlocks payload");
+        }
+
+        LOG.trace("Putting a blob [{}] from blocks from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
+
+        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
+
+        final List<Block> blockEntries = new LinkedList<>();
+
+        blobBlocks.forEach(blobBlock -> {
+            blockEntries.add(blobBlock.getBlockEntry());
+            client.stageBlockBlob(blobBlock.getBlockEntry().getName(),
+                    blobBlock.getBlockStream(),
+                    blobBlock.getBlockEntry().getSizeLong(),
+                    commonRequestOptions.getContentMD5(),
+                    commonRequestOptions.leaseId(),
+                    commonRequestOptions.getTimeout());
+        });
+
+        final boolean commitBlockListLater = configurationProxy.isCommitBlockListLater(exchange);
+
+        if (!commitBlockListLater) {
+            // let us commit now
+            exchange.getIn().setBody(blockEntries);
+            return commitBlobBlockList(exchange);
+        }
+
+        return new BlobOperationResponse(true);
+    }
+
+    @SuppressWarnings("unchecked")
+    public BlobOperationResponse commitBlobBlockList(final Exchange exchange) throws Exception {
+        ObjectHelper.notNull(exchange, "exchange cannot be null");
+
+        final Object object = exchange.getIn().getMandatoryBody();
+
+        List<Block> blockEntries = null;
+        if (object instanceof List) {
+            blockEntries = (List<Block>) object;
+        } else if (object instanceof Block) {
+            blockEntries = Collections.singletonList((Block) object);
+        }
+        if (blockEntries == null || blockEntries.isEmpty()) {
+            throw new IllegalArgumentException("Illegal commit block list payload");
+        }
+
+        LOG.trace("Putting a blob [{}] block list from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
+
+        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
+
+        final List<String> blockIds = blockEntries.stream()
+                .map(Block::getName)
+                .collect(Collectors.toList());
+
+        final Response<BlockBlobItem> response = client.commitBlockBlob(blockIds, commonRequestOptions.getBlobHttpHeaders(),
+                commonRequestOptions.getMetadata(),
+                commonRequestOptions.getAccessTier(), commonRequestOptions.getBlobRequestConditions(),
+                commonRequestOptions.getTimeout());
+
+        return buildResponse(response, true);
+    }
+
+    public BlobOperationResponse getBlobBlockList(final Exchange exchange) {
+        LOG.trace("Getting the blob block list [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
+
+        final BlockListType blockListType = configurationProxy.getBlockListType(exchange);
+        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
+
+        final Response<BlockList> response
+                = client.listBlobBlocks(blockListType, commonRequestOptions.leaseId(), commonRequestOptions.getTimeout());
+
+        return buildResponse(response, false);
+    }
+
+    public BlobOperationResponse createAppendBlob(final Exchange exchange) {
+        LOG.trace("Creating an append blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
+
+        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
+
+        final Response<AppendBlobItem> response
+                = client.createAppendBlob(commonRequestOptions.getBlobHttpHeaders(), commonRequestOptions.getMetadata(),
+                        commonRequestOptions.getBlobRequestConditions(), commonRequestOptions.getTimeout());
+
+        return buildResponse(response, true);
+    }
+
+    public BlobOperationResponse commitAppendBlob(final Exchange exchange) throws IOException {
+        ObjectHelper.notNull(exchange, "exchange cannot be null");
+
+        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
+        final boolean createAppendBlob = configurationProxy.isCreateAppendBlob(exchange);
+
+        // only if header is true and we don't have one exists
+        if (createAppendBlob && !client.appendBlobExists()) {
+            createAppendBlob(exchange);
+        }
+
+        final BlobStreamAndLength streamAndLength = BlobStreamAndLength.createBlobStreamAndLengthFromExchangeBody(exchange);
+
+        try {
+            final Response<AppendBlobItem> response
+                    = client.appendBlobBlock(streamAndLength.getInputStream(), streamAndLength.getStreamLength(),
+                            commonRequestOptions.getContentMD5(), commonRequestOptions.getBlobRequestConditions(),
+                            commonRequestOptions.getTimeout());
+
+            return buildResponse(response, true);
+        } finally {
+            closeInputStreamIfNeeded(streamAndLength.getInputStream());
+        }
+    }
+
+    public BlobOperationResponse createPageBlob(final Exchange exchange) {
+        LOG.trace("Creating a page blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
+
+        final Long pageSize = getPageBlobSize(exchange);
+        final BlobCommonRequestOptions requestOptions = getCommonRequestOptions(exchange);
+        final Long sequenceNumber = configurationProxy.getBlobSequenceNumber(exchange);
+
+        final Response<PageBlobItem> response
+                = client.createPageBlob(pageSize, sequenceNumber, requestOptions.getBlobHttpHeaders(),
+                        requestOptions.getMetadata(), requestOptions.getBlobRequestConditions(), requestOptions.getTimeout());
+
+        return buildResponse(response, true);
+    }
+
+    public BlobOperationResponse uploadPageBlob(final Exchange exchange) throws IOException {
+        ObjectHelper.notNull(exchange, "exchange cannot be null");
+
+        final boolean createPageBlob = configurationProxy.isCreatePageBlob(exchange);
+
+        // only if header is true and we don't have one exists
+        if (createPageBlob && !client.pageBlobExists()) {
+            createPageBlob(exchange);
+        }
+
+        final BlobStreamAndLength streamAndLength = BlobStreamAndLength.createBlobStreamAndLengthFromExchangeBody(exchange);
+        final BlobCommonRequestOptions requestOptions = getCommonRequestOptions(exchange);
+        final PageRange pageRange = configurationProxy.getPageRange(exchange);
+
+        if (pageRange == null) {
+            throw new IllegalArgumentException("You need to set page range in the exchange headers.");
+        }
+
+        try {
+            final Response<PageBlobItem> response
+                    = client.uploadPageBlob(pageRange, streamAndLength.getInputStream(), requestOptions.getContentMD5(),
+                            requestOptions.getBlobRequestConditions(), requestOptions.getTimeout());
+
+            return buildResponse(response, true);
+        } finally {
+            closeInputStreamIfNeeded(streamAndLength.getInputStream());
+        }
+    }
+
+    public BlobOperationResponse resizePageBlob(final Exchange exchange) {
+        LOG.trace("Resizing a page blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
+
+        final Long pageSize = getPageBlobSize(exchange);
+        final BlobCommonRequestOptions requestOptions = getCommonRequestOptions(exchange);
+
+        final Response<PageBlobItem> response
+                = client.resizePageBlob(pageSize, requestOptions.getBlobRequestConditions(), requestOptions.getTimeout());
+
+        return buildResponse(response, true);
+    }
+
+    public BlobOperationResponse clearPageBlob(final Exchange exchange) {
+        ObjectHelper.notNull(exchange, "exchange cannot be null");
+
+        final PageRange pageRange = configurationProxy.getPageRange(exchange);
+        final BlobCommonRequestOptions requestOptions = getCommonRequestOptions(exchange);
+
+        if (pageRange == null) {
+            throw new IllegalArgumentException("You need to set page range in the exchange headers.");
+        }
+
+        final Response<PageBlobItem> response
+                = client.clearPagesBlob(pageRange, requestOptions.getBlobRequestConditions(), requestOptions.getTimeout());
+
+        return buildResponse(response, true);
+    }
+
+    public BlobOperationResponse getPageBlobRanges(final Exchange exchange) {
+        ObjectHelper.notNull(exchange, "exchange cannot be null");
+
+        final BlobRange blobRange = configurationProxy.getBlobRange(exchange);
+        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
+
+        LOG.trace("Getting the page blob ranges [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange),
+                exchange);
+
+        final Response<PageList> response = client.getPageBlobRanges(blobRange, commonRequestOptions.getBlobRequestConditions(),
+                commonRequestOptions.getTimeout());
+
+        return buildResponse(response, false);
+    }
+
+    private DownloadRetryOptions getDownloadRetryOptions(final BlobConfigurationOptionsProxy configurationProxy) {
+        return new DownloadRetryOptions().setMaxRetryRequests(configurationProxy.getMaxRetryRequests());
+    }
+
+    private BlobCommonRequestOptions getCommonRequestOptions(final Exchange exchange) {
+        final BlobHttpHeaders blobHttpHeaders = configurationProxy.getBlobHttpHeaders(exchange);
+        final Map<String, String> metadata = configurationProxy.getMetadata(exchange);
+        final AccessTier accessTier = configurationProxy.getAccessTier(exchange);
+        final BlobRequestConditions blobRequestConditions = configurationProxy.getBlobRequestConditions(exchange);
+        final Duration timeout = configurationProxy.getTimeout(exchange);
+        final byte[] contentMD5 = configurationProxy.getContentMd5(exchange);
+
+        return new BlobCommonRequestOptions(blobHttpHeaders, metadata, accessTier, blobRequestConditions, contentMD5, timeout);
+    }
+
+    @SuppressWarnings("rawtypes")
+    private BlobOperationResponse buildResponse(final Response response, final boolean emptyBody) {
+        final Object body = emptyBody ? true : response.getValue();
+        BlobExchangeHeaders exchangeHeaders;
+
+        if (response.getValue() instanceof BlockBlobItem) {
+            exchangeHeaders
+                    = BlobExchangeHeaders.createBlobExchangeHeadersFromBlockBlobItem((BlockBlobItem) response.getValue());
+        } else if (response.getValue() instanceof AppendBlobItem) {
+            exchangeHeaders
+                    = BlobExchangeHeaders.createBlobExchangeHeadersFromAppendBlobItem((AppendBlobItem) response.getValue());
+        } else if (response.getValue() instanceof PageBlobItem) {
+            exchangeHeaders = BlobExchangeHeaders.createBlobExchangeHeadersFromPageBlobItem((PageBlobItem) response.getValue());
+        } else if (response.getValue() instanceof BlobProperties) {
+            exchangeHeaders
+                    = BlobExchangeHeaders.createBlobExchangeHeadersFromBlobProperties((BlobProperties) response.getValue());
+        } else {
+            exchangeHeaders = BlobExchangeHeaders.create();
+        }
+
+        exchangeHeaders.httpHeaders(response.getHeaders());
+
+        return new BlobOperationResponse(body, exchangeHeaders.toMap());
+    }
+
+    private Long getPageBlobSize(final Exchange exchange) {
+        // we try to get the size from the page range if exists
+        final PageRange pageRange = configurationProxy.getPageRange(exchange);
+        if (pageRange != null) {
+            return pageRange.getEnd() - pageRange.getStart() + 1; //e.g: 1023-0+1 = 1024 size
+        }
+        // now we try the page size
+        final Long pageSize = configurationProxy.getPageBlobSize(exchange);
+        if (pageSize != null) {
+            return pageSize;
+        }
+        return BlobConstants.PAGE_BLOB_DEFAULT_SIZE;
+    }
+
+    private void closeInputStreamIfNeeded(InputStream inputStream) throws IOException {
+        if (configurationProxy.getConfiguration().isCloseStreamAfterWrite()) {
+            inputStream.close();
+        }
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobServiceOperations.java b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobServiceOperations.java
new file mode 100644
index 0000000..631f33d
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobServiceOperations.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.operations;
+
+import java.time.Duration;
+
+import com.azure.storage.blob.models.ListBlobContainersOptions;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
+import org.apache.camel.component.azure.storage.blob.BlobConfigurationOptionsProxy;
+import org.apache.camel.component.azure.storage.blob.client.BlobServiceClientWrapper;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Operations related to {@link com.azure.storage.blob.BlobServiceClient}. This is at the service level.
+ */
+public class BlobServiceOperations {
+
+    private final BlobServiceClientWrapper client;
+    private final BlobConfigurationOptionsProxy configurationProxy;
+
+    public BlobServiceOperations(final BlobConfiguration configuration, final BlobServiceClientWrapper client) {
+        ObjectHelper.notNull(client, "client cannot be null");
+
+        this.client = client;
+        this.configurationProxy = new BlobConfigurationOptionsProxy(configuration);
+    }
+
+    public BlobOperationResponse listBlobContainers(final Exchange exchange) {
+        final ListBlobContainersOptions listBlobContainersOptions = configurationProxy.getListBlobContainersOptions(exchange);
+        final Duration timeout = configurationProxy.getTimeout(exchange);
+
+        return new BlobOperationResponse(client.listBlobContainers(listBlobContainersOptions, timeout));
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobComponentTest.java b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobComponentTest.java
new file mode 100644
index 0000000..0fc2066
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobComponentTest.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.util.Collections;
+
+import com.azure.storage.blob.BlobServiceClient;
+import com.azure.storage.common.StorageSharedKeyCredential;
+import org.apache.camel.Producer;
+import org.apache.camel.component.azure.storage.blob.client.BlobClientFactory;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+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.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class BlobComponentTest extends CamelTestSupport {
+
+    @Test
+    void testCreateEndpointWithMinConfigForClientOnly() {
+        final BlobConfiguration configuration = new BlobConfiguration();
+        configuration.setCredentials(storageSharedKeyCredential());
+        final BlobServiceClient serviceClient = BlobClientFactory.createBlobServiceClient(configuration);
+
+        context.getRegistry().bind("azureBlobClient", serviceClient);
+
+        final BlobEndpoint endpoint = (BlobEndpoint) context
+                .getEndpoint("azure-storage-blob://camelazure/container?blobName=blob&serviceClient=#azureBlobClient");
+
+        doTestCreateEndpointWithMinConfig(endpoint, true);
+    }
+
+    @Test
+    void testCreateEndpointWithMinConfigForCredsOnly() throws Exception {
+        context.getRegistry().bind("creds", storageSharedKeyCredential());
+
+        final BlobEndpoint endpoint = (BlobEndpoint) context
+                .getEndpoint("azure-storage-blob://camelazure/container?blobName=blob&credentials=#creds");
+
+        doTestCreateEndpointWithMinConfig(endpoint, false);
+    }
+
+    private void doTestCreateEndpointWithMinConfig(BlobEndpoint endpoint, boolean clientExpected) {
+        assertEquals("camelazure", endpoint.getConfiguration().getAccountName());
+        assertEquals("container", endpoint.getConfiguration().getContainerName());
+        assertEquals("blob", endpoint.getConfiguration().getBlobName());
+        if (clientExpected) {
+            assertNotNull(endpoint.getConfiguration().getServiceClient());
+            assertNull(endpoint.getConfiguration().getCredentials());
+        } else {
+            assertNull(endpoint.getConfiguration().getServiceClient());
+            assertNotNull(endpoint.getConfiguration().getCredentials());
+        }
+
+        assertEquals(BlobType.blockblob, endpoint.getConfiguration().getBlobType());
+        assertNull(endpoint.getConfiguration().getFileDir());
+        assertEquals(Long.valueOf(0L), endpoint.getConfiguration().getBlobOffset());
+        assertEquals(BlobOperationsDefinition.listBlobContainers, endpoint.getConfiguration().getOperation());
+        assertTrue(endpoint.getConfiguration().isCloseStreamAfterRead());
+        assertTrue(endpoint.getConfiguration().isCloseStreamAfterWrite());
+    }
+
+    @Test
+    void testCreateEndpointWithMaxConfig() {
+        context.getRegistry().bind("creds", storageSharedKeyCredential());
+        context.getRegistry().bind("metadata", Collections.emptyMap());
+
+        final String uri = "azure-storage-blob://camelazure/container"
+                           + "?blobName=blob&credentials=#creds&blobType=pageblob"
+                           + "&fileDir=/tmp&blobOffset=512&operation=clearPageBlob&dataCount=1024"
+                           + "&closeStreamAfterRead=false&closeStreamAfterWrite=false";
+        final BlobEndpoint endpoint = (BlobEndpoint) context.getEndpoint(uri);
+
+        assertEquals("camelazure", endpoint.getConfiguration().getAccountName());
+        assertEquals("container", endpoint.getConfiguration().getContainerName());
+        assertEquals("blob", endpoint.getConfiguration().getBlobName());
+        assertNull(endpoint.getConfiguration().getServiceClient());
+        assertNotNull(endpoint.getConfiguration().getCredentials());
+
+        assertEquals(BlobType.pageblob, endpoint.getConfiguration().getBlobType());
+        assertEquals("/tmp", endpoint.getConfiguration().getFileDir());
+        assertEquals(Long.valueOf(512L), endpoint.getConfiguration().getBlobOffset());
+        assertEquals(Long.valueOf(1024L), endpoint.getConfiguration().getDataCount());
+        assertEquals(BlobOperationsDefinition.clearPageBlob, endpoint.getConfiguration().getOperation());
+        assertFalse(endpoint.getConfiguration().isCloseStreamAfterRead());
+        assertFalse(endpoint.getConfiguration().isCloseStreamAfterWrite());
+    }
+
+    @Test
+    void testNoBlobNameProducerWithOpThatNeedsBlobName() throws Exception {
+        context.getRegistry().bind("creds", storageSharedKeyCredential());
+
+        BlobEndpoint endpointWithOp = (BlobEndpoint) context.getEndpoint(
+                "azure-storage-blob://camelazure/container?operation=deleteBlob&credentials=#creds");
+
+        Producer producer = endpointWithOp.createProducer();
+        DefaultExchange exchange = new DefaultExchange(context);
+
+        assertThrows(IllegalArgumentException.class, () -> producer.process(exchange));
+    }
+
+    @Test
+    void testHierarchicalBlobName() throws Exception {
+        context.getRegistry().bind("creds", storageSharedKeyCredential());
+
+        BlobEndpoint endpoint = (BlobEndpoint) context
+                .getEndpoint("azure-storage-blob://camelazure/container?blobName=blob/sub&credentials=#creds");
+        assertEquals("blob/sub", endpoint.getConfiguration().getBlobName());
+    }
+
+    private StorageSharedKeyCredential storageSharedKeyCredential() {
+        return new StorageSharedKeyCredential("fakeuser", "fakekey");
+    }
+
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxyTest.java b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxyTest.java
new file mode 100644
index 0000000..59a5a8c
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxyTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+class BlobConfigurationOptionsProxyTest extends CamelTestSupport {
+
+    @Test
+    void testIfCorrectOptionsReturnedCorrectly() {
+        final BlobConfiguration configuration = new BlobConfiguration();
+
+        // first case: when exchange is set
+        final Exchange exchange = new DefaultExchange(context);
+        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
+
+        exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "testBlobExchange");
+        configuration.setBlobName("testBlobConfig");
+
+        assertEquals("testBlobExchange", configurationOptionsProxy.getBlobName(exchange));
+
+        // second class: exchange is empty
+        exchange.getIn().setHeader(BlobConstants.BLOB_NAME, null);
+
+        assertEquals("testBlobConfig", configurationOptionsProxy.getBlobName(exchange));
+
+        // third class: if no option at all
+        configuration.setBlobName(null);
+
+        assertNull(configurationOptionsProxy.getBlobName(exchange));
+    }
+
+    @Test
+    void testIfCorrectOptionsReturnedCorrectlyWithPrefixAndRegexSet() {
+        final BlobConfiguration configuration = new BlobConfiguration();
+
+        final Exchange exchange = new DefaultExchange(context);
+        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
+
+        configuration.setPrefix("test");
+        configuration.setRegex(".*\\.exe");
+
+        assertNull(configurationOptionsProxy.getPrefix(exchange));
+        assertEquals(".*\\.exe", configurationOptionsProxy.getRegex(exchange));
+    }
+
+    @Test
+    void testIfCorrectOptionsReturnedCorrectlyWithPrefixAndRegexSetInHeader() {
+        final BlobConfiguration configuration = new BlobConfiguration();
+
+        // first case: when exchange is set
+        final Exchange exchange = new DefaultExchange(context);
+        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
+
+        configuration.setPrefix("test");
+        configuration.setRegex(".*\\.exe");
+        exchange.getIn().setHeader(BlobConstants.PREFIX, "test2");
+        exchange.getIn().setHeader(BlobConstants.REGEX, ".*\\.pdf");
+        assertNull(configurationOptionsProxy.getPrefix(exchange));
+        assertEquals(".*\\.pdf", configurationOptionsProxy.getRegex(exchange));
+    }
+
+    @Test
+    void testIfCorrectOptionsReturnedCorrectlyWithPrefixSet() {
+        final BlobConfiguration configuration = new BlobConfiguration();
+
+        // first case: when exchange is set
+        final Exchange exchange = new DefaultExchange(context);
+        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
+
+        configuration.setPrefix("test");
+        assertEquals("test", configurationOptionsProxy.getPrefix(exchange));
+
+        //test header override
+        exchange.getIn().setHeader(BlobConstants.PREFIX, "test2");
+        assertEquals("test2", configurationOptionsProxy.getPrefix(exchange));
+    }
+
+    @Test
+    void testIfCorrectOptionsReturnedCorrectlyWithRegexSet() {
+        final BlobConfiguration configuration = new BlobConfiguration();
+
+        // first case: when exchange is set
+        final Exchange exchange = new DefaultExchange(context);
+        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
+
+        configuration.setRegex(".*\\.exe");
+        assertEquals(".*\\.exe", configurationOptionsProxy.getRegex(exchange));
+
+        //test header override
+        exchange.getIn().setHeader(BlobConstants.REGEX, ".*\\.pdf");
+        assertEquals(".*\\.pdf", configurationOptionsProxy.getRegex(exchange));
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobTestUtils.java b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobTestUtils.java
new file mode 100644
index 0000000..2548bcd
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobTestUtils.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Objects;
+import java.util.Properties;
+
+public final class BlobTestUtils {
+
+    private BlobTestUtils() {
+    }
+
+    public static Properties getAzuriteProperties() {
+        final Properties properties = new Properties();
+        final String fileName = "azurite.properties";
+
+        final InputStream inputStream
+                = Objects.requireNonNull(BlobTestUtils.class.getClassLoader().getResourceAsStream(fileName));
+
+        try {
+            properties.load(inputStream);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Could not initialize Azurite properties", e);
+        }
+
+        return properties;
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BaseIT.java b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BaseIT.java
new file mode 100644
index 0000000..90591d0
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BaseIT.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.integration;
+
+import com.azure.storage.blob.BlobServiceClient;
+import com.azure.storage.common.StorageSharedKeyCredential;
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
+import org.apache.camel.test.infra.azure.common.AzureConfigs;
+import org.apache.camel.test.infra.azure.common.services.AzureService;
+import org.apache.camel.test.infra.azure.storage.blob.clients.AzureStorageBlobClientUtils;
+import org.apache.camel.test.infra.azure.storage.blob.services.AzureStorageBlobServiceFactory;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public class BaseIT extends CamelTestSupport {
+    @RegisterExtension
+    public static AzureService service;
+
+    protected BlobServiceClient serviceClient;
+    protected String containerName;
+    protected BlobConfiguration configuration;
+
+    static {
+        initCredentials();
+
+        service = AzureStorageBlobServiceFactory.createAzureService();
+    }
+
+    /*
+     * The previous behavior of the test code was such that if accessKey or accountName properties were
+     * set, the code would not start the azurite container and would execute against a remote environment.
+     * To avoid breaking tests for environments relying on this behavior, copy the old properties into the
+     *  new and set the test as remote.
+     */
+    private static void initCredentials() {
+        String accountName = System.getProperty("accountName");
+        String accessKey = System.getProperty("accessKey");
+
+        if (StringUtils.isNotEmpty(accountName) && StringUtils.isNotEmpty(accessKey)) {
+            System.setProperty(AzureConfigs.ACCOUNT_NAME, accountName);
+            System.setProperty(AzureConfigs.ACCOUNT_KEY, accessKey);
+            System.setProperty("azure.instance.type", "remote");
+        }
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+        context.getRegistry().bind("serviceClient", serviceClient);
+        return context;
+    }
+
+    @BeforeAll
+    public void initProperties() {
+        containerName = RandomStringUtils.randomAlphabetic(5).toLowerCase();
+
+        configuration = new BlobConfiguration();
+        configuration.setCredentials(new StorageSharedKeyCredential(
+                service.azureCredentials().accountName(), service.azureCredentials().accountKey()));
+        configuration.setContainerName(containerName);
+
+        serviceClient = AzureStorageBlobClientUtils.getClient();
+    }
+
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobConsumerITTest.java b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobConsumerITTest.java
new file mode 100644
index 0000000..4a18931
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobConsumerITTest.java
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.integration;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.nio.file.Path;
+import java.util.regex.Pattern;
+
+import com.azure.storage.blob.BlobContainerClient;
+import com.azure.storage.blob.specialized.BlobInputStream;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.azure.storage.blob.BlobConstants;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class BlobConsumerITTest extends BaseIT {
+
+    @TempDir
+    static Path testDir;
+    @EndpointInject("direct:start")
+    private ProducerTemplate templateStart;
+    private String batchContainerName;
+    private String blobName;
+    private String blobName2;
+
+    private BlobContainerClient containerClient;
+    private BlobContainerClient batchContainerClient;
+    private final String regex = ".*\\.pdf";
+
+    @BeforeAll
+    public void setup() {
+        batchContainerName = RandomStringUtils.randomAlphabetic(5).toLowerCase();
+        blobName = RandomStringUtils.randomAlphabetic(5);
+        blobName2 = RandomStringUtils.randomAlphabetic(5);
+
+        containerClient = serviceClient.getBlobContainerClient(containerName);
+        batchContainerClient = serviceClient.getBlobContainerClient(batchContainerName);
+
+        // create test container
+        containerClient.create();
+        batchContainerClient.create();
+    }
+
+    @Test
+    void testPollingToFile() throws Exception {
+        final MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+        mockEndpoint.expectedMessageCount(1);
+
+        templateStart.send("direct:createBlob", exchange -> {
+            exchange.getIn().setBody("Block Blob");
+            exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, containerName);
+            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
+        });
+
+        mockEndpoint.assertIsSatisfied();
+
+        final File file = mockEndpoint.getExchanges().get(0).getIn().getBody(File.class);
+        assertNotNull(file, "File must be set");
+        assertEquals("Block Blob", context().getTypeConverter().convertTo(String.class, file));
+    }
+
+    @Test
+    void testPollingToInputStream() throws Exception {
+        templateStart.send("direct:createBlob", exchange -> {
+            exchange.getIn().setBody("Block Blob");
+            exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, containerName);
+            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName2);
+        });
+
+        final MockEndpoint mockEndpoint = getMockEndpoint("mock:resultOutputStream");
+        mockEndpoint.expectedMessageCount(1);
+        mockEndpoint.assertIsSatisfied();
+
+        final BlobInputStream blobInputStream = mockEndpoint.getExchanges().get(0).getIn().getBody(BlobInputStream.class);
+        assertNotNull(blobInputStream, "BlobInputStream must be set");
+
+        final String bufferedText = new BufferedReader(new InputStreamReader(blobInputStream)).readLine();
+
+        assertEquals("Block Blob", bufferedText);
+    }
+
+    @Test
+    void testBatchFilePolling() throws Exception {
+        // test output stream based
+        final MockEndpoint mockEndpoint = getMockEndpoint("mock:resultBatch");
+        mockEndpoint.expectedMessageCount(2);
+
+        // test file based
+        final MockEndpoint mockEndpointFile = getMockEndpoint("mock:resultBatchFile");
+        mockEndpointFile.expectedMessageCount(2);
+
+        templateStart.send("direct:createBlob", exchange -> {
+            exchange.getIn().setBody("Block Batch Blob 1");
+            exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
+            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "test_batch_blob_1");
+        });
+
+        templateStart.send("direct:createBlob", exchange -> {
+            exchange.getIn().setBody("Block Batch Blob 2");
+            exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
+            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "test_batch_blob_2");
+        });
+
+        MockEndpoint.assertIsSatisfied(context());
+
+        final BlobInputStream blobInputStream = mockEndpoint.getExchanges().get(0).getIn().getBody(BlobInputStream.class);
+        final BlobInputStream blobInputStream2 = mockEndpoint.getExchanges().get(1).getIn().getBody(BlobInputStream.class);
+
+        assertNotNull(blobInputStream, "BlobInputStream must be set");
+        assertNotNull(blobInputStream2, "BlobInputStream must be set");
+
+        final String bufferedText = context().getTypeConverter().convertTo(String.class, blobInputStream);
+        final String bufferedText2 = context().getTypeConverter().convertTo(String.class, blobInputStream2);
+
+        assertEquals("Block Batch Blob 1", bufferedText);
+        assertEquals("Block Batch Blob 2", bufferedText2);
+
+        final File file = mockEndpointFile.getExchanges().get(0).getIn().getBody(File.class);
+        final File file2 = mockEndpointFile.getExchanges().get(1).getIn().getBody(File.class);
+
+        assertNotNull(file, "File must be set");
+        assertNotNull(file2, "File must be set");
+
+        assertEquals("Block Batch Blob 1", context().getTypeConverter().convertTo(String.class, file));
+        assertEquals("Block Batch Blob 2", context().getTypeConverter().convertTo(String.class, file2));
+    }
+
+    @Test
+    void testRegexPolling() throws Exception {
+        // test regex based
+        final MockEndpoint mockEndpoint = getMockEndpoint("mock:resultRegex");
+        mockEndpoint.expectedMessageCount(15);
+
+        // create pdf blobs
+        for (int i = 0; i < 10; i++) {
+            final int index = i;
+            templateStart.send("direct:createBlob", exchange -> {
+                exchange.getIn().setBody("Block Batch PDF Blob with RegEx Test: " + index);
+                exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
+                exchange.getIn().setHeader(BlobConstants.BLOB_NAME, generateRandomBlobName("regexp-test_batch_blob_", "pdf"));
+            });
+        }
+
+        for (int i = 0; i < 5; i++) {
+            final int index = i;
+            templateStart.send("direct:createBlob", exchange -> {
+                exchange.getIn().setBody("Block Batch PDF Blob with Prefix Test: " + index);
+                exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
+                exchange.getIn().setHeader(BlobConstants.BLOB_NAME, generateRandomBlobName("aaaa-test_batch_blob_", "pdf"));
+            });
+        }
+
+        // create docx blobs
+        for (int i = 0; i < 20; i++) {
+            final int index = i;
+            templateStart.send("direct:createBlob", exchange -> {
+                exchange.getIn().setBody("Block Batch DOCX Blob Test: " + index);
+                exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
+                exchange.getIn().setHeader(BlobConstants.BLOB_NAME, generateRandomBlobName("regexp-test_batch_blob_", "docx"));
+            });
+        }
+
+        mockEndpoint.assertIsSatisfied();
+
+        Pattern pattern = Pattern.compile(regex);
+        for (Exchange e : mockEndpoint.getExchanges()) {
+            String blobName = e.getIn().getHeader(BlobConstants.BLOB_NAME, String.class);
+            assertTrue(pattern.matcher(blobName).matches());
+        }
+    }
+
+    private String generateRandomBlobName(String prefix, String extension) {
+        return prefix + randomAlphabetic(5).toLowerCase() + "." + extension;
+    }
+
+    @AfterAll
+    public void tearDown() {
+        // delete container
+        containerClient.delete();
+        batchContainerClient.delete();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:createBlob")
+                        .to("azure-storage-blob://cameldev?blobServiceClient=#serviceClient&operation=uploadBlockBlob");
+
+                from("azure-storage-blob://cameldev/" + containerName + "?blobName=" + blobName
+                     + "&blobServiceClient=#serviceClient&fileDir="
+                     + testDir.toString()).to("mock:result");
+
+                from("azure-storage-blob://cameldev/" + containerName + "?blobName=" + blobName2
+                     + "&blobServiceClient=#serviceClient")
+                             .to("mock:resultOutputStream");
+
+                from("azure-storage-blob://cameldev/" + batchContainerName + "?blobServiceClient=#serviceClient")
+                        .to("mock:resultBatch");
+
+                from("azure-storage-blob://cameldev/" + batchContainerName + "?blobServiceClient=#serviceClient&fileDir="
+                     + testDir.toString()).to("mock:resultBatchFile");
+
+                // if regex is set then prefix should have no effect
+                from("azure-storage-blob://cameldev/" + batchContainerName
+                     + "?blobServiceClient=#serviceClient&prefix=aaaa&regex=" + regex)
+                             .idempotentConsumer(body(), new MemoryIdempotentRepository())
+                             .to("mock:resultRegex");
+            }
+        };
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobContainerOperationsITTest.java b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobContainerOperationsITTest.java
new file mode 100644
index 0000000..2e45bde
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobContainerOperationsITTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.integration;
+
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+import com.azure.storage.blob.models.BlobStorageException;
+import com.azure.storage.blob.models.PublicAccessType;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.azure.storage.blob.BlobConstants;
+import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
+import org.apache.camel.component.azure.storage.blob.client.BlobServiceClientWrapper;
+import org.apache.camel.component.azure.storage.blob.operations.BlobContainerOperations;
+import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
+import org.apache.camel.support.DefaultExchange;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class BlobContainerOperationsITTest extends BaseIT {
+
+    private BlobServiceClientWrapper blobServiceClientWrapper;
+
+    @BeforeAll
+    public void setup() {
+        blobServiceClientWrapper = new BlobServiceClientWrapper(serviceClient);
+    }
+
+    @Test
+    void testCreateAndDeleteContainer() {
+        final BlobContainerClientWrapper containerClientWrapper
+                = blobServiceClientWrapper.getBlobContainerClientWrapper("testcontainer1");
+        final BlobContainerOperations blobContainerOperations
+                = new BlobContainerOperations(configuration, containerClientWrapper);
+
+        final BlobOperationResponse response = blobContainerOperations.createContainer(null);
+
+        assertNotNull(response);
+        assertNotNull(response.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS));
+        assertTrue((boolean) response.getBody());
+
+        // delete everything
+        blobContainerOperations.deleteContainer(null);
+
+        // test with options being set
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setHeader(BlobConstants.METADATA, Collections.singletonMap("testKeyMetadata", "testValueMetadata"));
+        exchange.getIn().setHeader(BlobConstants.PUBLIC_ACCESS_TYPE, PublicAccessType.CONTAINER);
+
+        // try to create the container again, we try until we can
+        Awaitility.given()
+                .ignoreException(BlobStorageException.class)
+                .with()
+                .pollInterval(100, TimeUnit.MILLISECONDS)
+                .await()
+                .atMost(60, TimeUnit.SECONDS)
+                .until(() -> {
+                    final BlobOperationResponse response1 = blobContainerOperations.createContainer(exchange);
+                    assertNotNull(response1);
+                    assertNotNull(response1.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS));
+
+                    return (boolean) response1.getBody();
+                });
+    }
+
+    @AfterAll
+    public void cleanUp() {
+        blobServiceClientWrapper.getBlobContainerClientWrapper("testcontainer1").deleteContainer(null, null);
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobOperationsITTest.java b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobOperationsITTest.java
new file mode 100644
index 0000000..fbf60be
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobOperationsITTest.java
@@ -0,0 +1,422 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.integration;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.security.SecureRandom;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+
+import com.azure.storage.blob.models.PageList;
+import com.azure.storage.blob.models.PageRange;
+import com.azure.storage.blob.specialized.BlobInputStream;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.azure.storage.blob.BlobBlock;
+import org.apache.camel.component.azure.storage.blob.BlobConstants;
+import org.apache.camel.component.azure.storage.blob.BlobUtils;
+import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
+import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
+import org.apache.camel.component.azure.storage.blob.client.BlobServiceClientWrapper;
+import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
+import org.apache.camel.component.azure.storage.blob.operations.BlobOperations;
+import org.apache.camel.converter.stream.FileInputStreamCache;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class BlobOperationsITTest extends BaseIT {
+
+    private BlobContainerClientWrapper blobContainerClientWrapper;
+
+    private String randomBlobName;
+
+    @BeforeAll
+    public void setup() throws Exception {
+        randomBlobName = RandomStringUtils.randomAlphabetic(10);
+
+        blobContainerClientWrapper = new BlobServiceClientWrapper(serviceClient)
+                .getBlobContainerClientWrapper(configuration.getContainerName());
+
+        // create test container
+        blobContainerClientWrapper.createContainer(null, null, null);
+
+        // create test blob
+        final InputStream inputStream = new ByteArrayInputStream("awesome camel!".getBytes());
+        blobContainerClientWrapper.getBlobClientWrapper(randomBlobName).uploadBlockBlob(inputStream,
+                BlobUtils.getInputStreamLength(inputStream), null, null, null, null,
+                null, null);
+    }
+
+    @AfterAll
+    public void tearDown() {
+        blobContainerClientWrapper.deleteContainer(null, null);
+    }
+
+    @Test
+    void testGetBlob(@TempDir Path testDir) throws IOException {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper(randomBlobName);
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        // first: test with exchange set but no outputstream set
+        final Exchange exchange = new DefaultExchange(context);
+        final BlobOperationResponse response1 = operations.getBlob(exchange);
+
+        assertNotNull(response1);
+        assertNotNull(response1.getBody());
+        assertNotNull(response1.getHeaders());
+
+        final BlobInputStream inputStream = (BlobInputStream) response1.getBody();
+        final String bufferedText = new BufferedReader(new InputStreamReader(inputStream)).readLine();
+
+        assertEquals("awesome camel!", bufferedText);
+
+        // second: test with outputstream set on exchange
+        final File fileToWrite = new File(testDir.toFile(), "write_test_file.txt");
+        exchange.getIn().setBody(new FileOutputStream(fileToWrite));
+
+        final BlobOperationResponse response2 = operations.getBlob(exchange);
+        final String fileContent = FileUtils.readFileToString(fileToWrite, Charset.defaultCharset());
+
+        assertNotNull(response2);
+        assertNotNull(response2.getBody());
+        assertNotNull(response2.getHeaders());
+        assertTrue(fileContent.contains("awesome camel!"));
+    }
+
+    @Test
+    void testDownloadToFile(@TempDir Path testDir) throws IOException {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper(randomBlobName);
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setHeader(BlobConstants.FILE_DIR, testDir.toString());
+        exchange.getIn().setHeader(BlobConstants.BLOB_NAME, randomBlobName);
+
+        final BlobOperationResponse response = operations.downloadBlobToFile(exchange);
+
+        // third: test with outputstream set on exchange
+        final File fileToWrite = testDir.resolve(randomBlobName).toFile();
+        final String fileContent = FileUtils.readFileToString(fileToWrite, Charset.defaultCharset());
+
+        assertNotNull(response);
+        assertNotNull(response.getBody());
+        assertNotNull(response.getHeaders());
+        assertNotNull(response.getHeaders().get(BlobConstants.FILE_NAME));
+        assertTrue(fileContent.contains("awesome camel!"));
+    }
+
+    @Test
+    void testDownloadLink() {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper(randomBlobName);
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        final BlobOperationResponse response = operations.downloadLink(null);
+
+        assertNotNull(response);
+        assertTrue((boolean) response.getBody());
+        assertNotNull(response.getHeaders().get(BlobConstants.DOWNLOAD_LINK));
+    }
+
+    @Test
+    void testUploadBlockBlob() throws Exception {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        // first: test as file provided
+        final File fileToUpload
+                = new File(Objects.requireNonNull(getClass().getClassLoader().getResource("upload_test_file")).getFile());
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(fileToUpload);
+
+        final BlobOperationResponse response = operations.uploadBlockBlob(exchange);
+
+        assertNotNull(response);
+        assertTrue((boolean) response.getBody());
+        // check for eTag and md5 to make sure is uploaded
+        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
+        assertNotNull(response.getHeaders().get(BlobConstants.CONTENT_MD5));
+
+        // check content
+        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
+
+        assertEquals("awesome camel to upload!",
+                IOUtils.toString((InputStream) getBlobResponse.getBody(), Charset.defaultCharset()));
+
+        blobClientWrapper.delete(null, null, null);
+
+        // second: test as string provided
+        final String data = "Hello world from my awesome tests!";
+        final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+        exchange.getIn().setBody(dataStream);
+
+        final BlobOperationResponse response2 = operations.uploadBlockBlob(exchange);
+
+        assertNotNull(response2);
+        assertTrue((boolean) response2.getBody());
+        // check for eTag and md5 to make sure is uploaded
+        assertNotNull(response2.getHeaders().get(BlobConstants.E_TAG));
+        assertNotNull(response2.getHeaders().get(BlobConstants.CONTENT_MD5));
+
+        // check content
+        final BlobOperationResponse getBlobResponse2 = operations.getBlob(null);
+
+        assertEquals(data, IOUtils.toString((InputStream) getBlobResponse2.getBody(), Charset.defaultCharset()));
+
+        blobClientWrapper.delete(null, null, null);
+    }
+
+    @Test
+    void testUploadBlockBlobAsCachedStream() throws Exception {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        final File fileToUpload
+                = new File(Objects.requireNonNull(getClass().getClassLoader().getResource("upload_test_file")).getFile());
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(new FileInputStreamCache(fileToUpload));
+
+        final BlobOperationResponse response = operations.uploadBlockBlob(exchange);
+
+        assertNotNull(response);
+        assertTrue((boolean) response.getBody());
+        // check for eTag and md5 to make sure is uploaded
+        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
+        assertNotNull(response.getHeaders().get(BlobConstants.CONTENT_MD5));
+
+        // check content
+        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
+
+        assertEquals("awesome camel to upload!",
+                IOUtils.toString((InputStream) getBlobResponse.getBody(), Charset.defaultCharset()));
+
+        blobClientWrapper.delete(null, null, null);
+    }
+
+    @Test
+    void testCommitAndStageBlockBlob() throws Exception {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        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())));
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(blocks);
+        exchange.getIn().setHeader(BlobConstants.COMMIT_BLOCK_LIST_LATER, false);
+
+        final BlobOperationResponse response = operations.stageBlockBlobList(exchange);
+
+        assertNotNull(response);
+        assertNotNull(response.getBody());
+        // check for eTag and md5 to make sure is uploaded
+        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
+
+        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
+
+        assertEquals("HelloFromCamel", IOUtils.toString((InputStream) getBlobResponse.getBody(), Charset.defaultCharset()));
+
+        blobClientWrapper.delete(null, null, null);
+    }
+
+    @Test
+    void testGetBlobBlockList() {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper(randomBlobName);
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        final BlobOperationResponse response = operations.getBlobBlockList(null);
+
+        assertNotNull(response);
+        assertNotNull(response.getBody());
+        assertNotNull(response.getHeaders());
+    }
+
+    @Test
+    void testCreateAndUpdateAppendBlob() throws IOException {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        final String data = "Hello world from my awesome tests!";
+        final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(dataStream);
+        exchange.getIn().setHeader(BlobConstants.CREATE_APPEND_BLOB, true);
+
+        final BlobOperationResponse response = operations.commitAppendBlob(exchange);
+
+        assertNotNull(response);
+        assertTrue((boolean) response.getBody());
+        // check for eTag and md5 to make sure is uploaded
+        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
+        assertNotNull(response.getHeaders().get(BlobConstants.COMMITTED_BLOCK_COUNT));
+
+        // check content
+        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
+
+        assertEquals(data, IOUtils.toString((InputStream) getBlobResponse.getBody(), Charset.defaultCharset()));
+
+        blobClientWrapper.delete(null, null, null);
+    }
+
+    @Test
+    void testCreateAndUploadPageBlob() throws IOException {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
+        new SecureRandom().nextBytes(dataBytes);
+        final String data = new String(dataBytes, StandardCharsets.UTF_8);
+        final InputStream dataStream = new ByteArrayInputStream(dataBytes);
+
+        final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(dataStream);
+        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
+        exchange.getIn().setHeader(BlobConstants.CREATE_PAGE_BLOB, true);
+
+        final BlobOperationResponse response = operations.uploadPageBlob(exchange);
+
+        assertNotNull(response);
+        assertTrue((boolean) response.getBody());
+        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
+
+        // check content
+        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
+        final String dataResponse = IOUtils.toString((InputStream) getBlobResponse.getBody(), StandardCharsets.UTF_8);
+
+        assertEquals(data, dataResponse);
+
+        blobClientWrapper.delete(null, null, null);
+    }
+
+    @Test
+    void testResizePageBlob() throws IOException {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        byte[] dataBytes = new byte[1024]; // we set range for the page from 0-511
+        new SecureRandom().nextBytes(dataBytes);
+        final String data = new String(dataBytes, StandardCharsets.UTF_8);
+        final InputStream dataStream = new ByteArrayInputStream(dataBytes);
+
+        final PageRange pageRange = new PageRange().setStart(0).setEnd(1023);
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(dataStream);
+        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
+        exchange.getIn().setHeader(BlobConstants.CREATE_PAGE_BLOB, true);
+
+        // create our page
+        operations.uploadPageBlob(exchange);
+
+        // create the new size
+        exchange.getIn().removeHeader(BlobConstants.PAGE_BLOB_RANGE);
+        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_SIZE, 512L);
+
+        final BlobOperationResponse response = operations.resizePageBlob(exchange);
+
+        assertNotNull(response);
+        assertTrue((boolean) response.getBody());
+
+        // check for content
+        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
+        final BlobInputStream inputStream = (BlobInputStream) getBlobResponse.getBody();
+        assertEquals(512, IOUtils.toByteArray(inputStream).length);
+
+        blobClientWrapper.delete(null, null, null);
+    }
+
+    @Test
+    void testClearPages() throws IOException {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
+        new SecureRandom().nextBytes(dataBytes);
+        final String data = new String(dataBytes, StandardCharsets.UTF_8);
+        final InputStream dataStream = new ByteArrayInputStream(dataBytes);
+
+        final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(dataStream);
+        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
+        exchange.getIn().setHeader(BlobConstants.CREATE_PAGE_BLOB, true);
+
+        // create our page
+        operations.uploadPageBlob(exchange);
+
+        final BlobOperationResponse response = operations.clearPageBlob(exchange);
+
+        // check content
+        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
+
+        assertTrue(IOUtils.toString((InputStream) getBlobResponse.getBody(), StandardCharsets.UTF_8).trim().isEmpty());
+
+        blobClientWrapper.delete(null, null, null);
+    }
+
+    @Test
+    void testGetPageBlobRanges() throws IOException {
+        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
+        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
+
+        byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
+        new SecureRandom().nextBytes(dataBytes);
+        final String data = new String(dataBytes, StandardCharsets.UTF_8);
+        final InputStream dataStream = new ByteArrayInputStream(dataBytes);
+
+        final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(dataStream);
+        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
+        exchange.getIn().setHeader(BlobConstants.CREATE_PAGE_BLOB, true);
+
+        // create our page
+        operations.uploadPageBlob(exchange);
+
+        final BlobOperationResponse response = operations.getPageBlobRanges(exchange);
+
+        assertNotNull(response);
+
+        final PageList pageList = (PageList) response.getBody();
+
+        assertEquals(pageRange.getStart(), pageList.getPageRange().get(0).getStart());
+        assertEquals(pageRange.getEnd(), pageList.getPageRange().get(0).getEnd());
+
+        blobClientWrapper.delete(null, null, null);
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobProducerITTest.java b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobProducerITTest.java
new file mode 100644
index 0000000..f4ad930
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobProducerITTest.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.integration;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.azure.storage.blob.BlobContainerClient;
+import com.azure.storage.blob.models.PageRange;
+import org.apache.camel.EndpointInject;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.azure.storage.blob.BlobBlock;
+import org.apache.camel.component.azure.storage.blob.BlobConstants;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class BlobProducerITTest extends BaseIT {
+
+    @EndpointInject
+    private ProducerTemplate template;
+
+    @EndpointInject("mock:result")
+    private MockEndpoint result;
+    private String resultName = "mock:result";
+    private BlobContainerClient containerClient;
+
+    @BeforeAll
+    public void prepare() {
+        // create test container
+        containerClient = serviceClient.getBlobContainerClient(containerName);
+        containerClient.create();
+    }
+
+    @Test
+    void testUploadBlockBlob() throws InterruptedException {
+        final String blobName = RandomStringUtils.randomAlphabetic(10);
+
+        result.expectedMessageCount(1);
+
+        template.send("direct:uploadBlockBlob", exchange -> {
+            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
+            exchange.getIn().setBody("Block Blob");
+        });
+
+        result.assertIsSatisfied();
+    }
+
+    @Test
+    void testCommitAndStageBlockBlob() throws InterruptedException, IOException {
+        final String blobName = RandomStringUtils.randomAlphabetic(10);
+
+        result.expectedMessageCount(1);
+
+        result.expectedBodiesReceived(true);
+
+        template.send("direct:stageBlockBlobList", exchange -> {
+            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
+            exchange.getIn().setHeader(BlobConstants.COMMIT_BLOCK_LIST_LATER, false);
+
+            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);
+        });
+
+        result.assertIsSatisfied();
+
+        assertNotNull(result.getExchanges().get(0).getMessage().getHeader(BlobConstants.E_TAG));
+    }
+
+    @Test
+    void testCommitAppendBlobWithError() throws InterruptedException {
+        final String blobName = RandomStringUtils.randomAlphabetic(10);
+
+        template.send("direct:commitAppendBlobWithError", exchange -> {
+            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
+            exchange.getIn().setHeader(BlobConstants.CREATE_APPEND_BLOB, false);
+
+            final String data = "Hello world from my awesome tests!";
+            final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+
+            exchange.getIn().setBody(dataStream);
+        });
+
+        result.assertIsSatisfied();
+
+        // append blob not created because of the flag
+        assertTrue(result.getExchanges().isEmpty());
+    }
+
+    @Test
+    void testCreateAndUpdateAppendBlob() throws InterruptedException {
+        final String blobName = RandomStringUtils.randomAlphabetic(10);
+
+        result.expectedMessageCount(1);
+
+        result.expectedBodiesReceived(true);
+
+        template.send("direct:commitAppendBlob", exchange -> {
+            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
+
+            final String data = "Hello world from my awesome tests!";
+            final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
+
+            exchange.getIn().setBody(dataStream);
+        });
+
+        result.assertIsSatisfied();
+
+        assertNotNull(result.getExchanges().get(0).getMessage().getHeader(BlobConstants.E_TAG));
+        assertNotNull(result.getExchanges().get(0).getMessage().getHeader(BlobConstants.COMMITTED_BLOCK_COUNT));
+    }
+
+    @Test
+    void testCreateAndUploadPageBlob() throws InterruptedException {
+        final String blobName = RandomStringUtils.randomAlphabetic(10);
+
+        result.expectedMessageCount(1);
+
+        result.expectedBodiesReceived(true);
+
+        template.send("direct:uploadPageBlob", exchange -> {
+            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
+
+            byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
+            new SecureRandom().nextBytes(dataBytes);
+            final InputStream dataStream = new ByteArrayInputStream(dataBytes);
+            final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
+
+            exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
+            exchange.getIn().setBody(dataStream);
+        });
+
+        result.assertIsSatisfied();
+
+        assertNotNull(result.getExchanges().get(0).getMessage().getHeader(BlobConstants.E_TAG));
+    }
+
+    @Test
+    void testUploadBlockBlobWithConfigUri() throws InterruptedException {
+        result.expectedMessageCount(1);
+
+        template.send("direct:uploadBlockBlobWithConfigUri",
+                exchange -> exchange.getIn().setBody("Block Blob"));
+
+        result.assertIsSatisfied();
+    }
+
+    @AfterAll
+    public void tearDown() {
+        containerClient.delete();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:uploadBlockBlob")
+                        .to(componentUri("uploadBlockBlob"))
+                        .to(resultName);
+
+                from("direct:stageBlockBlobList")
+                        .to(componentUri("stageBlockBlobList"))
+                        .to(resultName);
+
+                from("direct:commitAppendBlob")
+                        .to(componentUri("commitAppendBlob"))
+                        .to(resultName);
+
+                from("direct:commitAppendBlobWithError")
+                        .to(componentUri("commitAppendBlob"))
+                        .to(resultName);
+
+                from("direct:uploadPageBlob")
+                        .to(componentUri("uploadPageBlob"))
+                        .to(resultName);
+
+                from("direct:uploadBlockBlobWithConfigUri")
+                        .to(componentUri("uploadBlockBlob") + "&blobName=uploadBlockName")
+                        .to(resultName);
+            }
+        };
+    }
+
+    private String componentUri(final String operation) {
+        return String.format("azure-storage-blob://cameldev/%s?blobServiceClient=#serviceClient&operation=%s", containerName,
+                operation);
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperationsTest.java b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperationsTest.java
new file mode 100644
index 0000000..d1761e4
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperationsTest.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.operations;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.azure.core.http.HttpHeaders;
+import com.azure.storage.blob.models.BlobItem;
+import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
+import org.apache.camel.component.azure.storage.blob.BlobConstants;
+import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.extension.ExtendWith;
+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.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@ExtendWith(MockitoExtension.class)
+class BlobContainerOperationsTest {
+
+    private BlobConfiguration configuration;
+
+    @Mock
+    private BlobContainerClientWrapper client;
+
+    @BeforeEach
+    public void setup() {
+        configuration = new BlobConfiguration();
+        configuration.setAccountName("cameldev");
+        configuration.setContainerName("awesome2");
+    }
+
+    @Test
+    void testCreateContainer() {
+        when(client.createContainer(any(), any(), any())).thenReturn(createContainerMock());
+
+        final BlobContainerOperations blobContainerOperations = new BlobContainerOperations(configuration, client);
+        final BlobOperationResponse response = blobContainerOperations.createContainer(null);
+
+        assertNotNull(response);
+        assertNotNull(response.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS));
+        assertTrue((boolean) response.getBody());
+    }
+
+    @Test
+    void testDeleteContainer() {
+        when(client.deleteContainer(any(), any())).thenReturn(deleteContainerMock());
+
+        final BlobContainerOperations blobContainerOperations = new BlobContainerOperations(configuration, client);
+        final BlobOperationResponse response = blobContainerOperations.deleteContainer(null);
+
+        assertNotNull(response);
+        assertNotNull(response.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS));
+        assertTrue((boolean) response.getBody());
+    }
+
+    @Test
+    void testListBlob() {
+        when(client.listBlobs(any(), any())).thenReturn(listBlobsMock());
+
+        final BlobContainerOperations blobContainerOperations = new BlobContainerOperations(configuration, client);
+        final BlobOperationResponse response = blobContainerOperations.listBlobs(null);
+
+        assertNotNull(response);
+
+        @SuppressWarnings("unchecked")
+        final List<BlobItem> body = (List<BlobItem>) response.getBody();
+        final List<String> items = body.stream().map(BlobItem::getName).collect(Collectors.toList());
+
+        assertTrue(items.contains("item-1"));
+        assertTrue(items.contains("item-2"));
+    }
+
+    @Test
+    void testListBlobWithRegex() {
+
+        BlobConfiguration myConfiguration = new BlobConfiguration();
+        myConfiguration.setAccountName("cameldev");
+        myConfiguration.setContainerName("awesome2");
+        myConfiguration.setRegex(".*\\.pdf");
+
+        when(client.listBlobs(any(), any())).thenReturn(listBlobsMockWithRegex());
+
+        final BlobContainerOperations blobContainerOperations = new BlobContainerOperations(myConfiguration, client);
+        final BlobOperationResponse response = blobContainerOperations.listBlobs(null);
+
+        assertNotNull(response);
+
+        @SuppressWarnings("unchecked")
+        final List<BlobItem> body = (List<BlobItem>) response.getBody();
+        final List<String> items = body.stream().map(BlobItem::getName).collect(Collectors.toList());
+        assertEquals(3, items.size());
+        assertTrue(items.contains("invoice1.pdf"));
+        assertTrue(items.contains("invoice2.pdf"));
+        assertTrue(items.contains("invoice5.pdf"));
+    }
+
+    private HttpHeaders createContainerMock() {
+        final HttpHeaders httpHeaders = new HttpHeaders();
+
+        httpHeaders.put("x-ms-request-id", "12345");
+        httpHeaders.put("Server", "Azure-Server");
+
+        return httpHeaders;
+    }
+
+    private HttpHeaders deleteContainerMock() {
+        final HttpHeaders httpHeaders = new HttpHeaders();
+
+        httpHeaders.put("x-ms-request-id", "12345");
+        httpHeaders.put("Server", "Azure-Server");
+        httpHeaders.put("x-ms-delete-type-permanent", "true");
+
+        return httpHeaders;
+    }
+
+    private List<BlobItem> listBlobsMock() {
+        final List<BlobItem> items = new LinkedList<>();
+
+        final BlobItem blobItem1 = new BlobItem().setName("item-1").setVersionId("1").setDeleted(false);
+        final BlobItem blobItem2 = new BlobItem().setName("item-2").setVersionId("2").setDeleted(true);
+
+        items.add(blobItem1);
+        items.add(blobItem2);
+
+        return items;
+    }
+
+    private List<BlobItem> listBlobsMockWithRegex() {
+        final List<BlobItem> items = listBlobsMock();
+
+        final BlobItem blobItemPdf1 = new BlobItem().setName("invoice1.pdf").setVersionId("1").setDeleted(false);
+        final BlobItem blobItemPdf2 = new BlobItem().setName("invoice2.pdf").setVersionId("2").setDeleted(true);
+        final BlobItem blobItemPdf3 = new BlobItem().setName("invoice5.pdf").setVersionId("2").setDeleted(true);
+
+        final BlobItem blobItemExe1 = new BlobItem().setName("office.exe").setVersionId("1").setDeleted(false);
+        final BlobItem blobItemExe2 = new BlobItem().setName("autorun.exe").setVersionId("2").setDeleted(false);
+        final BlobItem blobItemExe3 = new BlobItem().setName("start.exe").setVersionId("2").setDeleted(true);
+
+        items.add(blobItemPdf1);
+        items.add(blobItemPdf2);
+        items.add(blobItemPdf3);
+
+        items.add(blobItemExe1);
+        items.add(blobItemExe2);
+        items.add(blobItemExe3);
+
+        return items;
+    }
+
+}
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
new file mode 100644
index 0000000..8a57b0b
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationsTest.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.azure.storage.blob.operations;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.time.OffsetDateTime;
+import java.util.HashMap;
+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.BlobProperties;
+import com.azure.storage.blob.models.BlockBlobItem;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.azure.storage.blob.BlobBlock;
+import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
+import org.apache.camel.component.azure.storage.blob.BlobConstants;
+import org.apache.camel.component.azure.storage.blob.BlobType;
+import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.extension.ExtendWith;
+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.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@ExtendWith(MockitoExtension.class)
+class BlobOperationsTest extends CamelTestSupport {
+
+    private BlobConfiguration configuration;
+
+    @Mock
+    private BlobClientWrapper client;
+
+    @BeforeEach
+    public void setup() {
+        configuration = new BlobConfiguration();
+        configuration.setAccountName("cameldev");
+        configuration.setContainerName("awesome2");
+    }
+
+    @Test
+    void testGetBlob() throws IOException {
+        // mocking
+        final Map<String, Object> mockedResults = new HashMap<>();
+        mockedResults.put("inputStream", new ByteArrayInputStream("testInput".getBytes(Charset.defaultCharset())));
+        mockedResults.put("properties", createBlobProperties());
+
+        when(client.openInputStream(any(), any())).thenReturn(mockedResults);
+
+        final Exchange exchange = new DefaultExchange(context);
+
+        // first: test with no exchange provided
+        final BlobOperations operations = new BlobOperations(configuration, client);
+
+        final BlobOperationResponse response = operations.getBlob(null);
+
+        assertNotNull(response);
+        assertNotNull(response.getBody());
+        assertNotNull(response.getHeaders());
+        assertNotNull(response.getHeaders().get(BlobConstants.CREATION_TIME));
+        assertEquals("testInput", new BufferedReader(new InputStreamReader((InputStream) response.getBody())).readLine());
+
+        // second: test with exchange provided
+        configuration.setBlobType(BlobType.blockblob);
+        final BlobOperationResponse response2 = operations.getBlob(exchange);
+
+        assertNotNull(response2);
+        assertNotNull(response2.getBody());
+        assertNotNull(response2.getHeaders());
+        assertNotNull(response2.getHeaders().get(BlobConstants.CREATION_TIME));
+
+        // third: test with exchange provided but with outputstream set
+        // mocking
+        final ResponseBase<BlobDownloadHeaders, Void> mockedResults2 = new ResponseBase<>(
+                null, 200, new HttpHeaders().put("x-test-header", "123"), null, new BlobDownloadHeaders().setETag("tag1"));
+        when(client.downloadWithResponse(any(), any(), any(), any(), anyBoolean(), any())).thenReturn(mockedResults2);
+        exchange.getIn().setBody(new ByteArrayOutputStream());
+
+        final BlobOperationResponse response3 = operations.getBlob(exchange);
+
+        assertNotNull(response3);
+        assertNotNull(response3.getBody());
+        assertNotNull(response3.getHeaders());
+        assertEquals("tag1", response3.getHeaders().get(BlobConstants.E_TAG));
+    }
+
+    @Test
+    void testUploadBlockBlob() throws Exception {
+        // mocking
+        final BlockBlobItem blockBlobItem = new BlockBlobItem("testTag", OffsetDateTime.now(), null, false, null);
+        final HttpHeaders httpHeaders = new HttpHeaders().put("x-test-header", "123");
+
+        when(client.uploadBlockBlob(any(), anyLong(), any(), any(), any(), any(), any(), any()))
+                .thenReturn(new ResponseBase<>(null, 200, httpHeaders, blockBlobItem, null));
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody(new ByteArrayInputStream("test".getBytes(Charset.defaultCharset())));
+
+        // test upload with input stream
+        final BlobOperations operations = new BlobOperations(configuration, client);
+
+        final BlobOperationResponse operationResponse = operations.uploadBlockBlob(exchange);
+
+        assertNotNull(operationResponse);
+        assertTrue((boolean) operationResponse.getBody());
+        assertNotNull(operationResponse.getHeaders());
+        assertEquals("testTag", operationResponse.getHeaders().get(BlobConstants.E_TAG));
+        assertEquals("123", ((HttpHeaders) operationResponse.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS))
+                .get("x-test-header").getValue());
+    }
+
+    @Test
+    void testStageBlockBlobList() throws Exception {
+        final HttpHeaders httpHeaders = new HttpHeaders().put("x-test-header", "123");
+        when(client.stageBlockBlob(anyString(), any(), anyLong(), any(), any(), any())).thenReturn(httpHeaders);
+
+        final Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody("test");
+        exchange.getIn().setHeader(BlobConstants.COMMIT_BLOCK_LIST_LATER, true);
+
+        // test
+        final BlobOperations operations = new BlobOperations(configuration, client);
+
+        // in case of invalid payload
+        assertThrows(IllegalArgumentException.class, () -> operations.stageBlockBlobList(exchange));
+
+        // in case of correct payload
+        exchange.getIn().setBody(BlobBlock.createBlobBlock("1", new ByteArrayInputStream("test".getBytes())));
+
+        // test again
+        final BlobOperationResponse response = operations.stageBlockBlobList(exchange);
+
+        assertNotNull(response);
+        assertTrue((boolean) response.getBody());
+    }
+
+    private BlobProperties createBlobProperties() {
+        return new BlobProperties(
+                OffsetDateTime.now(), null, null, 0L, null, null, null, null, null,
+                null, null, null, null, null, null, null, null, null, null,
+                null, null, null, null, null, null, null, null,
+                null, null, null, null);
+    }
+}
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/resources/azurite.properties b/components/camel-azure/camel-azure-storage-blob/src/test/resources/azurite.properties
new file mode 100644
index 0000000..f058f35
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/resources/azurite.properties
@@ -0,0 +1,20 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+# Default Azurite properties
+# See https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azurite#well-known-storage-account-and-key
+accountName=devstoreaccount1
+accessKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==
\ No newline at end of file
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/resources/log4j2.properties b/components/camel-azure/camel-azure-storage-blob/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..ae1c0f8f
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/resources/log4j2.properties
@@ -0,0 +1,27 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License.  You may obtain a copy of the License at
+##
+##      http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-azure-storage-blob-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.out.type = Console
+appender.out.name = out
+appender.out.layout.type = PatternLayout
+appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
\ No newline at end of file
diff --git a/components/camel-azure/camel-azure-storage-blob/src/test/resources/upload_test_file b/components/camel-azure/camel-azure-storage-blob/src/test/resources/upload_test_file
new file mode 100644
index 0000000..582b34d
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-blob/src/test/resources/upload_test_file
@@ -0,0 +1 @@
+awesome camel to upload!
\ No newline at end of file
diff --git a/components/camel-azure/camel-azure-storage-datalake/pom.xml b/components/camel-azure/camel-azure-storage-datalake/pom.xml
new file mode 100644
index 0000000..f3643e5
--- /dev/null
+++ b/components/camel-azure/camel-azure-storage-datalake/pom.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+         http://www.apache.org/licenses/LICENSE-2.0
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-azure-parent</artifactId>
+        <version>3.9.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>camel-azure-storage-datalake</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Camel :: Azure Datalake Gen2</name>
+    <description>Camel Azure Datalake Gen2 Component</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-support</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.azure</groupId>
+            <artifactId>azure-storage-file-datalake</artifactId>
+            <version>${azure-storage-datalake-java-sdk12-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.azure</groupId>
+            <artifactId>azure-identity</artifactId>
+            <version>${azure-identity-version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <!-- test dependencies -->
+
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${commons-lang3-version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-infra-azure-common</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
... 9249 lines suppressed ...


[camel] 02/05: CAMEL-16321 - Have a middle folder for azure components

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 42e01103e1ea2b5cd380bad7277392d4fa28b6ff
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Wed Mar 10 07:38:32 2021 +0100

    CAMEL-16321 - Have a middle folder for azure components
---
 .../java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java     | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
index 9bde29d..82d9465 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
@@ -589,6 +589,7 @@ public class PrepareCatalogMojo extends AbstractMojo {
                 case "camel-vertx-common":
                 case "camel-vertx-kafka":
                 case "camel-infinispan":
+                case "camel-azure":
                 case "camel-aws":
                     return false;
                 default:
@@ -1165,6 +1166,9 @@ public class PrepareCatalogMojo extends AbstractMojo {
                 return Collections.singletonList(dir.resolve("camel-vertx-kafka-component"));
             case "camel-infinispan":
                 return Arrays.asList(dir.resolve("camel-infinispan"), dir.resolve("camel-infinispan-embedded"));
+            case "camel-azure":
+                return Arrays.asList(dir.resolve("camel-azure-eventhubs"), dir.resolve("camel-azure-storage-blob"), dir.resolve("camel-azure-storage-datalake"),
+                dir.resolve("camel-azure-storage-queue"));
             case "camel-aws":
                 return Arrays.asList(dir.resolve("camel-aws2-athena"), dir.resolve("camel-aws2-cw"),
                         dir.resolve("camel-aws2-ddb"), dir.resolve("camel-aws2-ec2"),


[camel] 01/05: CAMEL-16321 - Have a middle folder for azure components

Posted by ac...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b2f9b1bc774dd49d53edf26b744d03333528d1c4
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Wed Mar 10 07:35:29 2021 +0100

    CAMEL-16321 - Have a middle folder for azure components
---
 components/camel-azure-eventhubs/pom.xml           | 125 ----
 .../eventhubs/EventHubsComponentConfigurer.java    | 182 ------
 .../eventhubs/EventHubsEndpointConfigurer.java     | 178 ------
 .../eventhubs/EventHubsEndpointUriFactory.java     |  89 ---
 .../services/org/apache/camel/component.properties |   7 -
 .../org/apache/camel/component/azure-eventhubs     |   2 -
 .../camel/configurer/azure-eventhubs-component     |   2 -
 .../camel/configurer/azure-eventhubs-endpoint      |   2 -
 .../camel/urifactory/azure-eventhubs-endpoint      |   2 -
 .../component/azure/eventhubs/azure-eventhubs.json |  72 ---
 .../src/main/docs/azure-eventhubs-component.adoc   | 254 --------
 .../azure/eventhubs/EventHubsComponent.java        | 130 ----
 .../azure/eventhubs/EventHubsConfiguration.java    | 337 ----------
 .../EventHubsConfigurationOptionsProxy.java        |  60 --
 .../azure/eventhubs/EventHubsConstants.java        |  31 -
 .../azure/eventhubs/EventHubsConsumer.java         | 160 -----
 .../azure/eventhubs/EventHubsEndpoint.java         |  70 ---
 .../azure/eventhubs/EventHubsProducer.java         |  77 ---
 .../eventhubs/client/EventHubsClientFactory.java   | 144 -----
 .../operations/EventHubsProducerOperations.java    | 152 -----
 .../azure/eventhubs/EventHubsComponentTest.java    | 132 ----
 .../azure/eventhubs/EventHubsConsumerIT.java       | 146 -----
 .../azure/eventhubs/EventHubsProducerIT.java       | 139 ----
 .../azure/eventhubs/EventProcessorIT.java          | 110 ----
 .../azure/eventhubs/EventProcessorTest.java        |  57 --
 .../camel/component/azure/eventhubs/TestUtils.java |  60 --
 .../operations/EventHubsProducerOperationsIT.java  | 188 ------
 .../src/test/resources/log4j2.properties           |  27 -
 components/camel-azure-storage-blob/pom.xml        | 116 ----
 .../storage/blob/BlobComponentConfigurer.java      | 200 ------
 .../azure/storage/blob/BlobEndpointConfigurer.java | 202 ------
 .../azure/storage/blob/BlobEndpointUriFactory.java |  94 ---
 .../services/org/apache/camel/component.properties |   7 -
 .../org/apache/camel/component/azure-storage-blob  |   2 -
 .../camel/configurer/azure-storage-blob-component  |   2 -
 .../camel/configurer/azure-storage-blob-endpoint   |   2 -
 .../camel/urifactory/azure-storage-blob-endpoint   |   2 -
 .../azure/storage/blob/azure-storage-blob.json     |  87 ---
 .../main/docs/azure-storage-blob-component.adoc    | 697 ---------------------
 .../src/main/docs/azure-summary.adoc               |  15 -
 .../component/azure/storage/blob/BlobBlock.java    |  56 --
 .../storage/blob/BlobCommonRequestOptions.java     |  73 ---
 .../azure/storage/blob/BlobComponent.java          | 131 ----
 .../azure/storage/blob/BlobConfiguration.java      | 403 ------------
 .../blob/BlobConfigurationOptionsProxy.java        | 216 -------
 .../azure/storage/blob/BlobConstants.java          |  87 ---
 .../component/azure/storage/blob/BlobConsumer.java | 171 -----
 .../component/azure/storage/blob/BlobEndpoint.java | 110 ----
 .../azure/storage/blob/BlobExchangeHeaders.java    | 438 -------------
 .../storage/blob/BlobOperationsDefinition.java     | 122 ----
 .../component/azure/storage/blob/BlobProducer.java | 169 -----
 .../azure/storage/blob/BlobStreamAndLength.java    |  78 ---
 .../component/azure/storage/blob/BlobType.java     |  30 -
 .../component/azure/storage/blob/BlobUtils.java    |  55 --
 .../storage/blob/client/BlobClientFactory.java     |  60 --
 .../storage/blob/client/BlobClientWrapper.java     | 204 ------
 .../blob/client/BlobContainerClientWrapper.java    |  60 --
 .../blob/client/BlobServiceClientWrapper.java      |  48 --
 .../blob/operations/BlobContainerOperations.java   |  81 ---
 .../blob/operations/BlobOperationResponse.java     |  54 --
 .../storage/blob/operations/BlobOperations.java    | 468 --------------
 .../blob/operations/BlobServiceOperations.java     |  49 --
 .../azure/storage/blob/BlobComponentTest.java      | 134 ----
 .../blob/BlobConfigurationOptionsProxyTest.java    | 114 ----
 .../azure/storage/blob/BlobTestUtils.java          |  44 --
 .../azure/storage/blob/integration/BaseIT.java     |  85 ---
 .../blob/integration/BlobConsumerITTest.java       | 242 -------
 .../integration/BlobContainerOperationsITTest.java |  89 ---
 .../blob/integration/BlobOperationsITTest.java     | 422 -------------
 .../blob/integration/BlobProducerITTest.java       | 218 -------
 .../operations/BlobContainerOperationsTest.java    | 175 ------
 .../blob/operations/BlobOperationsTest.java        | 179 ------
 .../src/test/resources/azurite.properties          |  20 -
 .../src/test/resources/log4j2.properties           |  27 -
 .../src/test/resources/upload_test_file            |   1 -
 components/camel-azure-storage-datalake/pom.xml    | 144 -----
 .../datalake/DataLakeComponentConfigurer.java      | 229 -------
 .../datalake/DataLakeEndpointConfigurer.java       | 231 -------
 .../datalake/DataLakeEndpointUriFactory.java       |  97 ---
 .../services/org/apache/camel/component.properties |   7 -
 .../apache/camel/component/azure-storage-datalake  |   2 -
 .../configurer/azure-storage-datalake-component    |   2 -
 .../configurer/azure-storage-datalake-endpoint     |   2 -
 .../urifactory/azure-storage-datalake-endpoint     |   2 -
 .../storage/datalake/azure-storage-datalake.json   |  97 ---
 .../docs/azure-storage-datalake-component.adoc     | 553 ----------------
 .../azure/storage/datalake/DataLakeComponent.java  | 112 ----
 .../storage/datalake/DataLakeConfiguration.java    | 356 -----------
 .../DataLakeConfigurationOptionsProxy.java         | 267 --------
 .../azure/storage/datalake/DataLakeConstants.java  |  86 ---
 .../azure/storage/datalake/DataLakeConsumer.java   | 165 -----
 .../azure/storage/datalake/DataLakeEndpoint.java   |  97 ---
 .../storage/datalake/DataLakeExchangeHeaders.java  | 414 ------------
 .../datalake/DataLakeOperationsDefinition.java     |  35 --
 .../azure/storage/datalake/DataLakeProducer.java   | 172 -----
 .../azure/storage/datalake/DataLakeUtils.java      |  48 --
 .../storage/datalake/FileCommonRequestOptions.java |  78 ---
 .../storage/datalake/FileStreamAndLength.java      |  78 ---
 .../datalake/client/DataLakeClientFactory.java     |  94 ---
 .../client/DataLakeDirectoryClientWrapper.java     |  56 --
 .../datalake/client/DataLakeFileClientWrapper.java | 133 ----
 .../client/DataLakeFileSystemClientWrapper.java    |  70 ---
 .../client/DataLakeServiceClientWrapper.java       |  47 --
 .../operations/DataLakeDirectoryOperations.java    |  69 --
 .../operations/DataLakeFileOperations.java         | 240 -------
 .../operations/DataLakeFileSystemOperations.java   |  85 ---
 .../operations/DataLakeOperationResponse.java      |  53 --
 .../operations/DataLakeServiceOperations.java      |  42 --
 .../datalake/component/DataLakeComponentTest.java  |  86 ---
 .../azure/storage/datalake/integration/BaseIT.java |  94 ---
 .../datalake/integration/DataLakeConsumerIT.java   | 224 -------
 .../integration/DataLakeFileOperationIT.java       | 135 ----
 .../integration/DataLakeFileSystemOperationIT.java |  81 ---
 .../datalake/integration/DataLakeProducerIT.java   | 113 ----
 .../operations/DataLakeDirectoryOperationTest.java |  81 ---
 .../operations/DataLakeFileOperationTest.java      | 110 ----
 .../DataLakeFileSystemOperationTest.java           | 172 -----
 .../src/test/resources/log4j2.properties           |  27 -
 components/camel-azure-storage-queue/pom.xml       | 109 ----
 .../storage/queue/QueueComponentConfigurer.java    | 134 ----
 .../storage/queue/QueueEndpointConfigurer.java     | 130 ----
 .../storage/queue/QueueEndpointUriFactory.java     |  81 ---
 .../services/org/apache/camel/component.properties |   7 -
 .../org/apache/camel/component/azure-storage-queue |   2 -
 .../camel/configurer/azure-storage-queue-component |   2 -
 .../camel/configurer/azure-storage-queue-endpoint  |   2 -
 .../camel/urifactory/azure-storage-queue-endpoint  |   2 -
 .../azure/storage/queue/azure-storage-queue.json   |  62 --
 .../main/docs/azure-storage-queue-component.adoc   | 412 ------------
 .../azure/storage/queue/QueueComponent.java        | 129 ----
 .../azure/storage/queue/QueueConfiguration.java    | 246 --------
 .../queue/QueueConfigurationOptionsProxy.java      |  94 ---
 .../azure/storage/queue/QueueConstants.java        |  42 --
 .../azure/storage/queue/QueueConsumer.java         | 184 ------
 .../azure/storage/queue/QueueEndpoint.java         |  84 ---
 .../azure/storage/queue/QueueExchangeHeaders.java  | 140 -----
 .../storage/queue/QueueOperationDefinition.java    |  31 -
 .../azure/storage/queue/QueueProducer.java         | 115 ----
 .../storage/queue/client/QueueClientFactory.java   |  59 --
 .../storage/queue/client/QueueClientWrapper.java   |  77 ---
 .../queue/client/QueueServiceClientWrapper.java    |  49 --
 .../queue/operations/QueueOperationResponse.java   |  54 --
 .../storage/queue/operations/QueueOperations.java  | 209 ------
 .../queue/operations/QueueServiceOperations.java   |  52 --
 .../azure/storage/queue/QueueComponentTest.java    | 117 ----
 .../queue/QueueConfigurationOptionsProxyTest.java  |  55 --
 .../azure/storage/queue/QueueConsumerIT.java       | 113 ----
 .../azure/storage/queue/QueueProducerIT.java       | 216 -------
 .../azure/storage/queue/QueueTestUtils.java        |  53 --
 .../queue/operations/QueueOperationsIT.java        | 251 --------
 .../queue/operations/QueueOperationsTest.java      | 117 ----
 .../queue/operations/QueueServiceOperationsIT.java |  99 ---
 .../src/test/resources/log4j2.properties           |  27 -
 153 files changed, 18116 deletions(-)

diff --git a/components/camel-azure-eventhubs/pom.xml b/components/camel-azure-eventhubs/pom.xml
deleted file mode 100644
index bb169df..0000000
--- a/components/camel-azure-eventhubs/pom.xml
+++ /dev/null
@@ -1,125 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.camel</groupId>
-        <artifactId>components</artifactId>
-        <version>3.9.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>camel-azure-eventhubs</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Camel :: Azure Event Hubs</name>
-    <description>Camel Azure Event Hubs Component</description>
-
-    <properties>
-      <camel.osgi.import.pkg>
-        !org.apache.camel.component.azure.eventhubs*,
-        reactor*;version="[3,4)",
-        ${camel.osgi.import.defaults},
-        *
-      </camel.osgi.import.pkg>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-support</artifactId>
-        </dependency>
-
-        <!-- azure sdk -->
-        <dependency>
-            <groupId>com.azure</groupId>
-            <artifactId>azure-messaging-eventhubs</artifactId>
-            <version>${azure-eventhubs-java-version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.azure</groupId>
-            <artifactId>azure-messaging-eventhubs-checkpointstore-blob</artifactId>
-            <version>${azure-eventhubs-checkpointstore-blob-version}</version>
-        </dependency>
-
-        <!-- extras -->
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-        </dependency>
-
-        <!-- for testing -->
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test-junit5</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-slf4j-impl</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-junit-jupiter</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.awaitility</groupId>
-            <artifactId>awaitility</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <version>${commons-lang3-version}</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-    <profiles>
-        <profile>
-            <id>fullTests</id>
-            <build>
-                <plugins>
-                    <plugin>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <version>${maven-surefire-plugin-version}</version>
-                        <executions>
-                            <execution>
-                                <phase>integration-test</phase>
-                                <goals>
-                                    <goal>test</goal>
-                                </goals>
-                                <configuration>
-                                    <excludes>
-                                        <exclude>none</exclude>
-                                    </excludes>
-                                    <includes>
-                                        <include>**/*IT</include>
-                                    </includes>
-                                </configuration>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-</project>
diff --git a/components/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentConfigurer.java b/components/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentConfigurer.java
deleted file mode 100644
index 47175fc..0000000
--- a/components/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentConfigurer.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/* Generated by camel build tools - do NOT edit this file! */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.util.Map;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
-import org.apache.camel.spi.PropertyConfigurerGetter;
-import org.apache.camel.spi.ConfigurerStrategy;
-import org.apache.camel.spi.GeneratedPropertyConfigurer;
-import org.apache.camel.util.CaseInsensitiveMap;
-import org.apache.camel.support.component.PropertyConfigurerSupport;
-
-/**
- * Generated by camel build tools - do NOT edit this file!
- */
-@SuppressWarnings("unchecked")
-public class EventHubsComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
-
-    private org.apache.camel.component.azure.eventhubs.EventHubsConfiguration getOrCreateConfiguration(EventHubsComponent target) {
-        if (target.getConfiguration() == null) {
-            target.setConfiguration(new org.apache.camel.component.azure.eventhubs.EventHubsConfiguration());
-        }
-        return target.getConfiguration();
-    }
-
-    @Override
-    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
-        EventHubsComponent target = (EventHubsComponent) obj;
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "amqpretryoptions":
-        case "amqpRetryOptions": getOrCreateConfiguration(target).setAmqpRetryOptions(property(camelContext, com.azure.core.amqp.AmqpRetryOptions.class, value)); return true;
-        case "amqptransporttype":
-        case "amqpTransportType": getOrCreateConfiguration(target).setAmqpTransportType(property(camelContext, com.azure.core.amqp.AmqpTransportType.class, value)); return true;
-        case "autodiscoverclient":
-        case "autoDiscoverClient": getOrCreateConfiguration(target).setAutoDiscoverClient(property(camelContext, boolean.class, value)); return true;
-        case "autowiredenabled":
-        case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true;
-        case "blobaccesskey":
-        case "blobAccessKey": getOrCreateConfiguration(target).setBlobAccessKey(property(camelContext, java.lang.String.class, value)); return true;
-        case "blobaccountname":
-        case "blobAccountName": getOrCreateConfiguration(target).setBlobAccountName(property(camelContext, java.lang.String.class, value)); return true;
-        case "blobcontainername":
-        case "blobContainerName": getOrCreateConfiguration(target).setBlobContainerName(property(camelContext, java.lang.String.class, value)); return true;
-        case "blobstoragesharedkeycredential":
-        case "blobStorageSharedKeyCredential": getOrCreateConfiguration(target).setBlobStorageSharedKeyCredential(property(camelContext, com.azure.storage.common.StorageSharedKeyCredential.class, value)); return true;
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
-        case "checkpointstore":
-        case "checkpointStore": getOrCreateConfiguration(target).setCheckpointStore(property(camelContext, com.azure.messaging.eventhubs.CheckpointStore.class, value)); return true;
-        case "configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.azure.eventhubs.EventHubsConfiguration.class, value)); return true;
-        case "connectionstring":
-        case "connectionString": getOrCreateConfiguration(target).setConnectionString(property(camelContext, java.lang.String.class, value)); return true;
-        case "consumergroupname":
-        case "consumerGroupName": getOrCreateConfiguration(target).setConsumerGroupName(property(camelContext, java.lang.String.class, value)); return true;
-        case "eventposition":
-        case "eventPosition": getOrCreateConfiguration(target).setEventPosition(property(camelContext, java.util.Map.class, value)); return true;
-        case "lazystartproducer":
-        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
-        case "partitionid":
-        case "partitionId": getOrCreateConfiguration(target).setPartitionId(property(camelContext, java.lang.String.class, value)); return true;
-        case "partitionkey":
-        case "partitionKey": getOrCreateConfiguration(target).setPartitionKey(property(camelContext, java.lang.String.class, value)); return true;
-        case "prefetchcount":
-        case "prefetchCount": getOrCreateConfiguration(target).setPrefetchCount(property(camelContext, int.class, value)); return true;
-        case "producerasyncclient":
-        case "producerAsyncClient": getOrCreateConfiguration(target).setProducerAsyncClient(property(camelContext, com.azure.messaging.eventhubs.EventHubProducerAsyncClient.class, value)); return true;
-        case "sharedaccesskey":
-        case "sharedAccessKey": getOrCreateConfiguration(target).setSharedAccessKey(property(camelContext, java.lang.String.class, value)); return true;
-        case "sharedaccessname":
-        case "sharedAccessName": getOrCreateConfiguration(target).setSharedAccessName(property(camelContext, java.lang.String.class, value)); return true;
-        default: return false;
-        }
-    }
-
-    @Override
-    public Class<?> getOptionType(String name, boolean ignoreCase) {
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "amqpretryoptions":
-        case "amqpRetryOptions": return com.azure.core.amqp.AmqpRetryOptions.class;
-        case "amqptransporttype":
-        case "amqpTransportType": return com.azure.core.amqp.AmqpTransportType.class;
-        case "autodiscoverclient":
-        case "autoDiscoverClient": return boolean.class;
-        case "autowiredenabled":
-        case "autowiredEnabled": return boolean.class;
-        case "blobaccesskey":
-        case "blobAccessKey": return java.lang.String.class;
-        case "blobaccountname":
-        case "blobAccountName": return java.lang.String.class;
-        case "blobcontainername":
-        case "blobContainerName": return java.lang.String.class;
-        case "blobstoragesharedkeycredential":
-        case "blobStorageSharedKeyCredential": return com.azure.storage.common.StorageSharedKeyCredential.class;
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": return boolean.class;
-        case "checkpointstore":
-        case "checkpointStore": return com.azure.messaging.eventhubs.CheckpointStore.class;
-        case "configuration": return org.apache.camel.component.azure.eventhubs.EventHubsConfiguration.class;
-        case "connectionstring":
-        case "connectionString": return java.lang.String.class;
-        case "consumergroupname":
-        case "consumerGroupName": return java.lang.String.class;
-        case "eventposition":
-        case "eventPosition": return java.util.Map.class;
-        case "lazystartproducer":
-        case "lazyStartProducer": return boolean.class;
-        case "partitionid":
-        case "partitionId": return java.lang.String.class;
-        case "partitionkey":
-        case "partitionKey": return java.lang.String.class;
-        case "prefetchcount":
-        case "prefetchCount": return int.class;
-        case "producerasyncclient":
-        case "producerAsyncClient": return com.azure.messaging.eventhubs.EventHubProducerAsyncClient.class;
-        case "sharedaccesskey":
-        case "sharedAccessKey": return java.lang.String.class;
-        case "sharedaccessname":
-        case "sharedAccessName": return java.lang.String.class;
-        default: return null;
-        }
-    }
-
-    @Override
-    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
-        EventHubsComponent target = (EventHubsComponent) obj;
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "amqpretryoptions":
-        case "amqpRetryOptions": return getOrCreateConfiguration(target).getAmqpRetryOptions();
-        case "amqptransporttype":
-        case "amqpTransportType": return getOrCreateConfiguration(target).getAmqpTransportType();
-        case "autodiscoverclient":
-        case "autoDiscoverClient": return getOrCreateConfiguration(target).isAutoDiscoverClient();
-        case "autowiredenabled":
-        case "autowiredEnabled": return target.isAutowiredEnabled();
-        case "blobaccesskey":
-        case "blobAccessKey": return getOrCreateConfiguration(target).getBlobAccessKey();
-        case "blobaccountname":
-        case "blobAccountName": return getOrCreateConfiguration(target).getBlobAccountName();
-        case "blobcontainername":
-        case "blobContainerName": return getOrCreateConfiguration(target).getBlobContainerName();
-        case "blobstoragesharedkeycredential":
-        case "blobStorageSharedKeyCredential": return getOrCreateConfiguration(target).getBlobStorageSharedKeyCredential();
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
-        case "checkpointstore":
-        case "checkpointStore": return getOrCreateConfiguration(target).getCheckpointStore();
-        case "configuration": return target.getConfiguration();
-        case "connectionstring":
-        case "connectionString": return getOrCreateConfiguration(target).getConnectionString();
-        case "consumergroupname":
-        case "consumerGroupName": return getOrCreateConfiguration(target).getConsumerGroupName();
-        case "eventposition":
-        case "eventPosition": return getOrCreateConfiguration(target).getEventPosition();
-        case "lazystartproducer":
-        case "lazyStartProducer": return target.isLazyStartProducer();
-        case "partitionid":
-        case "partitionId": return getOrCreateConfiguration(target).getPartitionId();
-        case "partitionkey":
-        case "partitionKey": return getOrCreateConfiguration(target).getPartitionKey();
-        case "prefetchcount":
-        case "prefetchCount": return getOrCreateConfiguration(target).getPrefetchCount();
-        case "producerasyncclient":
-        case "producerAsyncClient": return getOrCreateConfiguration(target).getProducerAsyncClient();
-        case "sharedaccesskey":
-        case "sharedAccessKey": return getOrCreateConfiguration(target).getSharedAccessKey();
-        case "sharedaccessname":
-        case "sharedAccessName": return getOrCreateConfiguration(target).getSharedAccessName();
-        default: return null;
-        }
-    }
-
-    @Override
-    public Object getCollectionValueType(Object target, String name, boolean ignoreCase) {
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "eventposition":
-        case "eventPosition": return com.azure.messaging.eventhubs.models.EventPosition.class;
-        default: return null;
-        }
-    }
-}
-
diff --git a/components/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointConfigurer.java b/components/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointConfigurer.java
deleted file mode 100644
index b57289f..0000000
--- a/components/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointConfigurer.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/* Generated by camel build tools - do NOT edit this file! */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.util.Map;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
-import org.apache.camel.spi.PropertyConfigurerGetter;
-import org.apache.camel.spi.ConfigurerStrategy;
-import org.apache.camel.spi.GeneratedPropertyConfigurer;
-import org.apache.camel.util.CaseInsensitiveMap;
-import org.apache.camel.support.component.PropertyConfigurerSupport;
-
-/**
- * Generated by camel build tools - do NOT edit this file!
- */
-@SuppressWarnings("unchecked")
-public class EventHubsEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
-
-    @Override
-    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
-        EventHubsEndpoint target = (EventHubsEndpoint) obj;
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "amqpretryoptions":
-        case "amqpRetryOptions": target.getConfiguration().setAmqpRetryOptions(property(camelContext, com.azure.core.amqp.AmqpRetryOptions.class, value)); return true;
-        case "amqptransporttype":
-        case "amqpTransportType": target.getConfiguration().setAmqpTransportType(property(camelContext, com.azure.core.amqp.AmqpTransportType.class, value)); return true;
-        case "autodiscoverclient":
-        case "autoDiscoverClient": target.getConfiguration().setAutoDiscoverClient(property(camelContext, boolean.class, value)); return true;
-        case "blobaccesskey":
-        case "blobAccessKey": target.getConfiguration().setBlobAccessKey(property(camelContext, java.lang.String.class, value)); return true;
-        case "blobaccountname":
-        case "blobAccountName": target.getConfiguration().setBlobAccountName(property(camelContext, java.lang.String.class, value)); return true;
-        case "blobcontainername":
-        case "blobContainerName": target.getConfiguration().setBlobContainerName(property(camelContext, java.lang.String.class, value)); return true;
-        case "blobstoragesharedkeycredential":
-        case "blobStorageSharedKeyCredential": target.getConfiguration().setBlobStorageSharedKeyCredential(property(camelContext, com.azure.storage.common.StorageSharedKeyCredential.class, value)); return true;
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
-        case "checkpointstore":
-        case "checkpointStore": target.getConfiguration().setCheckpointStore(property(camelContext, com.azure.messaging.eventhubs.CheckpointStore.class, value)); return true;
-        case "connectionstring":
-        case "connectionString": target.getConfiguration().setConnectionString(property(camelContext, java.lang.String.class, value)); return true;
-        case "consumergroupname":
-        case "consumerGroupName": target.getConfiguration().setConsumerGroupName(property(camelContext, java.lang.String.class, value)); return true;
-        case "eventposition":
-        case "eventPosition": target.getConfiguration().setEventPosition(property(camelContext, java.util.Map.class, value)); return true;
-        case "exceptionhandler":
-        case "exceptionHandler": target.setExceptionHandler(property(camelContext, org.apache.camel.spi.ExceptionHandler.class, value)); return true;
-        case "exchangepattern":
-        case "exchangePattern": target.setExchangePattern(property(camelContext, org.apache.camel.ExchangePattern.class, value)); return true;
-        case "lazystartproducer":
-        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
-        case "partitionid":
-        case "partitionId": target.getConfiguration().setPartitionId(property(camelContext, java.lang.String.class, value)); return true;
-        case "partitionkey":
-        case "partitionKey": target.getConfiguration().setPartitionKey(property(camelContext, java.lang.String.class, value)); return true;
-        case "prefetchcount":
-        case "prefetchCount": target.getConfiguration().setPrefetchCount(property(camelContext, int.class, value)); return true;
-        case "producerasyncclient":
-        case "producerAsyncClient": target.getConfiguration().setProducerAsyncClient(property(camelContext, com.azure.messaging.eventhubs.EventHubProducerAsyncClient.class, value)); return true;
-        case "sharedaccesskey":
-        case "sharedAccessKey": target.getConfiguration().setSharedAccessKey(property(camelContext, java.lang.String.class, value)); return true;
-        case "sharedaccessname":
-        case "sharedAccessName": target.getConfiguration().setSharedAccessName(property(camelContext, java.lang.String.class, value)); return true;
-        default: return false;
-        }
-    }
-
-    @Override
-    public Class<?> getOptionType(String name, boolean ignoreCase) {
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "amqpretryoptions":
-        case "amqpRetryOptions": return com.azure.core.amqp.AmqpRetryOptions.class;
-        case "amqptransporttype":
-        case "amqpTransportType": return com.azure.core.amqp.AmqpTransportType.class;
-        case "autodiscoverclient":
-        case "autoDiscoverClient": return boolean.class;
-        case "blobaccesskey":
-        case "blobAccessKey": return java.lang.String.class;
-        case "blobaccountname":
-        case "blobAccountName": return java.lang.String.class;
-        case "blobcontainername":
-        case "blobContainerName": return java.lang.String.class;
-        case "blobstoragesharedkeycredential":
-        case "blobStorageSharedKeyCredential": return com.azure.storage.common.StorageSharedKeyCredential.class;
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": return boolean.class;
-        case "checkpointstore":
-        case "checkpointStore": return com.azure.messaging.eventhubs.CheckpointStore.class;
-        case "connectionstring":
-        case "connectionString": return java.lang.String.class;
-        case "consumergroupname":
-        case "consumerGroupName": return java.lang.String.class;
-        case "eventposition":
-        case "eventPosition": return java.util.Map.class;
-        case "exceptionhandler":
-        case "exceptionHandler": return org.apache.camel.spi.ExceptionHandler.class;
-        case "exchangepattern":
-        case "exchangePattern": return org.apache.camel.ExchangePattern.class;
-        case "lazystartproducer":
-        case "lazyStartProducer": return boolean.class;
-        case "partitionid":
-        case "partitionId": return java.lang.String.class;
-        case "partitionkey":
-        case "partitionKey": return java.lang.String.class;
-        case "prefetchcount":
-        case "prefetchCount": return int.class;
-        case "producerasyncclient":
-        case "producerAsyncClient": return com.azure.messaging.eventhubs.EventHubProducerAsyncClient.class;
-        case "sharedaccesskey":
-        case "sharedAccessKey": return java.lang.String.class;
-        case "sharedaccessname":
-        case "sharedAccessName": return java.lang.String.class;
-        default: return null;
-        }
-    }
-
-    @Override
-    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
-        EventHubsEndpoint target = (EventHubsEndpoint) obj;
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "amqpretryoptions":
-        case "amqpRetryOptions": return target.getConfiguration().getAmqpRetryOptions();
-        case "amqptransporttype":
-        case "amqpTransportType": return target.getConfiguration().getAmqpTransportType();
-        case "autodiscoverclient":
-        case "autoDiscoverClient": return target.getConfiguration().isAutoDiscoverClient();
-        case "blobaccesskey":
-        case "blobAccessKey": return target.getConfiguration().getBlobAccessKey();
-        case "blobaccountname":
-        case "blobAccountName": return target.getConfiguration().getBlobAccountName();
-        case "blobcontainername":
-        case "blobContainerName": return target.getConfiguration().getBlobContainerName();
-        case "blobstoragesharedkeycredential":
-        case "blobStorageSharedKeyCredential": return target.getConfiguration().getBlobStorageSharedKeyCredential();
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
-        case "checkpointstore":
-        case "checkpointStore": return target.getConfiguration().getCheckpointStore();
-        case "connectionstring":
-        case "connectionString": return target.getConfiguration().getConnectionString();
-        case "consumergroupname":
-        case "consumerGroupName": return target.getConfiguration().getConsumerGroupName();
-        case "eventposition":
-        case "eventPosition": return target.getConfiguration().getEventPosition();
-        case "exceptionhandler":
-        case "exceptionHandler": return target.getExceptionHandler();
-        case "exchangepattern":
-        case "exchangePattern": return target.getExchangePattern();
-        case "lazystartproducer":
-        case "lazyStartProducer": return target.isLazyStartProducer();
-        case "partitionid":
-        case "partitionId": return target.getConfiguration().getPartitionId();
-        case "partitionkey":
-        case "partitionKey": return target.getConfiguration().getPartitionKey();
-        case "prefetchcount":
-        case "prefetchCount": return target.getConfiguration().getPrefetchCount();
-        case "producerasyncclient":
-        case "producerAsyncClient": return target.getConfiguration().getProducerAsyncClient();
-        case "sharedaccesskey":
-        case "sharedAccessKey": return target.getConfiguration().getSharedAccessKey();
-        case "sharedaccessname":
-        case "sharedAccessName": return target.getConfiguration().getSharedAccessName();
-        default: return null;
-        }
-    }
-
-    @Override
-    public Object getCollectionValueType(Object target, String name, boolean ignoreCase) {
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "eventposition":
-        case "eventPosition": return com.azure.messaging.eventhubs.models.EventPosition.class;
-        default: return null;
-        }
-    }
-}
-
diff --git a/components/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointUriFactory.java b/components/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointUriFactory.java
deleted file mode 100644
index 272f4ab..0000000
--- a/components/camel-azure-eventhubs/src/generated/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpointUriFactory.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Generated by camel build tools - do NOT edit this file! */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.camel.spi.EndpointUriFactory;
-
-/**
- * Generated by camel build tools - do NOT edit this file!
- */
-public class EventHubsEndpointUriFactory extends org.apache.camel.support.component.EndpointUriFactorySupport implements EndpointUriFactory {
-
-    private static final String BASE = ":namespace/eventHubName";
-
-    private static final Set<String> PROPERTY_NAMES;
-    private static final Set<String> SECRET_PROPERTY_NAMES;
-    static {
-        Set<String> props = new HashSet<>(23);
-        props.add("blobStorageSharedKeyCredential");
-        props.add("connectionString");
-        props.add("autoDiscoverClient");
-        props.add("prefetchCount");
-        props.add("sharedAccessKey");
-        props.add("sharedAccessName");
-        props.add("partitionId");
-        props.add("checkpointStore");
-        props.add("exchangePattern");
-        props.add("amqpTransportType");
-        props.add("consumerGroupName");
-        props.add("eventPosition");
-        props.add("lazyStartProducer");
-        props.add("blobAccountName");
-        props.add("bridgeErrorHandler");
-        props.add("producerAsyncClient");
-        props.add("partitionKey");
-        props.add("namespace");
-        props.add("amqpRetryOptions");
-        props.add("blobContainerName");
-        props.add("eventHubName");
-        props.add("exceptionHandler");
-        props.add("blobAccessKey");
-        PROPERTY_NAMES = Collections.unmodifiableSet(props);
-        Set<String> secretProps = new HashSet<>(4);
-        secretProps.add("blobStorageSharedKeyCredential");
-        secretProps.add("connectionString");
-        secretProps.add("sharedAccessKey");
-        secretProps.add("blobAccessKey");
-        SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps);
-    }
-
-    @Override
-    public boolean isEnabled(String scheme) {
-        return "azure-eventhubs".equals(scheme);
-    }
-
-    @Override
-    public String buildUri(String scheme, Map<String, Object> properties, boolean encode) throws URISyntaxException {
-        String syntax = scheme + BASE;
-        String uri = syntax;
-
-        Map<String, Object> copy = new HashMap<>(properties);
-
-        uri = buildPathParameter(syntax, uri, "namespace", null, false, copy);
-        uri = buildPathParameter(syntax, uri, "eventHubName", null, false, copy);
-        uri = buildQueryParameters(uri, copy, encode);
-        return uri;
-    }
-
-    @Override
-    public Set<String> propertyNames() {
-        return PROPERTY_NAMES;
-    }
-
-    @Override
-    public Set<String> secretPropertyNames() {
-        return SECRET_PROPERTY_NAMES;
-    }
-
-    @Override
-    public boolean isLenientProperties() {
-        return false;
-    }
-}
-
diff --git a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component.properties b/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component.properties
deleted file mode 100644
index ee00325..0000000
--- a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-components=azure-eventhubs
-groupId=org.apache.camel
-artifactId=camel-azure-eventhubs
-version=3.9.0-SNAPSHOT
-projectName=Camel :: Azure Event Hubs
-projectDescription=Camel Azure Event Hubs Component
diff --git a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component/azure-eventhubs b/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component/azure-eventhubs
deleted file mode 100644
index bf24c2f..0000000
--- a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/component/azure-eventhubs
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.component.azure.eventhubs.EventHubsComponent
diff --git a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-component b/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-component
deleted file mode 100644
index 927b28a..0000000
--- a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-component
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.component.azure.eventhubs.EventHubsComponentConfigurer
diff --git a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-endpoint b/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-endpoint
deleted file mode 100644
index d500a7e..0000000
--- a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-eventhubs-endpoint
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.component.azure.eventhubs.EventHubsEndpointConfigurer
diff --git a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-eventhubs-endpoint b/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-eventhubs-endpoint
deleted file mode 100644
index e865df1..0000000
--- a/components/camel-azure-eventhubs/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-eventhubs-endpoint
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.component.azure.eventhubs.EventHubsEndpointUriFactory
diff --git a/components/camel-azure-eventhubs/src/generated/resources/org/apache/camel/component/azure/eventhubs/azure-eventhubs.json b/components/camel-azure-eventhubs/src/generated/resources/org/apache/camel/component/azure/eventhubs/azure-eventhubs.json
deleted file mode 100644
index 3822400..0000000
--- a/components/camel-azure-eventhubs/src/generated/resources/org/apache/camel/component/azure/eventhubs/azure-eventhubs.json
+++ /dev/null
@@ -1,72 +0,0 @@
-{
-  "component": {
-    "kind": "component",
-    "name": "azure-eventhubs",
-    "title": "Azure Event Hubs",
-    "description": "The azure-eventhubs component that integrates Azure Event Hubs using AMQP protocol. Azure EventHubs is a highly scalable publish-subscribe service that can ingest millions of events per second and stream them to multiple consumers.",
-    "deprecated": false,
-    "firstVersion": "3.5.0",
-    "label": "cloud,messaging",
-    "javaType": "org.apache.camel.component.azure.eventhubs.EventHubsComponent",
-    "supportLevel": "Stable",
-    "groupId": "org.apache.camel",
-    "artifactId": "camel-azure-eventhubs",
-    "version": "3.9.0-SNAPSHOT",
-    "scheme": "azure-eventhubs",
-    "extendsScheme": "",
-    "syntax": "azure-eventhubs:namespace\/eventHubName",
-    "async": false,
-    "api": false,
-    "consumerOnly": false,
-    "producerOnly": false,
-    "lenientProperties": false
-  },
-  "componentProperties": {
-    "amqpRetryOptions": { "kind": "property", "displayName": "Amqp Retry Options", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "com.azure.core.amqp.AmqpRetryOptions", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the retry policy for EventHubAsyncClient. If not specified, the default r [...]
-    "amqpTransportType": { "kind": "property", "displayName": "Amqp Transport Type", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "com.azure.core.amqp.AmqpTransportType", "enum": [ "Amqp", "AmqpWebSockets" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "AMQP", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the tran [...]
-    "autoDiscoverClient": { "kind": "property", "displayName": "Auto Discover Client", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Setting the autoDiscoverClient mechanism, if true, the component will look for a [...]
-    "configuration": { "kind": "property", "displayName": "Configuration", "group": "common", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "deprecated": false, "autowired": false, "secret": false, "description": "The component configurations" },
-    "blobAccessKey": { "kind": "property", "displayName": "Blob Access Key", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets access key for the associated azure acco [...]
-    "blobAccountName": { "kind": "property", "displayName": "Blob Account Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for a [...]
-    "blobContainerName": { "kind": "property", "displayName": "Blob Container Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets the blob container that shall b [...]
-    "blobStorageSharedKeyCredential": { "kind": "property", "displayName": "Blob Storage Shared Key Credential", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "com.azure.storage.common.StorageSharedKeyCredential", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default  [...]
-    "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a me [...]
-    "checkpointStore": { "kind": "property", "displayName": "Checkpoint Store", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "com.azure.messaging.eventhubs.CheckpointStore", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "BlobCheckpointStore", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the CheckpointStore the  [...]
-    "consumerGroupName": { "kind": "property", "displayName": "Consumer Group Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "$Default", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the name of the consumer group this consumer is associated  [...]
-    "eventPosition": { "kind": "property", "displayName": "Event Position", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, com.azure.messaging.eventhubs.models.EventPosition>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the map containing the event  [...]
-    "prefetchCount": { "kind": "property", "displayName": "Prefetch Count", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 500, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the count used by the receiver to control the number of events the Event Hub consumer w [...]
-    "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during star [...]
-    "partitionId": { "kind": "property", "displayName": "Partition Id", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the identifier of the Event Hub partition that the events will be sent to. If the identifier is not  [...]
-    "partitionKey": { "kind": "property", "displayName": "Partition Key", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to ma [...]
-    "producerAsyncClient": { "kind": "property", "displayName": "Producer Async Client", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "com.azure.messaging.eventhubs.EventHubProducerAsyncClient", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the EventHubProducerAsyncClient.An asynchr [...]
-    "autowiredEnabled": { "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which t [...]
-    "connectionString": { "kind": "property", "displayName": "Connection String", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply t [...]
-    "sharedAccessKey": { "kind": "property", "displayName": "Shared Access Key", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "The generated value for the SharedAccessName" },
-    "sharedAccessName": { "kind": "property", "displayName": "Shared Access Name", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "The name you chose for your EventHubs SAS keys" }
-  },
-  "properties": {
-    "namespace": { "kind": "path", "displayName": "Namespace", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "EventHubs namespace created in Azure Portal" },
-    "eventHubName": { "kind": "path", "displayName": "Event Hub Name", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "EventHubs name under a specific namcespace" },
-    "amqpRetryOptions": { "kind": "parameter", "displayName": "Amqp Retry Options", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "com.azure.core.amqp.AmqpRetryOptions", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the retry policy for EventHubAsyncClient. If not specified, the default  [...]
-    "amqpTransportType": { "kind": "parameter", "displayName": "Amqp Transport Type", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "com.azure.core.amqp.AmqpTransportType", "enum": [ "Amqp", "AmqpWebSockets" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "AMQP", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the tra [...]
-    "autoDiscoverClient": { "kind": "parameter", "displayName": "Auto Discover Client", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Setting the autoDiscoverClient mechanism, if true, the component will look for  [...]
-    "blobAccessKey": { "kind": "parameter", "displayName": "Blob Access Key", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets access key for the associated azure acc [...]
-    "blobAccountName": { "kind": "parameter", "displayName": "Blob Account Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for  [...]
-    "blobContainerName": { "kind": "parameter", "displayName": "Blob Container Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default BlobCheckpointStore, this sets the blob container that shall  [...]
-    "blobStorageSharedKeyCredential": { "kind": "parameter", "displayName": "Blob Storage Shared Key Credential", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "com.azure.storage.common.StorageSharedKeyCredential", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "In case you chose the default [...]
-    "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a m [...]
-    "checkpointStore": { "kind": "parameter", "displayName": "Checkpoint Store", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "com.azure.messaging.eventhubs.CheckpointStore", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "BlobCheckpointStore", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the CheckpointStore the [...]
-    "consumerGroupName": { "kind": "parameter", "displayName": "Consumer Group Name", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "$Default", "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the name of the consumer group this consumer is associated [...]
-    "eventPosition": { "kind": "parameter", "displayName": "Event Position", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, com.azure.messaging.eventhubs.models.EventPosition>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the map containing the event [...]
-    "prefetchCount": { "kind": "parameter", "displayName": "Prefetch Count", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 500, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the count used by the receiver to control the number of events the Event Hub consumer  [...]
-    "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the con [...]
-    "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
-    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during sta [...]
-    "partitionId": { "kind": "parameter", "displayName": "Partition Id", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the identifier of the Event Hub partition that the events will be sent to. If the identifier is not [...]
-    "partitionKey": { "kind": "parameter", "displayName": "Partition Key", "group": "producer", "label": "producer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to m [...]
-    "producerAsyncClient": { "kind": "parameter", "displayName": "Producer Async Client", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "com.azure.messaging.eventhubs.EventHubProducerAsyncClient", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Sets the EventHubProducerAsyncClient.An asynch [...]
-    "connectionString": { "kind": "parameter", "displayName": "Connection String", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply  [...]
-    "sharedAccessKey": { "kind": "parameter", "displayName": "Shared Access Key", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "The generated value for the SharedAccessName" },
-    "sharedAccessName": { "kind": "parameter", "displayName": "Shared Access Name", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.eventhubs.EventHubsConfiguration", "configurationField": "configuration", "description": "The name you chose for your EventHubs SAS keys" }
-  }
-}
diff --git a/components/camel-azure-eventhubs/src/main/docs/azure-eventhubs-component.adoc b/components/camel-azure-eventhubs/src/main/docs/azure-eventhubs-component.adoc
deleted file mode 100644
index 13cd941..0000000
--- a/components/camel-azure-eventhubs/src/main/docs/azure-eventhubs-component.adoc
+++ /dev/null
@@ -1,254 +0,0 @@
-[[azure-eventhubs-component]]
-= Azure Event Hubs Component
-:docTitle: Azure Event Hubs
-:artifactId: camel-azure-eventhubs
-:description: The azure-eventhubs component that integrates Azure Event Hubs using AMQP protocol. Azure EventHubs is a highly scalable publish-subscribe service that can ingest millions of events per second and stream them to multiple consumers.
-:since: 3.5
-:supportLevel: Stable
-:component-header: Both producer and consumer are supported
-include::{cq-version}@camel-quarkus:ROOT:partial$reference/components/azure-eventhubs.adoc[opts=optional]
-//Manually maintained attributes
-:group: Azure
-
-*Since Camel {since}*
-
-*{component-header}*
-
-The Azure Event Hubs used to integrate https://azure.microsoft.com/en-us/services/event-hubs/[Azure Event Hubs] using https://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol[AMQP protocol].
-Azure EventHubs is a highly scalable publish-subscribe service that can ingest millions of events per second and stream them to multiple consumers.
-
-NOTE: Besides AMQP protocol support, Event Hubs as well supports Kafka and HTTPS protocols. Therefore, you can use as well xref:components::kafka-component.adoc[Camel Kafka] component to produce and consume to Azure Event Hubs. You can lean more https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-quickstart-kafka-enabled-event-hubs[here].
-
-
-Prerequisites
-
-You must have a valid Windows Azure Event Hubs 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-eventhubs</artifactId>
-    <version>x.x.x</version>
-  <!-- use the same version as your Camel core version -->
-</dependency>
-------------------------------------------------------------
-
-== URI Format
-
-[source,text]
-------------------------------
-azure-eventhubs://[namespace/eventHubName][?options]
-------------------------------
-
-In case you supply the `connectionString`, `namespace` and `eventHubName` are not required as these options already included
-in the `connectionString`
-
-For example in order consume event from EventHub, use the following snippet:
-[source,java]
---------------------------------------------------------------------------------
-from("azure-eventhubs:/camel/camelHub?sharedAccessName=SASaccountName&sharedAccessKey=SASaccessKey&blobAccountName=accountName&blobAccessKey=accessKey&blobContainerName=containerName").
-to("file://queuedirectory");
---------------------------------------------------------------------------------
-
-== URI Options
-
-// endpoint options: START
-The Azure Event Hubs endpoint is configured using URI syntax:
-
-----
-azure-eventhubs:namespace/eventHubName
-----
-
-with the following path and query parameters:
-
-=== Path Parameters (2 parameters):
-
-
-[width="100%",cols="2,5,^1,2",options="header"]
-|===
-| Name | Description | Default | Type
-| *namespace* | EventHubs namespace created in Azure Portal |  | String
-| *eventHubName* | EventHubs name under a specific namcespace |  | String
-|===
-
-
-=== Query Parameters (21 parameters):
-
-
-[width="100%",cols="2,5,^1,2",options="header"]
-|===
-| Name | Description | Default | Type
-| *amqpRetryOptions* (common) | Sets the retry policy for EventHubAsyncClient. If not specified, the default retry options are used. |  | AmqpRetryOptions
-| *amqpTransportType* (common) | Sets the transport type by which all the communication with Azure Event Hubs occurs. Default value is AmqpTransportType#AMQP. There are 2 enums and the value can be one of: Amqp, AmqpWebSockets | AMQP | AmqpTransportType
-| *autoDiscoverClient* (common) | Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry automatically otherwise it will skip that checking. | true | boolean
-| *blobAccessKey* (consumer) | In case you chose the default BlobCheckpointStore, this sets access key for the associated azure account name to be used for authentication with azure blob services |  | String
-| *blobAccountName* (consumer) | In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for authentication with azure blob services. |  | String
-| *blobContainerName* (consumer) | In case you chose the default BlobCheckpointStore, this sets the blob container that shall be used by the BlobCheckpointStore to store the checkpoint offsets |  | String
-| *blobStorageSharedKeyCredential* (consumer) | In case you chose the default BlobCheckpointStore, StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication information |  | StorageSharedKeyCredential
-| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
-| *checkpointStore* (consumer) | Sets the CheckpointStore the EventProcessorClient will use for storing partition ownership and checkpoint information. Users can, optionally, provide their own implementation of CheckpointStore which will store ownership and checkpoint information. By default it set to use com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore which stores all checkpoint offsets into Azure Blob Storage | BlobCheckpointStore | CheckpointStore
-| *consumerGroupName* (consumer) | Sets the name of the consumer group this consumer is associated with. Events are read in the context of this group. The name of the consumer group that is created by default is {link #DEFAULT_CONSUMER_GROUP_NAME $Default}. | $Default | String
-| *eventPosition* (consumer) | Sets the map containing the event position to use for each partition if a checkpoint for the partition does not exist in CheckpointStore. This map is keyed off of the partition id. If there is no checkpoint in CheckpointStore and there is no entry in this map, the processing of the partition will start from {link EventPosition#latest() latest} position. |  | Map
-| *prefetchCount* (consumer) | Sets the count used by the receiver to control the number of events the Event Hub consumer will actively receive and queue locally without regard to whether a receive operation is currently active. | 500 | int
-| *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
-| *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
-| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
-| *partitionId* (producer) | Sets the identifier of the Event Hub partition that the events will be sent to. If the identifier is not specified, the Event Hubs service will be responsible for routing events that are sent to an available partition. |  | String
-| *partitionKey* (producer) | Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to map this key to a specific partition. The selection of a partition is stable for a given partition hashing key. Should any other batches of events be sent using the same exact partition hashing key, the Event Hubs service will route them all to the same partition. This should be specified only when there is a need to group events by partition, but there is fl [...]
-| *producerAsyncClient* (producer) | Sets the EventHubProducerAsyncClient.An asynchronous producer responsible for transmitting EventData to a specific Event Hub, grouped together in batches. Depending on the options specified when creating an \{linkEventDataBatch}, the events may be automatically routed to an available partition or specific to a partition. Use by this component to produce the data in camel producer. |  | EventHubProducerAsyncClient
-| *connectionString* (security) | Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply the connection string for your eventHub. The connection string for EventHubs already include all the necessary information to connection to your EventHub. To learn on how to generate the connection string, take a look at this documentation: \https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string |  | String
-| *sharedAccessKey* (security) | The generated value for the SharedAccessName |  | String
-| *sharedAccessName* (security) | The name you chose for your EventHubs SAS keys |  | String
-|===
-// endpoint options: END
-
-// component options: START
-The Azure Event Hubs component supports 21 options, which are listed below.
-
-
-
-[width="100%",cols="2,5,^1,2",options="header"]
-|===
-| Name | Description | Default | Type
-| *amqpRetryOptions* (common) | Sets the retry policy for EventHubAsyncClient. If not specified, the default retry options are used. |  | AmqpRetryOptions
-| *amqpTransportType* (common) | Sets the transport type by which all the communication with Azure Event Hubs occurs. Default value is AmqpTransportType#AMQP. There are 2 enums and the value can be one of: Amqp, AmqpWebSockets | AMQP | AmqpTransportType
-| *autoDiscoverClient* (common) | Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry automatically otherwise it will skip that checking. | true | boolean
-| *configuration* (common) | The component configurations |  | EventHubsConfiguration
-| *blobAccessKey* (consumer) | In case you chose the default BlobCheckpointStore, this sets access key for the associated azure account name to be used for authentication with azure blob services |  | String
-| *blobAccountName* (consumer) | In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for authentication with azure blob services. |  | String
-| *blobContainerName* (consumer) | In case you chose the default BlobCheckpointStore, this sets the blob container that shall be used by the BlobCheckpointStore to store the checkpoint offsets |  | String
-| *blobStorageSharedKeyCredential* (consumer) | In case you chose the default BlobCheckpointStore, StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication information |  | StorageSharedKeyCredential
-| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
-| *checkpointStore* (consumer) | Sets the CheckpointStore the EventProcessorClient will use for storing partition ownership and checkpoint information. Users can, optionally, provide their own implementation of CheckpointStore which will store ownership and checkpoint information. By default it set to use com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore which stores all checkpoint offsets into Azure Blob Storage | BlobCheckpointStore | CheckpointStore
-| *consumerGroupName* (consumer) | Sets the name of the consumer group this consumer is associated with. Events are read in the context of this group. The name of the consumer group that is created by default is {link #DEFAULT_CONSUMER_GROUP_NAME $Default}. | $Default | String
-| *eventPosition* (consumer) | Sets the map containing the event position to use for each partition if a checkpoint for the partition does not exist in CheckpointStore. This map is keyed off of the partition id. If there is no checkpoint in CheckpointStore and there is no entry in this map, the processing of the partition will start from {link EventPosition#latest() latest} position. |  | Map
-| *prefetchCount* (consumer) | Sets the count used by the receiver to control the number of events the Event Hub consumer will actively receive and queue locally without regard to whether a receive operation is currently active. | 500 | int
-| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
-| *partitionId* (producer) | Sets the identifier of the Event Hub partition that the events will be sent to. If the identifier is not specified, the Event Hubs service will be responsible for routing events that are sent to an available partition. |  | String
-| *partitionKey* (producer) | Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to map this key to a specific partition. The selection of a partition is stable for a given partition hashing key. Should any other batches of events be sent using the same exact partition hashing key, the Event Hubs service will route them all to the same partition. This should be specified only when there is a need to group events by partition, but there is fl [...]
-| *producerAsyncClient* (producer) | Sets the EventHubProducerAsyncClient.An asynchronous producer responsible for transmitting EventData to a specific Event Hub, grouped together in batches. Depending on the options specified when creating an \{linkEventDataBatch}, the events may be automatically routed to an available partition or specific to a partition. Use by this component to produce the data in camel producer. |  | EventHubProducerAsyncClient
-| *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which then gets configured on the component. This can be used for automatic configuring JDBC data sources, JMS connection factories, AWS Clients, etc. | true | boolean
-| *connectionString* (security) | Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply the connection string for your eventHub. The connection string for EventHubs already include all the necessary information to connection to your EventHub. To learn on how to generate the connection string, take a look at this documentation: \https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string |  | String
-| *sharedAccessKey* (security) | The generated value for the SharedAccessName |  | String
-| *sharedAccessName* (security) | The name you chose for your EventHubs SAS keys |  | String
-|===
-// component options: END
-
-
-== Authentication Information
-
-To use this component, you have 3 options in order to provide the required Azure authentication information:
-
-- Provide `sharedAccessName` and `sharedAccessKey` for your Azure Event Hubs account. The sharedAccessKey can
-be generated through your Event Hubs Azure portal.
-- Provide `connectionString` string, if you provide the connection string, you don't supply `namespace`, `eventHubName`, `sharedAccessKey` and `sharedAccessName`
-as these data already included in the `connectionString`, therefore is the simplest option to get started. Learn more https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string[here] on how to generate the connection string.
-- Provide a https://docs.microsoft.com/en-us/java/api/com.azure.messaging.eventhubs.eventhubproducerasyncclient?view=azure-java-stable[EventHubProducerAsyncClient] instance which can be
-provided into `producerAsyncClient`. However, this is *only possible for camel producer*, for the camel consumer, is not possible to inject the client due to some design constrain by the `EventProcessorClient`.
-
-
-== Checkpoint Store Information
-A checkpoint store stores and retrieves partition ownership information and checkpoint details for each partition in a given consumer group of an event hub instance. Users are not meant to implement an CheckpointStore.
-Users are expected to choose existing implementations of this interface, instantiate it, and pass it to the component through `checkpointStore` option.
-Users are not expected to use any of the methods on a checkpoint store, these are used internally by the client.
-
-Having said that, if the user does not pass any `CheckpointStore` implementation, the component will fallback to use https://docs.microsoft.com/en-us/javascript/api/@azure/eventhubs-checkpointstore-blob/blobcheckpointstore?view=azure-node-latest[`BlobCheckpointStore`] to store the checkpoint info in Azure Blob Storage account.
-If you chose to use the default `BlobCheckpointStore`, you will need to supply the following options:
-
-- `blobAccountName`: It sets Azure account name to be used for authentication with azure blob services.
-- `blobAccessKey` : It sets access key for the associated azure account name to be used for authentication with azure blob services.
-- `blobContainerName` : It sets the blob container that shall be used by the BlobCheckpointStore to store the checkpoint offsets.
-
-
-== Async Consumer and Producer
-
-This component implements the async Consumer and producer.
-
-This allows camel route to consume and produce events asynchronously without blocking any threads.
-
-
-== Usage
-
-=== Message headers evaluated by the component producer
-[width="100%",cols="10%,10%,10%,70%",options="header",]
-|=======================================================================
-|Header |Variable Name |Type |Description
-
-|`CamelAzureEventHubsPartitionKey`| `EventHubsConstants.PARTITION_KEY`|`String`| Overrides the hashing key to be provided for the batch of events, which instructs the Event Hubs service to map this key to a specific partition.
-|`CamelAzureEventHubsPartitionId`| `EventHubsConstants.PARTITION_ID`|`String`| Overrides the identifier of the Event Hub partition that the {link EventData events} will be sent to.
-|=======================================================================
-
-
-=== Message headers set by the component consumer
-[width="100%",cols="10%,10%,10%,70%",options="header",]
-|=======================================================================
-|Header |Variable Name |Type |Description
-
-|`CamelAzureEventHubsPartitionKey`| `EventHubsConstants.PARTITION_KEY`|`String`| It sets the partition hashing key if it was set when originally publishing the event. If it exists, this value was used to compute a hash to select a partition to send the message to. This is only present on a received {@link EventData}.
-|`CamelAzureEventHubsPartitionId`| `EventHubsConstants.PARTITION_ID`|`String`| It sets the partition id of the Event Hub.
-|`CamelAzureEventHubsOffset`| `EventHubsConstants.OFFSET`|`Long`| It sets the offset of the event when it was received from the associated Event Hub partition. This is only present on a received {@link EventData}.
-|`CamelAzureEventHubsEnqueuedTime`| `EventHubsConstants.ENQUEUED_TIME`|`Instant`| It sets the instant, in UTC, of when the event was enqueued in the Event Hub partition. This is only present on a received {@link EventData}.
-|`CamelAzureEventHubsSequenceNumber`| `EventHubsConstants.SEQUENCE_NUMBER`|`Long`| It sets the sequence number assigned to the event when it was enqueued in the associated Event Hub partition. This is unique for every message received in the Event Hub partition. This is only present on a received {@link EventData}.
-|=======================================================================
-
-=== Message body type
-The component's producer expects the data in the message body to be in `byte[]`. This allows the user to utilize Camel TypeConverter to marshal/unmarshal data with ease.
-The same goes as well for the component's consumer, it will set the encoded data as `byte[]` in the message body.
-
-
-=== Automatic detection of EventHubProducerAsyncClient client in registry
-
-The component is capable of detecting the presence of an EventHubProducerAsyncClient bean into the registry.
-If it's the only instance of that type it will be used as 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.
-
-=== Consumer Example
-The example below will unmarshal the events that was originally produced in JSON:
-```
-from("azure-eventhubs:?connectionString=RAW({{connectionString}})"&blobContainerName=containerTest&eventPosition=#eventPosition"
-    +"&blobAccountName={{blobAccountName}}&blobAccessKey=RAW({{blobAccessKey}})")
-.unmarshal().json(JsonLibrary.Jackson)
-.to(result);
-```
-
-=== Producer Example
-The example below will send events as String to EventHubs:
-```
-from("direct:start")
-.process(exchange -> {
-        exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
-        exchange.getIn().setBody("test event");
-})
-.to("azure-eventhubs:?connectionString=RAW({{connectionString}})"
-```
-
-Also, the component supports as well *aggregation* of messages by sending events as *iterable* of either Exchanges/Messages or normal data (e.g: list of Strings). For example:
-```
-from("direct:start")
-.process(exchange -> {
-        final List<String> messages = new LinkedList<>();
-        messages.add("Test String Message 1");
-        messages.add("Test String Message 2");
-
-        exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
-        exchange.getIn().setBody(messages);
-})
-.to("azure-eventhubs:?connectionString=RAW({{connectionString}})"
-```
-
-=== Development Notes (Important)
-When developing on this component, you will need to obtain your Azure accessKey in order to run the integration tests. 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:
-----
-mvn verify -PfullTests -DconnectionString=string -DblobAccountName=blob -DblobAccessKey=key
-----
-Whereby `blobAccountName` is your Azure account name and `blobAccessKey` is the access key being generated from Azure portal and `connectionString` is the eventHub connection string.
-
-
-include::camel-spring-boot::page$azure-eventhubs-starter.adoc[]
diff --git a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsComponent.java b/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsComponent.java
deleted file mode 100644
index d87ce3a..0000000
--- a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsComponent.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
-import org.apache.camel.Endpoint;
-import org.apache.camel.spi.Metadata;
-import org.apache.camel.spi.annotations.Component;
-import org.apache.camel.support.DefaultComponent;
-import org.apache.camel.util.ObjectHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Azure EventHubs component
- */
-@Component("azure-eventhubs")
-public class EventHubsComponent extends DefaultComponent {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EventHubsComponent.class);
-
-    @Metadata
-    private EventHubsConfiguration configuration = new EventHubsConfiguration();
-
-    public EventHubsComponent() {
-    }
-
-    @Override
-    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
-
-        final EventHubsConfiguration configuration
-                = this.configuration != null ? this.configuration.copy() : new EventHubsConfiguration();
-
-        final EventHubsEndpoint endpoint = new EventHubsEndpoint(uri, this, configuration);
-        setProperties(endpoint, parameters);
-
-        if (configuration.isAutoDiscoverClient()) {
-            checkAndSetRegistryClient(configuration::setProducerAsyncClient, configuration::getProducerAsyncClient,
-                    EventHubProducerAsyncClient.class);
-        }
-
-        // if we don't have client nor connectionString, we check for params
-        if (areAzureClientsNotSet(configuration) && ObjectHelper.isEmpty(configuration.getConnectionString())) {
-            checkAndSetNamespaceAndHubName(configuration, remaining);
-            validateConfigurations(configuration);
-        }
-
-        return endpoint;
-    }
-
-    /**
-     * The component configurations
-     */
-    public EventHubsConfiguration getConfiguration() {
-        return configuration;
-    }
-
-    public void setConfiguration(EventHubsConfiguration configuration) {
-        this.configuration = configuration;
-    }
-
-    private <C> void checkAndSetRegistryClient(
-            final Consumer<C> setClientFn, final Supplier<C> getClientFn, final Class<C> clientType) {
-        if (ObjectHelper.isEmpty(getClientFn.get())) {
-            final Set<C> clients = getCamelContext().getRegistry().findByType(clientType);
-            if (clients.size() == 1) {
-                setClientFn.accept(clients.stream().findFirst().get());
-            } else if (clients.size() > 1) {
-                LOG.info(String.format("More than one %s instance in the registry, make sure to have only one instance",
-                        clientType.getSimpleName()));
-            } else {
-                LOG.info(String.format("No %s instance in the registry", clientType.getSimpleName()));
-            }
-        } else {
-            LOG.info(String.format("%s instance is already set at endpoint level: skipping the check in the registry",
-                    clientType.getSimpleName()));
-        }
-    }
-
-    private void validateConfigurations(final EventHubsConfiguration configuration) {
-        if (!isAccessKeyAndAccessNameSet(configuration)) {
-            throw new IllegalArgumentException(
-                    "Azure EventHubs SharedAccessName/SharedAccessKey, ConsumerAsyncClient/ProducerAsyncClient "
-                                               + "or connectionString must be specified.");
-        }
-    }
-
-    private boolean isAccessKeyAndAccessNameSet(final EventHubsConfiguration configuration) {
-        return ObjectHelper.isNotEmpty(configuration.getSharedAccessName())
-                && ObjectHelper.isNotEmpty(configuration.getSharedAccessKey());
-    }
-
-    private boolean areAzureClientsNotSet(final EventHubsConfiguration configuration) {
-        return ObjectHelper.isEmpty(configuration.getProducerAsyncClient());
-    }
-
-    private void checkAndSetNamespaceAndHubName(final EventHubsConfiguration configuration, final String remaining) {
-        // only set if clients are empty and remaining exists
-        if (ObjectHelper.isEmpty(remaining)) {
-            throw new IllegalArgumentException("ConnectionString, AzureClients or Namespace and EventHub name must be set");
-        }
-
-        final String[] parts = remaining.split("/");
-
-        if (parts.length < 2) {
-            throw new IllegalArgumentException("ConnectionString, AzureClients or Namespace and EventHub name must be set");
-        }
-        configuration.setNamespace(parts[0]);
-        configuration.setEventHubName(parts[1]);
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfiguration.java b/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfiguration.java
deleted file mode 100644
index 526c609..0000000
--- a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfiguration.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.azure.core.amqp.AmqpRetryOptions;
-import com.azure.core.amqp.AmqpTransportType;
-import com.azure.messaging.eventhubs.CheckpointStore;
-import com.azure.messaging.eventhubs.EventData;
-import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
-import com.azure.messaging.eventhubs.EventProcessorClient;
-import com.azure.messaging.eventhubs.models.EventPosition;
-import com.azure.storage.common.StorageSharedKeyCredential;
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.spi.UriParam;
-import org.apache.camel.spi.UriParams;
-import org.apache.camel.spi.UriPath;
-
-@UriParams
-public class EventHubsConfiguration implements Cloneable {
-
-    @UriPath
-    private String namespace;
-    @UriPath
-    private String eventHubName;
-    @UriParam(label = "security")
-    private String sharedAccessName;
-    @UriParam(label = "security", secret = true)
-    private String sharedAccessKey;
-    @UriParam(label = "security", secret = true)
-    private String connectionString;
-    @UriParam(label = "common", defaultValue = "AMQP")
-    private AmqpTransportType amqpTransportType = AmqpTransportType.AMQP;
-    @UriParam(label = "common")
-    private AmqpRetryOptions amqpRetryOptions;
-    @UriParam(label = "common", defaultValue = "true")
-    private boolean autoDiscoverClient = true;
-    @UriParam(label = "consumer", defaultValue = "$Default")
-    private String consumerGroupName = "$Default";
-    @UriParam(label = "consumer", defaultValue = "500")
-    private int prefetchCount = 500;
-    @UriParam(label = "consumer", defaultValue = "BlobCheckpointStore")
-    private CheckpointStore checkpointStore;
-    @UriParam(label = "consumer")
-    private String blobAccountName;
-    @UriParam(label = "consumer", secret = true)
-    private String blobAccessKey;
-    @UriParam(label = "consumer")
-    private String blobContainerName;
-    @UriParam(label = "consumer", secret = true)
-    private StorageSharedKeyCredential blobStorageSharedKeyCredential;
-    @UriParam(label = "consumer")
-    private Map<String, EventPosition> eventPosition = new HashMap<>();
-    @UriParam(label = "producer")
-    private EventHubProducerAsyncClient producerAsyncClient;
-    @UriParam(label = "producer")
-    private String partitionKey;
-    @UriParam(label = "producer")
-    private String partitionId;
-
-    /**
-     * EventHubs namespace created in Azure Portal
-     */
-    public String getNamespace() {
-        return namespace;
-    }
-
-    public void setNamespace(String namespace) {
-        this.namespace = namespace;
-    }
-
-    /**
-     * EventHubs name under a specific namcespace
-     */
-    public String getEventHubName() {
-        return eventHubName;
-    }
-
-    public void setEventHubName(String eventHubName) {
-        this.eventHubName = eventHubName;
-    }
-
-    /**
-     * The name you chose for your EventHubs SAS keys
-     */
-    public String getSharedAccessName() {
-        return sharedAccessName;
-    }
-
-    public void setSharedAccessName(String sharedAccessName) {
-        this.sharedAccessName = sharedAccessName;
-    }
-
-    /**
-     * The generated value for the SharedAccessName
-     */
-    public String getSharedAccessKey() {
-        return sharedAccessKey;
-    }
-
-    public void setSharedAccessKey(String sharedAccessKey) {
-        this.sharedAccessKey = sharedAccessKey;
-    }
-
-    /**
-     * Instead of supplying namespace, sharedAccessKey, sharedAccessName ... etc, you can just supply the connection
-     * string for your eventHub. The connection string for EventHubs already include all the necessary information to
-     * connection to your EventHub. To learn on how to generate the connection string, take a look at this
-     * documentation: https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string
-     */
-    public String getConnectionString() {
-        return connectionString;
-    }
-
-    public void setConnectionString(String connectionString) {
-        this.connectionString = connectionString;
-    }
-
-    /**
-     * Sets the transport type by which all the communication with Azure Event Hubs occurs. Default value is
-     * {@link AmqpTransportType#AMQP}.
-     */
-    public AmqpTransportType getAmqpTransportType() {
-        return amqpTransportType;
-    }
-
-    public void setAmqpTransportType(AmqpTransportType amqpTransportType) {
-        this.amqpTransportType = amqpTransportType;
-    }
-
-    /**
-     * Sets the retry policy for {@link EventHubAsyncClient}. If not specified, the default retry options are used.
-     */
-    public AmqpRetryOptions getAmqpRetryOptions() {
-        return amqpRetryOptions;
-    }
-
-    public void setAmqpRetryOptions(AmqpRetryOptions amqpRetryOptions) {
-        this.amqpRetryOptions = amqpRetryOptions;
-    }
-
-    /**
-     * Sets the name of the consumer group this consumer is associated with. Events are read in the context of this
-     * group. The name of the consumer group that is created by default is {@link #DEFAULT_CONSUMER_GROUP_NAME
-     * "$Default"}.
-     */
-    public String getConsumerGroupName() {
-        return consumerGroupName;
-    }
-
-    public void setConsumerGroupName(String consumerGroupName) {
-        this.consumerGroupName = consumerGroupName;
-    }
-
-    /**
-     * Sets the count used by the receiver to control the number of events the Event Hub consumer will actively receive
-     * and queue locally without regard to whether a receive operation is currently active.
-     */
-    public int getPrefetchCount() {
-        return prefetchCount;
-    }
-
-    public void setPrefetchCount(int prefetchCount) {
-        this.prefetchCount = prefetchCount;
-    }
-
-    /**
-     * Sets the {@link EventHubProducerAsyncClient}.An asynchronous producer responsible for transmitting
-     * {@link EventData} to a specific Event Hub, grouped together in batches. Depending on the
-     * {@link CreateBatchOptions options} specified when creating an {@linkEventDataBatch}, the events may be
-     * automatically routed to an available partition or specific to a partition. Use by this component to produce the
-     * data in camel producer.
-     */
-    public EventHubProducerAsyncClient getProducerAsyncClient() {
-        return producerAsyncClient;
-    }
-
-    public void setProducerAsyncClient(EventHubProducerAsyncClient producerAsyncClient) {
-        this.producerAsyncClient = producerAsyncClient;
-    }
-
-    /**
-     * Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry
-     * automatically otherwise it will skip that checking.
-     */
-    public boolean isAutoDiscoverClient() {
-        return autoDiscoverClient;
-    }
-
-    public void setAutoDiscoverClient(boolean autoDiscoverClient) {
-        this.autoDiscoverClient = autoDiscoverClient;
-    }
-
-    /**
-     * Sets the identifier of the Event Hub partition that the {@link EventData events} will be sent to. If the
-     * identifier is not specified, the Event Hubs service will be responsible for routing events that are sent to an
-     * available partition.
-     */
-    public String getPartitionId() {
-        return partitionId;
-    }
-
-    public void setPartitionId(String partitionId) {
-        this.partitionId = partitionId;
-    }
-
-    /**
-     * Sets a hashing key to be provided for the batch of events, which instructs the Event Hubs service to map this key
-     * to a specific partition.
-     *
-     * The selection of a partition is stable for a given partition hashing key. Should any other batches of events be
-     * sent using the same exact partition hashing key, the Event Hubs service will route them all to the same
-     * partition.
-     *
-     * This should be specified only when there is a need to group events by partition, but there is flexibility into
-     * which partition they are routed. If ensuring that a batch of events is sent only to a specific partition, it is
-     * recommended that the {@link #setPartitionId(String) identifier of the position be specified directly} when
-     * sending the batch.
-     */
-    public String getPartitionKey() {
-        return partitionKey;
-    }
-
-    public void setPartitionKey(String partitionKey) {
-        this.partitionKey = partitionKey;
-    }
-
-    /**
-     * Sets the {@link CheckpointStore} the {@link EventProcessorClient} will use for storing partition ownership and
-     * checkpoint information.
-     *
-     * <p>
-     * Users can, optionally, provide their own implementation of {@link CheckpointStore} which will store ownership and
-     * checkpoint information.
-     * </p>
-     *
-     * By default it set to use {@link com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore} which
-     * stores all checkpoint offsets into Azure Blob Storage
-     */
-    public CheckpointStore getCheckpointStore() {
-        return checkpointStore;
-    }
-
-    public void setCheckpointStore(CheckpointStore checkpointStore) {
-        this.checkpointStore = checkpointStore;
-    }
-
-    /**
-     * In case you chose the default BlobCheckpointStore, this sets Azure account name to be used for authentication
-     * with azure blob services.
-     */
-    public String getBlobAccountName() {
-        return blobAccountName;
-    }
-
-    public void setBlobAccountName(String blobAccountName) {
-        this.blobAccountName = blobAccountName;
-    }
-
-    /**
-     * In case you chose the default BlobCheckpointStore, this sets access key for the associated azure account name to
-     * be used for authentication with azure blob services
-     */
-    public String getBlobAccessKey() {
-        return blobAccessKey;
-    }
-
-    public void setBlobAccessKey(String blobAccessKey) {
-        this.blobAccessKey = blobAccessKey;
-    }
-
-    /**
-     * In case you chose the default BlobCheckpointStore, this sets the blob container that shall be used by the
-     * BlobCheckpointStore to store the checkpoint offsets
-     */
-    public String getBlobContainerName() {
-        return blobContainerName;
-    }
-
-    public void setBlobContainerName(String blobContainerName) {
-        this.blobContainerName = blobContainerName;
-    }
-
-    /**
-     * In case you chose the default BlobCheckpointStore, StorageSharedKeyCredential can be injected to create the azure
-     * client, this holds the important authentication information
-     */
-    public StorageSharedKeyCredential getBlobStorageSharedKeyCredential() {
-        return blobStorageSharedKeyCredential;
-    }
-
-    public void setBlobStorageSharedKeyCredential(StorageSharedKeyCredential blobStorageSharedKeyCredential) {
-        this.blobStorageSharedKeyCredential = blobStorageSharedKeyCredential;
-    }
-
-    /**
-     * Sets the map containing the event position to use for each partition if a checkpoint for the partition does not
-     * exist in {@link CheckpointStore}. This map is keyed off of the partition id. If there is no checkpoint in
-     * {@link CheckpointStore} and there is no entry in this map, the processing of the partition will start from
-     * {@link EventPosition#latest() latest} position.
-     */
-    public Map<String, EventPosition> getEventPosition() {
-        return eventPosition;
-    }
-
-    public void setEventPosition(Map<String, EventPosition> eventPosition) {
-        this.eventPosition = eventPosition;
-    }
-
-    // *************************************************
-    //
-    // *************************************************
-
-    public EventHubsConfiguration copy() {
-        try {
-            return (EventHubsConfiguration) super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new RuntimeCamelException(e);
-        }
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfigurationOptionsProxy.java b/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfigurationOptionsProxy.java
deleted file mode 100644
index 05091b0..0000000
--- a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConfigurationOptionsProxy.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.util.function.Supplier;
-
-import org.apache.camel.Exchange;
-import org.apache.camel.util.ObjectHelper;
-
-/**
- * A proxy class for {@link EventHubsConfiguration} and {@link EventHubsConstants}. Ideally this is responsible to
- * obtain the correct configurations options either from configs or exchange headers
- */
-public class EventHubsConfigurationOptionsProxy {
-
-    private final EventHubsConfiguration configuration;
-
-    public EventHubsConfigurationOptionsProxy(final EventHubsConfiguration configuration) {
-        this.configuration = configuration;
-    }
-
-    private static <T> T getObjectFromHeaders(final Exchange exchange, final String headerName, final Class<T> classType) {
-        return exchange.getIn().getHeader(headerName, classType);
-    }
-
-    public String getPartitionKey(final Exchange exchange) {
-        return getOption(exchange, EventHubsConstants.PARTITION_KEY, configuration::getPartitionKey, String.class);
-    }
-
-    public String getPartitionId(final Exchange exchange) {
-        return getOption(exchange, EventHubsConstants.PARTITION_ID, configuration::getPartitionId, String.class);
-    }
-
-    public EventHubsConfiguration getConfiguration() {
-        return configuration;
-    }
-
-    private <R> R getOption(
-            final Exchange exchange, final String headerName, final Supplier<R> fallbackFn, final Class<R> type) {
-        // we first try to look if our value in exchange otherwise fallback to fallbackFn which could be either a function or constant
-        return ObjectHelper.isEmpty(exchange) || ObjectHelper.isEmpty(getObjectFromHeaders(exchange, headerName, type))
-                ? fallbackFn.get()
-                : getObjectFromHeaders(exchange, headerName, type);
-    }
-
-}
diff --git a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConstants.java b/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConstants.java
deleted file mode 100644
index f0b24ea..0000000
--- a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConstants.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-public final class EventHubsConstants {
-    private static final String HEADER_PREFIX = "CamelAzureEventHubs";
-    // common headers, set by consumer and evaluated by producer
-    public static final String PARTITION_KEY = HEADER_PREFIX + "PartitionKey";
-    public static final String PARTITION_ID = HEADER_PREFIX + "PartitionId";
-    // headers set by the consumer only
-    public static final String OFFSET = HEADER_PREFIX + "Offset";
-    public static final String ENQUEUED_TIME = HEADER_PREFIX + "EnqueuedTime";
-    public static final String SEQUENCE_NUMBER = HEADER_PREFIX + "SequenceNumber";
-
-    private EventHubsConstants() {
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumer.java b/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumer.java
deleted file mode 100644
index 56ccee6..0000000
--- a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumer.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import com.azure.messaging.eventhubs.EventProcessorClient;
-import com.azure.messaging.eventhubs.models.ErrorContext;
-import com.azure.messaging.eventhubs.models.EventContext;
-import org.apache.camel.Exchange;
-import org.apache.camel.ExtendedExchange;
-import org.apache.camel.Message;
-import org.apache.camel.Processor;
-import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
-import org.apache.camel.spi.Synchronization;
-import org.apache.camel.support.DefaultConsumer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EventHubsConsumer extends DefaultConsumer {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EventHubsConsumer.class);
-
-    // we use the EventProcessorClient as recommended by Azure docs to consume from all partitions
-    private EventProcessorClient processorClient;
-
-    public EventHubsConsumer(final EventHubsEndpoint endpoint, final Processor processor) {
-        super(endpoint, processor);
-    }
-
-    @Override
-    protected void doStart() throws Exception {
-        super.doStart();
-
-        // create the client
-        processorClient = EventHubsClientFactory.createEventProcessorClient(getConfiguration(),
-                this::onEventListener, this::onErrorListener);
-
-        // start the client but we will rely on the Azure Client Scheduler for thread management
-        processorClient.start();
-    }
-
-    @Override
-    protected void doStop() throws Exception {
-        if (processorClient != null) {
-            // shutdown the client
-            processorClient.stop();
-        }
-
-        // shutdown camel consumer
-        super.doStop();
-    }
-
-    public EventHubsConfiguration getConfiguration() {
-        return getEndpoint().getConfiguration();
-    }
-
-    @Override
-    public EventHubsEndpoint getEndpoint() {
-        return (EventHubsEndpoint) super.getEndpoint();
-    }
-
-    private Exchange createAzureEventHubExchange(final EventContext eventContext) {
-        final Exchange exchange = createExchange(true);
-        final Message message = exchange.getIn();
-
-        // set body as byte[] and let camel typeConverters do the job to convert
-        message.setBody(eventContext.getEventData().getBody());
-        // set headers
-        message.setHeader(EventHubsConstants.PARTITION_ID, eventContext.getPartitionContext().getPartitionId());
-        message.setHeader(EventHubsConstants.PARTITION_KEY, eventContext.getEventData().getPartitionKey());
-        message.setHeader(EventHubsConstants.OFFSET, eventContext.getEventData().getOffset());
-        message.setHeader(EventHubsConstants.ENQUEUED_TIME, eventContext.getEventData().getEnqueuedTime());
-        message.setHeader(EventHubsConstants.SEQUENCE_NUMBER, eventContext.getEventData().getSequenceNumber());
-
-        return exchange;
-    }
-
-    private Exchange createAzureEventHubExchange(final ErrorContext errorContext) {
-        final Exchange exchange = createExchange(true);
-        final Message message = exchange.getIn();
-
-        // set headers
-        message.setHeader(EventHubsConstants.PARTITION_ID, errorContext.getPartitionContext().getPartitionId());
-
-        // set exception
-        exchange.setException(errorContext.getThrowable());
-
-        return exchange;
-    }
-
-    private void onEventListener(final EventContext eventContext) {
-        final Exchange exchange = createAzureEventHubExchange(eventContext);
-
-        // add exchange callback
-        exchange.adapt(ExtendedExchange.class).addOnCompletion(new Synchronization() {
-            @Override
-            public void onComplete(Exchange exchange) {
-                // we update the consumer offsets
-                processCommit(exchange, eventContext);
-            }
-
-            @Override
-            public void onFailure(Exchange exchange) {
-                // we do nothing here
-                processRollback(exchange);
-            }
-        });
-        // send message to next processor in the route
-        getAsyncProcessor().process(exchange, doneSync -> LOG.trace("Processing exchange [{}] done.", exchange));
-    }
-
-    private void onErrorListener(final ErrorContext errorContext) {
-        final Exchange exchange = createAzureEventHubExchange(errorContext);
-
-        // log exception if an exception occurred and was not handled
-        if (exchange.getException() != null) {
-            getExceptionHandler().handleException("Error processing exchange", exchange,
-                    exchange.getException());
-        }
-    }
-
-    /**
-     * Strategy to commit the offset after message being processed successfully.
-     *
-     * @param exchange the exchange
-     */
-    private void processCommit(final Exchange exchange, final EventContext eventContext) {
-        try {
-            eventContext.updateCheckpoint();
-        } catch (Exception ex) {
-            getExceptionHandler().handleException("Error occurred during updating the checkpoint. This exception is ignored.",
-                    exchange, ex);
-        }
-    }
-
-    /**
-     * Strategy when processing the exchange failed.
-     *
-     * @param exchange the exchange
-     */
-    private void processRollback(Exchange exchange) {
-        final Exception cause = exchange.getException();
-        if (cause != null) {
-            getExceptionHandler().handleException("Error during processing exchange.", exchange, cause);
-        }
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpoint.java b/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpoint.java
deleted file mode 100644
index b9010e8..0000000
--- a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsEndpoint.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import org.apache.camel.Category;
-import org.apache.camel.Component;
-import org.apache.camel.Consumer;
-import org.apache.camel.Processor;
-import org.apache.camel.Producer;
-import org.apache.camel.spi.UriEndpoint;
-import org.apache.camel.spi.UriParam;
-import org.apache.camel.support.DefaultEndpoint;
-
-/**
- * The azure-eventhubs component that integrates Azure Event Hubs using AMQP protocol. Azure EventHubs is a highly
- * scalable publish-subscribe service that can ingest millions of events per second and stream them to multiple
- * consumers.
- */
-@UriEndpoint(firstVersion = "3.5.0", scheme = "azure-eventhubs", title = "Azure Event Hubs",
-             syntax = "azure-eventhubs:namespace/eventHubName", category = {
-                     Category.CLOUD, Category.MESSAGING })
-public class EventHubsEndpoint extends DefaultEndpoint {
-
-    @UriParam
-    private EventHubsConfiguration configuration;
-
-    public EventHubsEndpoint(final String uri, final Component component, final EventHubsConfiguration configuration) {
-        super(uri, component);
-        this.configuration = configuration;
-    }
-
-    @Override
-    public Producer createProducer() throws Exception {
-        return new EventHubsProducer(this);
-    }
-
-    @Override
-    public Consumer createConsumer(Processor processor) throws Exception {
-        final Consumer eventHubConsumer = new EventHubsConsumer(this, processor);
-        configureConsumer(eventHubConsumer);
-
-        return eventHubConsumer;
-    }
-
-    /**
-     * The component configurations
-     */
-    public EventHubsConfiguration getConfiguration() {
-        return configuration;
-    }
-
-    public void setConfiguration(EventHubsConfiguration configuration) {
-        this.configuration = configuration;
-    }
-
-}
diff --git a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsProducer.java b/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsProducer.java
deleted file mode 100644
index 1164156..0000000
--- a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/EventHubsProducer.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
-import org.apache.camel.AsyncCallback;
-import org.apache.camel.Endpoint;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
-import org.apache.camel.component.azure.eventhubs.operations.EventHubsProducerOperations;
-import org.apache.camel.support.DefaultAsyncProducer;
-
-public class EventHubsProducer extends DefaultAsyncProducer {
-
-    private EventHubProducerAsyncClient producerAsyncClient;
-    private EventHubsProducerOperations producerOperations;
-
-    public EventHubsProducer(final Endpoint endpoint) {
-        super(endpoint);
-    }
-
-    @Override
-    protected void doStart() throws Exception {
-        super.doStart();
-
-        // create the client
-        producerAsyncClient = EventHubsClientFactory.createEventHubProducerAsyncClient(getEndpoint().getConfiguration());
-
-        // create our operations
-        producerOperations = new EventHubsProducerOperations(producerAsyncClient, getConfiguration());
-    }
-
-    @Override
-    public boolean process(Exchange exchange, AsyncCallback callback) {
-        try {
-            return producerOperations.sendEvents(exchange, callback);
-        } catch (Exception e) {
-            exchange.setException(e);
-            callback.done(true);
-            return true;
-        }
-
-    }
-
-    @Override
-    protected void doStop() throws Exception {
-        if (producerAsyncClient != null) {
-            // shutdown async client
-            producerAsyncClient.close();
-        }
-
-        super.doStop();
-    }
-
-    @Override
-    public EventHubsEndpoint getEndpoint() {
-        return (EventHubsEndpoint) super.getEndpoint();
-    }
-
-    public EventHubsConfiguration getConfiguration() {
-        return getEndpoint().getConfiguration();
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/client/EventHubsClientFactory.java b/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/client/EventHubsClientFactory.java
deleted file mode 100644
index 89f1c6c..0000000
--- a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/client/EventHubsClientFactory.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs.client;
-
-import java.util.Locale;
-import java.util.function.Consumer;
-
-import com.azure.messaging.eventhubs.CheckpointStore;
-import com.azure.messaging.eventhubs.EventHubClientBuilder;
-import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
-import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
-import com.azure.messaging.eventhubs.EventProcessorClient;
-import com.azure.messaging.eventhubs.EventProcessorClientBuilder;
-import com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore;
-import com.azure.messaging.eventhubs.models.ErrorContext;
-import com.azure.messaging.eventhubs.models.EventContext;
-import com.azure.storage.blob.BlobContainerAsyncClient;
-import com.azure.storage.blob.BlobContainerClientBuilder;
-import com.azure.storage.common.StorageSharedKeyCredential;
-import org.apache.camel.component.azure.eventhubs.EventHubsConfiguration;
-import org.apache.camel.util.ObjectHelper;
-
-public final class EventHubsClientFactory {
-
-    private static final String SERVICE_URI_SEGMENT = "servicebus.windows.net";
-    private static final String BLOB_SERVICE_URI_SEGMENT = ".blob.core.windows.net";
-
-    private EventHubsClientFactory() {
-    }
-
-    public static EventHubProducerAsyncClient createEventHubProducerAsyncClient(final EventHubsConfiguration configuration) {
-        return new EventHubClientBuilder()
-                .connectionString(buildConnectionString(configuration))
-                .transportType(configuration.getAmqpTransportType())
-                .retry(configuration.getAmqpRetryOptions())
-                .buildAsyncProducerClient();
-    }
-
-    public static EventHubConsumerAsyncClient createEventHubConsumerAsyncClient(final EventHubsConfiguration configuration) {
-        return new EventHubClientBuilder()
-                .connectionString(buildConnectionString(configuration))
-                .consumerGroup(configuration.getConsumerGroupName())
-                .prefetchCount(configuration.getPrefetchCount())
-                .transportType(configuration.getAmqpTransportType())
-                .retry(configuration.getAmqpRetryOptions())
-                .buildAsyncConsumerClient();
-    }
-
-    public static EventProcessorClient createEventProcessorClient(
-            final EventHubsConfiguration configuration, final Consumer<EventContext> processEvent,
-            final Consumer<ErrorContext> processError) {
-        return new EventProcessorClientBuilder()
-                .initialPartitionEventPosition(configuration.getEventPosition())
-                .connectionString(buildConnectionString(configuration))
-                .checkpointStore(createCheckpointStore(configuration))
-                .consumerGroup(configuration.getConsumerGroupName())
-                .retry(configuration.getAmqpRetryOptions())
-                .transportType(configuration.getAmqpTransportType())
-                .processError(processError)
-                .processEvent(processEvent)
-                .buildEventProcessorClient();
-
-    }
-
-    // public for testing purposes
-    public static BlobContainerAsyncClient createBlobContainerClient(final EventHubsConfiguration configuration) {
-        return new BlobContainerClientBuilder()
-                .endpoint(buildAzureEndpointUri(configuration))
-                .containerName(configuration.getBlobContainerName())
-                .credential(getCredentialForClient(configuration))
-                .buildAsyncClient();
-    }
-
-    private static CheckpointStore createCheckpointStore(final EventHubsConfiguration configuration) {
-        if (ObjectHelper.isNotEmpty(configuration.getCheckpointStore())) {
-            return configuration.getCheckpointStore();
-        }
-        // so we have no checkpoint store, we fallback to default BlobCheckpointStore
-        // first we check if we have all required params for BlobCheckpointStore
-        if (ObjectHelper.isEmpty(configuration.getBlobContainerName())
-                || !isCredentialsSet(configuration)) {
-            throw new IllegalArgumentException(
-                    "Since there is no provided CheckpointStore, you will need to set blobAccountName, blobAccessName"
-                                               + " or blobContainerName in order to use the default BlobCheckpointStore");
-        }
-
-        // second build the BlobContainerAsyncClient
-        return new BlobCheckpointStore(createBlobContainerClient(configuration));
-    }
-
-    private static boolean isCredentialsSet(final EventHubsConfiguration configuration) {
-        if (ObjectHelper.isNotEmpty(configuration.getBlobStorageSharedKeyCredential())) {
-            return true;
-        }
-
-        return ObjectHelper.isNotEmpty(configuration.getBlobAccessKey())
-                && ObjectHelper.isNotEmpty(configuration.getBlobAccountName());
-    }
-
-    private static String buildConnectionString(final EventHubsConfiguration configuration) {
-        if (ObjectHelper.isNotEmpty(configuration.getConnectionString())) {
-            return configuration.getConnectionString();
-        }
-
-        return String.format(Locale.ROOT, "Endpoint=sb://%s.%s/;SharedAccessKeyName=%s;SharedAccessKey=%s;EntityPath=%s",
-                configuration.getNamespace(), SERVICE_URI_SEGMENT, configuration.getSharedAccessName(),
-                configuration.getSharedAccessKey(),
-                configuration.getEventHubName());
-    }
-
-    private static String buildAzureEndpointUri(final EventHubsConfiguration configuration) {
-        return String.format(Locale.ROOT, "https://%s" + BLOB_SERVICE_URI_SEGMENT, getAccountName(configuration));
-    }
-
-    private static StorageSharedKeyCredential getCredentialForClient(final EventHubsConfiguration configuration) {
-        final StorageSharedKeyCredential storageSharedKeyCredential = configuration.getBlobStorageSharedKeyCredential();
-
-        if (storageSharedKeyCredential != null) {
-            return storageSharedKeyCredential;
-        }
-
-        return new StorageSharedKeyCredential(configuration.getBlobAccountName(), configuration.getBlobAccessKey());
-    }
-
-    private static String getAccountName(final EventHubsConfiguration configuration) {
-        return ObjectHelper.isNotEmpty(configuration.getBlobStorageSharedKeyCredential())
-                ? configuration.getBlobStorageSharedKeyCredential().getAccountName()
-                : configuration.getBlobAccountName();
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperations.java b/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperations.java
deleted file mode 100644
index 4037ba2..0000000
--- a/components/camel-azure-eventhubs/src/main/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperations.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs.operations;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.azure.messaging.eventhubs.EventData;
-import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
-import com.azure.messaging.eventhubs.models.SendOptions;
-import org.apache.camel.AsyncCallback;
-import org.apache.camel.Exchange;
-import org.apache.camel.Message;
-import org.apache.camel.TypeConverter;
-import org.apache.camel.component.azure.eventhubs.EventHubsConfiguration;
-import org.apache.camel.component.azure.eventhubs.EventHubsConfigurationOptionsProxy;
-import org.apache.camel.util.ObjectHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import reactor.core.publisher.Mono;
-
-public class EventHubsProducerOperations {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EventHubsProducerOperations.class);
-
-    private final EventHubProducerAsyncClient producerAsyncClient;
-    private final EventHubsConfigurationOptionsProxy configurationOptionsProxy;
-
-    public EventHubsProducerOperations(final EventHubProducerAsyncClient producerAsyncClient,
-                                       final EventHubsConfiguration configuration) {
-        ObjectHelper.notNull(producerAsyncClient, "client cannot be null");
-
-        this.producerAsyncClient = producerAsyncClient;
-        configurationOptionsProxy = new EventHubsConfigurationOptionsProxy(configuration);
-    }
-
-    public boolean sendEvents(final Exchange exchange, final AsyncCallback callback) {
-        ObjectHelper.notNull(exchange, "exchange cannot be null");
-        ObjectHelper.notNull(callback, "callback cannot be null");
-
-        final SendOptions sendOptions = createSendOptions(configurationOptionsProxy.getPartitionKey(exchange),
-                configurationOptionsProxy.getPartitionId(exchange));
-        final Iterable<EventData> eventData = createEventData(exchange);
-
-        return sendAsyncEvents(eventData, sendOptions, exchange, callback);
-    }
-
-    private boolean sendAsyncEvents(
-            final Iterable<EventData> eventData, final SendOptions sendOptions, final Exchange exchange,
-            final AsyncCallback asyncCallback) {
-        sendAsyncEventsWithSuitableMethod(eventData, sendOptions)
-                .subscribe(unused -> LOG.debug("Processed one event..."), error -> {
-                    // error but we continue
-                    LOG.debug("Error processing async exchange with error:" + error.getMessage());
-                    exchange.setException(error);
-                    asyncCallback.done(false);
-                }, () -> {
-                    // we are done from everything, so mark it as sync done
-                    LOG.debug("All events with exchange have been sent successfully.");
-                    asyncCallback.done(false);
-                });
-
-        return false;
-    }
-
-    private Mono<Void> sendAsyncEventsWithSuitableMethod(final Iterable<EventData> eventData, final SendOptions sendOptions) {
-        if (ObjectHelper.isEmpty(sendOptions)) {
-            return producerAsyncClient.send(eventData);
-        }
-
-        return producerAsyncClient.send(eventData, sendOptions);
-    }
-
-    private SendOptions createSendOptions(final String partitionKey, final String partitionId) {
-        // if both are set, we don't want that
-        if (ObjectHelper.isNotEmpty(partitionKey) && ObjectHelper.isNotEmpty(partitionId)) {
-            throw new IllegalArgumentException("Both partitionKey and partitionId are set. Only one or the other can be set.");
-        }
-        // if both are not set, we return null and let EventHubs handle the partition assigning
-        if (ObjectHelper.isEmpty(partitionKey) && ObjectHelper.isEmpty(partitionId)) {
-            return null;
-        }
-
-        return new SendOptions()
-                .setPartitionId(partitionId)
-                .setPartitionKey(partitionKey);
-    }
-
-    @SuppressWarnings("unchecked")
-    private Iterable<EventData> createEventData(final Exchange exchange) {
-        // check if our exchange is list or contain some values
-        if (exchange.getIn().getBody() instanceof Iterable) {
-            return createEventDataFromIterable((Iterable<Object>) exchange.getIn().getBody(),
-                    exchange.getContext().getTypeConverter());
-        }
-
-        // we have only a single event here
-        return Collections.singletonList(createEventDataFromExchange(exchange));
-    }
-
-    private Iterable<EventData> createEventDataFromIterable(final Iterable<Object> inputData, final TypeConverter converter) {
-        final List<EventData> finalEventData = new LinkedList<>();
-
-        inputData.forEach(data -> {
-            if (data instanceof Exchange) {
-                finalEventData.add(createEventDataFromExchange((Exchange) data));
-            } else if (data instanceof Message) {
-                finalEventData.add(createEventDataFromMessage((Message) data));
-            } else {
-                finalEventData.add(createEventDataFromObject(data, converter));
-            }
-        });
-
-        return finalEventData;
-    }
-
-    private EventData createEventDataFromExchange(final Exchange exchange) {
-        return createEventDataFromMessage(exchange.getIn());
-    }
-
-    private EventData createEventDataFromMessage(final Message message) {
-        return createEventDataFromObject(message.getBody(), message.getExchange().getContext().getTypeConverter());
-    }
-
-    private EventData createEventDataFromObject(final Object inputData, final TypeConverter converter) {
-        final byte[] data = converter.convertTo(byte[].class, inputData);
-
-        if (ObjectHelper.isEmpty(data)) {
-            throw new IllegalArgumentException(
-                    String.format("Cannot convert message body %s to byte[]. You will need "
-                                  + "to make sure the data encoded in byte[] or add a Camel TypeConverter to convert the data to byte[]",
-                            inputData));
-        }
-
-        return new EventData(data);
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentTest.java b/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentTest.java
deleted file mode 100644
index 6ffdbb0..0000000
--- a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsComponentTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
-import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
-import org.apache.camel.ResolveEndpointFailedException;
-import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
-import org.apache.camel.test.junit5.CamelTestSupport;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class EventHubsComponentTest extends CamelTestSupport {
-
-    @Test
-    public void testCreateEndpointWithNoEventHubsNameOrNameSpace() throws Exception {
-        ResolveEndpointFailedException exception = assertThrows(ResolveEndpointFailedException.class,
-                () -> context.getEndpoint("azure-eventhubs:?sharedAccessKey=string&sharedAccessName=name"));
-
-        assertTrue(
-                exception.getMessage().contains("ConnectionString, AzureClients or Namespace and EventHub name must be set"));
-
-        ResolveEndpointFailedException exception2 = assertThrows(ResolveEndpointFailedException.class,
-                () -> context.getEndpoint("azure-eventhubs:name?sharedAccessKey=string&sharedAccessName=name"));
-
-        assertTrue(
-                exception2.getMessage().contains("ConnectionString, AzureClients or Namespace and EventHub name must be set"));
-    }
-
-    @Test
-    public void testCreateEndpointWithNoSuppliedClientsOrKeysOrConnectionString() {
-        final String expectedErrorMessage
-                = "Azure EventHubs SharedAccessName/SharedAccessKey, ConsumerAsyncClient/ProducerAsyncClient "
-                  + "or connectionString must be specified";
-
-        // first case: with no client or key or connectionstring
-        assertTrue(getErrorMessage("azure-eventhubs:name/hubName?").contains(expectedErrorMessage));
-
-        // second case: connectionString set
-        assertNotNull(context.getEndpoint("azure-eventhubs:?connectionString=string"));
-
-        // third case: either access key or access name set
-        assertTrue(getErrorMessage("azure-eventhubs:name/hubName?sharedAccessName=test").contains(expectedErrorMessage));
-        assertTrue(getErrorMessage("azure-eventhubs:name/hubName?sharedAccessKey=test").contains(expectedErrorMessage));
-        assertNotNull(context.getEndpoint("azure-eventhubs:name/hubName?sharedAccessName=test&sharedAccessKey=test"));
-
-        // forth case: with client set
-        final EventHubsConfiguration configuration = new EventHubsConfiguration();
-        configuration.setNamespace("test");
-        configuration.setConsumerGroupName("testGroup");
-        configuration.setSharedAccessKey("dummyKey");
-        configuration.setSharedAccessName("dummyUser");
-
-        final EventHubProducerAsyncClient producerAsyncClient
-                = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
-
-        context.getRegistry().bind("producerClient", producerAsyncClient);
-
-        assertNotNull(context
-                .getEndpoint("azure-eventhubs:name/hubName?autoDiscoverClient=false&producerAsyncClient=#producerClient"));
-    }
-
-    @Test
-    public void testClientAutoDiscovery() {
-        final EventHubsConfiguration configuration = new EventHubsConfiguration();
-        configuration.setNamespace("test");
-        configuration.setConsumerGroupName("testGroup");
-        configuration.setSharedAccessKey("dummyKey");
-        configuration.setSharedAccessName("dummyUser");
-
-        final EventHubConsumerAsyncClient consumerAsyncClient
-                = EventHubsClientFactory.createEventHubConsumerAsyncClient(configuration);
-        final EventHubConsumerAsyncClient consumerAsyncClient2
-                = EventHubsClientFactory.createEventHubConsumerAsyncClient(configuration);
-        final EventHubProducerAsyncClient producerAsyncClient
-                = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
-
-        // we dont allow more than one instance
-        context.getRegistry().bind("consumerClient", consumerAsyncClient);
-        context.getRegistry().bind("consumerClient2", consumerAsyncClient2);
-
-        assertThrows(ResolveEndpointFailedException.class, () -> context.getEndpoint("azure-eventhubs:name/hubName"));
-
-        context.getRegistry().bind("producerClient", producerAsyncClient);
-
-        final EventHubsEndpoint endpoint = (EventHubsEndpoint) context.getEndpoint("azure-eventhubs:name/hubName");
-
-        assertEquals(producerAsyncClient, endpoint.getConfiguration().getProducerAsyncClient());
-    }
-
-    @Test
-    public void testCreateEndpointWithConfig() {
-        final String uri = "azure-eventhubs:namespace/hubName?sharedAccessName=DummyAccessKeyName"
-                           + "&sharedAccessKey=DummyKey"
-                           + "&consumerGroupName=testConsumer&prefetchCount=100";
-
-        final EventHubsEndpoint endpoint = (EventHubsEndpoint) context.getEndpoint(uri);
-
-        assertEquals("namespace", endpoint.getConfiguration().getNamespace());
-        assertEquals("hubName", endpoint.getConfiguration().getEventHubName());
-        assertEquals("testConsumer", endpoint.getConfiguration().getConsumerGroupName());
-        assertEquals("DummyAccessKeyName", endpoint.getConfiguration().getSharedAccessName());
-        assertEquals("DummyKey", endpoint.getConfiguration().getSharedAccessKey());
-        assertEquals(100, endpoint.getConfiguration().getPrefetchCount());
-        assertTrue(endpoint.getConfiguration().isAutoDiscoverClient());
-    }
-
-    private String getErrorMessage(final String uri) {
-        ResolveEndpointFailedException exception
-                = assertThrows(ResolveEndpointFailedException.class, () -> context.getEndpoint(uri));
-        return exception.getMessage();
-    }
-
-}
diff --git a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumerIT.java b/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumerIT.java
deleted file mode 100644
index 88f04cb..0000000
--- a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsConsumerIT.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-
-import com.azure.messaging.eventhubs.EventData;
-import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
-import com.azure.messaging.eventhubs.models.EventPosition;
-import com.azure.messaging.eventhubs.models.SendOptions;
-import com.azure.storage.blob.BlobContainerAsyncClient;
-import org.apache.camel.CamelContext;
-import org.apache.camel.EndpointInject;
-import org.apache.camel.Exchange;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
-import org.apache.camel.component.mock.MockEndpoint;
-import org.apache.camel.test.junit5.CamelTestSupport;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-class EventHubsConsumerIT extends CamelTestSupport {
-
-    @EndpointInject("mock:result")
-    private MockEndpoint result;
-
-    private String containerName;
-    private BlobContainerAsyncClient containerAsyncClient;
-    private EventHubsConfiguration configuration;
-
-    @BeforeAll
-    public void prepare() throws Exception {
-        containerName = RandomStringUtils.randomAlphabetic(5).toLowerCase();
-
-        final Properties properties = TestUtils.loadAzureAccessFromJvmEnv();
-
-        configuration = new EventHubsConfiguration();
-        configuration.setBlobAccessKey(properties.getProperty(TestUtils.BLOB_ACCESS_KEY));
-        configuration.setBlobAccountName(properties.getProperty(TestUtils.BLOB_ACCOUNT_NAME));
-        configuration.setBlobContainerName(containerName);
-        configuration.setConnectionString(properties.getProperty(TestUtils.CONNECTION_STRING));
-
-        containerAsyncClient = EventHubsClientFactory.createBlobContainerClient(configuration);
-
-        // create test container
-        containerAsyncClient.create().block();
-    }
-
-    @Test
-    public void testConsumerEvents() throws InterruptedException {
-        // send test data
-        final EventHubProducerAsyncClient producerAsyncClient
-                = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
-
-        final String messageBody = RandomStringUtils.randomAlphabetic(30);
-        final String messageKey = RandomStringUtils.randomAlphabetic(5);
-
-        producerAsyncClient
-                .send(Collections.singletonList(new EventData(messageBody)), new SendOptions().setPartitionKey(messageKey))
-                .block();
-
-        result.expectedMinimumMessageCount(1);
-        result.setAssertPeriod(20000);
-
-        final List<Exchange> exchanges = result.getExchanges();
-        result.assertIsSatisfied();
-
-        // now we check our messages
-        final Exchange returnedMessage = exchanges.stream()
-                .filter(Objects::nonNull)
-                .filter(exchange -> exchange.getMessage().getHeader(EventHubsConstants.PARTITION_KEY)
-                                    != null
-                        && exchange.getMessage().getHeader(EventHubsConstants.PARTITION_KEY).equals(messageKey))
-                .findFirst()
-                .orElse(null);
-
-        assertNotNull(returnedMessage);
-
-        assertEquals(messageKey, returnedMessage.getMessage().getHeader(EventHubsConstants.PARTITION_KEY));
-
-        assertNotNull(returnedMessage.getMessage().getBody());
-        assertNotNull(returnedMessage.getMessage().getHeader(EventHubsConstants.PARTITION_ID));
-        assertNotNull(returnedMessage.getMessage().getHeader(EventHubsConstants.SEQUENCE_NUMBER));
-        assertNotNull(returnedMessage.getMessage().getHeader(EventHubsConstants.OFFSET));
-        assertNotNull(returnedMessage.getMessage().getHeader(EventHubsConstants.ENQUEUED_TIME));
-    }
-
-    @AfterAll
-    public void tearDown() {
-        // delete testing container
-        containerAsyncClient.delete().block();
-    }
-
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
-            @Override
-            public void configure() throws Exception {
-                from("azure-eventhubs:?"
-                     + "connectionString=RAW({{connectionString}})"
-                     + "&blobContainerName=" + containerName + "&eventPosition=#eventPosition"
-                     + "&blobAccountName={{blobAccountName}}&blobAccessKey=RAW({{blobAccessKey}})")
-                             .to(result);
-
-            }
-        };
-    }
-
-    @Override
-    protected CamelContext createCamelContext() throws Exception {
-        final Map<String, EventPosition> positionMap = new HashMap<>();
-        positionMap.put("0", EventPosition.earliest());
-        positionMap.put("1", EventPosition.earliest());
-
-        CamelContext context = super.createCamelContext();
-        context.getRegistry().bind("eventPosition", positionMap);
-
-        return context;
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsProducerIT.java b/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsProducerIT.java
deleted file mode 100644
index 30e6a32..0000000
--- a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventHubsProducerIT.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.util.Properties;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import com.azure.messaging.eventhubs.EventHubClientBuilder;
-import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
-import com.azure.messaging.eventhubs.models.EventPosition;
-import org.apache.camel.EndpointInject;
-import org.apache.camel.Exchange;
-import org.apache.camel.ProducerTemplate;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
-import org.apache.camel.component.mock.MockEndpoint;
-import org.apache.camel.test.junit5.CamelTestSupport;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-class EventHubsProducerIT extends CamelTestSupport {
-
-    @EndpointInject
-    private ProducerTemplate template;
-
-    @EndpointInject("mock:result")
-    private MockEndpoint result;
-
-    private EventHubConsumerAsyncClient consumerAsyncClient;
-
-    @BeforeAll
-    public void prepare() throws Exception {
-        final Properties properties = TestUtils.loadAzureAccessFromJvmEnv();
-
-        final EventHubsConfiguration configuration = new EventHubsConfiguration();
-        configuration.setConnectionString(properties.getProperty(TestUtils.CONNECTION_STRING));
-        configuration.setConsumerGroupName(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME);
-
-        consumerAsyncClient = EventHubsClientFactory.createEventHubConsumerAsyncClient(configuration);
-    }
-
-    @Test
-    public void testSendEventWithSpecificPartition() throws InterruptedException {
-
-        final String messageBody = RandomStringUtils.randomAlphabetic(30);
-        final String firstPartition = "0";
-
-        final AtomicBoolean eventExists = new AtomicBoolean();
-
-        final CompletableFuture<Exchange> resultAsync = template.asyncSend("direct:sendAsync", exchange -> {
-            exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
-            exchange.getIn().setBody(messageBody);
-        });
-
-        resultAsync.whenComplete((exchange, throwable) -> {
-            // we sent our exchange, let's check it out
-            final Boolean eventFlag = consumerAsyncClient.receiveFromPartition(firstPartition, EventPosition.earliest())
-                    .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
-                            && partitionEvent.getData().getBodyAsString()
-                                    .contains(messageBody))
-                    .block();
-
-            if (eventFlag == null) {
-                eventExists.set(false);
-            }
-
-            eventExists.set(eventFlag);
-        });
-
-        result.expectedMinimumMessageCount(1);
-        result.setAssertPeriod(20000);
-        result.assertIsSatisfied();
-
-        assertTrue(eventExists.get());
-    }
-
-    @Test
-    public void testSendingNonValidData() throws InterruptedException {
-
-        final String messageBody = RandomStringUtils.randomAlphabetic(30);
-        final String firstPartition = "0";
-
-        final AtomicReference<Exchange> resultExchange = new AtomicReference<>();
-
-        final CompletableFuture<Exchange> resultAsync = template.asyncSend("direct:sendAsync", exchange -> {
-            exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
-            exchange.getIn().setHeader(EventHubsConstants.PARTITION_KEY, "testKey");
-            exchange.getIn().setBody(messageBody);
-        });
-
-        resultAsync.whenComplete((exchange, throwable) -> resultExchange.set(exchange));
-
-        result.setAssertPeriod(100);
-        result.assertIsSatisfied();
-
-        assertNotNull(resultExchange.get());
-        assertNotNull(resultExchange.get().getException());
-    }
-
-    @AfterAll
-    public void tearDown() {
-        consumerAsyncClient.close();
-    }
-
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
-            @Override
-            public void configure() throws Exception {
-                from("direct:sendAsync")
-                        .to("azure-eventhubs:?connectionString=RAW({{connectionString}})")
-                        .to(result);
-            }
-        };
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorIT.java b/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorIT.java
deleted file mode 100644
index f0273a0..0000000
--- a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorIT.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
-
-import com.azure.messaging.eventhubs.EventData;
-import com.azure.messaging.eventhubs.EventHubClientBuilder;
-import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
-import com.azure.messaging.eventhubs.EventProcessorClient;
-import com.azure.messaging.eventhubs.models.ErrorContext;
-import com.azure.messaging.eventhubs.models.EventContext;
-import com.azure.messaging.eventhubs.models.EventPosition;
-import com.azure.messaging.eventhubs.models.SendOptions;
-import com.azure.storage.blob.BlobContainerAsyncClient;
-import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.awaitility.Awaitility;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class EventProcessorIT {
-
-    private EventHubsConfiguration configuration;
-    private BlobContainerAsyncClient containerAsyncClient;
-
-    @BeforeAll
-    public void prepare() throws Exception {
-        final Properties properties = TestUtils.loadAzureAccessFromJvmEnv();
-        final String containerName = RandomStringUtils.randomAlphabetic(5).toLowerCase();
-
-        configuration = new EventHubsConfiguration();
-        configuration.setConnectionString(properties.getProperty("connectionString"));
-        configuration.setConsumerGroupName(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME);
-        configuration.setBlobAccessKey(properties.getProperty("blobAccessKey"));
-        configuration.setBlobAccountName(properties.getProperty("blobAccountName"));
-
-        Map<String, EventPosition> positionMap = new HashMap<>();
-        positionMap.put("0", EventPosition.earliest());
-
-        configuration.setEventPosition(positionMap);
-        configuration.setBlobContainerName(containerName);
-
-        containerAsyncClient = EventHubsClientFactory.createBlobContainerClient(configuration);
-
-        // create test container
-        containerAsyncClient.create().block();
-    }
-
-    @Test
-    public void testEventProcessingWithBlobCheckpointStore() {
-        final AtomicBoolean doneAsync = new AtomicBoolean();
-        final EventHubProducerAsyncClient producerAsyncClient
-                = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
-        final Consumer<EventContext> onEvent = eventContext -> {
-            final String body = eventContext.getEventData().getBodyAsString();
-            if (eventContext.getPartitionContext().getPartitionId().equals("0")
-                    && body.contains("Testing Event Consumer With BlobStore")) {
-                assertTrue(true);
-                doneAsync.set(true);
-            }
-        };
-        final Consumer<ErrorContext> onError = errorContext -> {
-        };
-        final EventProcessorClient processorClient
-                = EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError);
-
-        processorClient.start();
-
-        producerAsyncClient.send(Collections.singletonList(new EventData("Testing Event Consumer With BlobStore")),
-                new SendOptions().setPartitionId("0")).block();
-
-        Awaitility.await()
-                .timeout(30, TimeUnit.SECONDS)
-                .untilTrue(doneAsync);
-
-        processorClient.stop();
-        producerAsyncClient.close();
-    }
-
-    @AfterAll
-    public void tearDown() {
-        containerAsyncClient.delete().block();
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorTest.java b/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorTest.java
deleted file mode 100644
index 9b4ba1f..0000000
--- a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/EventProcessorTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.util.function.Consumer;
-
-import com.azure.messaging.eventhubs.models.ErrorContext;
-import com.azure.messaging.eventhubs.models.EventContext;
-import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-public class EventProcessorTest {
-
-    @Test
-    public void testCreateEventProcessorWithNonValidOptions() {
-        final EventHubsConfiguration configuration = new EventHubsConfiguration();
-        final Consumer<EventContext> onEvent = event -> {
-        };
-        final Consumer<ErrorContext> onError = error -> {
-        };
-
-        assertThrows(IllegalArgumentException.class,
-                () -> EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
-
-        configuration.setBlobContainerName("testContainer");
-        assertThrows(IllegalArgumentException.class,
-                () -> EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
-
-        configuration.setBlobAccountName("testAcc");
-        assertThrows(IllegalArgumentException.class,
-                () -> EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
-
-        configuration.setBlobAccessKey("testAccess");
-        assertNotNull(EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
-
-        configuration.setBlobContainerName(null);
-        assertThrows(IllegalArgumentException.class,
-                () -> EventHubsClientFactory.createEventProcessorClient(configuration, onEvent, onError));
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/TestUtils.java b/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/TestUtils.java
deleted file mode 100644
index 0d6f6df..0000000
--- a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/TestUtils.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Objects;
-import java.util.Properties;
-
-public final class TestUtils {
-
-    public static final String CONNECTION_STRING = "connectionString";
-    public static final String BLOB_ACCOUNT_NAME = "blobAccountName";
-    public static final String BLOB_ACCESS_KEY = "blobAccessKey";
-
-    private TestUtils() {
-    }
-
-    public static Properties loadAzurePropertiesFile() throws IOException {
-        final Properties properties = new Properties();
-        final String fileName = "azure_key.properties";
-
-        final InputStream inputStream = Objects.requireNonNull(TestUtils.class.getClassLoader().getResourceAsStream(fileName));
-
-        properties.load(inputStream);
-
-        return properties;
-    }
-
-    public static Properties loadAzureAccessFromJvmEnv() throws Exception {
-        final Properties properties = new Properties();
-        if (System.getProperty(CONNECTION_STRING) == null
-                || System.getProperty(BLOB_ACCOUNT_NAME) == null
-                || System.getProperty(BLOB_ACCESS_KEY) == null) {
-            throw new Exception(
-                    "Make sure to supply azure eventHubs connectionString, e.g:  mvn verify -PfullTests -DconnectionString=string"
-                                + " -DblobAccountName=blob -DblobAccessKey=key");
-        }
-        properties.setProperty(CONNECTION_STRING, System.getProperty(CONNECTION_STRING));
-        properties.setProperty(BLOB_ACCOUNT_NAME, System.getProperty(BLOB_ACCOUNT_NAME));
-        properties.setProperty(BLOB_ACCESS_KEY, System.getProperty(BLOB_ACCESS_KEY));
-
-        return properties;
-    }
-
-}
diff --git a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperationsIT.java b/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperationsIT.java
deleted file mode 100644
index e5d7960..0000000
--- a/components/camel-azure-eventhubs/src/test/java/org/apache/camel/component/azure/eventhubs/operations/EventHubsProducerOperationsIT.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.eventhubs.operations;
-
-import java.time.Duration;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-
-import com.azure.messaging.eventhubs.EventHubClientBuilder;
-import com.azure.messaging.eventhubs.EventHubConsumerAsyncClient;
-import com.azure.messaging.eventhubs.EventHubProducerAsyncClient;
-import com.azure.messaging.eventhubs.models.EventPosition;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.azure.eventhubs.EventHubsConfiguration;
-import org.apache.camel.component.azure.eventhubs.EventHubsConstants;
-import org.apache.camel.component.azure.eventhubs.TestUtils;
-import org.apache.camel.component.azure.eventhubs.client.EventHubsClientFactory;
-import org.apache.camel.support.DefaultExchange;
-import org.apache.camel.test.junit5.CamelTestSupport;
-import org.awaitility.Awaitility;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-class EventHubsProducerOperationsIT extends CamelTestSupport {
-
-    private EventHubsConfiguration configuration;
-    private EventHubProducerAsyncClient producerAsyncClient;
-    private EventHubConsumerAsyncClient consumerAsyncClient;
-
-    @BeforeAll
-    public void prepare() throws Exception {
-        final Properties properties = TestUtils.loadAzureAccessFromJvmEnv();
-
-        configuration = new EventHubsConfiguration();
-        configuration.setConnectionString(properties.getProperty("connectionString"));
-        configuration.setConsumerGroupName(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME);
-
-        producerAsyncClient = EventHubsClientFactory.createEventHubProducerAsyncClient(configuration);
-        consumerAsyncClient = EventHubsClientFactory.createEventHubConsumerAsyncClient(configuration);
-    }
-
-    @Test
-    public void testSendEventWithSpecificPartition() {
-        final EventHubsProducerOperations operations = new EventHubsProducerOperations(producerAsyncClient, configuration);
-        final String firstPartition = producerAsyncClient.getPartitionIds().blockLast();
-        final Exchange exchange = new DefaultExchange(context);
-
-        exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
-        exchange.getIn().setBody("test should be in firstPartition");
-
-        operations.sendEvents(exchange, doneSync -> {
-        });
-
-        Awaitility.await()
-                .atMost(30, TimeUnit.SECONDS)
-                .pollDelay(Duration.ofSeconds(2))
-                .pollInterval(Duration.ofSeconds(2))
-                .until(() -> {
-                    final Boolean eventExists = consumerAsyncClient
-                            .receiveFromPartition(firstPartition, EventPosition.earliest())
-                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
-                                    && partitionEvent.getData().getBodyAsString()
-                                            .contains("test should be in firstPartition"))
-                            .block();
-
-                    if (eventExists == null) {
-                        return false;
-                    }
-
-                    return eventExists;
-                });
-    }
-
-    @Test
-    public void testIterableExchangesSendEventsWithSpecificPartition() {
-        final EventHubsProducerOperations operations = new EventHubsProducerOperations(producerAsyncClient, configuration);
-        final String firstPartition = producerAsyncClient.getPartitionIds().blockLast();
-
-        final Exchange exchange1 = new DefaultExchange(context);
-        final Exchange exchange2 = new DefaultExchange(context);
-
-        exchange1.getIn().setBody("Exchange Message 1");
-        exchange2.getIn().setBody("Exchange Message 2");
-
-        final List<Exchange> exchanges = new LinkedList<>();
-        exchanges.add(exchange1);
-        exchanges.add(exchange2);
-
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(exchanges);
-
-        operations.sendEvents(exchange, doneSync -> {
-        });
-
-        Awaitility.await()
-                .atMost(40, TimeUnit.SECONDS)
-                .pollDelay(Duration.ofSeconds(2))
-                .pollInterval(Duration.ofSeconds(2))
-                .until(() -> {
-                    final Boolean event1Exists = consumerAsyncClient
-                            .receiveFromPartition(firstPartition, EventPosition.earliest())
-                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
-                                    && partitionEvent.getData().getBodyAsString()
-                                            .contains("Exchange Message 1"))
-                            .block();
-
-                    final Boolean event2Exists = consumerAsyncClient
-                            .receiveFromPartition(firstPartition, EventPosition.earliest())
-                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
-                                    && partitionEvent.getData().getBodyAsString()
-                                            .contains("Exchange Message 2"))
-                            .block();
-
-                    if (event1Exists == null || event2Exists == null) {
-                        return false;
-                    }
-
-                    return event1Exists && event2Exists;
-                });
-    }
-
-    @Test
-    public void testIterableStringSendEventsWithSpecificPartition() {
-        final EventHubsProducerOperations operations = new EventHubsProducerOperations(producerAsyncClient, configuration);
-        final String firstPartition = producerAsyncClient.getPartitionIds().blockLast();
-
-        final List<String> messages = new LinkedList<>();
-        messages.add("Test String Message 1");
-        messages.add("Test String Message 2");
-
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(messages);
-
-        operations.sendEvents(exchange, doneSync -> {
-        });
-
-        Awaitility.await()
-                .atMost(40, TimeUnit.SECONDS)
-                .pollDelay(Duration.ofSeconds(2))
-                .pollInterval(Duration.ofSeconds(2))
-                .until(() -> {
-                    final Boolean event1Exists = consumerAsyncClient
-                            .receiveFromPartition(firstPartition, EventPosition.earliest())
-                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
-                                    && partitionEvent.getData().getBodyAsString()
-                                            .contains("Test String Message 1"))
-                            .block();
-
-                    final Boolean event2Exists = consumerAsyncClient
-                            .receiveFromPartition(firstPartition, EventPosition.earliest())
-                            .any(partitionEvent -> partitionEvent.getPartitionContext().getPartitionId().equals(firstPartition)
-                                    && partitionEvent.getData().getBodyAsString()
-                                            .contains("Test String Message 2"))
-                            .block();
-
-                    if (event1Exists == null || event2Exists == null) {
-                        return false;
-                    }
-
-                    return event1Exists && event2Exists;
-                });
-    }
-
-    @AfterAll
-    public void tearDown() {
-        producerAsyncClient.close();
-        consumerAsyncClient.close();
-    }
-}
diff --git a/components/camel-azure-eventhubs/src/test/resources/log4j2.properties b/components/camel-azure-eventhubs/src/test/resources/log4j2.properties
deleted file mode 100644
index 5ec8843..0000000
--- a/components/camel-azure-eventhubs/src/test/resources/log4j2.properties
+++ /dev/null
@@ -1,27 +0,0 @@
-## ---------------------------------------------------------------------------
-## Licensed to the Apache Software Foundation (ASF) under one or more
-## contributor license agreements.  See the NOTICE file distributed with
-## this work for additional information regarding copyright ownership.
-## The ASF licenses this file to You under the Apache License, Version 2.0
-## (the "License"); you may not use this file except in compliance with
-## the License.  You may obtain a copy of the License at
-##
-##      http://www.apache.org/licenses/LICENSE-2.0
-##
-## Unless required by applicable law or agreed to in writing, software
-## distributed under the License is distributed on an "AS IS" BASIS,
-## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-## See the License for the specific language governing permissions and
-## limitations under the License.
-## ---------------------------------------------------------------------------
-appender.file.type = File
-appender.file.name = file
-appender.file.fileName = target/camel-eventhubs-test.log
-appender.file.layout.type = PatternLayout
-appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
-appender.out.type = Console
-appender.out.name = out
-appender.out.layout.type = PatternLayout
-appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
-rootLogger.level = INFO
-rootLogger.appenderRef.file.ref = file
\ No newline at end of file
diff --git a/components/camel-azure-storage-blob/pom.xml b/components/camel-azure-storage-blob/pom.xml
deleted file mode 100644
index 75222ff..0000000
--- a/components/camel-azure-storage-blob/pom.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.camel</groupId>
-        <artifactId>components</artifactId>
-        <version>3.9.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>camel-azure-storage-blob</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Camel :: Azure Storage Blob</name>
-    <description>Camel Azure Blob Storage Service Component</description>
-
-    <properties>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-support</artifactId>
-        </dependency>
-
-        <!-- azure sdk -->
-        <dependency>
-            <groupId>com.azure</groupId>
-            <artifactId>azure-storage-blob</artifactId>
-            <version>${azure-storage-blob-java-sdk12-version}</version>
-        </dependency>
-
-        <!-- extras -->
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-        </dependency>
-
-        <!-- for testing -->
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test-junit5</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-slf4j-impl</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-junit-jupiter</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <version>${commons-lang3-version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.awaitility</groupId>
-            <artifactId>awaitility</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.testcontainers</groupId>
-            <artifactId>junit-jupiter</artifactId>
-            <version>${testcontainers-version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <!-- test infra -->
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test-infra-common</artifactId>
-            <version>${project.version}</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test-infra-azure-common</artifactId>
-            <version>${project.version}</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test-infra-azure-storage-blob</artifactId>
-            <version>${project.version}</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
diff --git a/components/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java b/components/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
deleted file mode 100644
index 7100ed3..0000000
--- a/components/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobComponentConfigurer.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/* Generated by camel build tools - do NOT edit this file! */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.util.Map;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
-import org.apache.camel.spi.PropertyConfigurerGetter;
-import org.apache.camel.spi.ConfigurerStrategy;
-import org.apache.camel.spi.GeneratedPropertyConfigurer;
-import org.apache.camel.util.CaseInsensitiveMap;
-import org.apache.camel.support.component.PropertyConfigurerSupport;
-
-/**
- * Generated by camel build tools - do NOT edit this file!
- */
-@SuppressWarnings("unchecked")
-public class BlobComponentConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
-
-    private org.apache.camel.component.azure.storage.blob.BlobConfiguration getOrCreateConfiguration(BlobComponent target) {
-        if (target.getConfiguration() == null) {
-            target.setConfiguration(new org.apache.camel.component.azure.storage.blob.BlobConfiguration());
-        }
-        return target.getConfiguration();
-    }
-
-    @Override
-    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
-        BlobComponent target = (BlobComponent) obj;
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "accesskey":
-        case "accessKey": getOrCreateConfiguration(target).setAccessKey(property(camelContext, java.lang.String.class, value)); return true;
-        case "autodiscoverclient":
-        case "autoDiscoverClient": getOrCreateConfiguration(target).setAutoDiscoverClient(property(camelContext, boolean.class, value)); return true;
-        case "autowiredenabled":
-        case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true;
-        case "blobname":
-        case "blobName": getOrCreateConfiguration(target).setBlobName(property(camelContext, java.lang.String.class, value)); return true;
-        case "bloboffset":
-        case "blobOffset": getOrCreateConfiguration(target).setBlobOffset(property(camelContext, long.class, value)); return true;
-        case "blobsequencenumber":
-        case "blobSequenceNumber": getOrCreateConfiguration(target).setBlobSequenceNumber(property(camelContext, java.lang.Long.class, value)); return true;
-        case "blobtype":
-        case "blobType": getOrCreateConfiguration(target).setBlobType(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobType.class, value)); return true;
-        case "blocklisttype":
-        case "blockListType": getOrCreateConfiguration(target).setBlockListType(property(camelContext, com.azure.storage.blob.models.BlockListType.class, value)); return true;
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
-        case "closestreamafterread":
-        case "closeStreamAfterRead": getOrCreateConfiguration(target).setCloseStreamAfterRead(property(camelContext, boolean.class, value)); return true;
-        case "closestreamafterwrite":
-        case "closeStreamAfterWrite": getOrCreateConfiguration(target).setCloseStreamAfterWrite(property(camelContext, boolean.class, value)); return true;
-        case "commitblocklistlater":
-        case "commitBlockListLater": getOrCreateConfiguration(target).setCommitBlockListLater(property(camelContext, boolean.class, value)); return true;
-        case "configuration": target.setConfiguration(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobConfiguration.class, value)); return true;
-        case "createappendblob":
-        case "createAppendBlob": getOrCreateConfiguration(target).setCreateAppendBlob(property(camelContext, boolean.class, value)); return true;
-        case "createpageblob":
-        case "createPageBlob": getOrCreateConfiguration(target).setCreatePageBlob(property(camelContext, boolean.class, value)); return true;
-        case "credentials": getOrCreateConfiguration(target).setCredentials(property(camelContext, com.azure.storage.common.StorageSharedKeyCredential.class, value)); return true;
-        case "datacount":
-        case "dataCount": getOrCreateConfiguration(target).setDataCount(property(camelContext, java.lang.Long.class, value)); return true;
-        case "downloadlinkexpiration":
-        case "downloadLinkExpiration": getOrCreateConfiguration(target).setDownloadLinkExpiration(property(camelContext, java.lang.Long.class, value)); return true;
-        case "filedir":
-        case "fileDir": getOrCreateConfiguration(target).setFileDir(property(camelContext, java.lang.String.class, value)); return true;
-        case "lazystartproducer":
-        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
-        case "maxresultsperpage":
-        case "maxResultsPerPage": getOrCreateConfiguration(target).setMaxResultsPerPage(property(camelContext, java.lang.Integer.class, value)); return true;
-        case "maxretryrequests":
-        case "maxRetryRequests": getOrCreateConfiguration(target).setMaxRetryRequests(property(camelContext, int.class, value)); return true;
-        case "operation": getOrCreateConfiguration(target).setOperation(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition.class, value)); return true;
-        case "pageblobsize":
-        case "pageBlobSize": getOrCreateConfiguration(target).setPageBlobSize(property(camelContext, java.lang.Long.class, value)); return true;
-        case "prefix": getOrCreateConfiguration(target).setPrefix(property(camelContext, java.lang.String.class, value)); return true;
-        case "regex": getOrCreateConfiguration(target).setRegex(property(camelContext, java.lang.String.class, value)); return true;
-        case "serviceclient":
-        case "serviceClient": getOrCreateConfiguration(target).setServiceClient(property(camelContext, com.azure.storage.blob.BlobServiceClient.class, value)); return true;
-        case "timeout": getOrCreateConfiguration(target).setTimeout(property(camelContext, java.time.Duration.class, value)); return true;
-        default: return false;
-        }
-    }
-
-    @Override
-    public Class<?> getOptionType(String name, boolean ignoreCase) {
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "accesskey":
-        case "accessKey": return java.lang.String.class;
-        case "autodiscoverclient":
-        case "autoDiscoverClient": return boolean.class;
-        case "autowiredenabled":
-        case "autowiredEnabled": return boolean.class;
-        case "blobname":
-        case "blobName": return java.lang.String.class;
-        case "bloboffset":
-        case "blobOffset": return long.class;
-        case "blobsequencenumber":
-        case "blobSequenceNumber": return java.lang.Long.class;
-        case "blobtype":
-        case "blobType": return org.apache.camel.component.azure.storage.blob.BlobType.class;
-        case "blocklisttype":
-        case "blockListType": return com.azure.storage.blob.models.BlockListType.class;
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": return boolean.class;
-        case "closestreamafterread":
-        case "closeStreamAfterRead": return boolean.class;
-        case "closestreamafterwrite":
-        case "closeStreamAfterWrite": return boolean.class;
-        case "commitblocklistlater":
-        case "commitBlockListLater": return boolean.class;
-        case "configuration": return org.apache.camel.component.azure.storage.blob.BlobConfiguration.class;
-        case "createappendblob":
-        case "createAppendBlob": return boolean.class;
-        case "createpageblob":
-        case "createPageBlob": return boolean.class;
-        case "credentials": return com.azure.storage.common.StorageSharedKeyCredential.class;
-        case "datacount":
-        case "dataCount": return java.lang.Long.class;
-        case "downloadlinkexpiration":
-        case "downloadLinkExpiration": return java.lang.Long.class;
-        case "filedir":
-        case "fileDir": return java.lang.String.class;
-        case "lazystartproducer":
-        case "lazyStartProducer": return boolean.class;
-        case "maxresultsperpage":
-        case "maxResultsPerPage": return java.lang.Integer.class;
-        case "maxretryrequests":
-        case "maxRetryRequests": return int.class;
-        case "operation": return org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition.class;
-        case "pageblobsize":
-        case "pageBlobSize": return java.lang.Long.class;
-        case "prefix": return java.lang.String.class;
-        case "regex": return java.lang.String.class;
-        case "serviceclient":
-        case "serviceClient": return com.azure.storage.blob.BlobServiceClient.class;
-        case "timeout": return java.time.Duration.class;
-        default: return null;
-        }
-    }
-
-    @Override
-    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
-        BlobComponent target = (BlobComponent) obj;
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "accesskey":
-        case "accessKey": return getOrCreateConfiguration(target).getAccessKey();
-        case "autodiscoverclient":
-        case "autoDiscoverClient": return getOrCreateConfiguration(target).isAutoDiscoverClient();
-        case "autowiredenabled":
-        case "autowiredEnabled": return target.isAutowiredEnabled();
-        case "blobname":
-        case "blobName": return getOrCreateConfiguration(target).getBlobName();
-        case "bloboffset":
-        case "blobOffset": return getOrCreateConfiguration(target).getBlobOffset();
-        case "blobsequencenumber":
-        case "blobSequenceNumber": return getOrCreateConfiguration(target).getBlobSequenceNumber();
-        case "blobtype":
-        case "blobType": return getOrCreateConfiguration(target).getBlobType();
-        case "blocklisttype":
-        case "blockListType": return getOrCreateConfiguration(target).getBlockListType();
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
-        case "closestreamafterread":
-        case "closeStreamAfterRead": return getOrCreateConfiguration(target).isCloseStreamAfterRead();
-        case "closestreamafterwrite":
-        case "closeStreamAfterWrite": return getOrCreateConfiguration(target).isCloseStreamAfterWrite();
-        case "commitblocklistlater":
-        case "commitBlockListLater": return getOrCreateConfiguration(target).isCommitBlockListLater();
-        case "configuration": return target.getConfiguration();
-        case "createappendblob":
-        case "createAppendBlob": return getOrCreateConfiguration(target).isCreateAppendBlob();
-        case "createpageblob":
-        case "createPageBlob": return getOrCreateConfiguration(target).isCreatePageBlob();
-        case "credentials": return getOrCreateConfiguration(target).getCredentials();
-        case "datacount":
-        case "dataCount": return getOrCreateConfiguration(target).getDataCount();
-        case "downloadlinkexpiration":
-        case "downloadLinkExpiration": return getOrCreateConfiguration(target).getDownloadLinkExpiration();
-        case "filedir":
-        case "fileDir": return getOrCreateConfiguration(target).getFileDir();
-        case "lazystartproducer":
-        case "lazyStartProducer": return target.isLazyStartProducer();
-        case "maxresultsperpage":
-        case "maxResultsPerPage": return getOrCreateConfiguration(target).getMaxResultsPerPage();
-        case "maxretryrequests":
-        case "maxRetryRequests": return getOrCreateConfiguration(target).getMaxRetryRequests();
-        case "operation": return getOrCreateConfiguration(target).getOperation();
-        case "pageblobsize":
-        case "pageBlobSize": return getOrCreateConfiguration(target).getPageBlobSize();
-        case "prefix": return getOrCreateConfiguration(target).getPrefix();
-        case "regex": return getOrCreateConfiguration(target).getRegex();
-        case "serviceclient":
-        case "serviceClient": return getOrCreateConfiguration(target).getServiceClient();
-        case "timeout": return getOrCreateConfiguration(target).getTimeout();
-        default: return null;
-        }
-    }
-}
-
diff --git a/components/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java b/components/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
deleted file mode 100644
index 78990ee..0000000
--- a/components/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointConfigurer.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/* Generated by camel build tools - do NOT edit this file! */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.util.Map;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
-import org.apache.camel.spi.PropertyConfigurerGetter;
-import org.apache.camel.spi.ConfigurerStrategy;
-import org.apache.camel.spi.GeneratedPropertyConfigurer;
-import org.apache.camel.util.CaseInsensitiveMap;
-import org.apache.camel.support.component.PropertyConfigurerSupport;
-
-/**
- * Generated by camel build tools - do NOT edit this file!
- */
-@SuppressWarnings("unchecked")
-public class BlobEndpointConfigurer extends PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter {
-
-    @Override
-    public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
-        BlobEndpoint target = (BlobEndpoint) obj;
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "accesskey":
-        case "accessKey": target.getConfiguration().setAccessKey(property(camelContext, java.lang.String.class, value)); return true;
-        case "autodiscoverclient":
-        case "autoDiscoverClient": target.getConfiguration().setAutoDiscoverClient(property(camelContext, boolean.class, value)); return true;
-        case "blobname":
-        case "blobName": target.getConfiguration().setBlobName(property(camelContext, java.lang.String.class, value)); return true;
-        case "bloboffset":
-        case "blobOffset": target.getConfiguration().setBlobOffset(property(camelContext, long.class, value)); return true;
-        case "blobsequencenumber":
-        case "blobSequenceNumber": target.getConfiguration().setBlobSequenceNumber(property(camelContext, java.lang.Long.class, value)); return true;
-        case "blobserviceclient":
-        case "blobServiceClient": target.setBlobServiceClient(property(camelContext, com.azure.storage.blob.BlobServiceClient.class, value)); return true;
-        case "blobtype":
-        case "blobType": target.getConfiguration().setBlobType(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobType.class, value)); return true;
-        case "blocklisttype":
-        case "blockListType": target.getConfiguration().setBlockListType(property(camelContext, com.azure.storage.blob.models.BlockListType.class, value)); return true;
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
-        case "closestreamafterread":
-        case "closeStreamAfterRead": target.getConfiguration().setCloseStreamAfterRead(property(camelContext, boolean.class, value)); return true;
-        case "closestreamafterwrite":
-        case "closeStreamAfterWrite": target.getConfiguration().setCloseStreamAfterWrite(property(camelContext, boolean.class, value)); return true;
-        case "commitblocklistlater":
-        case "commitBlockListLater": target.getConfiguration().setCommitBlockListLater(property(camelContext, boolean.class, value)); return true;
-        case "createappendblob":
-        case "createAppendBlob": target.getConfiguration().setCreateAppendBlob(property(camelContext, boolean.class, value)); return true;
-        case "createpageblob":
-        case "createPageBlob": target.getConfiguration().setCreatePageBlob(property(camelContext, boolean.class, value)); return true;
-        case "credentials": target.getConfiguration().setCredentials(property(camelContext, com.azure.storage.common.StorageSharedKeyCredential.class, value)); return true;
-        case "datacount":
-        case "dataCount": target.getConfiguration().setDataCount(property(camelContext, java.lang.Long.class, value)); return true;
-        case "downloadlinkexpiration":
-        case "downloadLinkExpiration": target.getConfiguration().setDownloadLinkExpiration(property(camelContext, java.lang.Long.class, value)); return true;
-        case "exceptionhandler":
-        case "exceptionHandler": target.setExceptionHandler(property(camelContext, org.apache.camel.spi.ExceptionHandler.class, value)); return true;
-        case "exchangepattern":
-        case "exchangePattern": target.setExchangePattern(property(camelContext, org.apache.camel.ExchangePattern.class, value)); return true;
-        case "filedir":
-        case "fileDir": target.getConfiguration().setFileDir(property(camelContext, java.lang.String.class, value)); return true;
-        case "lazystartproducer":
-        case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
-        case "maxresultsperpage":
-        case "maxResultsPerPage": target.getConfiguration().setMaxResultsPerPage(property(camelContext, java.lang.Integer.class, value)); return true;
-        case "maxretryrequests":
-        case "maxRetryRequests": target.getConfiguration().setMaxRetryRequests(property(camelContext, int.class, value)); return true;
-        case "operation": target.getConfiguration().setOperation(property(camelContext, org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition.class, value)); return true;
-        case "pageblobsize":
-        case "pageBlobSize": target.getConfiguration().setPageBlobSize(property(camelContext, java.lang.Long.class, value)); return true;
-        case "prefix": target.getConfiguration().setPrefix(property(camelContext, java.lang.String.class, value)); return true;
-        case "regex": target.getConfiguration().setRegex(property(camelContext, java.lang.String.class, value)); return true;
-        case "serviceclient":
-        case "serviceClient": target.getConfiguration().setServiceClient(property(camelContext, com.azure.storage.blob.BlobServiceClient.class, value)); return true;
-        case "timeout": target.getConfiguration().setTimeout(property(camelContext, java.time.Duration.class, value)); return true;
-        default: return false;
-        }
-    }
-
-    @Override
-    public Class<?> getOptionType(String name, boolean ignoreCase) {
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "accesskey":
-        case "accessKey": return java.lang.String.class;
-        case "autodiscoverclient":
-        case "autoDiscoverClient": return boolean.class;
-        case "blobname":
-        case "blobName": return java.lang.String.class;
-        case "bloboffset":
-        case "blobOffset": return long.class;
-        case "blobsequencenumber":
-        case "blobSequenceNumber": return java.lang.Long.class;
-        case "blobserviceclient":
-        case "blobServiceClient": return com.azure.storage.blob.BlobServiceClient.class;
-        case "blobtype":
-        case "blobType": return org.apache.camel.component.azure.storage.blob.BlobType.class;
-        case "blocklisttype":
-        case "blockListType": return com.azure.storage.blob.models.BlockListType.class;
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": return boolean.class;
-        case "closestreamafterread":
-        case "closeStreamAfterRead": return boolean.class;
-        case "closestreamafterwrite":
-        case "closeStreamAfterWrite": return boolean.class;
-        case "commitblocklistlater":
-        case "commitBlockListLater": return boolean.class;
-        case "createappendblob":
-        case "createAppendBlob": return boolean.class;
-        case "createpageblob":
-        case "createPageBlob": return boolean.class;
-        case "credentials": return com.azure.storage.common.StorageSharedKeyCredential.class;
-        case "datacount":
-        case "dataCount": return java.lang.Long.class;
-        case "downloadlinkexpiration":
-        case "downloadLinkExpiration": return java.lang.Long.class;
-        case "exceptionhandler":
-        case "exceptionHandler": return org.apache.camel.spi.ExceptionHandler.class;
-        case "exchangepattern":
-        case "exchangePattern": return org.apache.camel.ExchangePattern.class;
-        case "filedir":
-        case "fileDir": return java.lang.String.class;
-        case "lazystartproducer":
-        case "lazyStartProducer": return boolean.class;
-        case "maxresultsperpage":
-        case "maxResultsPerPage": return java.lang.Integer.class;
-        case "maxretryrequests":
-        case "maxRetryRequests": return int.class;
-        case "operation": return org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition.class;
-        case "pageblobsize":
-        case "pageBlobSize": return java.lang.Long.class;
-        case "prefix": return java.lang.String.class;
-        case "regex": return java.lang.String.class;
-        case "serviceclient":
-        case "serviceClient": return com.azure.storage.blob.BlobServiceClient.class;
-        case "timeout": return java.time.Duration.class;
-        default: return null;
-        }
-    }
-
-    @Override
-    public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
-        BlobEndpoint target = (BlobEndpoint) obj;
-        switch (ignoreCase ? name.toLowerCase() : name) {
-        case "accesskey":
-        case "accessKey": return target.getConfiguration().getAccessKey();
-        case "autodiscoverclient":
-        case "autoDiscoverClient": return target.getConfiguration().isAutoDiscoverClient();
-        case "blobname":
-        case "blobName": return target.getConfiguration().getBlobName();
-        case "bloboffset":
-        case "blobOffset": return target.getConfiguration().getBlobOffset();
-        case "blobsequencenumber":
-        case "blobSequenceNumber": return target.getConfiguration().getBlobSequenceNumber();
-        case "blobserviceclient":
-        case "blobServiceClient": return target.getBlobServiceClient();
-        case "blobtype":
-        case "blobType": return target.getConfiguration().getBlobType();
-        case "blocklisttype":
-        case "blockListType": return target.getConfiguration().getBlockListType();
-        case "bridgeerrorhandler":
-        case "bridgeErrorHandler": return target.isBridgeErrorHandler();
-        case "closestreamafterread":
-        case "closeStreamAfterRead": return target.getConfiguration().isCloseStreamAfterRead();
-        case "closestreamafterwrite":
-        case "closeStreamAfterWrite": return target.getConfiguration().isCloseStreamAfterWrite();
-        case "commitblocklistlater":
-        case "commitBlockListLater": return target.getConfiguration().isCommitBlockListLater();
-        case "createappendblob":
-        case "createAppendBlob": return target.getConfiguration().isCreateAppendBlob();
-        case "createpageblob":
-        case "createPageBlob": return target.getConfiguration().isCreatePageBlob();
-        case "credentials": return target.getConfiguration().getCredentials();
-        case "datacount":
-        case "dataCount": return target.getConfiguration().getDataCount();
-        case "downloadlinkexpiration":
-        case "downloadLinkExpiration": return target.getConfiguration().getDownloadLinkExpiration();
-        case "exceptionhandler":
-        case "exceptionHandler": return target.getExceptionHandler();
-        case "exchangepattern":
-        case "exchangePattern": return target.getExchangePattern();
-        case "filedir":
-        case "fileDir": return target.getConfiguration().getFileDir();
-        case "lazystartproducer":
-        case "lazyStartProducer": return target.isLazyStartProducer();
-        case "maxresultsperpage":
-        case "maxResultsPerPage": return target.getConfiguration().getMaxResultsPerPage();
-        case "maxretryrequests":
-        case "maxRetryRequests": return target.getConfiguration().getMaxRetryRequests();
-        case "operation": return target.getConfiguration().getOperation();
-        case "pageblobsize":
-        case "pageBlobSize": return target.getConfiguration().getPageBlobSize();
-        case "prefix": return target.getConfiguration().getPrefix();
-        case "regex": return target.getConfiguration().getRegex();
-        case "serviceclient":
-        case "serviceClient": return target.getConfiguration().getServiceClient();
-        case "timeout": return target.getConfiguration().getTimeout();
-        default: return null;
-        }
-    }
-}
-
diff --git a/components/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java b/components/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
deleted file mode 100644
index 3bc4ecc..0000000
--- a/components/camel-azure-storage-blob/src/generated/java/org/apache/camel/component/azure/storage/blob/BlobEndpointUriFactory.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Generated by camel build tools - do NOT edit this file! */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.camel.spi.EndpointUriFactory;
-
-/**
- * Generated by camel build tools - do NOT edit this file!
- */
-public class BlobEndpointUriFactory extends org.apache.camel.support.component.EndpointUriFactorySupport implements EndpointUriFactory {
-
-    private static final String BASE = ":accountName/containerName";
-
-    private static final Set<String> PROPERTY_NAMES;
-    private static final Set<String> SECRET_PROPERTY_NAMES;
-    static {
-        Set<String> props = new HashSet<>(31);
-        props.add("blobName");
-        props.add("accountName");
-        props.add("credentials");
-        props.add("prefix");
-        props.add("createPageBlob");
-        props.add("blobOffset");
-        props.add("timeout");
-        props.add("dataCount");
-        props.add("blobServiceClient");
-        props.add("maxRetryRequests");
-        props.add("bridgeErrorHandler");
-        props.add("containerName");
-        props.add("closeStreamAfterRead");
-        props.add("closeStreamAfterWrite");
-        props.add("autoDiscoverClient");
-        props.add("maxResultsPerPage");
-        props.add("downloadLinkExpiration");
-        props.add("exchangePattern");
-        props.add("blockListType");
-        props.add("createAppendBlob");
-        props.add("regex");
-        props.add("lazyStartProducer");
-        props.add("blobSequenceNumber");
-        props.add("accessKey");
-        props.add("commitBlockListLater");
-        props.add("serviceClient");
-        props.add("fileDir");
-        props.add("blobType");
-        props.add("pageBlobSize");
-        props.add("exceptionHandler");
-        props.add("operation");
-        PROPERTY_NAMES = Collections.unmodifiableSet(props);
-        Set<String> secretProps = new HashSet<>(1);
-        secretProps.add("accessKey");
-        SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps);
-    }
-
-    @Override
-    public boolean isEnabled(String scheme) {
-        return "azure-storage-blob".equals(scheme);
-    }
-
-    @Override
-    public String buildUri(String scheme, Map<String, Object> properties, boolean encode) throws URISyntaxException {
-        String syntax = scheme + BASE;
-        String uri = syntax;
-
-        Map<String, Object> copy = new HashMap<>(properties);
-
-        uri = buildPathParameter(syntax, uri, "accountName", null, false, copy);
-        uri = buildPathParameter(syntax, uri, "containerName", null, false, copy);
-        uri = buildQueryParameters(uri, copy, encode);
-        return uri;
-    }
-
-    @Override
-    public Set<String> propertyNames() {
-        return PROPERTY_NAMES;
-    }
-
-    @Override
-    public Set<String> secretPropertyNames() {
-        return SECRET_PROPERTY_NAMES;
-    }
-
-    @Override
-    public boolean isLenientProperties() {
-        return false;
-    }
-}
-
diff --git a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component.properties b/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component.properties
deleted file mode 100644
index 68ceed4..0000000
--- a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-components=azure-storage-blob
-groupId=org.apache.camel
-artifactId=camel-azure-storage-blob
-version=3.9.0-SNAPSHOT
-projectName=Camel :: Azure Storage Blob
-projectDescription=Camel Azure Blob Storage Service Component
diff --git a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component/azure-storage-blob b/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component/azure-storage-blob
deleted file mode 100644
index cf117de..0000000
--- a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/component/azure-storage-blob
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.component.azure.storage.blob.BlobComponent
diff --git a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-component b/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-component
deleted file mode 100644
index cc4ee61..0000000
--- a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-component
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.component.azure.storage.blob.BlobComponentConfigurer
diff --git a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-endpoint b/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-endpoint
deleted file mode 100644
index e8f26cb..0000000
--- a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/configurer/azure-storage-blob-endpoint
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.component.azure.storage.blob.BlobEndpointConfigurer
diff --git a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-storage-blob-endpoint b/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-storage-blob-endpoint
deleted file mode 100644
index cd307b4..0000000
--- a/components/camel-azure-storage-blob/src/generated/resources/META-INF/services/org/apache/camel/urifactory/azure-storage-blob-endpoint
+++ /dev/null
@@ -1,2 +0,0 @@
-# Generated by camel build tools - do NOT edit this file!
-class=org.apache.camel.component.azure.storage.blob.BlobEndpointUriFactory
diff --git a/components/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json b/components/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
deleted file mode 100644
index 1a50cca..0000000
--- a/components/camel-azure-storage-blob/src/generated/resources/org/apache/camel/component/azure/storage/blob/azure-storage-blob.json
+++ /dev/null
@@ -1,87 +0,0 @@
-{
-  "component": {
-    "kind": "component",
-    "name": "azure-storage-blob",
-    "title": "Azure Storage Blob Service",
-    "description": "Store and retrieve blobs from Azure Storage Blob Service using SDK v12.",
-    "deprecated": false,
-    "firstVersion": "3.3.0",
-    "label": "cloud,file",
-    "javaType": "org.apache.camel.component.azure.storage.blob.BlobComponent",
-    "supportLevel": "Stable",
-    "groupId": "org.apache.camel",
-    "artifactId": "camel-azure-storage-blob",
-    "version": "3.9.0-SNAPSHOT",
-    "scheme": "azure-storage-blob",
-    "extendsScheme": "",
-    "syntax": "azure-storage-blob:accountName\/containerName",
-    "async": false,
-    "api": false,
-    "consumerOnly": false,
-    "producerOnly": false,
-    "lenientProperties": false
-  },
-  "componentProperties": {
-    "autoDiscoverClient": { "kind": "property", "displayName": "Auto Discover Client", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Setting the autoDiscoverClient mechanism, if true, the component will look for a c [...]
-    "blobName": { "kind": "property", "displayName": "Blob Name", "group": "common", "label": "common", "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": "The blob name, to consume specific blob from a container. However on producer, is only required for the operations on [...]
-    "blobOffset": { "kind": "property", "displayName": "Blob Offset", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Set the blob offset for the upload or download operations, default is 0" },
-    "blobType": { "kind": "property", "displayName": "Blob Type", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobType", "enum": [ "blockblob", "appendblob", "pageblob" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "blockblob", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description":  [...]
-    "closeStreamAfterRead": { "kind": "property", "displayName": "Close Stream After Read", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Close the stream after read or keep it open, default is true" },
-    "configuration": { "kind": "property", "displayName": "Configuration", "group": "common", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "deprecated": false, "autowired": false, "secret": false, "description": "The component configurations" },
-    "credentials": { "kind": "property", "displayName": "Credentials", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.common.StorageSharedKeyCredential", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "StorageSharedKeyCredential can be injected to create the azure client, this holds t [...]
-    "dataCount": { "kind": "property", "displayName": "Data Count", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "How many bytes to include in the range. Must be greater than or equal to 0 if specified." },
-    "fileDir": { "kind": "property", "displayName": "File Dir", "group": "common", "label": "common", "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": "The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer" },
-    "maxResultsPerPage": { "kind": "property", "displayName": "Max Results Per Page", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the requ [...]
-    "maxRetryRequests": { "kind": "property", "displayName": "Max Retry Requests", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum number of additional HTTP Get requests that will be made while reading  [...]
-    "prefix": { "kind": "property", "displayName": "Prefix", "group": "common", "label": "common", "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": "Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs." },
-    "regex": { "kind": "property", "displayName": "Regex", "group": "common", "label": "common", "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": "Filters the results to return only blobs whose names match the specified regular expression. May be null to return all if bo [...]
-    "serviceClient": { "kind": "property", "displayName": "Service Client", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.blob.BlobServiceClient", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Client to a storage account. This client does not hold any state about a particular stora [...]
-    "timeout": { "kind": "property", "displayName": "Timeout", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "java.time.Duration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "An optional timeout value beyond which a RuntimeException will be raised." },
-    "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a me [...]
-    "blobSequenceNumber": { "kind": "property", "displayName": "Blob Sequence Number", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "0", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "A user-controlled value that you can use to track requests. The value of [...]
-    "blockListType": { "kind": "property", "displayName": "Block List Type", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "com.azure.storage.blob.models.BlockListType", "enum": [ "committed", "uncommitted", "all" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "COMMITTED", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description":  [...]
-    "closeStreamAfterWrite": { "kind": "property", "displayName": "Close Stream After Write", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Close the stream after write or keep it open, default is true" },
-    "commitBlockListLater": { "kind": "property", "displayName": "Commit Block List Later", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the staged blocks will not be committed directly." },
-    "createAppendBlob": { "kind": "property", "displayName": "Create Append Blob", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the append blocks will be created when committing append blocks." },
-    "createPageBlob": { "kind": "property", "displayName": "Create Page Blob", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the page blob will be created when uploading page blob." },
-    "downloadLinkExpiration": { "kind": "property", "displayName": "Download Link Expiration", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Override the default expiration (millis) of URL download link." },
-    "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during star [...]
-    "operation": { "kind": "property", "displayName": "Operation", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition", "enum": [ "listBlobContainers", "createBlobContainer", "deleteBlobContainer", "listBlobs", "getBlob", "deleteBlob", "downloadBlobToFile", "downloadLink", "uploadBlockBlob", "stageBlockBlobList", "commitBlobBlockList", "getBlobBlockList", "createAppendBlob", "c [...]
-    "pageBlobSize": { "kind": "property", "displayName": "Page Blob Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "512", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum size for the page blob, up to 8 TB. The page blob size must  [...]
-    "autowiredEnabled": { "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which t [...]
-    "accessKey": { "kind": "property", "displayName": "Access Key", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Access key for the associated azure account name to be used for authentication with azure blob services" }
-  },
-  "properties": {
-    "accountName": { "kind": "path", "displayName": "Account Name", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Azure account name to be used for authentication with azure blob services" },
-    "containerName": { "kind": "path", "displayName": "Container 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": "The blob container name" },
-    "autoDiscoverClient": { "kind": "parameter", "displayName": "Auto Discover Client", "group": "common", "label": "common", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Setting the autoDiscoverClient mechanism, if true, the component will look for a  [...]
-    "blobName": { "kind": "parameter", "displayName": "Blob Name", "group": "common", "label": "common", "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": "The blob name, to consume specific blob from a container. However on producer, is only required for the operations o [...]
-    "blobOffset": { "kind": "parameter", "displayName": "Blob Offset", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Set the blob offset for the upload or download operations, default is 0" },
-    "blobServiceClient": { "kind": "parameter", "displayName": "Blob Service Client", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.blob.BlobServiceClient", "deprecated": false, "autowired": false, "secret": false, "description": "Client to a storage account. This client does not hold any state about a particular storage account but is instead a convenient way of sending off appropriate requests to the resource on the service. It may  [...]
-    "blobType": { "kind": "parameter", "displayName": "Blob Type", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobType", "enum": [ "blockblob", "appendblob", "pageblob" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "blockblob", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": [...]
-    "closeStreamAfterRead": { "kind": "parameter", "displayName": "Close Stream After Read", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Close the stream after read or keep it open, default is true" },
-    "credentials": { "kind": "parameter", "displayName": "Credentials", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.common.StorageSharedKeyCredential", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "StorageSharedKeyCredential can be injected to create the azure client, this holds  [...]
-    "dataCount": { "kind": "parameter", "displayName": "Data Count", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "How many bytes to include in the range. Must be greater than or equal to 0 if specified." },
-    "fileDir": { "kind": "parameter", "displayName": "File Dir", "group": "common", "label": "common", "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": "The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer" },
-    "maxResultsPerPage": { "kind": "parameter", "displayName": "Max Results Per Page", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the req [...]
-    "maxRetryRequests": { "kind": "parameter", "displayName": "Max Retry Requests", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum number of additional HTTP Get requests that will be made while reading [...]
-    "prefix": { "kind": "parameter", "displayName": "Prefix", "group": "common", "label": "common", "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": "Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs." },
-    "regex": { "kind": "parameter", "displayName": "Regex", "group": "common", "label": "common", "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": "Filters the results to return only blobs whose names match the specified regular expression. May be null to return all if b [...]
-    "serviceClient": { "kind": "parameter", "displayName": "Service Client", "group": "common", "label": "", "required": false, "type": "object", "javaType": "com.azure.storage.blob.BlobServiceClient", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Client to a storage account. This client does not hold any state about a particular stor [...]
-    "timeout": { "kind": "parameter", "displayName": "Timeout", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "java.time.Duration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "An optional timeout value beyond which a RuntimeException will be raised." },
-    "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a m [...]
-    "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the con [...]
-    "exchangePattern": { "kind": "parameter", "displayName": "Exchange Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", "InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, "description": "Sets the exchange pattern when the consumer creates an exchange." },
-    "blobSequenceNumber": { "kind": "parameter", "displayName": "Blob Sequence Number", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "0", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "A user-controlled value that you can use to track requests. The value o [...]
-    "blockListType": { "kind": "parameter", "displayName": "Block List Type", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "com.azure.storage.blob.models.BlockListType", "enum": [ "committed", "uncommitted", "all" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "COMMITTED", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": [...]
-    "closeStreamAfterWrite": { "kind": "parameter", "displayName": "Close Stream After Write", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Close the stream after write or keep it open, default is true" },
-    "commitBlockListLater": { "kind": "parameter", "displayName": "Commit Block List Later", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the staged blocks will not be committed directly." },
-    "createAppendBlob": { "kind": "parameter", "displayName": "Create Append Blob", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the append blocks will be created when committing append blo [...]
-    "createPageBlob": { "kind": "parameter", "displayName": "Create Page Blob", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "When is set to true, the page blob will be created when uploading page blob." },
-    "downloadLinkExpiration": { "kind": "parameter", "displayName": "Download Link Expiration", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Override the default expiration (millis) of URL download link." },
-    "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during sta [...]
-    "operation": { "kind": "parameter", "displayName": "Operation", "group": "producer", "label": "producer", "required": false, "type": "object", "javaType": "org.apache.camel.component.azure.storage.blob.BlobOperationsDefinition", "enum": [ "listBlobContainers", "createBlobContainer", "deleteBlobContainer", "listBlobs", "getBlob", "deleteBlob", "downloadBlobToFile", "downloadLink", "uploadBlockBlob", "stageBlockBlobList", "commitBlobBlockList", "getBlobBlockList", "createAppendBlob", " [...]
-    "pageBlobSize": { "kind": "parameter", "displayName": "Page Blob Size", "group": "producer", "label": "producer", "required": false, "type": "integer", "javaType": "java.lang.Long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "512", "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Specifies the maximum size for the page blob, up to 8 TB. The page blob size must [...]
-    "accessKey": { "kind": "parameter", "displayName": "Access Key", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": true, "configurationClass": "org.apache.camel.component.azure.storage.blob.BlobConfiguration", "configurationField": "configuration", "description": "Access key for the associated azure account name to be used for authentication with azure blob services" }
-  }
-}
diff --git a/components/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc b/components/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
deleted file mode 100644
index abf081e..0000000
--- a/components/camel-azure-storage-blob/src/main/docs/azure-storage-blob-component.adoc
+++ /dev/null
@@ -1,697 +0,0 @@
-[[azure-storage-blob-component]]
-= Azure Storage Blob Service Component
-:docTitle: Azure Storage Blob Service
-:artifactId: camel-azure-storage-blob
-:description: Store and retrieve blobs from Azure Storage Blob Service using SDK v12.
-:since: 3.3
-:supportLevel: Stable
-:component-header: Both producer and consumer are supported
-include::{cq-version}@camel-quarkus:ROOT:partial$reference/components/azure-storage-blob.adoc[opts=optional]
-//Manually maintained attributes
-:group: Azure
-
-*Since Camel {since}*
-
-*{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 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 case of consumer, accountName, containerName are required. In case of producer, it depends on the operation that 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&...
-
-For example in order to download a blob content from the block blob `hello.txt`
-located on the `container1` in the `camelazure` storage account, use the following snippet:
-
-[source,java]
---------------------------------------------------------------------------------
-from("azure-storage-blob:/camelazure/container1?blobName=hello.txt&accessKey=yourAccessKey").
-to("file://blobdirectory");
---------------------------------------------------------------------------------
-
-
-
-== URI Options
-
-
-// component options: START
-The Azure Storage Blob Service component supports 28 options, which are listed below.
-
-
-
-[width="100%",cols="2,5,^1,2",options="header"]
-|===
-| Name | Description | Default | Type
-| *autoDiscoverClient* (common) | Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry automatically otherwise it will skip that checking. | true | boolean
-| *blobName* (common) | The blob name, to consume specific blob from a container. However on producer, is only required for the operations on the blob level |  | String
-| *blobOffset* (common) | Set the blob offset for the upload or download operations, default is 0 | 0 | long
-| *blobType* (common) | The blob type in order to initiate the appropriate settings for each blob type. There are 3 enums and the value can be one of: blockblob, appendblob, pageblob | blockblob | BlobType
-| *closeStreamAfterRead* (common) | Close the stream after read or keep it open, default is true | true | boolean
-| *configuration* (common) | The component configurations |  | BlobConfiguration
-| *credentials* (common) | StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication information |  | StorageSharedKeyCredential
-| *dataCount* (common) | How many bytes to include in the range. Must be greater than or equal to 0 if specified. |  | Long
-| *fileDir* (common) | The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer |  | String
-| *maxResultsPerPage* (common) | Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not specify maxResultsPerPage or specifies a value greater than 5,000, the server will return up to 5,000 items. |  | Integer
-| *maxRetryRequests* (common) | Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a response body. | 0 | int
-| *prefix* (common) | Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs. |  | String
-| *regex* (common) | Filters the results to return only blobs whose names match the specified regular expression. May be null to return all if both prefix and regex are set, regex takes the priority and prefix is ignored. |  | String
-| *serviceClient* (common) | Client to a storage account. This client does not hold any state about a particular storage account but is instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used to construct URLs to blobs and containers. This client contains operations on a service account. Operations on a container are available on BlobContainerClient through BlobServiceClient#getBlobContainerClient(String), and operations on a blob  [...]
-| *timeout* (common) | An optional timeout value beyond which a RuntimeException will be raised. |  | Duration
-| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
-| *blobSequenceNumber* (producer) | A user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 263 - 1.The default value is 0. | 0 | Long
-| *blockListType* (producer) | Specifies which type of blocks to return. There are 3 enums and the value can be one of: committed, uncommitted, all | COMMITTED | BlockListType
-| *closeStreamAfterWrite* (producer) | Close the stream after write or keep it open, default is true | true | boolean
-| *commitBlockListLater* (producer) | When is set to true, the staged blocks will not be committed directly. | true | boolean
-| *createAppendBlob* (producer) | When is set to true, the append blocks will be created when committing append blocks. | true | boolean
-| *createPageBlob* (producer) | When is set to true, the page blob will be created when uploading page blob. | true | boolean
-| *downloadLinkExpiration* (producer) | Override the default expiration (millis) of URL download link. |  | Long
-| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
-| *operation* (producer) | The blob operation that can be used with this component on the producer. There are 19 enums and the value can be one of: listBlobContainers, createBlobContainer, deleteBlobContainer, listBlobs, getBlob, deleteBlob, downloadBlobToFile, downloadLink, uploadBlockBlob, stageBlockBlobList, commitBlobBlockList, getBlobBlockList, createAppendBlob, commitAppendBlob, createPageBlob, uploadPageBlob, resizePageBlob, clearPageBlob, getPageBlobRanges | listBlobContainers |  [...]
-| *pageBlobSize* (producer) | Specifies the maximum size for the page blob, up to 8 TB. The page blob size must be aligned to a 512-byte boundary. | 512 | Long
-| *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching type, which then gets configured on the component. This can be used for automatic configuring JDBC data sources, JMS connection factories, AWS Clients, etc. | true | boolean
-| *accessKey* (security) | Access key for the associated azure account name to be used for authentication with azure blob services |  | String
-|===
-// component options: END
-
-// endpoint options: START
-The Azure Storage Blob Service endpoint is configured using URI syntax:
-
-----
-azure-storage-blob:accountName/containerName
-----
-
-with the following path and query parameters:
-
-=== Path Parameters (2 parameters):
-
-
-[width="100%",cols="2,5,^1,2",options="header"]
-|===
-| Name | Description | Default | Type
-| *accountName* | Azure account name to be used for authentication with azure blob services |  | String
-| *containerName* | The blob container name |  | String
-|===
-
-
-=== Query Parameters (29 parameters):
-
-
-[width="100%",cols="2,5,^1,2",options="header"]
-|===
-| Name | Description | Default | Type
-| *autoDiscoverClient* (common) | Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry automatically otherwise it will skip that checking. | true | boolean
-| *blobName* (common) | The blob name, to consume specific blob from a container. However on producer, is only required for the operations on the blob level |  | String
-| *blobOffset* (common) | Set the blob offset for the upload or download operations, default is 0 | 0 | long
-| *blobServiceClient* (common) | Client to a storage account. This client does not hold any state about a particular storage account but is instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used to construct URLs to blobs and containers. This client contains operations on a service account. Operations on a container are available on BlobContainerClient through getBlobContainerClient(String), and operations on a blob are available  [...]
-| *blobType* (common) | The blob type in order to initiate the appropriate settings for each blob type. There are 3 enums and the value can be one of: blockblob, appendblob, pageblob | blockblob | BlobType
-| *closeStreamAfterRead* (common) | Close the stream after read or keep it open, default is true | true | boolean
-| *credentials* (common) | StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication information |  | StorageSharedKeyCredential
-| *dataCount* (common) | How many bytes to include in the range. Must be greater than or equal to 0 if specified. |  | Long
-| *fileDir* (common) | The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer |  | String
-| *maxResultsPerPage* (common) | Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not specify maxResultsPerPage or specifies a value greater than 5,000, the server will return up to 5,000 items. |  | Integer
-| *maxRetryRequests* (common) | Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a response body. | 0 | int
-| *prefix* (common) | Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs. |  | String
-| *regex* (common) | Filters the results to return only blobs whose names match the specified regular expression. May be null to return all if both prefix and regex are set, regex takes the priority and prefix is ignored. |  | String
-| *serviceClient* (common) | Client to a storage account. This client does not hold any state about a particular storage account but is instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used to construct URLs to blobs and containers. This client contains operations on a service account. Operations on a container are available on BlobContainerClient through BlobServiceClient#getBlobContainerClient(String), and operations on a blob  [...]
-| *timeout* (common) | An optional timeout value beyond which a RuntimeException will be raised. |  | Duration
-| *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
-| *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
-| *exchangePattern* (consumer) | Sets the exchange pattern when the consumer creates an exchange. There are 3 enums and the value can be one of: InOnly, InOut, InOptionalOut |  | ExchangePattern
-| *blobSequenceNumber* (producer) | A user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 263 - 1.The default value is 0. | 0 | Long
-| *blockListType* (producer) | Specifies which type of blocks to return. There are 3 enums and the value can be one of: committed, uncommitted, all | COMMITTED | BlockListType
-| *closeStreamAfterWrite* (producer) | Close the stream after write or keep it open, default is true | true | boolean
-| *commitBlockListLater* (producer) | When is set to true, the staged blocks will not be committed directly. | true | boolean
-| *createAppendBlob* (producer) | When is set to true, the append blocks will be created when committing append blocks. | true | boolean
-| *createPageBlob* (producer) | When is set to true, the page blob will be created when uploading page blob. | true | boolean
-| *downloadLinkExpiration* (producer) | Override the default expiration (millis) of URL download link. |  | Long
-| *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
-| *operation* (producer) | The blob operation that can be used with this component on the producer. There are 19 enums and the value can be one of: listBlobContainers, createBlobContainer, deleteBlobContainer, listBlobs, getBlob, deleteBlob, downloadBlobToFile, downloadLink, uploadBlockBlob, stageBlockBlobList, commitBlobBlockList, getBlobBlockList, createAppendBlob, commitAppendBlob, createPageBlob, uploadPageBlob, resizePageBlob, clearPageBlob, getPageBlobRanges | listBlobContainers |  [...]
-| *pageBlobSize* (producer) | Specifies the maximum size for the page blob, up to 8 TB. The page blob size must be aligned to a 512-byte boundary. | 512 | Long
-| *accessKey* (security) | Access key for the associated azure account name to be used for authentication with azure blob services |  | String
-|===
-// endpoint options: END
-
-*Required information options:*
-
-To use this component, you have 3 options in order to provide the required Azure authentication information:
-
-- Provide `accountName` and `accessKey` for your Azure account, this is the simplest way to get started. The accessKey can
-be generated through your Azure portal.
-- Provide a https://azuresdkartifacts.blob.core.windows.net/azure-sdk-for-java/staging/apidocs/com/azure/storage/common/StorageSharedKeyCredential.html[StorageSharedKeyCredential] instance which can be
-provided into `credentials` option.
-- Provide a 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
-provided 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.
-
-
-== Batch Consumer
-
-This component implements the Batch Consumer.
-
-This allows you for instance to know how many messages exists in this
-batch and for instance let the Aggregator
-aggregate this number of messages.
-
-
-== Usage
-
-=== Message headers evaluated by the component producer
-[width="100%",cols="10%,10%,10%,10%,60%",options="header",]
-|=======================================================================
-|Header |Variable Name |Type |Operations |Description
-
-|`CamelAzureStorageBlobTimeout` |`BlobConstants.TIMEOUT`|`Duration`|All|An optional timeout value beyond which a {@link RuntimeException} will be raised.
-|`CamelAzureStorageBlobMetadata`|`BlobConstants.METADATA`|`Map<String,String>`|Operations related to container and blob| Metadata to associate with the container or blob.
-|`CamelAzureStorageBlobPublicAccessType`|`BlobConstants.PUBLIC_ACCESS_TYPE`|`PublicAccessType`|`createContainer`|Specifies how the data in this container is available to the public. Pass `null` for no public access.
-|`CamelAzureStorageBlobRequestCondition`|`BlobConstants.BLOB_REQUEST_CONDITION`|`BlobRequestConditions`|Operations related to container and blob|This contains values which will restrict the successful operation of a variety of requests to the conditions present. These conditions are entirely optional.
-|`CamelAzureStorageBlobListDetails`|`BlobConstants.BLOB_LIST_DETAILS`|`BlobListDetails`|`listBlobs`|The details for listing specific blobs
-|`CamelAzureStorageBlobPrefix`|`BlobConstants.PREFIX`|`String`|`listBlobs`,`getBlob`|Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all blobs.
-|`CamelAzureStorageBlobMaxResultsPerPage`|`BlobConstants.MAX_RESULTS_PER_PAGE`|`Integer`|`listBlobs`| Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not specify maxResultsPerPage or specifies a value greater than 5,000, the server will return up to 5,000 items.
-|`CamelAzureStorageBlobListBlobOptions`|`BlobConstants.LIST_BLOB_OPTIONS`|`ListBlobsOptions`|`listBlobs`|Defines options available to configure the behavior of a call to listBlobsFlatSegment on a {@link BlobContainerClient} object.
-|`CamelAzureStorageBlobHttpHeaders`|`BlobConstants.BLOB_HTTP_HEADERS`|`BlobHttpHeaders`|`uploadBlockBlob`, `commitBlobBlockList`, `createAppendBlob`, `createPageBlob`|  Additional parameters for a set of operations.
-|`CamelAzureStorageBlobAccessTier`|`BlobConstants.ACCESS_TIER`|`AccessTier`|`uploadBlockBlob`, `commitBlobBlockList`| Defines values for AccessTier.
-|`CamelAzureStorageBlobContentMD5`|`BlobConstants.CONTENT_MD5`|`byte[]`|Most operations related to upload blob|An MD5 hash of the block content. This hash is used to verify the integrity of the block during transport. When this header is specified, the storage service compares the hash of the content that has arrived with this header value. Note that this MD5 hash is not stored with the blob. If the two hashes do not match, the operation will fail.
-|`CamelAzureStorageBlobPageBlobRange`|`BlobConstants.PAGE_BLOB_RANGE`|`PageRange`|Operations related to page blob| A {@link PageRange} object. Given that pages must be aligned with 512-byte boundaries, the start offset must be a modulus of 512 and the end offset must be a modulus of 512 - 1. Examples of valid byte ranges are 0-511, 512-1023, etc.
-|`CamelAzureStorageBlobCommitBlobBlockListLater`|`BlobConstants.COMMIT_BLOCK_LIST_LATER`|`boolean`|`stageBlockBlobList`| When is set to `true`, the staged blocks will not be committed directly.
-|`CamelAzureStorageBlobCreateAppendBlob`|`BlobConstants.CREATE_APPEND_BLOB`|`boolean`|`commitAppendBlob`| When is set to `true`, the append blocks will be created when committing append blocks.
-|`CamelAzureStorageBlobCreatePageBlob`|`BlobConstants.CREATE_PAGE_BLOB`|`boolean`|`uploadPageBlob`| When is set to `true`, the page blob will be created when uploading page blob.
-|`CamelAzureStorageBlobBlockListType`|`BlobConstants.BLOCK_LIST_TYPE`|`BlockListType`|`getBlobBlockList`| Specifies which type of blocks to return.
-|`CamelAzureStorageBlobPageBlobSize`|`BlobConstants.PAGE_BLOB_SIZE`|`Long`|`createPageBlob`, `resizePageBlob`| Specifies the maximum size for the page blob, up to 8 TB. The page blob size must be aligned to a 512-byte boundary.
-|`CamelAzureStorageBlobSequenceNumber`|`BlobConstants.BLOB_SEQUENCE_NUMBER`|`Long`|`createPageBlob`|A user-controlled value that you can use to track requests. The value of the sequence number must be between 0 and 2^63 - 1.The default value is 0.
-|`CamelAzureStorageBlobDeleteSnapshotsOptionType`|`BlobConstants.DELETE_SNAPSHOT_OPTION_TYPE`|`DeleteSnapshotsOptionType`|`deleteBlob`| Specifies the behavior for deleting the snapshots on this blob. {@code Include} will delete the base blob and all snapshots. {@code Only} will delete only the snapshots. If a snapshot is being deleted, you must pass null.
-|`CamelAzureStorageBlobListBlobContainersOptions`|`BlobConstants.LIST_BLOB_CONTAINERS_OPTIONS`|`ListBlobContainersOptions`|`listBlobContainers`| A {@link ListBlobContainersOptions} which specifies what data should be returned by the service.
-|`CamelAzureStorageBlobParallelTransferOptions`|`BlobConstants.PARALLEL_TRANSFER_OPTIONS`|`ParallelTransferOptions`|`downloadBlobToFile`| {@link ParallelTransferOptions} to use to download to file. Number of parallel transfers parameter is ignored.
-|`CamelAzureStorageBlobFileDir`|`BlobConstants.FILE_DIR`|`String`|`downloadBlobToFile`|The file directory where the downloaded blobs will be saved to.
-|`CamelAzureStorageBlobDownloadLinkExpiration`|`BlobConstants.DOWNLOAD_LINK_EXPIRATION`|`Long`|`downloadLink`| Override the default expiration (millis) of URL download link.
-|`CamelAzureStorageBlobBlobName`|`BlobConstants.BLOB_NAME`|`String`|Operations related to blob| Override/set the blob name on the exchange headers.
-|`CamelAzureStorageBlobContainerName`|`BlobConstants.BLOB_CONTAINER_NAME`|`String`|Operations related to container and blob|Override/set the container name on the exchange headers.
-|`CamelAzureStorageBlobOperation`|`BlobConstants.BLOB_OPERATION`|`BlobOperationsDefinition`|All|Specify the producer operation to execute, please see the doc on this page related to producer operation.
-|`CamelAzureStorageBlobRegex`|`BlobConstants.REGEX`|`String`|`listBlobs`,`getBlob`|Filters the results to return only blobs whose names match the specified regular expression. May be null to return all. If both prefix and regex are set, regex takes the priority and prefix is ignored.
-|=======================================================================
-
-=== Message headers set by either component producer or consumer
-[width="100%",cols="10%,10%,10%,70%",options="header",]
-|=======================================================================
-|Header |Variable Name |Type |Description
-
-|`CamelAzureStorageBlobAccessTier`|`BlobConstants.ACCESS_TIER`|`AccessTier`| Access tier of the blob.
-|`CamelAzureStorageBlobAccessTierChangeTime`|`BlobConstants.ACCESS_TIER_CHANGE_TIME`|`OffsetDateTime`| Datetime when the access tier of the blob last changed.
-|`CamelAzureStorageBlobArchiveStatus`|`BlobConstants.ARCHIVE_STATUS`|`ArchiveStatus`|Archive status of the blob.
-|`CamelAzureStorageBlobCreationTime`|`BlobConstants.CREATION_TIME`|`OffsetDateTime`|Creation time of the blob.
-|`CamelAzureStorageBlobSequenceNumber`|`BlobConstants.BLOB_SEQUENCE_NUMBER`|`Long`|The current sequence number for a page blob.
-|`CamelAzureStorageBlobBlobSize`|`BlobConstants.BLOB_SIZE`|`long`|The size of the blob.
-|`CamelAzureStorageBlobBlobType`|`BlobConstants.BLOB_TYPE`|`BlobType`|The type of the blob.
-|`CamelAzureStorageBlobCacheControl`|`BlobConstants.CACHE_CONTROL`|`String`|Cache control specified for the blob.
-|`CamelAzureStorageBlobCommittedBlockCount`|`BlobConstants.COMMITTED_BLOCK_COUNT`|`Integer`|  Number of blocks committed to an append blob
-|`CamelAzureStorageBlobContentDisposition`|`BlobConstants.CONTENT_DISPOSITION`|`String`|Content disposition specified for the blob.
-|`CamelAzureStorageBlobContentEncoding`|`BlobConstants.CONTENT_ENCODING`|`String`|Content encoding specified for the blob.
-|`CamelAzureStorageBlobContentLanguage`|`BlobConstants.CONTENT_LANGUAGE`|`String`|Content language specified for the blob.
-|`CamelAzureStorageBlobContentMd5`|`BlobConstants.CONTENT_MD5`|`byte[]`|Content MD5 specified for the blob.
-|`CamelAzureStorageBlobContentType`|`BlobConstants.CONTENT_TYPE`|`String`|Content type specified for the blob.
-|`CamelAzureStorageBlobCopyCompletionTime`|`BlobConstants.COPY_COMPILATION_TIME`|`OffsetDateTime`|Datetime when the last copy operation on the blob completed.
-|`CamelAzureStorageBlobCopyDestinationSnapshot`|`BlobConstants.COPY_DESTINATION_SNAPSHOT`|`String`|Snapshot identifier of the last incremental copy snapshot for the blob.
-|`CamelAzureStorageBlobCopyId`|`BlobConstants.COPY_ID`|`String`|Identifier of the last copy operation performed on the blob.
-|`CamelAzureStorageBlobCopyProgress`|`BlobConstants.COPY_PROGRESS`|`String`|Progress of the last copy operation performed on the blob.
-|`CamelAzureStorageBlobCopySource`|`BlobConstants.COPY_SOURCE`|`String`|Source of the last copy operation performed on the blob.
-|`CamelAzureStorageBlobCopyStatus`|`BlobConstants.COPY_STATUS`|`CopyStatusType`|Status of the last copy operation performed on the blob.
-|`CamelAzureStorageBlobCopyStatusDescription` | `BlobConstants.COPY_STATUS_DESCRIPTION`|`String`|Description of the last copy operation on the blob.
-|`CamelAzureStorageBlobETag`|`BlobConstants.E_TAG`|`String`| The E Tag of the blob
-|`CamelAzureStorageBlobIsAccessTierInferred`|`BlobConstants.IS_ACCESS_TIER_INFRRRED`|`boolean`| Flag indicating if the access tier of the blob was inferred from properties of the blob.
-|`CamelAzureStorageBlobIsIncrementalCopy`|`BlobConstants.IS_INCREMENTAL_COPY`|`boolean`|Flag indicating if the blob was incrementally copied.
-|`CamelAzureStorageBlobIsServerEncrypted`|`BlobConstants.IS_SERVER_ENCRYPTED`|`boolean`|Flag indicating if the blob's content is encrypted on the server.
-|`CamelAzureStorageBlobLastModified`|`BlobConstants.LAST_MODIFIED`|`OffsetDateTime`|Datetime when the blob was last modified.
-|`CamelAzureStorageBlobLeaseDuration`|`BlobConstants.LEASE_DURATION`|`LeaseDurationType`|Type of lease on the blob.
-|`CamelAzureStorageBlobLeaseState`|`BlobConstants.LEASE_STATE`|`LeaseStateType`|State of the lease on the blob.
-|`CamelAzureStorageBlobLeaseStatus`|`BlobConstants.LEASE_STATUS`|`LeaseStatusType`|Status of the lease on the blob.
-|`CamelAzureStorageBlobMetadata`|`BlobConstants.METADATA`|`Map<String, String>`| Additional metadata associated with the blob.
-|`CamelAzureStorageBlobAppendOffset`|`BlobConstants.APPEND_OFFSET`|`String`| The offset at which the block was committed to the block blob.
-|`CamelAzureStorageBlobFileName`|`BlobConstants.FILE_NAME`|`String`|The downloaded filename from the operation `downloadBlobToFile`.
-|`CamelAzureStorageBlobDownloadLink`|`BlobConstants.DOWNLOAD_LINK`|`String`|The download link generated by `downloadLink` operation.
-|`CamelAzureStorageBlobRawHttpHeaders`|`BlobConstants.RAW_HTTP_HEADERS`|`HttpHeaders`|Returns non-parsed httpHeaders that can be used by the user.
-|=======================================================================
-
-=== 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:
-[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:
-
-[source,java]
------------------------------------------------------------------------
-from("azure-storage-blob://cameldev/container1?blobName=myblob&serviceClient=#client")
-.to("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 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 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.
-|===
-
-*Operations on the container level*
-
-For these operations, `accountName` and `containerName` are *required*.
-[width="100%",cols="10%,90%",options="header",]
-|===
-|Operation |Description
-|`createBlobContainer` | Creates a new container within a storage account. If a container with the same name already exists, the producer will ignore it.
-|`deleteBlobContainer` | Deletes 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.
-|===
-
-*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|Downloads 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 {@link FileAlreadyExistsException} will be thrown.
-|`downloadLink`  |Common| Generates the download link for the specified blob using shared access signatures (SAS). This by default only limit 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.
-|`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`|Writes a blob by specifying the list of block IDs that are to make up the blob. In order 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 block list 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 data to a page blob.
-|`uploadPageBlob`|`PageBlob`|Writes one or more pages to the page blob. The write 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`| Frees 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.
-|===
-
-Refer to the example section in this page to learn how to use these operations into your camel application.
-
-=== Consumer Examples
-To consume a blob into a file using file component, this can be done like this:
-[source,java]
---------------------------------------------------------------------------------
-from("azure-storage-blob:/camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey").
-to("file://blobdirectory");
---------------------------------------------------------------------------------
-
-However, you can also write to file directly without using the file component, you will need to specify `fileDir` folder path in order to save your blob in your machine.
-[source,java]
---------------------------------------------------------------------------------
-from("azure-storage-blob:/camelazure/container1?blobName=hello.txt&accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir").
-to("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:
-[source,java]
---------------------------------------------------------------------------------
-from("azure-storage-blob:/camelazure/container1?accountName=yourAccountName&accessKey=yourAccessKey&fileDir=/var/to/awesome/dir").
-to("mock:results");
---------------------------------------------------------------------------------
-
-
-
-=== Producer Operations Examples
-- `listBlobContainers`:
-
-[source,java]
---------------------------------------------------------------------------------
-from("direct:start")
-  .process(exchange -> {
-    // set the header you want the producer to evaluate, refer to the previous
-    // section to learn about the headers that can be set
-    // e.g:
-    exchange.getIn().setHeader(BlobConstants.LIST_BLOB_CONTAINERS_OPTIONS, new ListBlobContainersOptions().setMaxResultsPerPage(10));
-  })
-  .to("azure-storage-blob:/camelazure?operation=listBlobContainers&client&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `createBlobContainer`:
-
-[source,java]
---------------------------------------------------------------------------------
-from("direct:start")
-  .process(exchange -> {
-    // set the header you want the producer to evaluate, refer to the previous
-    // section to learn about the headers that can be set
-    // e.g:
-    exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "newContainerName");
-  })
-  .to("azure-storage-blob:/camelazure/container1?operation=createBlobContainer&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `deleteBlobContainer`:
-
-[source,java]
---------------------------------------------------------------------------------
-from("direct:start")
-  .process(exchange -> {
-    // set the header you want the producer to evaluate, refer to the previous
-    // section to learn about the headers that can be set
-    // e.g:
-    exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "overridenName");
-  })
-  .to("azure-storage-blob:/camelazure/container1?operation=deleteBlobContainer&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `listBlobs`:
-
-[source,java]
---------------------------------------------------------------------------------
-from("direct:start")
-  .process(exchange -> {
-    // set the header you want the producer to evaluate, refer to the previous
-    // section to learn about the headers that can be set
-    // e.g:
-    exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "overridenName");
-  })
-  .to("azure-storage-blob:/camelazure/container1?operation=listBlobs&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-
-- `getBlob`:
-
-We can either set an `outputStream` in the exchange body and write the data to it. E.g:
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-    // set the header you want the producer to evaluate, refer to the previous
-    // section to learn about the headers that can be set
-    // e.g:
-    exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, "overridenName");
-
-    // set our body
-    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 proceeded further downstream:
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=getBlob&serviceClient=#client")
-  .process(exchange -> {
-      InputStream inputStream = exchange.getMessage().getBody(InputStream.class);
-      // We use Apache common IO for simplicity, but you are free to do whatever dealing
-      // with inputStream
-      System.out.println(IOUtils.toString(inputStream, StandardCharsets.UTF_8.name()));
-  })
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `deleteBlob`:
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-    // set the header you want the producer to evaluate, refer to the previous
-    // section to learn about the headers that can be set
-    // e.g:
-    exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "overridenName");
-  })
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=deleteBlob&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `downloadBlobToFile`:
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-    // set the header you want the producer to evaluate, refer to the previous
-    // section to learn about the headers that can be set
-    // e.g:
-    exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "overridenName");
-  })
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=downloadBlobToFile&fileDir=/var/mydir&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `downloadLink`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=downloadLink&serviceClient=#client")
-  .process(exchange -> {
-      String link = exchange.getMessage().getHeader(BlobConstants.DOWNLOAD_LINK, String.class);
-      System.out.println("My link " + link);
-  })
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `uploadBlockBlob`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-    // set the header you want the producer to evaluate, refer to the previous
-    // section to learn about the headers that can be set
-    // e.g:
-    exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "overridenName");
-    exchange.getIn().setBody("Block Blob");
-  })
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=uploadBlockBlob&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `stageBlockBlobList`
-
-[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`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-      // We assume here you have the knowledge of these blocks you want to commit
-      final List<Block> blocksIds = new LinkedList<>();
-      blocksIds.add(new Block().setName("id-1"));
-      blocksIds.add(new Block().setName("id-2"));
-      blocksIds.add(new Block().setName("id-3"));
-
-      exchange.getIn().setBody(blocksIds);
-  })
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=commitBlockBlobList&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `getBlobBlockList`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=getBlobBlockList&serviceClient=#client")
-  .log("${body}")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-
-- `createAppendBlob`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=createAppendBlob&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `commitAppendBlob`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-    final String data = "Hello world from my awesome tests!";
-    final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
-
-    exchange.getIn().setBody(dataStream);
-
-    // of course you can set whatever headers you like, refer to the headers section to learn more
-  })
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=commitAppendBlob&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `createPageBlob`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=createPageBlob&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `uploadPageBlob`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-    byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
-    new Random().nextBytes(dataBytes);
-    final InputStream dataStream = new ByteArrayInputStream(dataBytes);
-    final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
-
-    exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
-    exchange.getIn().setBody(dataStream);
-  })
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=uploadPageBlob&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `resizePageBlob`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-    final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
-
-    exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
-  })
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=resizePageBlob&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `clearPageBlob`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-    final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
-
-    exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
-  })
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=clearPageBlob&serviceClient=#client")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-- `getPageBlobRanges`
-
-[source,java]
---------------------------------------------------------------------------------
-
-from("direct:start")
-  .process(exchange -> {
-    final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
-
-    exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
-  })
-  .to("azure-storage-blob:/camelazure/container1?blobName=blob&operation=getPageBlobRanges&serviceClient=#client")
-  .log("${body}")
-  .to("mock:result");
---------------------------------------------------------------------------------
-
-
-=== Development Notes (Important)
-All integration tests use [Testcontainers](https://www.testcontainers.org/) 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:
-----
-mvn verify -PfullTests -DaccountName=myacc -DaccessKey=mykey
-----
-Whereby `accountName` is your Azure account name and `accessKey` is the access key being generated from Azure portal.
-
-
-include::camel-spring-boot::page$azure-storage-blob-starter.adoc[]
diff --git a/components/camel-azure-storage-blob/src/main/docs/azure-summary.adoc b/components/camel-azure-storage-blob/src/main/docs/azure-summary.adoc
deleted file mode 100644
index a20afe8..0000000
--- a/components/camel-azure-storage-blob/src/main/docs/azure-summary.adoc
+++ /dev/null
@@ -1,15 +0,0 @@
-[[Azure-CamelComponentsforMicrosoftAzureServices]]
-= Camel Components for Microsoft Azure Services
-//attributes written by hand, not generated
-:docTitle: Azure
-
-The Camel Components for https://azure.microsoft.com/[Microsoft Azure Services]
-provide connectivity to Azure services from Camel.
-
-== {docTitle} components
-
-See the following for usage of each component:
-
-indexDescriptionList::[attributes='group={docTitle}',descAttribute=description]
-
-include::camel-spring-boot::page$azure-starter.adoc[]
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobBlock.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobBlock.java
deleted file mode 100644
index e079a51..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobBlock.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.UUID;
-
-import com.azure.core.util.Base64Util;
-import com.azure.storage.blob.models.Block;
-
-public final class BlobBlock {
-    private final InputStream blockStream;
-    private final Block blockEntry;
-
-    private BlobBlock(Block blockEntry, InputStream blockStream) {
-        this.blockStream = blockStream;
-        this.blockEntry = blockEntry;
-    }
-
-    public static BlobBlock createBlobBlock(final InputStream inputStream) throws IOException {
-        return createBlobBlock(Base64Util.encodeToString(UUID.randomUUID().toString().getBytes()), inputStream);
-    }
-
-    public static BlobBlock createBlobBlock(final String blockId, final InputStream inputStream) throws IOException {
-        return createBlobBlock(blockId, BlobUtils.getInputStreamLength(inputStream), inputStream);
-    }
-
-    public static BlobBlock createBlobBlock(final String blockId, final long size, final InputStream inputStream) {
-        final Block block = new Block().setName(blockId).setSizeLong(size);
-
-        return new BlobBlock(block, inputStream);
-    }
-
-    public InputStream getBlockStream() {
-        return blockStream;
-    }
-
-    public Block getBlockEntry() {
-        return blockEntry;
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobCommonRequestOptions.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobCommonRequestOptions.java
deleted file mode 100644
index 84de6c6..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobCommonRequestOptions.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.time.Duration;
-import java.util.Map;
-
-import com.azure.storage.blob.models.AccessTier;
-import com.azure.storage.blob.models.BlobHttpHeaders;
-import com.azure.storage.blob.models.BlobRequestConditions;
-
-public class BlobCommonRequestOptions {
-
-    private final BlobHttpHeaders blobHttpHeaders;
-    private final Map<String, String> metadata;
-    private final AccessTier accessTier;
-    private final BlobRequestConditions blobRequestConditions;
-    private final byte[] contentMD5;
-    private final Duration timeout;
-
-    public BlobCommonRequestOptions(BlobHttpHeaders blobHttpHeaders, Map<String, String> metadata, AccessTier accessTier,
-                                    BlobRequestConditions blobRequestConditions, byte[] contentMD5, Duration timeout) {
-        this.blobHttpHeaders = blobHttpHeaders;
-        this.metadata = metadata;
-        this.accessTier = accessTier;
-        this.blobRequestConditions = blobRequestConditions;
-        this.contentMD5 = contentMD5;
-        this.timeout = timeout;
-    }
-
-    public BlobHttpHeaders getBlobHttpHeaders() {
-        return blobHttpHeaders;
-    }
-
-    public Map<String, String> getMetadata() {
-        return metadata;
-    }
-
-    public AccessTier getAccessTier() {
-        return accessTier;
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T extends BlobRequestConditions> T getBlobRequestConditions() {
-        return blobRequestConditions == null ? null : (T) blobRequestConditions;
-    }
-
-    public byte[] getContentMD5() {
-        return contentMD5;
-    }
-
-    public Duration getTimeout() {
-        return timeout;
-    }
-
-    public String leaseId() {
-        return blobRequestConditions != null ? blobRequestConditions.getLeaseId() : null;
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java
deleted file mode 100644
index 75e1e9d..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobComponent.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.util.Map;
-import java.util.Set;
-
-import com.azure.storage.blob.BlobServiceClient;
-import com.azure.storage.common.StorageSharedKeyCredential;
-import org.apache.camel.CamelContext;
-import org.apache.camel.Endpoint;
-import org.apache.camel.spi.Metadata;
-import org.apache.camel.spi.annotations.Component;
-import org.apache.camel.support.DefaultComponent;
-import org.apache.camel.util.ObjectHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Azure Blob Storage component using azure java sdk v12.x
- */
-@Component("azure-storage-blob")
-public class BlobComponent extends DefaultComponent {
-
-    private static final Logger LOG = LoggerFactory.getLogger(BlobComponent.class);
-
-    @Metadata
-    private BlobConfiguration configuration = new BlobConfiguration();
-
-    public BlobComponent() {
-    }
-
-    public BlobComponent(final CamelContext camelContext) {
-        super(camelContext);
-    }
-
-    @Override
-    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
-
-        if (remaining == null || remaining.trim().length() == 0) {
-            throw new IllegalArgumentException("At least the account name must be specified.");
-        }
-
-        final BlobConfiguration config = this.configuration != null
-                ? this.configuration.copy()
-                : new BlobConfiguration();
-
-        final String[] parts = remaining.split("/");
-
-        // only account name is being set
-        config.setAccountName(parts[0]);
-
-        // also container name is being set
-        if (parts.length > 1) {
-            config.setContainerName(parts[1]);
-        }
-
-        final BlobEndpoint endpoint = new BlobEndpoint(uri, this, config);
-        setProperties(endpoint, parameters);
-
-        if (config.isAutoDiscoverClient()) {
-            checkAndSetRegistryClient(config);
-        }
-
-        checkCredentials(config);
-        validateConfigurations(config);
-
-        return endpoint;
-    }
-
-    /**
-     * The component configurations
-     */
-    public BlobConfiguration getConfiguration() {
-        return configuration;
-    }
-
-    public void setConfiguration(BlobConfiguration configuration) {
-        this.configuration = configuration;
-    }
-
-    private void checkCredentials(final BlobConfiguration configuration) {
-        final BlobServiceClient client = configuration.getServiceClient();
-
-        // if no azureBlobClient is provided fallback to credentials
-        if (client == null) {
-            Set<StorageSharedKeyCredential> storageSharedKeyCredentials
-                    = getCamelContext().getRegistry().findByType(StorageSharedKeyCredential.class);
-            if (storageSharedKeyCredentials.size() == 1) {
-                configuration.setCredentials(storageSharedKeyCredentials.stream().findFirst().get());
-            }
-        }
-    }
-
-    private void checkAndSetRegistryClient(final BlobConfiguration configuration) {
-        if (ObjectHelper.isEmpty(configuration.getServiceClient())) {
-            final Set<BlobServiceClient> clients = getCamelContext().getRegistry().findByType(BlobServiceClient.class);
-            if (clients.size() == 1) {
-                configuration.setServiceClient(clients.stream().findFirst().get());
-            } else if (clients.size() > 1) {
-                LOG.info("More than one BlobServiceClient instance in the registry, make sure to have only one instance");
-            } else {
-                LOG.info("No BlobServiceClient instance in the registry");
-            }
-        } else {
-            LOG.info("BlobServiceClient instance is already set at endpoint level: skipping the check in the registry");
-        }
-    }
-
-    private void validateConfigurations(final BlobConfiguration configuration) {
-        if (configuration.getServiceClient() == null
-                && configuration.getAccessKey() == null
-                && configuration.getCredentials() == null) {
-            throw new IllegalArgumentException("Azure Storage accessKey or BlobServiceClient must be specified.");
-        }
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
deleted file mode 100644
index b87e19a..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfiguration.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.time.Duration;
-
-import com.azure.storage.blob.BlobClient;
-import com.azure.storage.blob.BlobContainerClient;
-import com.azure.storage.blob.BlobServiceClient;
-import com.azure.storage.blob.models.BlockListType;
-import com.azure.storage.common.StorageSharedKeyCredential;
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.spi.UriParam;
-import org.apache.camel.spi.UriParams;
-import org.apache.camel.spi.UriPath;
-
-@UriParams
-public class BlobConfiguration implements Cloneable {
-
-    @UriPath
-    private String accountName;
-    @UriPath
-    private String containerName;
-    @UriParam
-    private StorageSharedKeyCredential credentials;
-    @UriParam
-    private BlobServiceClient serviceClient;
-    @UriParam(label = "security", secret = true)
-    private String accessKey;
-    @UriParam(label = "producer",
-              enums = "listBlobContainers,createBlobContainer,deleteBlobContainer,listBlobs,getBlob,deleteBlob,downloadBlobToFile,downloadLink,"
-                      + "uploadBlockBlob,stageBlockBlobList,commitBlobBlockList,getBlobBlockList,createAppendBlob,commitAppendBlob,createPageBlob,uploadPageBlob,resizePageBlob,"
-                      + "clearPageBlob,getPageBlobRanges",
-              defaultValue = "listBlobContainers")
-    private BlobOperationsDefinition operation = BlobOperationsDefinition.listBlobContainers;
-    @UriParam(label = "common")
-    private String blobName;
-    @UriParam(label = "common", enums = "blockblob,appendblob,pageblob", defaultValue = "blockblob")
-    private BlobType blobType = BlobType.blockblob;
-    @UriParam(label = "common")
-    private String fileDir;
-    @UriParam(label = "common", defaultValue = "0")
-    private long blobOffset;
-    @UriParam(label = "common")
-    private Long dataCount;
-    @UriParam(label = "common")
-    private Duration timeout;
-    @UriParam(label = "common")
-    private String prefix;
-    @UriParam(label = "common")
-    private Integer maxResultsPerPage;
-    @UriParam(label = "common", defaultValue = "0")
-    private int maxRetryRequests;
-    @UriParam(label = "common", defaultValue = "true")
-    private boolean autoDiscoverClient = true;
-    @UriParam(defaultValue = "true")
-    private boolean closeStreamAfterRead = true;
-    @UriParam(label = "producer", defaultValue = "true")
-    private boolean closeStreamAfterWrite = true;
-    @UriParam(label = "producer")
-    private Long downloadLinkExpiration;
-    @UriParam(label = "producer", defaultValue = "true")
-    private boolean commitBlockListLater = true;
-    @UriParam(label = "producer", defaultValue = "true")
-    private boolean createAppendBlob = true;
-    @UriParam(label = "producer", defaultValue = "true")
-    private boolean createPageBlob = true;
-    @UriParam(label = "producer", defaultValue = "0")
-    private Long blobSequenceNumber;
-    @UriParam(label = "producer", defaultValue = "512")
-    private Long pageBlobSize = BlobConstants.PAGE_BLOB_DEFAULT_SIZE;
-    @UriParam(label = "producer", defaultValue = "COMMITTED")
-    private BlockListType blockListType = BlockListType.COMMITTED;
-    @UriParam(label = "common")
-    private String regex;
-
-    /**
-     * Azure account name to be used for authentication with azure blob services
-     */
-    public String getAccountName() {
-        return accountName;
-    }
-
-    public void setAccountName(String accountName) {
-        this.accountName = accountName;
-    }
-
-    /**
-     * The blob container name
-     */
-    public String getContainerName() {
-        return containerName;
-    }
-
-    public void setContainerName(String containerName) {
-        this.containerName = containerName;
-    }
-
-    /**
-     * StorageSharedKeyCredential can be injected to create the azure client, this holds the important authentication
-     * information
-     */
-    public StorageSharedKeyCredential getCredentials() {
-        return credentials;
-    }
-
-    public void setCredentials(StorageSharedKeyCredential credentials) {
-        this.credentials = credentials;
-    }
-
-    /**
-     * Client to a storage account. This client does not hold any state about a particular storage account but is
-     * instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used
-     * to construct URLs to blobs and containers.
-     *
-     * This client contains operations on a service account. Operations on a container are available on
-     * {@link BlobContainerClient} through {@link BlobServiceClient#getBlobContainerClient(String)}, and operations on a
-     * blob are available on {@link BlobClient} through {@link BlobContainerClient#getBlobClient(String)}.
-     */
-    public BlobServiceClient getServiceClient() {
-        return serviceClient;
-    }
-
-    public void setServiceClient(BlobServiceClient serviceClient) {
-        this.serviceClient = serviceClient;
-    }
-
-    /**
-     * Access key for the associated azure account name to be used for authentication with azure blob services
-     */
-    public String getAccessKey() {
-        return accessKey;
-    }
-
-    public void setAccessKey(String accessKey) {
-        this.accessKey = accessKey;
-    }
-
-    /**
-     * The blob operation that can be used with this component on the producer
-     */
-    public BlobOperationsDefinition getOperation() {
-        return operation;
-    }
-
-    public void setOperation(BlobOperationsDefinition operation) {
-        this.operation = operation;
-    }
-
-    /**
-     * The blob name, to consume specific blob from a container. However on producer, is only required for the
-     * operations on the blob level
-     */
-    public String getBlobName() {
-        return blobName;
-    }
-
-    public void setBlobName(String blobName) {
-        this.blobName = blobName;
-    }
-
-    /**
-     * The blob type in order to initiate the appropriate settings for each blob type
-     */
-    public BlobType getBlobType() {
-        return blobType;
-    }
-
-    public void setBlobType(BlobType blobType) {
-        this.blobType = blobType;
-    }
-
-    /**
-     * The file directory where the downloaded blobs will be saved to, this can be used in both, producer and consumer
-     */
-    public String getFileDir() {
-        return fileDir;
-    }
-
-    public void setFileDir(String fileDir) {
-        this.fileDir = fileDir;
-    }
-
-    /**
-     * Set the blob offset for the upload or download operations, default is 0
-     */
-    public long getBlobOffset() {
-        return blobOffset;
-    }
-
-    public void setBlobOffset(long blobOffset) {
-        this.blobOffset = blobOffset;
-    }
-
-    /**
-     * How many bytes to include in the range. Must be greater than or equal to 0 if specified.
-     */
-    public Long getDataCount() {
-        return dataCount;
-    }
-
-    public void setDataCount(Long dataCount) {
-        this.dataCount = dataCount;
-    }
-
-    /**
-     * Specifies the maximum number of additional HTTP Get requests that will be made while reading the data from a
-     * response body.
-     */
-    public int getMaxRetryRequests() {
-        return maxRetryRequests;
-    }
-
-    public void setMaxRetryRequests(int maxRetryRequests) {
-        this.maxRetryRequests = maxRetryRequests;
-    }
-
-    /**
-     * An optional timeout value beyond which a {@link RuntimeException} will be raised.
-     */
-    public Duration getTimeout() {
-        return timeout;
-    }
-
-    public void setTimeout(Duration timeout) {
-        this.timeout = timeout;
-    }
-
-    /**
-     * Filters the results to return only blobs whose names begin with the specified prefix. May be null to return all
-     * blobs.
-     */
-    public String getPrefix() {
-        return prefix;
-    }
-
-    public void setPrefix(String prefix) {
-        this.prefix = prefix;
-    }
-
-    /**
-     * Specifies the maximum number of blobs to return, including all BlobPrefix elements. If the request does not
-     * specify maxResultsPerPage or specifies a value greater than 5,000, the server will return up to 5,000 items.
-     */
-    public Integer getMaxResultsPerPage() {
-        return maxResultsPerPage;
-    }
-
-    public void setMaxResultsPerPage(Integer maxResultsPerPage) {
-        this.maxResultsPerPage = maxResultsPerPage;
-    }
-
-    /**
-     * Close the stream after read or keep it open, default is true
-     */
-    public boolean isCloseStreamAfterRead() {
-        return closeStreamAfterRead;
-    }
-
-    public void setCloseStreamAfterRead(boolean closeStreamAfterRead) {
-        this.closeStreamAfterRead = closeStreamAfterRead;
-    }
-
-    /**
-     * Close the stream after write or keep it open, default is true
-     */
-    public boolean isCloseStreamAfterWrite() {
-        return closeStreamAfterWrite;
-    }
-
-    public void setCloseStreamAfterWrite(boolean closeStreamAfterWrite) {
-        this.closeStreamAfterWrite = closeStreamAfterWrite;
-    }
-
-    /**
-     * Specifies the maximum size for the page blob, up to 8 TB. The page blob size must be aligned to a 512-byte
-     * boundary.
-     */
-    public Long getPageBlobSize() {
-        return pageBlobSize;
-    }
-
-    public void setPageBlobSize(Long pageBlobSize) {
-        this.pageBlobSize = pageBlobSize;
-    }
-
-    /**
-     * Override the default expiration (millis) of URL download link.
-     */
-    public Long getDownloadLinkExpiration() {
-        return downloadLinkExpiration;
-    }
-
-    public void setDownloadLinkExpiration(Long downloadLinkExpiration) {
-        this.downloadLinkExpiration = downloadLinkExpiration;
-    }
-
-    /**
-     * When is set to `true`, the staged blocks will not be committed directly.
-     */
-    public boolean isCommitBlockListLater() {
-        return commitBlockListLater;
-    }
-
-    public void setCommitBlockListLater(boolean commitBlockListLater) {
-        this.commitBlockListLater = commitBlockListLater;
-    }
-
-    /**
-     * When is set to `true`, the append blocks will be created when committing append blocks.
-     */
-    public boolean isCreateAppendBlob() {
-        return createAppendBlob;
-    }
-
-    public void setCreateAppendBlob(boolean createAppendBlob) {
-        this.createAppendBlob = createAppendBlob;
-    }
-
-    /**
-     * When is set to `true`, the page blob will be created when uploading page blob.
-     */
-    public boolean isCreatePageBlob() {
-        return createPageBlob;
-    }
-
-    public void setCreatePageBlob(boolean createPageBlob) {
-        this.createPageBlob = createPageBlob;
-    }
-
-    /**
-     * A user-controlled value that you can use to track requests. The value of the sequence number must be between 0
-     * and 2^63 - 1.The default value is 0.
-     */
-    public Long getBlobSequenceNumber() {
-        return blobSequenceNumber;
-    }
-
-    public void setBlobSequenceNumber(Long blobSequenceNumber) {
-        this.blobSequenceNumber = blobSequenceNumber;
-    }
-
-    /**
-     * Specifies which type of blocks to return.
-     */
-    public BlockListType getBlockListType() {
-        return blockListType;
-    }
-
-    public void setBlockListType(BlockListType blockListType) {
-        this.blockListType = blockListType;
-    }
-
-    /**
-     * Setting the autoDiscoverClient mechanism, if true, the component will look for a client instance in the registry
-     * automatically otherwise it will skip that checking.
-     */
-    public boolean isAutoDiscoverClient() {
-        return autoDiscoverClient;
-    }
-
-    public void setAutoDiscoverClient(boolean autoDiscoverClient) {
-        this.autoDiscoverClient = autoDiscoverClient;
-    }
-
-    /**
-     * Filters the results to return only blobs whose names match the specified regular expression. May be null to
-     * return all if both prefix and regex are set, regex takes the priority and prefix is ignored.
-     */
-    public String getRegex() {
-        return regex;
-    }
-
-    public void setRegex(String regex) {
-        this.regex = regex;
-    }
-
-    // *************************************************
-    //
-    // *************************************************
-
-    public BlobConfiguration copy() {
-        try {
-            return (BlobConfiguration) super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new RuntimeCamelException(e);
-        }
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxy.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxy.java
deleted file mode 100644
index 76edf24..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxy.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.time.Duration;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-import com.azure.storage.blob.models.AccessTier;
-import com.azure.storage.blob.models.BlobHttpHeaders;
-import com.azure.storage.blob.models.BlobListDetails;
-import com.azure.storage.blob.models.BlobRange;
-import com.azure.storage.blob.models.BlobRequestConditions;
-import com.azure.storage.blob.models.BlockListType;
-import com.azure.storage.blob.models.DeleteSnapshotsOptionType;
-import com.azure.storage.blob.models.ListBlobContainersOptions;
-import com.azure.storage.blob.models.ListBlobsOptions;
-import com.azure.storage.blob.models.PageRange;
-import com.azure.storage.blob.models.ParallelTransferOptions;
-import com.azure.storage.blob.models.PublicAccessType;
-import org.apache.camel.Exchange;
-import org.apache.camel.util.ObjectHelper;
-
-/**
- * A proxy class for {@link BlobConfigurationOptionsProxy} and {@link BlobExchangeHeaders}. Ideally this is responsible
- * to obtain the correct configurations options either from configs or exchange headers
- */
-public class BlobConfigurationOptionsProxy {
-
-    private final BlobConfiguration configuration;
-
-    public BlobConfigurationOptionsProxy(final BlobConfiguration configuration) {
-        this.configuration = configuration;
-    }
-
-    public ListBlobContainersOptions getListBlobContainersOptions(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getListBlobContainersOptionsFromHeaders, () -> null, exchange);
-    }
-
-    public Duration getTimeout(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getTimeoutFromHeaders, configuration::getTimeout, exchange);
-    }
-
-    public ListBlobsOptions getListBlobsOptions(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getListBlobsOptionsFromHeaders, () -> null, exchange);
-    }
-
-    public BlobListDetails getBlobListDetails(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getBlobListDetailsFromHeaders, () -> null, exchange);
-    }
-
-    public String getPrefix(final Exchange exchange) {
-        //if regex is set, prefix will not take effect
-        if (ObjectHelper.isNotEmpty(getRegex(exchange))) {
-            return null;
-        }
-        return getOption(BlobExchangeHeaders::getPrefixFromHeaders, configuration::getPrefix, exchange);
-    }
-
-    public String getRegex(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getRegexFromHeaders, configuration::getRegex, exchange);
-    }
-
-    public Integer getMaxResultsPerPage(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getMaxResultsPerPageFromHeaders, configuration::getMaxResultsPerPage, exchange);
-    }
-
-    public ListBlobsOptions getListBlobOptions(final Exchange exchange) {
-        ListBlobsOptions blobsOptions = getListBlobsOptions(exchange);
-
-        if (blobsOptions == null) {
-            blobsOptions = new ListBlobsOptions();
-        }
-
-        if (!ObjectHelper.isEmpty(blobsOptions)) {
-            return blobsOptions;
-        } else {
-            blobsOptions = new ListBlobsOptions();
-        }
-
-        final BlobListDetails blobListDetails = getBlobListDetails(exchange);
-        final String prefix = getPrefix(exchange);
-        final Integer maxResultsPerPage = getMaxResultsPerPage(exchange);
-
-        blobsOptions.setDetails(blobListDetails);
-        blobsOptions.setMaxResultsPerPage(maxResultsPerPage);
-        blobsOptions.setPrefix(prefix);
-
-        return blobsOptions;
-    }
-
-    public Map<String, String> getMetadata(final Exchange exchange) {
-        return BlobExchangeHeaders.getMetadataFromHeaders(exchange);
-    }
-
-    public PublicAccessType getPublicAccessType(final Exchange exchange) {
-        return BlobExchangeHeaders.getPublicAccessTypeFromHeaders(exchange);
-    }
-
-    public BlobRequestConditions getBlobRequestConditions(final Exchange exchange) {
-        return BlobExchangeHeaders.getBlobRequestConditionsFromHeaders(exchange);
-    }
-
-    public PageRange getPageRange(final Exchange exchange) {
-        return BlobExchangeHeaders.getPageRangeFromHeaders(exchange);
-    }
-
-    public BlobRange getBlobRange(final Exchange exchange) {
-        if (configuration.getBlobType() == BlobType.pageblob) {
-            final PageRange pageRange = getPageRange(exchange);
-            if (pageRange != null) {
-                final long blobOffset = pageRange.getStart();
-                final long dataCount = pageRange.getEnd() - pageRange.getStart();
-
-                return new BlobRange(blobOffset, dataCount);
-            }
-        }
-        return new BlobRange(configuration.getBlobOffset(), configuration.getDataCount());
-    }
-
-    public BlobHttpHeaders getBlobHttpHeaders(final Exchange exchange) {
-        return BlobExchangeHeaders.getBlobHttpHeadersFromHeaders(exchange);
-    }
-
-    public AccessTier getAccessTier(final Exchange exchange) {
-        return BlobExchangeHeaders.getAccessTierFromHeaders(exchange);
-    }
-
-    public byte[] getContentMd5(final Exchange exchange) {
-        return BlobExchangeHeaders.getContentMd5FromHeaders(exchange);
-    }
-
-    public String getFileDir(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getFileDirFromHeaders, configuration::getFileDir, exchange);
-    }
-
-    public ParallelTransferOptions getParallelTransferOptions(final Exchange exchange) {
-        return BlobExchangeHeaders.getParallelTransferOptionsFromHeaders(exchange);
-    }
-
-    public DeleteSnapshotsOptionType getDeleteSnapshotsOptionType(final Exchange exchange) {
-        return BlobExchangeHeaders.getDeleteSnapshotsOptionTypeFromHeaders(exchange);
-    }
-
-    public Long getDownloadLinkExpiration(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getDownloadLinkExpirationFromHeaders, configuration::getDownloadLinkExpiration,
-                exchange);
-    }
-
-    public boolean isCommitBlockListLater(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getCommitBlockListFlagFromHeaders, configuration::isCommitBlockListLater,
-                exchange);
-    }
-
-    public BlockListType getBlockListType(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getBlockListTypeFromHeaders, configuration::getBlockListType, exchange);
-    }
-
-    public boolean isCreateAppendBlob(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getCreateAppendBlobFlagFromHeaders, configuration::isCreateAppendBlob, exchange);
-    }
-
-    public Long getPageBlobSize(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getPageBlobSize, configuration::getPageBlobSize, exchange);
-    }
-
-    public Long getBlobSequenceNumber(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getBlobSequenceNumberFromHeaders, configuration::getBlobSequenceNumber, exchange);
-    }
-
-    public boolean isCreatePageBlob(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getCreatePageBlobFlagFromHeaders, configuration::isCreatePageBlob, exchange);
-    }
-
-    public String getBlobName(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getBlobNameFromHeaders, configuration::getBlobName, exchange);
-    }
-
-    public String getContainerName(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getBlobContainerNameFromHeaders, configuration::getContainerName, exchange);
-    }
-
-    public BlobOperationsDefinition getOperation(final Exchange exchange) {
-        return getOption(BlobExchangeHeaders::getBlobOperationsDefinitionFromHeaders, configuration::getOperation, exchange);
-    }
-
-    public int getMaxRetryRequests() {
-        return configuration.getMaxRetryRequests();
-    }
-
-    public BlobConfiguration getConfiguration() {
-        return configuration;
-    }
-
-    private <R> R getOption(final Function<Exchange, R> exchangeFn, final Supplier<R> fallbackFn, final Exchange exchange) {
-        // we first try to look if our value in exchange otherwise fallback to fallbackFn which could be either a function or constant
-        return ObjectHelper.isEmpty(exchange) || ObjectHelper.isEmpty(exchangeFn.apply(exchange))
-                ? fallbackFn.get()
-                : exchangeFn.apply(exchange);
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConstants.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConstants.java
deleted file mode 100644
index b2426c7..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConstants.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-public final class BlobConstants {
-    // constants
-    public static final Long PAGE_BLOB_DEFAULT_SIZE = 512L;
-    private static final String HEADER_PREFIX = "CamelAzureStorageBlob";
-    // header names
-    public static final String BLOB_OPERATION = HEADER_PREFIX + "Operation";
-    public static final String BLOB_HTTP_HEADERS = HEADER_PREFIX + "HttpHeaders";
-    public static final String E_TAG = HEADER_PREFIX + "ETag";
-    public static final String CREATION_TIME = HEADER_PREFIX + "CreationTime";
-    public static final String LAST_MODIFIED = HEADER_PREFIX + "LastModified";
-    public static final String CONTENT_TYPE = HEADER_PREFIX + "ContentType";
-    public static final String CONTENT_MD5 = HEADER_PREFIX + "ContentMD5";
-    public static final String CONTENT_ENCODING = HEADER_PREFIX + "ContentEncoding";
-    public static final String CONTENT_DISPOSITION = HEADER_PREFIX + "ContentDisposition";
-    public static final String CONTENT_LANGUAGE = HEADER_PREFIX + "ContentLanguage";
-    public static final String CACHE_CONTROL = HEADER_PREFIX + "CacheControl";
-    public static final String BLOB_SIZE = HEADER_PREFIX + "BlobSize";
-    public static final String BLOB_SEQUENCE_NUMBER = HEADER_PREFIX + "SequenceNumber";
-    public static final String BLOB_TYPE = HEADER_PREFIX + "BlobType";
-    public static final String LEASE_STATUS = HEADER_PREFIX + "LeaseStatus";
-    public static final String LEASE_STATE = HEADER_PREFIX + "LeaseState";
-    public static final String LEASE_DURATION = HEADER_PREFIX + "LeaseDuration";
-    public static final String COPY_ID = HEADER_PREFIX + "CopyId";
-    public static final String COPY_STATUS = HEADER_PREFIX + "CopyStatus";
-    public static final String COPY_SOURCE = HEADER_PREFIX + "CopySource";
-    public static final String COPY_PROGRESS = HEADER_PREFIX + "CopyProgress";
-    public static final String COPY_COMPILATION_TIME = HEADER_PREFIX + "CopyCompletionTime";
-    public static final String COPY_STATUS_DESCRIPTION = HEADER_PREFIX + "CopyStatusDescription";
-    public static final String COPY_DESTINATION_SNAPSHOT = HEADER_PREFIX + "CopyDestinationSnapshot";
-    public static final String IS_SERVER_ENCRYPTED = HEADER_PREFIX + "IsServerEncrypted";
-    public static final String IS_INCREMENTAL_COPY = HEADER_PREFIX + "IsIncrementalCopy";
-    public static final String ACCESS_TIER = HEADER_PREFIX + "AccessTier";
-    public static final String IS_ACCESS_TIER_INFRRRED = HEADER_PREFIX + "IsAccessTierInferred";
-    public static final String ARCHIVE_STATUS = HEADER_PREFIX + "ArchiveStatus";
-    public static final String ENCRYPTION_KEY_SHA_256 = HEADER_PREFIX + "EncryptionKeySha256";
-    public static final String ENCRYPTION_SCOPE = HEADER_PREFIX + "EncryptionScope";
-    public static final String ACCESS_TIER_CHANGE_TIME = HEADER_PREFIX + "accessTierChangeTime";
-    public static final String METADATA = HEADER_PREFIX + "Metadata";
-    public static final String COMMITTED_BLOCK_COUNT = HEADER_PREFIX + "CommittedBlockCount";
-    public static final String APPEND_OFFSET = HEADER_PREFIX + "AppendOffset";
-    public static final String RAW_HTTP_HEADERS = HEADER_PREFIX + "RawHttpHeaders";
-    public static final String FILE_NAME = HEADER_PREFIX + "FileName";
-    public static final String DOWNLOAD_LINK = HEADER_PREFIX + "DownloadLink";
-    // headers to be retrieved
-    public static final String LIST_BLOB_OPTIONS = HEADER_PREFIX + "ListBlobOptions";
-    public static final String BLOB_LIST_DETAILS = HEADER_PREFIX + "ListDetails";
-    public static final String PREFIX = HEADER_PREFIX + "Prefix";
-    public static final String REGEX = HEADER_PREFIX + "Regex";
-    public static final String MAX_RESULTS_PER_PAGE = HEADER_PREFIX + "MaxResultsPerPage";
-    public static final String TIMEOUT = HEADER_PREFIX + "Timeout";
-    public static final String PUBLIC_ACCESS_TYPE = HEADER_PREFIX + "PublicAccessType";
-    public static final String BLOB_REQUEST_CONDITION = HEADER_PREFIX + "RequestCondition";
-    public static final String BLOB_CONTAINER_NAME = HEADER_PREFIX + "BlobContainerName";
-    public static final String BLOB_NAME = HEADER_PREFIX + "BlobName";
-    public static final String FILE_DIR = HEADER_PREFIX + "FileDir";
-    public static final String PAGE_BLOB_RANGE = HEADER_PREFIX + "PageBlobRange";
-    public static final String PAGE_BLOB_SIZE = HEADER_PREFIX + "PageBlobSize";
-    public static final String COMMIT_BLOCK_LIST_LATER = HEADER_PREFIX + "CommitBlobBlockListLater";
-    public static final String BLOCK_LIST_TYPE = HEADER_PREFIX + "BlockListType";
-    public static final String CREATE_APPEND_BLOB = HEADER_PREFIX + "CreateAppendBlob";
-    public static final String CREATE_PAGE_BLOB = HEADER_PREFIX + "CreatePageBlob";
-    public static final String DELETE_SNAPSHOT_OPTION_TYPE = HEADER_PREFIX + "DeleteSnapshotsOptionType";
-    public static final String LIST_BLOB_CONTAINERS_OPTIONS = HEADER_PREFIX + "ListBlobContainersOptions";
-    public static final String PARALLEL_TRANSFER_OPTIONS = HEADER_PREFIX + "ParallelTransferOptions";
-    public static final String DOWNLOAD_LINK_EXPIRATION = HEADER_PREFIX + "DownloadLinkExpiration";
-
-    private BlobConstants() {
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConsumer.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConsumer.java
deleted file mode 100644
index 00e9490..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobConsumer.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.io.IOException;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-
-import com.azure.storage.blob.BlobContainerClient;
-import com.azure.storage.blob.models.BlobItem;
-import com.azure.storage.blob.models.BlobStorageException;
-import org.apache.camel.Exchange;
-import org.apache.camel.ExtendedExchange;
-import org.apache.camel.Processor;
-import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
-import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
-import org.apache.camel.component.azure.storage.blob.operations.BlobContainerOperations;
-import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
-import org.apache.camel.component.azure.storage.blob.operations.BlobOperations;
-import org.apache.camel.spi.Synchronization;
-import org.apache.camel.support.ScheduledBatchPollingConsumer;
-import org.apache.camel.util.CastUtils;
-import org.apache.camel.util.ObjectHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class BlobConsumer extends ScheduledBatchPollingConsumer {
-
-    private static final Logger LOG = LoggerFactory.getLogger(BlobConsumer.class);
-
-    public BlobConsumer(final BlobEndpoint endpoint, final Processor processor) {
-        super(endpoint, processor);
-    }
-
-    @Override
-    protected int poll() throws Exception {
-        final String containerName = getEndpoint().getConfiguration().getContainerName();
-        final String blobName = getEndpoint().getConfiguration().getBlobName();
-        final BlobContainerClient blobContainerClient
-                = getEndpoint().getBlobServiceClient().getBlobContainerClient(containerName);
-
-        Queue<Exchange> exchanges;
-
-        try {
-            if (ObjectHelper.isNotEmpty(blobName)) {
-                // here we have a blob which means we just download a single blob
-                final Exchange exchange = createExchangeFromBlob(blobName, blobContainerClient);
-                exchanges = new LinkedList<>();
-                exchanges.add(exchange);
-            } else {
-                // download multiple blobs since we only have no blobName set
-                exchanges = createBatchExchangesFromContainer(blobContainerClient);
-            }
-            return processBatch(CastUtils.cast(exchanges));
-        } catch (BlobStorageException ex) {
-            if (404 == ex.getStatusCode()) {
-                return 0;
-            } else {
-                throw ex;
-            }
-        }
-    }
-
-    private Exchange createExchangeFromBlob(final String blobName, final BlobContainerClient blobContainerClient)
-            throws IOException {
-        final BlobClientWrapper clientWrapper
-                = new BlobClientWrapper(blobContainerClient.getBlobClient(blobName));
-        final BlobOperations operations = new BlobOperations(getEndpoint().getConfiguration(), clientWrapper);
-        final Exchange exchange = createExchange(true);
-
-        BlobOperationResponse response;
-        if (!ObjectHelper.isEmpty(getEndpoint().getConfiguration().getFileDir())) {
-            // if we have a fileDir set, we download our content
-            response = operations.downloadBlobToFile(exchange);
-        } else {
-            // otherwise, we rely on the outputstream/inputstream
-            response = operations.getBlob(exchange);
-        }
-
-        getEndpoint().setResponseOnExchange(response, exchange);
-
-        exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
-        return exchange;
-    }
-
-    @SuppressWarnings("unchecked")
-    private Queue<Exchange> createBatchExchangesFromContainer(final BlobContainerClient blobContainerClient)
-            throws IOException {
-        final BlobContainerClientWrapper containerClientWrapper = new BlobContainerClientWrapper(blobContainerClient);
-        final BlobContainerOperations containerOperations
-                = new BlobContainerOperations(getEndpoint().getConfiguration(), containerClientWrapper);
-
-        final List<BlobItem> blobs = (List<BlobItem>) containerOperations.listBlobs(null).getBody();
-
-        final Queue<Exchange> exchanges = new LinkedList<>();
-
-        for (BlobItem blobItem : blobs) {
-            exchanges.add(createExchangeFromBlob(blobItem.getName(), blobContainerClient));
-        }
-        return exchanges;
-    }
-
-    @Override
-    public BlobEndpoint getEndpoint() {
-        return (BlobEndpoint) super.getEndpoint();
-    }
-
-    @Override
-    public int processBatch(Queue<Object> exchanges) {
-        final int total = exchanges.size();
-
-        for (int index = 0; index < total && isBatchAllowed(); index++) {
-            // only loop if we are started (allowed to run)
-            final Exchange exchange = ObjectHelper.cast(Exchange.class, exchanges.poll());
-
-            // add current index and total as properties
-            exchange.setProperty(Exchange.BATCH_INDEX, index);
-            exchange.setProperty(Exchange.BATCH_SIZE, total);
-            exchange.setProperty(Exchange.BATCH_COMPLETE, index == total - 1);
-
-            // update pending number of exchanges
-            pendingExchanges = total - index - 1;
-
-            // add on completion to handle after work when the exchange is done
-            exchange.adapt(ExtendedExchange.class).addOnCompletion(new Synchronization() {
-                @Override
-                public void onComplete(Exchange exchange) {
-                    LOG.trace("Complected from processing all exchanges...");
-                }
-
-                @Override
-                public void onFailure(Exchange exchange) {
-                    processRollback(exchange);
-                }
-            });
-
-            LOG.trace("Processing exchange [{}]...", exchange);
-            getAsyncProcessor().process(exchange, doneSync -> LOG.trace("Processing exchange [{}] done.", exchange));
-        }
-        return total;
-    }
-
-    /**
-     * Strategy when processing the exchange failed.
-     *
-     * @param exchange the exchange
-     */
-    protected void processRollback(Exchange exchange) {
-        Exception cause = exchange.getException();
-        if (cause != null) {
-            LOG.warn("Exchange failed, so rolling back message status: {}", exchange, cause);
-        } else {
-            LOG.warn("Exchange failed, so rolling back message status: {}", exchange);
-        }
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java
deleted file mode 100644
index e8f072f..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobEndpoint.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import com.azure.storage.blob.BlobClient;
-import com.azure.storage.blob.BlobContainerClient;
-import com.azure.storage.blob.BlobServiceClient;
-import org.apache.camel.Category;
-import org.apache.camel.Component;
-import org.apache.camel.Consumer;
-import org.apache.camel.Exchange;
-import org.apache.camel.Message;
-import org.apache.camel.Processor;
-import org.apache.camel.Producer;
-import org.apache.camel.component.azure.storage.blob.client.BlobClientFactory;
-import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
-import org.apache.camel.spi.UriEndpoint;
-import org.apache.camel.spi.UriParam;
-import org.apache.camel.support.DefaultEndpoint;
-import org.apache.camel.util.ObjectHelper;
-
-/**
- * Store and retrieve blobs from Azure Storage Blob Service using SDK v12.
- */
-@UriEndpoint(firstVersion = "3.3.0", scheme = "azure-storage-blob", title = "Azure Storage Blob Service",
-             syntax = "azure-storage-blob:accountName/containerName", category = { Category.CLOUD, Category.FILE })
-public class BlobEndpoint extends DefaultEndpoint {
-
-    @UriParam
-    private BlobServiceClient blobServiceClient;
-
-    @UriParam
-    private BlobConfiguration configuration;
-
-    public BlobEndpoint(final String uri, final Component component, final BlobConfiguration configuration) {
-        super(uri, component);
-        this.configuration = configuration;
-    }
-
-    @Override
-    public Producer createProducer() {
-        return new BlobProducer(this);
-    }
-
-    @Override
-    public Consumer createConsumer(Processor processor) {
-        // we need blobname as well as blob container in order to create it
-        if (ObjectHelper.isEmpty(configuration.getContainerName())) {
-            throw new IllegalArgumentException("Container name must be set.");
-        }
-        return new BlobConsumer(this, processor);
-    }
-
-    @Override
-    public void doStart() throws Exception {
-        super.doStart();
-
-        blobServiceClient = configuration.getServiceClient() != null
-                ? configuration.getServiceClient() : BlobClientFactory.createBlobServiceClient(configuration);
-    }
-
-    public void setResponseOnExchange(final BlobOperationResponse response, final Exchange exchange) {
-        final Message message = exchange.getIn();
-
-        message.setBody(response.getBody());
-        message.setHeaders(response.getHeaders());
-    }
-
-    /**
-     * The component configurations
-     */
-    public BlobConfiguration getConfiguration() {
-        return configuration;
-    }
-
-    public void setConfiguration(BlobConfiguration configuration) {
-        this.configuration = configuration;
-    }
-
-    /**
-     * Client to a storage account. This client does not hold any state about a particular storage account but is
-     * instead a convenient way of sending off appropriate requests to the resource on the service. It may also be used
-     * to construct URLs to blobs and containers.
-     *
-     * This client contains operations on a service account. Operations on a container are available on
-     * {@link BlobContainerClient} through {@link #getBlobContainerClient(String)}, and operations on a blob are
-     * available on {@link BlobClient} through {@link #getBlobContainerClient(String).getBlobClient(String)}.
-     */
-    public BlobServiceClient getBlobServiceClient() {
-        return blobServiceClient;
-    }
-
-    public void setBlobServiceClient(BlobServiceClient blobServiceClient) {
-        this.blobServiceClient = blobServiceClient;
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobExchangeHeaders.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobExchangeHeaders.java
deleted file mode 100644
index 8faed08..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobExchangeHeaders.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.time.Duration;
-import java.time.OffsetDateTime;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.azure.core.http.HttpHeaders;
-import com.azure.storage.blob.models.AccessTier;
-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.BlobListDetails;
-import com.azure.storage.blob.models.BlobProperties;
-import com.azure.storage.blob.models.BlobRequestConditions;
-import com.azure.storage.blob.models.BlobType;
-import com.azure.storage.blob.models.BlockBlobItem;
-import com.azure.storage.blob.models.BlockListType;
-import com.azure.storage.blob.models.CopyStatusType;
-import com.azure.storage.blob.models.DeleteSnapshotsOptionType;
-import com.azure.storage.blob.models.LeaseDurationType;
-import com.azure.storage.blob.models.LeaseStateType;
-import com.azure.storage.blob.models.LeaseStatusType;
-import com.azure.storage.blob.models.ListBlobContainersOptions;
-import com.azure.storage.blob.models.ListBlobsOptions;
-import com.azure.storage.blob.models.PageBlobItem;
-import com.azure.storage.blob.models.PageRange;
-import com.azure.storage.blob.models.ParallelTransferOptions;
-import com.azure.storage.blob.models.PublicAccessType;
-import org.apache.camel.Exchange;
-import org.apache.camel.util.ObjectHelper;
-
-public class BlobExchangeHeaders {
-
-    private final Map<String, Object> headers = new HashMap<>();
-
-    public static BlobExchangeHeaders createBlobExchangeHeadersFromBlobProperties(final BlobProperties properties) {
-        return new BlobExchangeHeaders()
-                .accessTierHeader(properties.getAccessTier())
-                .accessTierChangeTime(properties.getAccessTierChangeTime())
-                .archiveStatus(properties.getArchiveStatus())
-                .blobSequenceNumber(properties.getBlobSequenceNumber())
-                .blobSize(properties.getBlobSize())
-                .blobType(properties.getBlobType())
-                .cacheControl(properties.getCacheControl())
-                .committedBlockCount(properties.getCommittedBlockCount())
-                .contentDisposition(properties.getContentDisposition())
-                .contentEncoding(properties.getContentEncoding())
-                .contentLanguage(properties.getContentLanguage())
-                .contentMd5(properties.getContentMd5())
-                .contentType(properties.getContentType())
-                .copyCompletionTime(properties.getCopyCompletionTime())
-                .copyDestinationSnapshot(properties.getCopyDestinationSnapshot())
-                .copyId(properties.getCopyId())
-                .copyProgress(properties.getCopyProgress())
-                .copySource(properties.getCopySource())
-                .copyStatus(properties.getCopyStatus())
-                .copyStatusDescription(properties.getCopyStatusDescription())
-                .creationTime(properties.getCreationTime())
-                .encryptionKeySha256(properties.getEncryptionKeySha256())
-                .eTag(properties.getETag())
-                .isAccessTierInferred(properties.isAccessTierInferred())
-                .isIncrementalCopy(properties.isIncrementalCopy())
-                .isServerEncrypted(properties.isServerEncrypted())
-                .lastModified(properties.getLastModified())
-                .leaseDuration(properties.getLeaseDuration())
-                .leaseState(properties.getLeaseState())
-                .leaseStatus(properties.getLeaseStatus())
-                .metadata(properties.getMetadata());
-    }
-
-    public static BlobExchangeHeaders createBlobExchangeHeadersFromBlobDownloadHeaders(
-            final BlobDownloadHeaders blobDownloadHeaders) {
-        return createBlobExchangeHeadersFromBlobProperties(buildBlobProperties(blobDownloadHeaders));
-    }
-
-    public static BlobExchangeHeaders createBlobExchangeHeadersFromBlockBlobItem(final BlockBlobItem blockBlobItem) {
-        return new BlobExchangeHeaders()
-                .eTag(blockBlobItem.getETag())
-                .lastModified(blockBlobItem.getLastModified())
-                .contentMd5(blockBlobItem.getContentMd5())
-                .isServerEncrypted(blockBlobItem.isServerEncrypted())
-                .encryptionKeySha256(blockBlobItem.getEncryptionKeySha256())
-                .encryptionScope(blockBlobItem.getEncryptionScope());
-    }
-
-    public static BlobExchangeHeaders createBlobExchangeHeadersFromAppendBlobItem(final AppendBlobItem appendBlobItem) {
-        return new BlobExchangeHeaders()
-                .eTag(appendBlobItem.getETag())
-                .lastModified(appendBlobItem.getLastModified())
-                .contentMd5(appendBlobItem.getContentMd5())
-                .isServerEncrypted(appendBlobItem.isServerEncrypted())
-                .encryptionKeySha256(appendBlobItem.getEncryptionKeySha256())
-                .encryptionScope(appendBlobItem.getEncryptionScope())
-                .appendOffset(appendBlobItem.getBlobAppendOffset())
-                .committedBlockCount(appendBlobItem.getBlobCommittedBlockCount());
-    }
-
-    public static BlobExchangeHeaders createBlobExchangeHeadersFromPageBlobItem(final PageBlobItem pageBlobItem) {
-        return new BlobExchangeHeaders()
-                .eTag(pageBlobItem.getETag())
-                .lastModified(pageBlobItem.getLastModified())
-                .contentMd5(pageBlobItem.getContentMd5())
-                .isServerEncrypted(pageBlobItem.isServerEncrypted())
-                .encryptionScope(pageBlobItem.getEncryptionScope())
-                .blobSequenceNumber(pageBlobItem.getBlobSequenceNumber());
-    }
-
-    public static BlobExchangeHeaders create() {
-        return new BlobExchangeHeaders();
-    }
-
-    private static BlobProperties buildBlobProperties(final BlobDownloadHeaders hd) {
-        return new BlobProperties(
-                null, hd.getLastModified(), hd.getETag(),
-                hd.getContentLength() == null ? 0 : hd.getContentLength(), hd.getContentType(), null,
-                hd.getContentEncoding(), hd.getContentDisposition(), hd.getContentLanguage(), hd.getCacheControl(),
-                hd.getBlobSequenceNumber(), hd.getBlobType(), hd.getLeaseStatus(), hd.getLeaseState(),
-                hd.getLeaseDuration(), hd.getCopyId(), hd.getCopyStatus(), hd.getCopySource(), hd.getCopyProgress(),
-                hd.getCopyCompletionTime(), hd.getCopyStatusDescription(), hd.isServerEncrypted(),
-                null, null, null, null, null, hd.getEncryptionKeySha256(), null, hd.getMetadata(),
-                hd.getBlobCommittedBlockCount());
-    }
-
-    public static Duration getTimeoutFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.TIMEOUT, Duration.class);
-    }
-
-    @SuppressWarnings("unchecked")
-    public static Map<String, String> getMetadataFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.METADATA, Map.class);
-    }
-
-    public static PublicAccessType getPublicAccessTypeFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.PUBLIC_ACCESS_TYPE, PublicAccessType.class);
-    }
-
-    public static BlobRequestConditions getBlobRequestConditionsFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.BLOB_REQUEST_CONDITION, BlobRequestConditions.class);
-    }
-
-    public static BlobListDetails getBlobListDetailsFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.BLOB_LIST_DETAILS, BlobListDetails.class);
-    }
-
-    public static ListBlobsOptions getListBlobsOptionsFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.LIST_BLOB_OPTIONS, ListBlobsOptions.class);
-    }
-
-    public static String getPrefixFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.PREFIX, String.class);
-    }
-
-    public static String getRegexFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.REGEX, String.class);
-    }
-
-    public static Integer getMaxResultsPerPageFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.MAX_RESULTS_PER_PAGE, Integer.class);
-    }
-
-    public static BlobHttpHeaders getBlobHttpHeadersFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.BLOB_HTTP_HEADERS, BlobHttpHeaders.class);
-    }
-
-    public static AccessTier getAccessTierFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.ACCESS_TIER, AccessTier.class);
-    }
-
-    public static byte[] getContentMd5FromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.CONTENT_MD5, byte[].class);
-    }
-
-    public static PageRange getPageRangeFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.PAGE_BLOB_RANGE, PageRange.class);
-    }
-
-    public static Boolean getCommitBlockListFlagFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.COMMIT_BLOCK_LIST_LATER, Boolean.class);
-    }
-
-    public static Boolean getCreateAppendBlobFlagFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.CREATE_APPEND_BLOB, Boolean.class);
-    }
-
-    public static Boolean getCreatePageBlobFlagFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.CREATE_PAGE_BLOB, Boolean.class);
-    }
-
-    public static BlockListType getBlockListTypeFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.BLOCK_LIST_TYPE, BlockListType.class);
-    }
-
-    public static Long getPageBlobSize(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.PAGE_BLOB_SIZE, Long.class);
-    }
-
-    public static Long getBlobSequenceNumberFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.BLOB_SEQUENCE_NUMBER, Long.class);
-    }
-
-    public static DeleteSnapshotsOptionType getDeleteSnapshotsOptionTypeFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.DELETE_SNAPSHOT_OPTION_TYPE, DeleteSnapshotsOptionType.class);
-    }
-
-    public static ListBlobContainersOptions getListBlobContainersOptionsFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.LIST_BLOB_CONTAINERS_OPTIONS, ListBlobContainersOptions.class);
-    }
-
-    public static ParallelTransferOptions getParallelTransferOptionsFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.PARALLEL_TRANSFER_OPTIONS, ParallelTransferOptions.class);
-    }
-
-    public static String getFileDirFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.FILE_DIR, String.class);
-    }
-
-    public static Long getDownloadLinkExpirationFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.DOWNLOAD_LINK_EXPIRATION, Long.class);
-    }
-
-    public static String getBlobNameFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.BLOB_NAME, String.class);
-    }
-
-    public static String getBlobContainerNameFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.BLOB_CONTAINER_NAME, String.class);
-    }
-
-    public static BlobOperationsDefinition getBlobOperationsDefinitionFromHeaders(final Exchange exchange) {
-        return getObjectFromHeaders(exchange, BlobConstants.BLOB_OPERATION, BlobOperationsDefinition.class);
-    }
-
-    private static <T> T getObjectFromHeaders(final Exchange exchange, final String headerName, final Class<T> classType) {
-        return ObjectHelper.isEmpty(exchange) ? null : exchange.getIn().getHeader(headerName, classType);
-    }
-
-    public Map<String, Object> toMap() {
-        return headers;
-    }
-
-    public BlobExchangeHeaders accessTierHeader(final AccessTier accessTier) {
-        headers.put(BlobConstants.ACCESS_TIER, accessTier);
-        return this;
-    }
-
-    public BlobExchangeHeaders accessTierChangeTime(final OffsetDateTime accessTierChangeTime) {
-        headers.put(BlobConstants.ACCESS_TIER_CHANGE_TIME, accessTierChangeTime);
-        return this;
-    }
-
-    public BlobExchangeHeaders archiveStatus(final ArchiveStatus archiveStatus) {
-        headers.put(BlobConstants.ARCHIVE_STATUS, archiveStatus);
-        return this;
-    }
-
-    public BlobExchangeHeaders creationTime(final OffsetDateTime creationTime) {
-        headers.put(BlobConstants.CREATION_TIME, creationTime);
-        return this;
-    }
-
-    public BlobExchangeHeaders blobSequenceNumber(final Long sequence) {
-        headers.put(BlobConstants.BLOB_SEQUENCE_NUMBER, sequence);
-        return this;
-    }
-
-    public BlobExchangeHeaders blobSize(final long size) {
-        headers.put(BlobConstants.BLOB_SIZE, size);
-        return this;
-    }
-
-    public BlobExchangeHeaders blobType(final BlobType blobType) {
-        headers.put(BlobConstants.BLOB_TYPE, blobType);
-        return this;
-    }
-
-    public BlobExchangeHeaders cacheControl(final String cache) {
-        headers.put(BlobConstants.CACHE_CONTROL, cache);
-        return this;
-    }
-
-    public BlobExchangeHeaders committedBlockCount(final Integer count) {
-        headers.put(BlobConstants.COMMITTED_BLOCK_COUNT, count);
-        return this;
-    }
-
-    public BlobExchangeHeaders contentDisposition(final String content) {
-        headers.put(BlobConstants.CONTENT_DISPOSITION, content);
-        return this;
-    }
-
-    public BlobExchangeHeaders contentEncoding(final String contentEncoding) {
-        headers.put(BlobConstants.CONTENT_ENCODING, contentEncoding);
-        return this;
-    }
-
-    public BlobExchangeHeaders contentLanguage(final String contentLanguageHeader) {
-        headers.put(BlobConstants.CONTENT_LANGUAGE, contentLanguageHeader);
-        return this;
-    }
-
-    public BlobExchangeHeaders contentMd5(final byte[] md5) {
-        headers.put(BlobConstants.CONTENT_MD5, md5);
-        return this;
-    }
-
-    public BlobExchangeHeaders contentType(final String type) {
-        headers.put(BlobConstants.CONTENT_TYPE, type);
-        return this;
-    }
-
-    public BlobExchangeHeaders copyCompletionTime(final OffsetDateTime offsetDateTime) {
-        headers.put(BlobConstants.COPY_COMPILATION_TIME, offsetDateTime);
-        return this;
-    }
-
-    public BlobExchangeHeaders copyDestinationSnapshot(final String copyDest) {
-        headers.put(BlobConstants.COPY_DESTINATION_SNAPSHOT, copyDest);
-        return this;
-    }
-
-    public BlobExchangeHeaders copyId(final String copyId) {
-        headers.put(BlobConstants.COPY_ID, copyId);
-        return this;
-    }
-
-    public BlobExchangeHeaders copyProgress(final String copyProg) {
-        headers.put(BlobConstants.COPY_PROGRESS, copyProg);
-        return this;
-    }
-
-    public BlobExchangeHeaders copySource(final String copySource) {
-        headers.put(BlobConstants.COPY_SOURCE, copySource);
-        return this;
-    }
-
-    public BlobExchangeHeaders copyStatus(final CopyStatusType copyStatusType) {
-        headers.put(BlobConstants.COPY_STATUS, copyStatusType);
-        return this;
-    }
-
-    public BlobExchangeHeaders copyStatusDescription(final String copyStatusDes) {
-        headers.put(BlobConstants.COPY_STATUS_DESCRIPTION, copyStatusDes);
-        return this;
-    }
-
-    public BlobExchangeHeaders encryptionKeySha256(final String encryptionKeySha256) {
-        headers.put(BlobConstants.ENCRYPTION_KEY_SHA_256, encryptionKeySha256);
-        return this;
-    }
-
-    public BlobExchangeHeaders encryptionScope(final String scope) {
-        headers.put(BlobConstants.ENCRYPTION_SCOPE, scope);
-        return this;
-    }
-
-    public BlobExchangeHeaders eTag(final String eTag) {
-        headers.put(BlobConstants.E_TAG, eTag);
-        return this;
-    }
-
-    public BlobExchangeHeaders isAccessTierInferred(final Boolean isAccess) {
-        headers.put(BlobConstants.IS_ACCESS_TIER_INFRRRED, isAccess);
-        return this;
-    }
-
-    public BlobExchangeHeaders isIncrementalCopy(final Boolean isIncr) {
-        headers.put(BlobConstants.IS_INCREMENTAL_COPY, isIncr);
-        return this;
-    }
-
-    public BlobExchangeHeaders isServerEncrypted(final Boolean isServerEncrypted) {
-        headers.put(BlobConstants.IS_SERVER_ENCRYPTED, isServerEncrypted);
-        return this;
-    }
-
-    public BlobExchangeHeaders lastModified(final OffsetDateTime offsetDateTime) {
-        headers.put(BlobConstants.LAST_MODIFIED, offsetDateTime);
-        return this;
-    }
-
-    public BlobExchangeHeaders leaseDuration(final LeaseDurationType leaseDurationType) {
-        headers.put(BlobConstants.LEASE_DURATION, leaseDurationType);
-        return this;
-    }
-
-    public BlobExchangeHeaders leaseState(final LeaseStateType leaseStateType) {
-        headers.put(BlobConstants.LEASE_STATE, leaseStateType);
-        return this;
-    }
-
-    public BlobExchangeHeaders leaseStatus(final LeaseStatusType leaseStatusType) {
-        headers.put(BlobConstants.LEASE_STATUS, leaseStatusType);
-        return this;
-    }
-
-    public BlobExchangeHeaders metadata(final Map<String, String> metadata) {
-        headers.put(BlobConstants.METADATA, metadata);
-        return this;
-    }
-
-    public BlobExchangeHeaders appendOffset(final String offset) {
-        headers.put(BlobConstants.APPEND_OFFSET, offset);
-        return this;
-    }
-
-    public BlobExchangeHeaders fileName(final String fileName) {
-        headers.put(BlobConstants.FILE_NAME, fileName);
-        return this;
-    }
-
-    public BlobExchangeHeaders downloadLink(final String downloadLink) {
-        headers.put(BlobConstants.DOWNLOAD_LINK, downloadLink);
-        return this;
-    }
-
-    public BlobExchangeHeaders httpHeaders(final HttpHeaders httpHeaders) {
-        headers.put(BlobConstants.RAW_HTTP_HEADERS, httpHeaders);
-        return this;
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobOperationsDefinition.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobOperationsDefinition.java
deleted file mode 100644
index f94d07d..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobOperationsDefinition.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.nio.file.FileAlreadyExistsException;
-
-public enum BlobOperationsDefinition {
-    // Operations on the service level
-    //
-    /**
-     * Returns a list of containers in the storage account.
-     */
-    listBlobContainers,
-
-    // Operations on the container level
-    //
-    /**
-     * Creates a new container within a storage account. If a container with the same name already exists, the producer
-     * will ignore it.
-     */
-    createBlobContainer,
-    /**
-     * Deletes the specified container in the storage account. If the container doesn't exist the operation fails.
-     */
-    deleteBlobContainer,
-    /**
-     * Returns a list of blobs in this container, with folder structures flattened.
-     */
-    listBlobs,
-
-    // Operations on the blob level
-    //
-    /**
-     * Get the content of the blob, can be restricted to a blob range.
-     */
-    getBlob,
-    /**
-     * Delete a blob
-     */
-    deleteBlob,
-    /**
-     * Downloads 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 {@link FileAlreadyExistsException} will
-     * be thrown.
-     */
-    downloadBlobToFile,
-    /**
-     * Generates the download link for the specified blob using shared access signatures (SAS). This by default only
-     * limit to 1hour of allowed access. However, you can override the default expiration duration through the headers.
-     */
-    downloadLink,
-    /**
-     * 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.
-     */
-    uploadBlockBlob,
-    /**
-     * 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` is set to false, this
-     * will also commit the blocks.
-     */
-    stageBlockBlobList,
-    /**
-     * Writes a blob by specifying the list of block IDs that are to make up the blob. In order 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.
-     */
-    commitBlobBlockList,
-    /**
-     * Returns the list of blocks that have been uploaded as part of a block blob using the specified block list filter.
-     */
-    getBlobBlockList,
-    /**
-     * Creates a 0-length append blob. Call commitAppendBlo`b operation to append data to an append blob.
-     */
-    createAppendBlob,
-    /**
-     * Commits a new block of data to the end of the existing append blob. In case of header
-     * `CamelAzureStorageBlobAppendBlobCreated` is set to false, it will attempt to create the appendBlob through
-     * internal call to `createAppendBlob` operation.
-     */
-    commitAppendBlob,
-    /**
-     * Creates a page blob of the specified length. Call `uploadPageBlob` operation to upload data data to a page blob.
-     */
-    createPageBlob,
-    /**
-     * Writes one or more pages to the page blob. The write size must be a multiple of 512. In case of header
-     * `CamelAzureStorageBlobPageBlockCreated` is set to false, it will attempt to create the appendBlob through
-     * internal call to `createPageBlob` operation.
-     */
-    uploadPageBlob,
-    /**
-     * Resizes the page blob to the specified size (which must be a multiple of 512).
-     */
-    resizePageBlob,
-    /**
-     * Frees the specified pages from the page blob. The size of the range must be a multiple of 512.
-     */
-    clearPageBlob,
-    /**
-     * Returns the list of valid page ranges for a page blob or snapshot of a page blob.
-     */
-    getPageBlobRanges,
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobProducer.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobProducer.java
deleted file mode 100644
index 4e7c6de..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobProducer.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import org.apache.camel.Endpoint;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
-import org.apache.camel.component.azure.storage.blob.client.BlobServiceClientWrapper;
-import org.apache.camel.component.azure.storage.blob.operations.BlobContainerOperations;
-import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
-import org.apache.camel.component.azure.storage.blob.operations.BlobOperations;
-import org.apache.camel.component.azure.storage.blob.operations.BlobServiceOperations;
-import org.apache.camel.support.DefaultProducer;
-import org.apache.camel.util.ObjectHelper;
-
-/**
- * A Producer which sends messages to the Azure Storage Blob Service
- */
-public class BlobProducer extends DefaultProducer {
-
-    private final BlobConfiguration configuration;
-    private final BlobConfigurationOptionsProxy configurationProxy;
-    private final BlobServiceOperations blobServiceOperations;
-    private final BlobServiceClientWrapper blobServiceClientWrapper;
-
-    public BlobProducer(final Endpoint endpoint) {
-        super(endpoint);
-        this.configuration = getEndpoint().getConfiguration();
-        this.blobServiceClientWrapper = new BlobServiceClientWrapper(getEndpoint().getBlobServiceClient());
-        this.blobServiceOperations = new BlobServiceOperations(configuration, blobServiceClientWrapper);
-        this.configurationProxy = new BlobConfigurationOptionsProxy(configuration);
-    }
-
-    @Override
-    public void process(final Exchange exchange) throws Exception {
-        BlobOperationsDefinition operation = determineOperation(exchange);
-
-        if (ObjectHelper.isEmpty(operation)) {
-            operation = BlobOperationsDefinition.listBlobContainers;
-        }
-
-        switch (operation) {
-            // service operations
-            case listBlobContainers:
-                setResponse(exchange, blobServiceOperations.listBlobContainers(exchange));
-                break;
-            // container operations
-            case createBlobContainer:
-                setResponse(exchange, getContainerOperations(exchange).createContainer(exchange));
-                break;
-            case deleteBlobContainer:
-                setResponse(exchange, getContainerOperations(exchange).deleteContainer(exchange));
-                break;
-            case listBlobs:
-                setResponse(exchange, getContainerOperations(exchange).listBlobs(exchange));
-                break;
-            // blob operations
-            case getBlob:
-                setResponse(exchange, getBlobOperations(exchange).getBlob(exchange));
-                break;
-            case deleteBlob:
-                setResponse(exchange, getBlobOperations(exchange).deleteBlob(exchange));
-                break;
-            case downloadBlobToFile:
-                setResponse(exchange, getBlobOperations(exchange).downloadBlobToFile(exchange));
-                break;
-            case downloadLink:
-                setResponse(exchange, getBlobOperations(exchange).downloadLink(exchange));
-                break;
-            // block blob operations
-            case uploadBlockBlob:
-                setResponse(exchange, getBlobOperations(exchange).uploadBlockBlob(exchange));
-                break;
-            case stageBlockBlobList:
-                setResponse(exchange, getBlobOperations(exchange).stageBlockBlobList(exchange));
-                break;
-            case commitBlobBlockList:
-                setResponse(exchange, getBlobOperations(exchange).commitBlobBlockList(exchange));
-                break;
-            case getBlobBlockList:
-                setResponse(exchange, getBlobOperations(exchange).getBlobBlockList(exchange));
-                break;
-            // append blob operations
-            case createAppendBlob:
-                setResponse(exchange, getBlobOperations(exchange).createAppendBlob(exchange));
-                break;
-            case commitAppendBlob:
-                setResponse(exchange, getBlobOperations(exchange).commitAppendBlob(exchange));
-                break;
-            // page blob operations
-            case createPageBlob:
-                setResponse(exchange, getBlobOperations(exchange).createPageBlob(exchange));
-                break;
-            case uploadPageBlob:
-                setResponse(exchange, getBlobOperations(exchange).uploadPageBlob(exchange));
-                break;
-            case resizePageBlob:
-                setResponse(exchange, getBlobOperations(exchange).resizePageBlob(exchange));
-                break;
-            case clearPageBlob:
-                setResponse(exchange, getBlobOperations(exchange).clearPageBlob(exchange));
-                break;
-            case getPageBlobRanges:
-                setResponse(exchange, getBlobOperations(exchange).getPageBlobRanges(exchange));
-                break;
-            default:
-                throw new IllegalArgumentException("Unsupported operation");
-        }
-    }
-
-    private void setResponse(final Exchange exchange, final BlobOperationResponse blobOperationResponse) {
-        exchange.getMessage().setBody(blobOperationResponse.getBody());
-        exchange.getMessage().setHeaders(blobOperationResponse.getHeaders());
-    }
-
-    @Override
-    public BlobEndpoint getEndpoint() {
-        return (BlobEndpoint) super.getEndpoint();
-    }
-
-    private BlobOperationsDefinition determineOperation(final Exchange exchange) {
-        return configurationProxy.getOperation(exchange);
-    }
-
-    private BlobContainerOperations getContainerOperations(final Exchange exchange) {
-        return new BlobContainerOperations(
-                configuration, blobServiceClientWrapper.getBlobContainerClientWrapper(determineContainerName(exchange)));
-    }
-
-    private BlobOperations getBlobOperations(final Exchange exchange) {
-        final BlobClientWrapper clientWrapper
-                = blobServiceClientWrapper.getBlobContainerClientWrapper(determineContainerName(exchange))
-                        .getBlobClientWrapper(determineBlobName(exchange));
-
-        return new BlobOperations(configuration, clientWrapper);
-    }
-
-    private String determineContainerName(final Exchange exchange) {
-        final String containerName = configurationProxy.getContainerName(exchange);
-
-        if (ObjectHelper.isEmpty(containerName)) {
-            throw new IllegalArgumentException("Container name must be specified");
-        }
-        return containerName;
-    }
-
-    public String determineBlobName(final Exchange exchange) {
-        final String blobName = configurationProxy.getBlobName(exchange);
-
-        if (ObjectHelper.isEmpty(blobName)) {
-            throw new IllegalArgumentException("Blob name must be specified");
-        }
-        return blobName;
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobStreamAndLength.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobStreamAndLength.java
deleted file mode 100644
index a38a604..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobStreamAndLength.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.camel.Exchange;
-import org.apache.camel.WrappedFile;
-
-public final class BlobStreamAndLength {
-
-    private final InputStream inputStream;
-
-    private final long streamLength;
-
-    private BlobStreamAndLength(InputStream inputStream, long streamLength) {
-        this.inputStream = inputStream;
-        this.streamLength = streamLength;
-    }
-
-    @SuppressWarnings("rawtypes")
-    public static BlobStreamAndLength createBlobStreamAndLengthFromExchangeBody(final Exchange exchange) throws IOException {
-        Object body = exchange.getIn().getBody();
-
-        if (body instanceof WrappedFile) {
-            // unwrap file
-            body = ((WrappedFile) body).getFile();
-        }
-
-        if (body instanceof InputStream) {
-            return new BlobStreamAndLength((InputStream) body, BlobUtils.getInputStreamLength((InputStream) body));
-        }
-        if (body instanceof File) {
-            return new BlobStreamAndLength(new BufferedInputStream(new FileInputStream((File) body)), ((File) body).length());
-        }
-        if (body instanceof byte[]) {
-            return new BlobStreamAndLength(new ByteArrayInputStream((byte[]) body), ((byte[]) body).length);
-        }
-
-        // try as input stream
-        final InputStream inputStream
-                = exchange.getContext().getTypeConverter().tryConvertTo(InputStream.class, exchange, body);
-
-        if (inputStream == null) {
-            // fallback to string based
-            throw new IllegalArgumentException("Unsupported blob type:" + body.getClass().getName());
-        }
-
-        return new BlobStreamAndLength(inputStream, BlobUtils.getInputStreamLength(inputStream));
-    }
-
-    public InputStream getInputStream() {
-        return inputStream;
-    }
-
-    public long getStreamLength() {
-        return streamLength;
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobType.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobType.java
deleted file mode 100644
index 3e2b5b9..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobType.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-/**
- * Blob Type
- */
-// The lower case naming is done to make component URI look better
-// when a type needs to be set and make it consistent with the values
-// used by Azure SDK BlobType parse implementation which is currently not
-// directly accessible
-public enum BlobType {
-    blockblob,
-    appendblob,
-    pageblob
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobUtils.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobUtils.java
deleted file mode 100644
index 02ada37..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/BlobUtils.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.camel.Exchange;
-import org.apache.camel.Message;
-import org.apache.camel.util.ObjectHelper;
-import org.apache.commons.io.IOUtils;
-
-public final class BlobUtils {
-
-    private BlobUtils() {
-    }
-
-    public static Message getInMessage(final Exchange exchange) {
-        return ObjectHelper.isEmpty(exchange) ? null : exchange.getIn();
-    }
-
-    public static Long getInputStreamLength(final InputStream inputStream) throws IOException {
-        final long length = IOUtils.toByteArray(inputStream).length;
-        inputStream.reset();
-
-        return length;
-    }
-
-    public static String getContainerName(final BlobConfiguration configuration, final Exchange exchange) {
-        return ObjectHelper.isEmpty(BlobExchangeHeaders.getBlobContainerNameFromHeaders(exchange))
-                ? configuration.getContainerName()
-                : BlobExchangeHeaders.getBlobContainerNameFromHeaders(exchange);
-    }
-
-    public static String getBlobName(final BlobConfiguration configuration, final Exchange exchange) {
-        return ObjectHelper.isEmpty(BlobExchangeHeaders.getBlobNameFromHeaders(exchange))
-                ? configuration.getBlobName()
-                : BlobExchangeHeaders.getBlobNameFromHeaders(exchange);
-    }
-
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java
deleted file mode 100644
index 46f71fc..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientFactory.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.client;
-
-import java.util.Locale;
-
-import com.azure.storage.blob.BlobServiceClient;
-import com.azure.storage.blob.BlobServiceClientBuilder;
-import com.azure.storage.common.StorageSharedKeyCredential;
-import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
-import org.apache.camel.util.ObjectHelper;
-
-public final class BlobClientFactory {
-
-    private static final String SERVICE_URI_SEGMENT = ".blob.core.windows.net";
-
-    private BlobClientFactory() {
-    }
-
-    public static BlobServiceClient createBlobServiceClient(final BlobConfiguration configuration) {
-        return new BlobServiceClientBuilder()
-                .endpoint(buildAzureEndpointUri(configuration))
-                .credential(getCredentialForClient(configuration))
-                .buildClient();
-    }
-
-    private static String buildAzureEndpointUri(final BlobConfiguration configuration) {
-        return String.format(Locale.ROOT, "https://%s" + SERVICE_URI_SEGMENT, getAccountName(configuration));
-    }
-
-    private static StorageSharedKeyCredential getCredentialForClient(final BlobConfiguration configuration) {
-        final StorageSharedKeyCredential storageSharedKeyCredential = configuration.getCredentials();
-
-        if (storageSharedKeyCredential != null) {
-            return storageSharedKeyCredential;
-        }
-
-        return new StorageSharedKeyCredential(configuration.getAccountName(), configuration.getAccessKey());
-    }
-
-    private static String getAccountName(final BlobConfiguration configuration) {
-        return !ObjectHelper.isEmpty(configuration.getCredentials())
-                ? configuration.getCredentials().getAccountName() : configuration.getAccountName();
-    }
-
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientWrapper.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientWrapper.java
deleted file mode 100644
index 8a8d548..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobClientWrapper.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.client;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import com.azure.core.http.HttpHeaders;
-import com.azure.core.http.rest.Response;
-import com.azure.core.http.rest.ResponseBase;
-import com.azure.core.util.Context;
-import com.azure.storage.blob.BlobClient;
-import com.azure.storage.blob.models.AccessTier;
-import com.azure.storage.blob.models.AppendBlobItem;
-import com.azure.storage.blob.models.AppendBlobRequestConditions;
-import com.azure.storage.blob.models.BlobDownloadHeaders;
-import com.azure.storage.blob.models.BlobHttpHeaders;
-import com.azure.storage.blob.models.BlobProperties;
-import com.azure.storage.blob.models.BlobRange;
-import com.azure.storage.blob.models.BlobRequestConditions;
-import com.azure.storage.blob.models.BlockBlobItem;
-import com.azure.storage.blob.models.BlockList;
-import com.azure.storage.blob.models.BlockListType;
-import com.azure.storage.blob.models.DeleteSnapshotsOptionType;
-import com.azure.storage.blob.models.DownloadRetryOptions;
-import com.azure.storage.blob.models.PageBlobItem;
-import com.azure.storage.blob.models.PageBlobRequestConditions;
-import com.azure.storage.blob.models.PageList;
-import com.azure.storage.blob.models.PageRange;
-import com.azure.storage.blob.models.ParallelTransferOptions;
-import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
-import com.azure.storage.blob.specialized.AppendBlobClient;
-import com.azure.storage.blob.specialized.BlobInputStream;
-import com.azure.storage.blob.specialized.BlockBlobClient;
-import com.azure.storage.blob.specialized.PageBlobClient;
-import org.apache.camel.util.ObjectHelper;
-
-public class BlobClientWrapper {
-
-    private final BlobClient client;
-
-    public BlobClientWrapper(final BlobClient client) {
-        ObjectHelper.notNull(client, "client can not be null");
-
-        this.client = client;
-    }
-
-    public String getBlobName() {
-        return client.getBlobName();
-    }
-
-    public String getBlobUrl() {
-        return client.getBlobUrl();
-    }
-
-    public Response<Void> delete(
-            final DeleteSnapshotsOptionType deleteBlobSnapshotOptions,
-            final BlobRequestConditions requestConditions, final Duration timeout) {
-        return client.deleteWithResponse(deleteBlobSnapshotOptions, requestConditions, timeout, Context.NONE);
-    }
-
-    public Map<String, Object> openInputStream(final BlobRange blobRange, final BlobRequestConditions blobRequestConditions) {
-
-        final BlobInputStream blobInputStream = client.openInputStream(blobRange, blobRequestConditions);
-
-        // Hack to fold the response in order to ease the mocking in the unit tests
-        final Map<String, Object> results = new HashMap<>();
-        results.put("inputStream", blobInputStream);
-        results.put("properties", blobInputStream.getProperties());
-
-        return results;
-    }
-
-    public ResponseBase<BlobDownloadHeaders, Void> downloadWithResponse(
-            final OutputStream stream, final BlobRange range,
-            final DownloadRetryOptions options, final BlobRequestConditions requestConditions, final boolean getRangeContentMd5,
-            final Duration timeout) {
-        return client.downloadWithResponse(stream, range, options, requestConditions, getRangeContentMd5, timeout,
-                Context.NONE);
-    }
-
-    public Response<BlobProperties> downloadToFileWithResponse(
-            final String filePath, final BlobRange range,
-            final ParallelTransferOptions parallelTransferOptions, final DownloadRetryOptions downloadRetryOptions,
-            final BlobRequestConditions requestConditions,
-            final boolean rangeGetContentMd5, final Duration timeout) {
-        return client.downloadToFileWithResponse(filePath, range, parallelTransferOptions, downloadRetryOptions,
-                requestConditions, rangeGetContentMd5, timeout, Context.NONE);
-    }
-
-    public Response<BlockBlobItem> uploadBlockBlob(
-            final InputStream data, final long length, final BlobHttpHeaders headers,
-            final Map<String, String> metadata, AccessTier tier, final byte[] contentMd5,
-            final BlobRequestConditions requestConditions,
-            final Duration timeout) {
-        return getBlockBlobClient().uploadWithResponse(data, length, headers, metadata, tier, contentMd5, requestConditions,
-                timeout, Context.NONE);
-    }
-
-    public HttpHeaders stageBlockBlob(
-            final String base64BlockId, final InputStream data, final long length, final byte[] contentMd5,
-            final String leaseId, final Duration timeout) {
-        return client.getBlockBlobClient()
-                .stageBlockWithResponse(base64BlockId, data, length, contentMd5, leaseId, timeout, Context.NONE).getHeaders();
-    }
-
-    public Response<BlockBlobItem> commitBlockBlob(
-            final List<String> base64BlockIds, final BlobHttpHeaders headers,
-            final Map<String, String> metadata, final AccessTier tier, final BlobRequestConditions requestConditions,
-            final Duration timeout) {
-        return getBlockBlobClient().commitBlockListWithResponse(base64BlockIds, headers, metadata, tier, requestConditions,
-                timeout, Context.NONE);
-    }
-
-    public Response<BlockList> listBlobBlocks(final BlockListType listType, final String leaseId, final Duration timeout) {
-        return getBlockBlobClient().listBlocksWithResponse(listType, leaseId, timeout, Context.NONE);
-    }
-
-    public Response<AppendBlobItem> createAppendBlob(
-            final BlobHttpHeaders headers, final Map<String, String> metadata,
-            final BlobRequestConditions requestConditions, final Duration timeout) {
-
-        return getAppendBlobClient().createWithResponse(headers, metadata, requestConditions, timeout, Context.NONE);
-    }
-
-    public Response<AppendBlobItem> appendBlobBlock(
-            final InputStream data, final long length, final byte[] contentMd5,
-            final AppendBlobRequestConditions appendBlobRequestConditions, final Duration timeout) {
-        return getAppendBlobClient().appendBlockWithResponse(data, length, contentMd5, appendBlobRequestConditions, timeout,
-                Context.NONE);
-    }
-
-    public boolean appendBlobExists() {
-        return getAppendBlobClient().exists();
-    }
-
-    public Response<PageBlobItem> createPageBlob(
-            final long size, final Long sequenceNumber, final BlobHttpHeaders headers,
-            final Map<String, String> metadata, final BlobRequestConditions requestConditions, final Duration timeout) {
-        return getPageBlobClient().createWithResponse(size, sequenceNumber, headers, metadata, requestConditions, timeout,
-                Context.NONE);
-    }
-
-    public Response<PageBlobItem> uploadPageBlob(
-            final PageRange pageRange, final InputStream body, final byte[] contentMd5,
-            final PageBlobRequestConditions pageBlobRequestConditions, final Duration timeout) {
-        return getPageBlobClient().uploadPagesWithResponse(pageRange, body, contentMd5, pageBlobRequestConditions, timeout,
-                Context.NONE);
-    }
-
-    public Response<PageBlobItem> resizePageBlob(
-            final long size, final BlobRequestConditions requestConditions, final Duration timeout) {
-        return getPageBlobClient().resizeWithResponse(size, requestConditions, timeout, Context.NONE);
-    }
-
-    public Response<PageBlobItem> clearPagesBlob(
-            final PageRange pageRange, final PageBlobRequestConditions pageBlobRequestConditions, final Duration timeout) {
-        return getPageBlobClient().clearPagesWithResponse(pageRange, pageBlobRequestConditions, timeout, Context.NONE);
-    }
-
-    public Response<PageList> getPageBlobRanges(
-            final BlobRange blobRange, final BlobRequestConditions requestConditions,
-            final Duration timeout) {
-        return getPageBlobClient().getPageRangesWithResponse(blobRange, requestConditions, timeout, Context.NONE);
-    }
-
-    public boolean pageBlobExists() {
-        return getPageBlobClient().exists();
-    }
-
-    public String generateSas(final BlobServiceSasSignatureValues blobServiceSasSignatureValues) {
-        return client.generateSas(blobServiceSasSignatureValues);
-    }
-
-    private BlockBlobClient getBlockBlobClient() {
-        return client.getBlockBlobClient();
-    }
-
-    private AppendBlobClient getAppendBlobClient() {
-        return client.getAppendBlobClient();
-    }
-
-    private PageBlobClient getPageBlobClient() {
-        return client.getPageBlobClient();
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobContainerClientWrapper.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobContainerClientWrapper.java
deleted file mode 100644
index 6047d68..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobContainerClientWrapper.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.client;
-
-import java.time.Duration;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import com.azure.core.http.HttpHeaders;
-import com.azure.core.util.Context;
-import com.azure.storage.blob.BlobContainerClient;
-import com.azure.storage.blob.models.BlobItem;
-import com.azure.storage.blob.models.BlobRequestConditions;
-import com.azure.storage.blob.models.ListBlobsOptions;
-import com.azure.storage.blob.models.PublicAccessType;
-import org.apache.camel.util.ObjectHelper;
-
-public class BlobContainerClientWrapper {
-
-    private final BlobContainerClient client;
-
-    public BlobContainerClientWrapper(final BlobContainerClient client) {
-        this.client = client;
-    }
-
-    public HttpHeaders createContainer(
-            final Map<String, String> metadata, final PublicAccessType publicAccessType, final Duration timeout) {
-        return client.createWithResponse(metadata, publicAccessType, timeout, Context.NONE).getHeaders();
-    }
-
-    public HttpHeaders deleteContainer(final BlobRequestConditions blobRequestConditions, final Duration timeout) {
-        return client.deleteWithResponse(blobRequestConditions, timeout, Context.NONE).getHeaders();
-    }
-
-    public List<BlobItem> listBlobs(final ListBlobsOptions listBlobsOptions, final Duration timeout) {
-        return client.listBlobs(listBlobsOptions, timeout).stream().collect(Collectors.toList());
-    }
-
-    public BlobClientWrapper getBlobClientWrapper(final String blobName) {
-        if (!ObjectHelper.isEmpty(blobName)) {
-            return new BlobClientWrapper(client.getBlobClient(blobName));
-        }
-        throw new IllegalArgumentException("Cannot initialize a blob since no blob name was provided.");
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobServiceClientWrapper.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobServiceClientWrapper.java
deleted file mode 100644
index dd2cb3b..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/client/BlobServiceClientWrapper.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.client;
-
-import java.time.Duration;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import com.azure.storage.blob.BlobServiceClient;
-import com.azure.storage.blob.models.BlobContainerItem;
-import com.azure.storage.blob.models.ListBlobContainersOptions;
-import org.apache.camel.util.ObjectHelper;
-
-public class BlobServiceClientWrapper {
-
-    private final BlobServiceClient client;
-
-    public BlobServiceClientWrapper(final BlobServiceClient client) {
-        ObjectHelper.notNull(client, "client cannot be null");
-
-        this.client = client;
-    }
-
-    public List<BlobContainerItem> listBlobContainers(final ListBlobContainersOptions options, final Duration timeout) {
-        return client.listBlobContainers(options, timeout).stream().collect(Collectors.toList());
-    }
-
-    public BlobContainerClientWrapper getBlobContainerClientWrapper(final String containerName) {
-        if (!ObjectHelper.isEmpty(containerName)) {
-            return new BlobContainerClientWrapper(client.getBlobContainerClient(containerName));
-        }
-        throw new IllegalArgumentException("Cannot initialize a blob container since no container name was provided.");
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperations.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperations.java
deleted file mode 100644
index 23f4a98..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperations.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.operations;
-
-import java.time.Duration;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import com.azure.storage.blob.models.BlobItem;
-import com.azure.storage.blob.models.BlobRequestConditions;
-import com.azure.storage.blob.models.ListBlobsOptions;
-import com.azure.storage.blob.models.PublicAccessType;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
-import org.apache.camel.component.azure.storage.blob.BlobConfigurationOptionsProxy;
-import org.apache.camel.component.azure.storage.blob.BlobExchangeHeaders;
-import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
-import org.apache.camel.util.ObjectHelper;
-
-/**
- * All operations related to {@link com.azure.storage.blob.BlobContainerClient}. This is at the container level.
- */
-public class BlobContainerOperations {
-
-    private final BlobContainerClientWrapper client;
-    private final BlobConfigurationOptionsProxy configurationProxy;
-
-    public BlobContainerOperations(final BlobConfiguration configuration, final BlobContainerClientWrapper client) {
-        ObjectHelper.notNull(client, "client cannot be null");
-        this.client = client;
-        this.configurationProxy = new BlobConfigurationOptionsProxy(configuration);
-    }
-
-    public BlobOperationResponse listBlobs(final Exchange exchange) {
-        final ListBlobsOptions listBlobOptions = configurationProxy.getListBlobOptions(exchange);
-        final Duration timeout = configurationProxy.getTimeout(exchange);
-        final String regex = configurationProxy.getRegex(exchange);
-        List<BlobItem> blobs = client.listBlobs(listBlobOptions, timeout);
-        if (ObjectHelper.isEmpty(regex)) {
-            return new BlobOperationResponse(blobs);
-        }
-        List<BlobItem> filteredBlobs = blobs.stream()
-                .filter(x -> x.getName().matches(regex))
-                .collect(Collectors.toCollection(LinkedList<BlobItem>::new));
-        return new BlobOperationResponse(filteredBlobs);
-    }
-
-    public BlobOperationResponse createContainer(final Exchange exchange) {
-        final Map<String, String> metadata = configurationProxy.getMetadata(exchange);
-        final PublicAccessType publicAccessType = configurationProxy.getPublicAccessType(exchange);
-        final Duration timeout = configurationProxy.getTimeout(exchange);
-
-        final BlobExchangeHeaders blobExchangeHeaders
-                = new BlobExchangeHeaders().httpHeaders(client.createContainer(metadata, publicAccessType, timeout));
-        return new BlobOperationResponse(true, blobExchangeHeaders.toMap());
-    }
-
-    public BlobOperationResponse deleteContainer(final Exchange exchange) {
-        final BlobRequestConditions blobRequestConditions = configurationProxy.getBlobRequestConditions(exchange);
-        final Duration timeout = configurationProxy.getTimeout(exchange);
-        final BlobExchangeHeaders blobExchangeHeaders
-                = new BlobExchangeHeaders().httpHeaders(client.deleteContainer(blobRequestConditions, timeout));
-        return new BlobOperationResponse(true, blobExchangeHeaders.toMap());
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationResponse.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationResponse.java
deleted file mode 100644
index cec4675..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationResponse.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.operations;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class BlobOperationResponse {
-
-    private Object body;
-    private Map<String, Object> headers = new HashMap<>();
-
-    public BlobOperationResponse() {
-    }
-
-    public BlobOperationResponse(final Object body, final Map<String, Object> headers) {
-        this.body = body;
-        this.headers = headers;
-    }
-
-    public BlobOperationResponse(final Object body) {
-        setBody(body);
-    }
-
-    public Object getBody() {
-        return body;
-    }
-
-    public void setBody(Object body) {
-        this.body = body;
-    }
-
-    public Map<String, Object> getHeaders() {
-        return headers;
-    }
-
-    public void setHeaders(final Map<String, Object> headers) {
-        this.headers = headers;
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperations.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperations.java
deleted file mode 100644
index 6080d8e..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperations.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.operations;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.time.Duration;
-import java.time.OffsetDateTime;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import com.azure.core.http.rest.Response;
-import com.azure.core.http.rest.ResponseBase;
-import com.azure.storage.blob.BlobClient;
-import com.azure.storage.blob.models.AccessTier;
-import com.azure.storage.blob.models.AppendBlobItem;
-import com.azure.storage.blob.models.BlobDownloadHeaders;
-import com.azure.storage.blob.models.BlobHttpHeaders;
-import com.azure.storage.blob.models.BlobProperties;
-import com.azure.storage.blob.models.BlobRange;
-import com.azure.storage.blob.models.BlobRequestConditions;
-import com.azure.storage.blob.models.Block;
-import com.azure.storage.blob.models.BlockBlobItem;
-import com.azure.storage.blob.models.BlockList;
-import com.azure.storage.blob.models.BlockListType;
-import com.azure.storage.blob.models.DeleteSnapshotsOptionType;
-import com.azure.storage.blob.models.DownloadRetryOptions;
-import com.azure.storage.blob.models.PageBlobItem;
-import com.azure.storage.blob.models.PageList;
-import com.azure.storage.blob.models.PageRange;
-import com.azure.storage.blob.models.ParallelTransferOptions;
-import com.azure.storage.blob.sas.BlobSasPermission;
-import com.azure.storage.blob.sas.BlobServiceSasSignatureValues;
-import org.apache.camel.Exchange;
-import org.apache.camel.Message;
-import org.apache.camel.component.azure.storage.blob.BlobBlock;
-import org.apache.camel.component.azure.storage.blob.BlobCommonRequestOptions;
-import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
-import org.apache.camel.component.azure.storage.blob.BlobConfigurationOptionsProxy;
-import org.apache.camel.component.azure.storage.blob.BlobConstants;
-import org.apache.camel.component.azure.storage.blob.BlobExchangeHeaders;
-import org.apache.camel.component.azure.storage.blob.BlobStreamAndLength;
-import org.apache.camel.component.azure.storage.blob.BlobUtils;
-import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
-import org.apache.camel.util.ObjectHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * All operations related {@link BlobClient}. This is at the blob level.
- */
-public class BlobOperations {
-
-    private static final Logger LOG = LoggerFactory.getLogger(BlobOperations.class);
-
-    private final BlobClientWrapper client;
-    private final BlobConfigurationOptionsProxy configurationProxy;
-
-    public BlobOperations(final BlobConfiguration configuration, final BlobClientWrapper client) {
-        ObjectHelper.notNull(client, "client can not be null.");
-
-        this.client = client;
-        this.configurationProxy = new BlobConfigurationOptionsProxy(configuration);
-    }
-
-    public BlobOperationResponse getBlob(final Exchange exchange) throws IOException {
-        LOG.trace("Getting a blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
-
-        final Message message = BlobUtils.getInMessage(exchange);
-        final OutputStream outputStream = ObjectHelper.isEmpty(message) ? null : message.getBody(OutputStream.class);
-        final BlobRange blobRange = configurationProxy.getBlobRange(exchange);
-        final BlobCommonRequestOptions blobCommonRequestOptions = getCommonRequestOptions(exchange);
-
-        if (outputStream == null) {
-            // Then we create an input stream
-            final Map<String, Object> blobInputStream
-                    = client.openInputStream(blobRange, blobCommonRequestOptions.getBlobRequestConditions());
-            final BlobExchangeHeaders blobExchangeHeaders = BlobExchangeHeaders
-                    .createBlobExchangeHeadersFromBlobProperties((BlobProperties) blobInputStream.get("properties"));
-
-            return new BlobOperationResponse(blobInputStream.get("inputStream"), blobExchangeHeaders.toMap());
-        }
-        // we have an outputStream set, so we use it
-        final DownloadRetryOptions downloadRetryOptions = getDownloadRetryOptions(configurationProxy);
-
-        try {
-            final ResponseBase<BlobDownloadHeaders, Void> response = client.downloadWithResponse(outputStream, blobRange,
-                    downloadRetryOptions, blobCommonRequestOptions.getBlobRequestConditions(),
-                    blobCommonRequestOptions.getContentMD5() != null, blobCommonRequestOptions.getTimeout());
-
-            final BlobExchangeHeaders blobExchangeHeaders
-                    = BlobExchangeHeaders.createBlobExchangeHeadersFromBlobDownloadHeaders(response.getDeserializedHeaders())
-                            .httpHeaders(response.getHeaders());
-
-            return new BlobOperationResponse(outputStream, blobExchangeHeaders.toMap());
-        } finally {
-            if (configurationProxy.getConfiguration().isCloseStreamAfterRead()) {
-                outputStream.close();
-            }
-        }
-    }
-
-    public BlobOperationResponse downloadBlobToFile(final Exchange exchange) {
-        // check for fileDir
-        final String fileDir = configurationProxy.getFileDir(exchange);
-        if (ObjectHelper.isEmpty(fileDir)) {
-            throw new IllegalArgumentException("In order to download a blob, you will need to specify the fileDir in the URI");
-        }
-
-        final File fileToDownload = new File(fileDir, client.getBlobName());
-        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
-        final BlobRange blobRange = configurationProxy.getBlobRange(exchange);
-        final ParallelTransferOptions parallelTransferOptions = configurationProxy.getParallelTransferOptions(exchange);
-        final DownloadRetryOptions downloadRetryOptions = getDownloadRetryOptions(configurationProxy);
-
-        final Response<BlobProperties> response = client.downloadToFileWithResponse(fileToDownload.toString(), blobRange,
-                parallelTransferOptions, downloadRetryOptions,
-                commonRequestOptions.getBlobRequestConditions(), commonRequestOptions.getContentMD5() != null,
-                commonRequestOptions.getTimeout());
-
-        final BlobExchangeHeaders exchangeHeaders
-                = BlobExchangeHeaders.createBlobExchangeHeadersFromBlobProperties(response.getValue())
-                        .httpHeaders(response.getHeaders())
-                        .fileName(fileToDownload.toString());
-
-        return new BlobOperationResponse(fileToDownload, exchangeHeaders.toMap());
-    }
-
-    public BlobOperationResponse deleteBlob(final Exchange exchange) {
-        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
-        final DeleteSnapshotsOptionType deleteSnapshotsOptionType = configurationProxy.getDeleteSnapshotsOptionType(exchange);
-
-        return buildResponse(client.delete(deleteSnapshotsOptionType, commonRequestOptions.getBlobRequestConditions(),
-                commonRequestOptions.getTimeout()), true);
-    }
-
-    public BlobOperationResponse downloadLink(final Exchange exchange) {
-        final OffsetDateTime offsetDateTime = OffsetDateTime.now();
-        final long defaultExpirationTime = 60L * 60L; // 1 hour
-        final BlobSasPermission sasPermission = new BlobSasPermission().setReadPermission(true); // only read access
-        final Long expirationMillis = configurationProxy.getDownloadLinkExpiration(exchange);
-
-        OffsetDateTime offsetDateTimeToSet;
-        if (expirationMillis != null) {
-            offsetDateTimeToSet = offsetDateTime.plusSeconds(expirationMillis / 1000);
-        } else {
-            offsetDateTimeToSet = offsetDateTime.plusSeconds(defaultExpirationTime);
-        }
-
-        final BlobServiceSasSignatureValues serviceSasSignatureValues
-                = new BlobServiceSasSignatureValues(offsetDateTimeToSet, sasPermission);
-        final String url = client.getBlobUrl() + "?" + client.generateSas(serviceSasSignatureValues);
-
-        final BlobExchangeHeaders headers = BlobExchangeHeaders.create().downloadLink(url);
-
-        return new BlobOperationResponse(true, headers.toMap());
-    }
-
-    public BlobOperationResponse uploadBlockBlob(final Exchange exchange) throws IOException {
-        ObjectHelper.notNull(exchange, "exchange cannot be null");
-
-        final BlobStreamAndLength blobStreamAndLength = BlobStreamAndLength.createBlobStreamAndLengthFromExchangeBody(exchange);
-        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
-
-        LOG.trace("Putting a block blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
-
-        try {
-            final Response<BlockBlobItem> response = client.uploadBlockBlob(blobStreamAndLength.getInputStream(),
-                    blobStreamAndLength.getStreamLength(), commonRequestOptions.getBlobHttpHeaders(),
-                    commonRequestOptions.getMetadata(), commonRequestOptions.getAccessTier(),
-                    commonRequestOptions.getContentMD5(), commonRequestOptions.getBlobRequestConditions(),
-                    commonRequestOptions.getTimeout());
-
-            return buildResponse(response, true);
-        } finally {
-            closeInputStreamIfNeeded(blobStreamAndLength.getInputStream());
-        }
-    }
-
-    public BlobOperationResponse stageBlockBlobList(final Exchange exchange) throws Exception {
-        ObjectHelper.notNull(exchange, "exchange cannot be null");
-
-        final Object object = exchange.getIn().getMandatoryBody();
-
-        List<BlobBlock> blobBlocks = null;
-        if (object instanceof List) {
-            // noinspection unchecked
-            blobBlocks = (List<BlobBlock>) object;
-        } else if (object instanceof BlobBlock) {
-            blobBlocks = Collections.singletonList((BlobBlock) object);
-        }
-        if (blobBlocks == null || blobBlocks.isEmpty()) {
-            throw new IllegalArgumentException("Illegal storageBlocks payload");
-        }
-
-        LOG.trace("Putting a blob [{}] from blocks from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
-
-        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
-
-        final List<Block> blockEntries = new LinkedList<>();
-
-        blobBlocks.forEach(blobBlock -> {
-            blockEntries.add(blobBlock.getBlockEntry());
-            client.stageBlockBlob(blobBlock.getBlockEntry().getName(),
-                    blobBlock.getBlockStream(),
-                    blobBlock.getBlockEntry().getSizeLong(),
-                    commonRequestOptions.getContentMD5(),
-                    commonRequestOptions.leaseId(),
-                    commonRequestOptions.getTimeout());
-        });
-
-        final boolean commitBlockListLater = configurationProxy.isCommitBlockListLater(exchange);
-
-        if (!commitBlockListLater) {
-            // let us commit now
-            exchange.getIn().setBody(blockEntries);
-            return commitBlobBlockList(exchange);
-        }
-
-        return new BlobOperationResponse(true);
-    }
-
-    @SuppressWarnings("unchecked")
-    public BlobOperationResponse commitBlobBlockList(final Exchange exchange) throws Exception {
-        ObjectHelper.notNull(exchange, "exchange cannot be null");
-
-        final Object object = exchange.getIn().getMandatoryBody();
-
-        List<Block> blockEntries = null;
-        if (object instanceof List) {
-            blockEntries = (List<Block>) object;
-        } else if (object instanceof Block) {
-            blockEntries = Collections.singletonList((Block) object);
-        }
-        if (blockEntries == null || blockEntries.isEmpty()) {
-            throw new IllegalArgumentException("Illegal commit block list payload");
-        }
-
-        LOG.trace("Putting a blob [{}] block list from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
-
-        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
-
-        final List<String> blockIds = blockEntries.stream()
-                .map(Block::getName)
-                .collect(Collectors.toList());
-
-        final Response<BlockBlobItem> response = client.commitBlockBlob(blockIds, commonRequestOptions.getBlobHttpHeaders(),
-                commonRequestOptions.getMetadata(),
-                commonRequestOptions.getAccessTier(), commonRequestOptions.getBlobRequestConditions(),
-                commonRequestOptions.getTimeout());
-
-        return buildResponse(response, true);
-    }
-
-    public BlobOperationResponse getBlobBlockList(final Exchange exchange) {
-        LOG.trace("Getting the blob block list [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
-
-        final BlockListType blockListType = configurationProxy.getBlockListType(exchange);
-        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
-
-        final Response<BlockList> response
-                = client.listBlobBlocks(blockListType, commonRequestOptions.leaseId(), commonRequestOptions.getTimeout());
-
-        return buildResponse(response, false);
-    }
-
-    public BlobOperationResponse createAppendBlob(final Exchange exchange) {
-        LOG.trace("Creating an append blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
-
-        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
-
-        final Response<AppendBlobItem> response
-                = client.createAppendBlob(commonRequestOptions.getBlobHttpHeaders(), commonRequestOptions.getMetadata(),
-                        commonRequestOptions.getBlobRequestConditions(), commonRequestOptions.getTimeout());
-
-        return buildResponse(response, true);
-    }
-
-    public BlobOperationResponse commitAppendBlob(final Exchange exchange) throws IOException {
-        ObjectHelper.notNull(exchange, "exchange cannot be null");
-
-        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
-        final boolean createAppendBlob = configurationProxy.isCreateAppendBlob(exchange);
-
-        // only if header is true and we don't have one exists
-        if (createAppendBlob && !client.appendBlobExists()) {
-            createAppendBlob(exchange);
-        }
-
-        final BlobStreamAndLength streamAndLength = BlobStreamAndLength.createBlobStreamAndLengthFromExchangeBody(exchange);
-
-        try {
-            final Response<AppendBlobItem> response
-                    = client.appendBlobBlock(streamAndLength.getInputStream(), streamAndLength.getStreamLength(),
-                            commonRequestOptions.getContentMD5(), commonRequestOptions.getBlobRequestConditions(),
-                            commonRequestOptions.getTimeout());
-
-            return buildResponse(response, true);
-        } finally {
-            closeInputStreamIfNeeded(streamAndLength.getInputStream());
-        }
-    }
-
-    public BlobOperationResponse createPageBlob(final Exchange exchange) {
-        LOG.trace("Creating a page blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
-
-        final Long pageSize = getPageBlobSize(exchange);
-        final BlobCommonRequestOptions requestOptions = getCommonRequestOptions(exchange);
-        final Long sequenceNumber = configurationProxy.getBlobSequenceNumber(exchange);
-
-        final Response<PageBlobItem> response
-                = client.createPageBlob(pageSize, sequenceNumber, requestOptions.getBlobHttpHeaders(),
-                        requestOptions.getMetadata(), requestOptions.getBlobRequestConditions(), requestOptions.getTimeout());
-
-        return buildResponse(response, true);
-    }
-
-    public BlobOperationResponse uploadPageBlob(final Exchange exchange) throws IOException {
-        ObjectHelper.notNull(exchange, "exchange cannot be null");
-
-        final boolean createPageBlob = configurationProxy.isCreatePageBlob(exchange);
-
-        // only if header is true and we don't have one exists
-        if (createPageBlob && !client.pageBlobExists()) {
-            createPageBlob(exchange);
-        }
-
-        final BlobStreamAndLength streamAndLength = BlobStreamAndLength.createBlobStreamAndLengthFromExchangeBody(exchange);
-        final BlobCommonRequestOptions requestOptions = getCommonRequestOptions(exchange);
-        final PageRange pageRange = configurationProxy.getPageRange(exchange);
-
-        if (pageRange == null) {
-            throw new IllegalArgumentException("You need to set page range in the exchange headers.");
-        }
-
-        try {
-            final Response<PageBlobItem> response
-                    = client.uploadPageBlob(pageRange, streamAndLength.getInputStream(), requestOptions.getContentMD5(),
-                            requestOptions.getBlobRequestConditions(), requestOptions.getTimeout());
-
-            return buildResponse(response, true);
-        } finally {
-            closeInputStreamIfNeeded(streamAndLength.getInputStream());
-        }
-    }
-
-    public BlobOperationResponse resizePageBlob(final Exchange exchange) {
-        LOG.trace("Resizing a page blob [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange), exchange);
-
-        final Long pageSize = getPageBlobSize(exchange);
-        final BlobCommonRequestOptions requestOptions = getCommonRequestOptions(exchange);
-
-        final Response<PageBlobItem> response
-                = client.resizePageBlob(pageSize, requestOptions.getBlobRequestConditions(), requestOptions.getTimeout());
-
-        return buildResponse(response, true);
-    }
-
-    public BlobOperationResponse clearPageBlob(final Exchange exchange) {
-        ObjectHelper.notNull(exchange, "exchange cannot be null");
-
-        final PageRange pageRange = configurationProxy.getPageRange(exchange);
-        final BlobCommonRequestOptions requestOptions = getCommonRequestOptions(exchange);
-
-        if (pageRange == null) {
-            throw new IllegalArgumentException("You need to set page range in the exchange headers.");
-        }
-
-        final Response<PageBlobItem> response
-                = client.clearPagesBlob(pageRange, requestOptions.getBlobRequestConditions(), requestOptions.getTimeout());
-
-        return buildResponse(response, true);
-    }
-
-    public BlobOperationResponse getPageBlobRanges(final Exchange exchange) {
-        ObjectHelper.notNull(exchange, "exchange cannot be null");
-
-        final BlobRange blobRange = configurationProxy.getBlobRange(exchange);
-        final BlobCommonRequestOptions commonRequestOptions = getCommonRequestOptions(exchange);
-
-        LOG.trace("Getting the page blob ranges [{}] from exchange [{}]...", configurationProxy.getBlobName(exchange),
-                exchange);
-
-        final Response<PageList> response = client.getPageBlobRanges(blobRange, commonRequestOptions.getBlobRequestConditions(),
-                commonRequestOptions.getTimeout());
-
-        return buildResponse(response, false);
-    }
-
-    private DownloadRetryOptions getDownloadRetryOptions(final BlobConfigurationOptionsProxy configurationProxy) {
-        return new DownloadRetryOptions().setMaxRetryRequests(configurationProxy.getMaxRetryRequests());
-    }
-
-    private BlobCommonRequestOptions getCommonRequestOptions(final Exchange exchange) {
-        final BlobHttpHeaders blobHttpHeaders = configurationProxy.getBlobHttpHeaders(exchange);
-        final Map<String, String> metadata = configurationProxy.getMetadata(exchange);
-        final AccessTier accessTier = configurationProxy.getAccessTier(exchange);
-        final BlobRequestConditions blobRequestConditions = configurationProxy.getBlobRequestConditions(exchange);
-        final Duration timeout = configurationProxy.getTimeout(exchange);
-        final byte[] contentMD5 = configurationProxy.getContentMd5(exchange);
-
-        return new BlobCommonRequestOptions(blobHttpHeaders, metadata, accessTier, blobRequestConditions, contentMD5, timeout);
-    }
-
-    @SuppressWarnings("rawtypes")
-    private BlobOperationResponse buildResponse(final Response response, final boolean emptyBody) {
-        final Object body = emptyBody ? true : response.getValue();
-        BlobExchangeHeaders exchangeHeaders;
-
-        if (response.getValue() instanceof BlockBlobItem) {
-            exchangeHeaders
-                    = BlobExchangeHeaders.createBlobExchangeHeadersFromBlockBlobItem((BlockBlobItem) response.getValue());
-        } else if (response.getValue() instanceof AppendBlobItem) {
-            exchangeHeaders
-                    = BlobExchangeHeaders.createBlobExchangeHeadersFromAppendBlobItem((AppendBlobItem) response.getValue());
-        } else if (response.getValue() instanceof PageBlobItem) {
-            exchangeHeaders = BlobExchangeHeaders.createBlobExchangeHeadersFromPageBlobItem((PageBlobItem) response.getValue());
-        } else if (response.getValue() instanceof BlobProperties) {
-            exchangeHeaders
-                    = BlobExchangeHeaders.createBlobExchangeHeadersFromBlobProperties((BlobProperties) response.getValue());
-        } else {
-            exchangeHeaders = BlobExchangeHeaders.create();
-        }
-
-        exchangeHeaders.httpHeaders(response.getHeaders());
-
-        return new BlobOperationResponse(body, exchangeHeaders.toMap());
-    }
-
-    private Long getPageBlobSize(final Exchange exchange) {
-        // we try to get the size from the page range if exists
-        final PageRange pageRange = configurationProxy.getPageRange(exchange);
-        if (pageRange != null) {
-            return pageRange.getEnd() - pageRange.getStart() + 1; //e.g: 1023-0+1 = 1024 size
-        }
-        // now we try the page size
-        final Long pageSize = configurationProxy.getPageBlobSize(exchange);
-        if (pageSize != null) {
-            return pageSize;
-        }
-        return BlobConstants.PAGE_BLOB_DEFAULT_SIZE;
-    }
-
-    private void closeInputStreamIfNeeded(InputStream inputStream) throws IOException {
-        if (configurationProxy.getConfiguration().isCloseStreamAfterWrite()) {
-            inputStream.close();
-        }
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobServiceOperations.java b/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobServiceOperations.java
deleted file mode 100644
index 631f33d..0000000
--- a/components/camel-azure-storage-blob/src/main/java/org/apache/camel/component/azure/storage/blob/operations/BlobServiceOperations.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.operations;
-
-import java.time.Duration;
-
-import com.azure.storage.blob.models.ListBlobContainersOptions;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
-import org.apache.camel.component.azure.storage.blob.BlobConfigurationOptionsProxy;
-import org.apache.camel.component.azure.storage.blob.client.BlobServiceClientWrapper;
-import org.apache.camel.util.ObjectHelper;
-
-/**
- * Operations related to {@link com.azure.storage.blob.BlobServiceClient}. This is at the service level.
- */
-public class BlobServiceOperations {
-
-    private final BlobServiceClientWrapper client;
-    private final BlobConfigurationOptionsProxy configurationProxy;
-
-    public BlobServiceOperations(final BlobConfiguration configuration, final BlobServiceClientWrapper client) {
-        ObjectHelper.notNull(client, "client cannot be null");
-
-        this.client = client;
-        this.configurationProxy = new BlobConfigurationOptionsProxy(configuration);
-    }
-
-    public BlobOperationResponse listBlobContainers(final Exchange exchange) {
-        final ListBlobContainersOptions listBlobContainersOptions = configurationProxy.getListBlobContainersOptions(exchange);
-        final Duration timeout = configurationProxy.getTimeout(exchange);
-
-        return new BlobOperationResponse(client.listBlobContainers(listBlobContainersOptions, timeout));
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobComponentTest.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobComponentTest.java
deleted file mode 100644
index 0fc2066..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobComponentTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.util.Collections;
-
-import com.azure.storage.blob.BlobServiceClient;
-import com.azure.storage.common.StorageSharedKeyCredential;
-import org.apache.camel.Producer;
-import org.apache.camel.component.azure.storage.blob.client.BlobClientFactory;
-import org.apache.camel.support.DefaultExchange;
-import org.apache.camel.test.junit5.CamelTestSupport;
-import org.junit.jupiter.api.Test;
-
-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.assertNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class BlobComponentTest extends CamelTestSupport {
-
-    @Test
-    void testCreateEndpointWithMinConfigForClientOnly() {
-        final BlobConfiguration configuration = new BlobConfiguration();
-        configuration.setCredentials(storageSharedKeyCredential());
-        final BlobServiceClient serviceClient = BlobClientFactory.createBlobServiceClient(configuration);
-
-        context.getRegistry().bind("azureBlobClient", serviceClient);
-
-        final BlobEndpoint endpoint = (BlobEndpoint) context
-                .getEndpoint("azure-storage-blob://camelazure/container?blobName=blob&serviceClient=#azureBlobClient");
-
-        doTestCreateEndpointWithMinConfig(endpoint, true);
-    }
-
-    @Test
-    void testCreateEndpointWithMinConfigForCredsOnly() throws Exception {
-        context.getRegistry().bind("creds", storageSharedKeyCredential());
-
-        final BlobEndpoint endpoint = (BlobEndpoint) context
-                .getEndpoint("azure-storage-blob://camelazure/container?blobName=blob&credentials=#creds");
-
-        doTestCreateEndpointWithMinConfig(endpoint, false);
-    }
-
-    private void doTestCreateEndpointWithMinConfig(BlobEndpoint endpoint, boolean clientExpected) {
-        assertEquals("camelazure", endpoint.getConfiguration().getAccountName());
-        assertEquals("container", endpoint.getConfiguration().getContainerName());
-        assertEquals("blob", endpoint.getConfiguration().getBlobName());
-        if (clientExpected) {
-            assertNotNull(endpoint.getConfiguration().getServiceClient());
-            assertNull(endpoint.getConfiguration().getCredentials());
-        } else {
-            assertNull(endpoint.getConfiguration().getServiceClient());
-            assertNotNull(endpoint.getConfiguration().getCredentials());
-        }
-
-        assertEquals(BlobType.blockblob, endpoint.getConfiguration().getBlobType());
-        assertNull(endpoint.getConfiguration().getFileDir());
-        assertEquals(Long.valueOf(0L), endpoint.getConfiguration().getBlobOffset());
-        assertEquals(BlobOperationsDefinition.listBlobContainers, endpoint.getConfiguration().getOperation());
-        assertTrue(endpoint.getConfiguration().isCloseStreamAfterRead());
-        assertTrue(endpoint.getConfiguration().isCloseStreamAfterWrite());
-    }
-
-    @Test
-    void testCreateEndpointWithMaxConfig() {
-        context.getRegistry().bind("creds", storageSharedKeyCredential());
-        context.getRegistry().bind("metadata", Collections.emptyMap());
-
-        final String uri = "azure-storage-blob://camelazure/container"
-                           + "?blobName=blob&credentials=#creds&blobType=pageblob"
-                           + "&fileDir=/tmp&blobOffset=512&operation=clearPageBlob&dataCount=1024"
-                           + "&closeStreamAfterRead=false&closeStreamAfterWrite=false";
-        final BlobEndpoint endpoint = (BlobEndpoint) context.getEndpoint(uri);
-
-        assertEquals("camelazure", endpoint.getConfiguration().getAccountName());
-        assertEquals("container", endpoint.getConfiguration().getContainerName());
-        assertEquals("blob", endpoint.getConfiguration().getBlobName());
-        assertNull(endpoint.getConfiguration().getServiceClient());
-        assertNotNull(endpoint.getConfiguration().getCredentials());
-
-        assertEquals(BlobType.pageblob, endpoint.getConfiguration().getBlobType());
-        assertEquals("/tmp", endpoint.getConfiguration().getFileDir());
-        assertEquals(Long.valueOf(512L), endpoint.getConfiguration().getBlobOffset());
-        assertEquals(Long.valueOf(1024L), endpoint.getConfiguration().getDataCount());
-        assertEquals(BlobOperationsDefinition.clearPageBlob, endpoint.getConfiguration().getOperation());
-        assertFalse(endpoint.getConfiguration().isCloseStreamAfterRead());
-        assertFalse(endpoint.getConfiguration().isCloseStreamAfterWrite());
-    }
-
-    @Test
-    void testNoBlobNameProducerWithOpThatNeedsBlobName() throws Exception {
-        context.getRegistry().bind("creds", storageSharedKeyCredential());
-
-        BlobEndpoint endpointWithOp = (BlobEndpoint) context.getEndpoint(
-                "azure-storage-blob://camelazure/container?operation=deleteBlob&credentials=#creds");
-
-        Producer producer = endpointWithOp.createProducer();
-        DefaultExchange exchange = new DefaultExchange(context);
-
-        assertThrows(IllegalArgumentException.class, () -> producer.process(exchange));
-    }
-
-    @Test
-    void testHierarchicalBlobName() throws Exception {
-        context.getRegistry().bind("creds", storageSharedKeyCredential());
-
-        BlobEndpoint endpoint = (BlobEndpoint) context
-                .getEndpoint("azure-storage-blob://camelazure/container?blobName=blob/sub&credentials=#creds");
-        assertEquals("blob/sub", endpoint.getConfiguration().getBlobName());
-    }
-
-    private StorageSharedKeyCredential storageSharedKeyCredential() {
-        return new StorageSharedKeyCredential("fakeuser", "fakekey");
-    }
-
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxyTest.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxyTest.java
deleted file mode 100644
index 59a5a8c..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobConfigurationOptionsProxyTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import org.apache.camel.Exchange;
-import org.apache.camel.support.DefaultExchange;
-import org.apache.camel.test.junit5.CamelTestSupport;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-
-class BlobConfigurationOptionsProxyTest extends CamelTestSupport {
-
-    @Test
-    void testIfCorrectOptionsReturnedCorrectly() {
-        final BlobConfiguration configuration = new BlobConfiguration();
-
-        // first case: when exchange is set
-        final Exchange exchange = new DefaultExchange(context);
-        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
-
-        exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "testBlobExchange");
-        configuration.setBlobName("testBlobConfig");
-
-        assertEquals("testBlobExchange", configurationOptionsProxy.getBlobName(exchange));
-
-        // second class: exchange is empty
-        exchange.getIn().setHeader(BlobConstants.BLOB_NAME, null);
-
-        assertEquals("testBlobConfig", configurationOptionsProxy.getBlobName(exchange));
-
-        // third class: if no option at all
-        configuration.setBlobName(null);
-
-        assertNull(configurationOptionsProxy.getBlobName(exchange));
-    }
-
-    @Test
-    void testIfCorrectOptionsReturnedCorrectlyWithPrefixAndRegexSet() {
-        final BlobConfiguration configuration = new BlobConfiguration();
-
-        final Exchange exchange = new DefaultExchange(context);
-        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
-
-        configuration.setPrefix("test");
-        configuration.setRegex(".*\\.exe");
-
-        assertNull(configurationOptionsProxy.getPrefix(exchange));
-        assertEquals(".*\\.exe", configurationOptionsProxy.getRegex(exchange));
-    }
-
-    @Test
-    void testIfCorrectOptionsReturnedCorrectlyWithPrefixAndRegexSetInHeader() {
-        final BlobConfiguration configuration = new BlobConfiguration();
-
-        // first case: when exchange is set
-        final Exchange exchange = new DefaultExchange(context);
-        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
-
-        configuration.setPrefix("test");
-        configuration.setRegex(".*\\.exe");
-        exchange.getIn().setHeader(BlobConstants.PREFIX, "test2");
-        exchange.getIn().setHeader(BlobConstants.REGEX, ".*\\.pdf");
-        assertNull(configurationOptionsProxy.getPrefix(exchange));
-        assertEquals(".*\\.pdf", configurationOptionsProxy.getRegex(exchange));
-    }
-
-    @Test
-    void testIfCorrectOptionsReturnedCorrectlyWithPrefixSet() {
-        final BlobConfiguration configuration = new BlobConfiguration();
-
-        // first case: when exchange is set
-        final Exchange exchange = new DefaultExchange(context);
-        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
-
-        configuration.setPrefix("test");
-        assertEquals("test", configurationOptionsProxy.getPrefix(exchange));
-
-        //test header override
-        exchange.getIn().setHeader(BlobConstants.PREFIX, "test2");
-        assertEquals("test2", configurationOptionsProxy.getPrefix(exchange));
-    }
-
-    @Test
-    void testIfCorrectOptionsReturnedCorrectlyWithRegexSet() {
-        final BlobConfiguration configuration = new BlobConfiguration();
-
-        // first case: when exchange is set
-        final Exchange exchange = new DefaultExchange(context);
-        final BlobConfigurationOptionsProxy configurationOptionsProxy = new BlobConfigurationOptionsProxy(configuration);
-
-        configuration.setRegex(".*\\.exe");
-        assertEquals(".*\\.exe", configurationOptionsProxy.getRegex(exchange));
-
-        //test header override
-        exchange.getIn().setHeader(BlobConstants.REGEX, ".*\\.pdf");
-        assertEquals(".*\\.pdf", configurationOptionsProxy.getRegex(exchange));
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobTestUtils.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobTestUtils.java
deleted file mode 100644
index 2548bcd..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/BlobTestUtils.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Objects;
-import java.util.Properties;
-
-public final class BlobTestUtils {
-
-    private BlobTestUtils() {
-    }
-
-    public static Properties getAzuriteProperties() {
-        final Properties properties = new Properties();
-        final String fileName = "azurite.properties";
-
-        final InputStream inputStream
-                = Objects.requireNonNull(BlobTestUtils.class.getClassLoader().getResourceAsStream(fileName));
-
-        try {
-            properties.load(inputStream);
-        } catch (IOException e) {
-            throw new IllegalArgumentException("Could not initialize Azurite properties", e);
-        }
-
-        return properties;
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BaseIT.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BaseIT.java
deleted file mode 100644
index 90591d0..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BaseIT.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.integration;
-
-import com.azure.storage.blob.BlobServiceClient;
-import com.azure.storage.common.StorageSharedKeyCredential;
-import org.apache.camel.CamelContext;
-import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
-import org.apache.camel.test.infra.azure.common.AzureConfigs;
-import org.apache.camel.test.infra.azure.common.services.AzureService;
-import org.apache.camel.test.infra.azure.storage.blob.clients.AzureStorageBlobClientUtils;
-import org.apache.camel.test.infra.azure.storage.blob.services.AzureStorageBlobServiceFactory;
-import org.apache.camel.test.junit5.CamelTestSupport;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.extension.RegisterExtension;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-public class BaseIT extends CamelTestSupport {
-    @RegisterExtension
-    public static AzureService service;
-
-    protected BlobServiceClient serviceClient;
-    protected String containerName;
-    protected BlobConfiguration configuration;
-
-    static {
-        initCredentials();
-
-        service = AzureStorageBlobServiceFactory.createAzureService();
-    }
-
-    /*
-     * The previous behavior of the test code was such that if accessKey or accountName properties were
-     * set, the code would not start the azurite container and would execute against a remote environment.
-     * To avoid breaking tests for environments relying on this behavior, copy the old properties into the
-     *  new and set the test as remote.
-     */
-    private static void initCredentials() {
-        String accountName = System.getProperty("accountName");
-        String accessKey = System.getProperty("accessKey");
-
-        if (StringUtils.isNotEmpty(accountName) && StringUtils.isNotEmpty(accessKey)) {
-            System.setProperty(AzureConfigs.ACCOUNT_NAME, accountName);
-            System.setProperty(AzureConfigs.ACCOUNT_KEY, accessKey);
-            System.setProperty("azure.instance.type", "remote");
-        }
-    }
-
-    @Override
-    protected CamelContext createCamelContext() throws Exception {
-        CamelContext context = super.createCamelContext();
-        context.getRegistry().bind("serviceClient", serviceClient);
-        return context;
-    }
-
-    @BeforeAll
-    public void initProperties() {
-        containerName = RandomStringUtils.randomAlphabetic(5).toLowerCase();
-
-        configuration = new BlobConfiguration();
-        configuration.setCredentials(new StorageSharedKeyCredential(
-                service.azureCredentials().accountName(), service.azureCredentials().accountKey()));
-        configuration.setContainerName(containerName);
-
-        serviceClient = AzureStorageBlobClientUtils.getClient();
-    }
-
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobConsumerITTest.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobConsumerITTest.java
deleted file mode 100644
index 4a18931..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobConsumerITTest.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.integration;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.InputStreamReader;
-import java.nio.file.Path;
-import java.util.regex.Pattern;
-
-import com.azure.storage.blob.BlobContainerClient;
-import com.azure.storage.blob.specialized.BlobInputStream;
-import org.apache.camel.EndpointInject;
-import org.apache.camel.Exchange;
-import org.apache.camel.ProducerTemplate;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.azure.storage.blob.BlobConstants;
-import org.apache.camel.component.mock.MockEndpoint;
-import org.apache.camel.support.processor.idempotent.MemoryIdempotentRepository;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-
-import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class BlobConsumerITTest extends BaseIT {
-
-    @TempDir
-    static Path testDir;
-    @EndpointInject("direct:start")
-    private ProducerTemplate templateStart;
-    private String batchContainerName;
-    private String blobName;
-    private String blobName2;
-
-    private BlobContainerClient containerClient;
-    private BlobContainerClient batchContainerClient;
-    private final String regex = ".*\\.pdf";
-
-    @BeforeAll
-    public void setup() {
-        batchContainerName = RandomStringUtils.randomAlphabetic(5).toLowerCase();
-        blobName = RandomStringUtils.randomAlphabetic(5);
-        blobName2 = RandomStringUtils.randomAlphabetic(5);
-
-        containerClient = serviceClient.getBlobContainerClient(containerName);
-        batchContainerClient = serviceClient.getBlobContainerClient(batchContainerName);
-
-        // create test container
-        containerClient.create();
-        batchContainerClient.create();
-    }
-
-    @Test
-    void testPollingToFile() throws Exception {
-        final MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
-        mockEndpoint.expectedMessageCount(1);
-
-        templateStart.send("direct:createBlob", exchange -> {
-            exchange.getIn().setBody("Block Blob");
-            exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, containerName);
-            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
-        });
-
-        mockEndpoint.assertIsSatisfied();
-
-        final File file = mockEndpoint.getExchanges().get(0).getIn().getBody(File.class);
-        assertNotNull(file, "File must be set");
-        assertEquals("Block Blob", context().getTypeConverter().convertTo(String.class, file));
-    }
-
-    @Test
-    void testPollingToInputStream() throws Exception {
-        templateStart.send("direct:createBlob", exchange -> {
-            exchange.getIn().setBody("Block Blob");
-            exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, containerName);
-            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName2);
-        });
-
-        final MockEndpoint mockEndpoint = getMockEndpoint("mock:resultOutputStream");
-        mockEndpoint.expectedMessageCount(1);
-        mockEndpoint.assertIsSatisfied();
-
-        final BlobInputStream blobInputStream = mockEndpoint.getExchanges().get(0).getIn().getBody(BlobInputStream.class);
-        assertNotNull(blobInputStream, "BlobInputStream must be set");
-
-        final String bufferedText = new BufferedReader(new InputStreamReader(blobInputStream)).readLine();
-
-        assertEquals("Block Blob", bufferedText);
-    }
-
-    @Test
-    void testBatchFilePolling() throws Exception {
-        // test output stream based
-        final MockEndpoint mockEndpoint = getMockEndpoint("mock:resultBatch");
-        mockEndpoint.expectedMessageCount(2);
-
-        // test file based
-        final MockEndpoint mockEndpointFile = getMockEndpoint("mock:resultBatchFile");
-        mockEndpointFile.expectedMessageCount(2);
-
-        templateStart.send("direct:createBlob", exchange -> {
-            exchange.getIn().setBody("Block Batch Blob 1");
-            exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
-            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "test_batch_blob_1");
-        });
-
-        templateStart.send("direct:createBlob", exchange -> {
-            exchange.getIn().setBody("Block Batch Blob 2");
-            exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
-            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, "test_batch_blob_2");
-        });
-
-        MockEndpoint.assertIsSatisfied(context());
-
-        final BlobInputStream blobInputStream = mockEndpoint.getExchanges().get(0).getIn().getBody(BlobInputStream.class);
-        final BlobInputStream blobInputStream2 = mockEndpoint.getExchanges().get(1).getIn().getBody(BlobInputStream.class);
-
-        assertNotNull(blobInputStream, "BlobInputStream must be set");
-        assertNotNull(blobInputStream2, "BlobInputStream must be set");
-
-        final String bufferedText = context().getTypeConverter().convertTo(String.class, blobInputStream);
-        final String bufferedText2 = context().getTypeConverter().convertTo(String.class, blobInputStream2);
-
-        assertEquals("Block Batch Blob 1", bufferedText);
-        assertEquals("Block Batch Blob 2", bufferedText2);
-
-        final File file = mockEndpointFile.getExchanges().get(0).getIn().getBody(File.class);
-        final File file2 = mockEndpointFile.getExchanges().get(1).getIn().getBody(File.class);
-
-        assertNotNull(file, "File must be set");
-        assertNotNull(file2, "File must be set");
-
-        assertEquals("Block Batch Blob 1", context().getTypeConverter().convertTo(String.class, file));
-        assertEquals("Block Batch Blob 2", context().getTypeConverter().convertTo(String.class, file2));
-    }
-
-    @Test
-    void testRegexPolling() throws Exception {
-        // test regex based
-        final MockEndpoint mockEndpoint = getMockEndpoint("mock:resultRegex");
-        mockEndpoint.expectedMessageCount(15);
-
-        // create pdf blobs
-        for (int i = 0; i < 10; i++) {
-            final int index = i;
-            templateStart.send("direct:createBlob", exchange -> {
-                exchange.getIn().setBody("Block Batch PDF Blob with RegEx Test: " + index);
-                exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
-                exchange.getIn().setHeader(BlobConstants.BLOB_NAME, generateRandomBlobName("regexp-test_batch_blob_", "pdf"));
-            });
-        }
-
-        for (int i = 0; i < 5; i++) {
-            final int index = i;
-            templateStart.send("direct:createBlob", exchange -> {
-                exchange.getIn().setBody("Block Batch PDF Blob with Prefix Test: " + index);
-                exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
-                exchange.getIn().setHeader(BlobConstants.BLOB_NAME, generateRandomBlobName("aaaa-test_batch_blob_", "pdf"));
-            });
-        }
-
-        // create docx blobs
-        for (int i = 0; i < 20; i++) {
-            final int index = i;
-            templateStart.send("direct:createBlob", exchange -> {
-                exchange.getIn().setBody("Block Batch DOCX Blob Test: " + index);
-                exchange.getIn().setHeader(BlobConstants.BLOB_CONTAINER_NAME, batchContainerName);
-                exchange.getIn().setHeader(BlobConstants.BLOB_NAME, generateRandomBlobName("regexp-test_batch_blob_", "docx"));
-            });
-        }
-
-        mockEndpoint.assertIsSatisfied();
-
-        Pattern pattern = Pattern.compile(regex);
-        for (Exchange e : mockEndpoint.getExchanges()) {
-            String blobName = e.getIn().getHeader(BlobConstants.BLOB_NAME, String.class);
-            assertTrue(pattern.matcher(blobName).matches());
-        }
-    }
-
-    private String generateRandomBlobName(String prefix, String extension) {
-        return prefix + randomAlphabetic(5).toLowerCase() + "." + extension;
-    }
-
-    @AfterAll
-    public void tearDown() {
-        // delete container
-        containerClient.delete();
-        batchContainerClient.delete();
-    }
-
-    @Override
-    protected RouteBuilder createRouteBuilder() {
-        return new RouteBuilder() {
-            @Override
-            public void configure() {
-                from("direct:createBlob")
-                        .to("azure-storage-blob://cameldev?blobServiceClient=#serviceClient&operation=uploadBlockBlob");
-
-                from("azure-storage-blob://cameldev/" + containerName + "?blobName=" + blobName
-                     + "&blobServiceClient=#serviceClient&fileDir="
-                     + testDir.toString()).to("mock:result");
-
-                from("azure-storage-blob://cameldev/" + containerName + "?blobName=" + blobName2
-                     + "&blobServiceClient=#serviceClient")
-                             .to("mock:resultOutputStream");
-
-                from("azure-storage-blob://cameldev/" + batchContainerName + "?blobServiceClient=#serviceClient")
-                        .to("mock:resultBatch");
-
-                from("azure-storage-blob://cameldev/" + batchContainerName + "?blobServiceClient=#serviceClient&fileDir="
-                     + testDir.toString()).to("mock:resultBatchFile");
-
-                // if regex is set then prefix should have no effect
-                from("azure-storage-blob://cameldev/" + batchContainerName
-                     + "?blobServiceClient=#serviceClient&prefix=aaaa&regex=" + regex)
-                             .idempotentConsumer(body(), new MemoryIdempotentRepository())
-                             .to("mock:resultRegex");
-            }
-        };
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobContainerOperationsITTest.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobContainerOperationsITTest.java
deleted file mode 100644
index 2e45bde..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobContainerOperationsITTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.integration;
-
-import java.util.Collections;
-import java.util.concurrent.TimeUnit;
-
-import com.azure.storage.blob.models.BlobStorageException;
-import com.azure.storage.blob.models.PublicAccessType;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.azure.storage.blob.BlobConstants;
-import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
-import org.apache.camel.component.azure.storage.blob.client.BlobServiceClientWrapper;
-import org.apache.camel.component.azure.storage.blob.operations.BlobContainerOperations;
-import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
-import org.apache.camel.support.DefaultExchange;
-import org.awaitility.Awaitility;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class BlobContainerOperationsITTest extends BaseIT {
-
-    private BlobServiceClientWrapper blobServiceClientWrapper;
-
-    @BeforeAll
-    public void setup() {
-        blobServiceClientWrapper = new BlobServiceClientWrapper(serviceClient);
-    }
-
-    @Test
-    void testCreateAndDeleteContainer() {
-        final BlobContainerClientWrapper containerClientWrapper
-                = blobServiceClientWrapper.getBlobContainerClientWrapper("testcontainer1");
-        final BlobContainerOperations blobContainerOperations
-                = new BlobContainerOperations(configuration, containerClientWrapper);
-
-        final BlobOperationResponse response = blobContainerOperations.createContainer(null);
-
-        assertNotNull(response);
-        assertNotNull(response.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS));
-        assertTrue((boolean) response.getBody());
-
-        // delete everything
-        blobContainerOperations.deleteContainer(null);
-
-        // test with options being set
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setHeader(BlobConstants.METADATA, Collections.singletonMap("testKeyMetadata", "testValueMetadata"));
-        exchange.getIn().setHeader(BlobConstants.PUBLIC_ACCESS_TYPE, PublicAccessType.CONTAINER);
-
-        // try to create the container again, we try until we can
-        Awaitility.given()
-                .ignoreException(BlobStorageException.class)
-                .with()
-                .pollInterval(100, TimeUnit.MILLISECONDS)
-                .await()
-                .atMost(60, TimeUnit.SECONDS)
-                .until(() -> {
-                    final BlobOperationResponse response1 = blobContainerOperations.createContainer(exchange);
-                    assertNotNull(response1);
-                    assertNotNull(response1.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS));
-
-                    return (boolean) response1.getBody();
-                });
-    }
-
-    @AfterAll
-    public void cleanUp() {
-        blobServiceClientWrapper.getBlobContainerClientWrapper("testcontainer1").deleteContainer(null, null);
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobOperationsITTest.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobOperationsITTest.java
deleted file mode 100644
index fbf60be..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobOperationsITTest.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.integration;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
-import java.security.SecureRandom;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-
-import com.azure.storage.blob.models.PageList;
-import com.azure.storage.blob.models.PageRange;
-import com.azure.storage.blob.specialized.BlobInputStream;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.azure.storage.blob.BlobBlock;
-import org.apache.camel.component.azure.storage.blob.BlobConstants;
-import org.apache.camel.component.azure.storage.blob.BlobUtils;
-import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
-import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
-import org.apache.camel.component.azure.storage.blob.client.BlobServiceClientWrapper;
-import org.apache.camel.component.azure.storage.blob.operations.BlobOperationResponse;
-import org.apache.camel.component.azure.storage.blob.operations.BlobOperations;
-import org.apache.camel.converter.stream.FileInputStreamCache;
-import org.apache.camel.support.DefaultExchange;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class BlobOperationsITTest extends BaseIT {
-
-    private BlobContainerClientWrapper blobContainerClientWrapper;
-
-    private String randomBlobName;
-
-    @BeforeAll
-    public void setup() throws Exception {
-        randomBlobName = RandomStringUtils.randomAlphabetic(10);
-
-        blobContainerClientWrapper = new BlobServiceClientWrapper(serviceClient)
-                .getBlobContainerClientWrapper(configuration.getContainerName());
-
-        // create test container
-        blobContainerClientWrapper.createContainer(null, null, null);
-
-        // create test blob
-        final InputStream inputStream = new ByteArrayInputStream("awesome camel!".getBytes());
-        blobContainerClientWrapper.getBlobClientWrapper(randomBlobName).uploadBlockBlob(inputStream,
-                BlobUtils.getInputStreamLength(inputStream), null, null, null, null,
-                null, null);
-    }
-
-    @AfterAll
-    public void tearDown() {
-        blobContainerClientWrapper.deleteContainer(null, null);
-    }
-
-    @Test
-    void testGetBlob(@TempDir Path testDir) throws IOException {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper(randomBlobName);
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        // first: test with exchange set but no outputstream set
-        final Exchange exchange = new DefaultExchange(context);
-        final BlobOperationResponse response1 = operations.getBlob(exchange);
-
-        assertNotNull(response1);
-        assertNotNull(response1.getBody());
-        assertNotNull(response1.getHeaders());
-
-        final BlobInputStream inputStream = (BlobInputStream) response1.getBody();
-        final String bufferedText = new BufferedReader(new InputStreamReader(inputStream)).readLine();
-
-        assertEquals("awesome camel!", bufferedText);
-
-        // second: test with outputstream set on exchange
-        final File fileToWrite = new File(testDir.toFile(), "write_test_file.txt");
-        exchange.getIn().setBody(new FileOutputStream(fileToWrite));
-
-        final BlobOperationResponse response2 = operations.getBlob(exchange);
-        final String fileContent = FileUtils.readFileToString(fileToWrite, Charset.defaultCharset());
-
-        assertNotNull(response2);
-        assertNotNull(response2.getBody());
-        assertNotNull(response2.getHeaders());
-        assertTrue(fileContent.contains("awesome camel!"));
-    }
-
-    @Test
-    void testDownloadToFile(@TempDir Path testDir) throws IOException {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper(randomBlobName);
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setHeader(BlobConstants.FILE_DIR, testDir.toString());
-        exchange.getIn().setHeader(BlobConstants.BLOB_NAME, randomBlobName);
-
-        final BlobOperationResponse response = operations.downloadBlobToFile(exchange);
-
-        // third: test with outputstream set on exchange
-        final File fileToWrite = testDir.resolve(randomBlobName).toFile();
-        final String fileContent = FileUtils.readFileToString(fileToWrite, Charset.defaultCharset());
-
-        assertNotNull(response);
-        assertNotNull(response.getBody());
-        assertNotNull(response.getHeaders());
-        assertNotNull(response.getHeaders().get(BlobConstants.FILE_NAME));
-        assertTrue(fileContent.contains("awesome camel!"));
-    }
-
-    @Test
-    void testDownloadLink() {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper(randomBlobName);
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        final BlobOperationResponse response = operations.downloadLink(null);
-
-        assertNotNull(response);
-        assertTrue((boolean) response.getBody());
-        assertNotNull(response.getHeaders().get(BlobConstants.DOWNLOAD_LINK));
-    }
-
-    @Test
-    void testUploadBlockBlob() throws Exception {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        // first: test as file provided
-        final File fileToUpload
-                = new File(Objects.requireNonNull(getClass().getClassLoader().getResource("upload_test_file")).getFile());
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(fileToUpload);
-
-        final BlobOperationResponse response = operations.uploadBlockBlob(exchange);
-
-        assertNotNull(response);
-        assertTrue((boolean) response.getBody());
-        // check for eTag and md5 to make sure is uploaded
-        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
-        assertNotNull(response.getHeaders().get(BlobConstants.CONTENT_MD5));
-
-        // check content
-        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
-
-        assertEquals("awesome camel to upload!",
-                IOUtils.toString((InputStream) getBlobResponse.getBody(), Charset.defaultCharset()));
-
-        blobClientWrapper.delete(null, null, null);
-
-        // second: test as string provided
-        final String data = "Hello world from my awesome tests!";
-        final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
-        exchange.getIn().setBody(dataStream);
-
-        final BlobOperationResponse response2 = operations.uploadBlockBlob(exchange);
-
-        assertNotNull(response2);
-        assertTrue((boolean) response2.getBody());
-        // check for eTag and md5 to make sure is uploaded
-        assertNotNull(response2.getHeaders().get(BlobConstants.E_TAG));
-        assertNotNull(response2.getHeaders().get(BlobConstants.CONTENT_MD5));
-
-        // check content
-        final BlobOperationResponse getBlobResponse2 = operations.getBlob(null);
-
-        assertEquals(data, IOUtils.toString((InputStream) getBlobResponse2.getBody(), Charset.defaultCharset()));
-
-        blobClientWrapper.delete(null, null, null);
-    }
-
-    @Test
-    void testUploadBlockBlobAsCachedStream() throws Exception {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        final File fileToUpload
-                = new File(Objects.requireNonNull(getClass().getClassLoader().getResource("upload_test_file")).getFile());
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(new FileInputStreamCache(fileToUpload));
-
-        final BlobOperationResponse response = operations.uploadBlockBlob(exchange);
-
-        assertNotNull(response);
-        assertTrue((boolean) response.getBody());
-        // check for eTag and md5 to make sure is uploaded
-        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
-        assertNotNull(response.getHeaders().get(BlobConstants.CONTENT_MD5));
-
-        // check content
-        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
-
-        assertEquals("awesome camel to upload!",
-                IOUtils.toString((InputStream) getBlobResponse.getBody(), Charset.defaultCharset()));
-
-        blobClientWrapper.delete(null, null, null);
-    }
-
-    @Test
-    void testCommitAndStageBlockBlob() throws Exception {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        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())));
-
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(blocks);
-        exchange.getIn().setHeader(BlobConstants.COMMIT_BLOCK_LIST_LATER, false);
-
-        final BlobOperationResponse response = operations.stageBlockBlobList(exchange);
-
-        assertNotNull(response);
-        assertNotNull(response.getBody());
-        // check for eTag and md5 to make sure is uploaded
-        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
-
-        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
-
-        assertEquals("HelloFromCamel", IOUtils.toString((InputStream) getBlobResponse.getBody(), Charset.defaultCharset()));
-
-        blobClientWrapper.delete(null, null, null);
-    }
-
-    @Test
-    void testGetBlobBlockList() {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper(randomBlobName);
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        final BlobOperationResponse response = operations.getBlobBlockList(null);
-
-        assertNotNull(response);
-        assertNotNull(response.getBody());
-        assertNotNull(response.getHeaders());
-    }
-
-    @Test
-    void testCreateAndUpdateAppendBlob() throws IOException {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        final String data = "Hello world from my awesome tests!";
-        final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
-
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(dataStream);
-        exchange.getIn().setHeader(BlobConstants.CREATE_APPEND_BLOB, true);
-
-        final BlobOperationResponse response = operations.commitAppendBlob(exchange);
-
-        assertNotNull(response);
-        assertTrue((boolean) response.getBody());
-        // check for eTag and md5 to make sure is uploaded
-        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
-        assertNotNull(response.getHeaders().get(BlobConstants.COMMITTED_BLOCK_COUNT));
-
-        // check content
-        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
-
-        assertEquals(data, IOUtils.toString((InputStream) getBlobResponse.getBody(), Charset.defaultCharset()));
-
-        blobClientWrapper.delete(null, null, null);
-    }
-
-    @Test
-    void testCreateAndUploadPageBlob() throws IOException {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
-        new SecureRandom().nextBytes(dataBytes);
-        final String data = new String(dataBytes, StandardCharsets.UTF_8);
-        final InputStream dataStream = new ByteArrayInputStream(dataBytes);
-
-        final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(dataStream);
-        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
-        exchange.getIn().setHeader(BlobConstants.CREATE_PAGE_BLOB, true);
-
-        final BlobOperationResponse response = operations.uploadPageBlob(exchange);
-
-        assertNotNull(response);
-        assertTrue((boolean) response.getBody());
-        assertNotNull(response.getHeaders().get(BlobConstants.E_TAG));
-
-        // check content
-        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
-        final String dataResponse = IOUtils.toString((InputStream) getBlobResponse.getBody(), StandardCharsets.UTF_8);
-
-        assertEquals(data, dataResponse);
-
-        blobClientWrapper.delete(null, null, null);
-    }
-
-    @Test
-    void testResizePageBlob() throws IOException {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        byte[] dataBytes = new byte[1024]; // we set range for the page from 0-511
-        new SecureRandom().nextBytes(dataBytes);
-        final String data = new String(dataBytes, StandardCharsets.UTF_8);
-        final InputStream dataStream = new ByteArrayInputStream(dataBytes);
-
-        final PageRange pageRange = new PageRange().setStart(0).setEnd(1023);
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(dataStream);
-        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
-        exchange.getIn().setHeader(BlobConstants.CREATE_PAGE_BLOB, true);
-
-        // create our page
-        operations.uploadPageBlob(exchange);
-
-        // create the new size
-        exchange.getIn().removeHeader(BlobConstants.PAGE_BLOB_RANGE);
-        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_SIZE, 512L);
-
-        final BlobOperationResponse response = operations.resizePageBlob(exchange);
-
-        assertNotNull(response);
-        assertTrue((boolean) response.getBody());
-
-        // check for content
-        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
-        final BlobInputStream inputStream = (BlobInputStream) getBlobResponse.getBody();
-        assertEquals(512, IOUtils.toByteArray(inputStream).length);
-
-        blobClientWrapper.delete(null, null, null);
-    }
-
-    @Test
-    void testClearPages() throws IOException {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
-        new SecureRandom().nextBytes(dataBytes);
-        final String data = new String(dataBytes, StandardCharsets.UTF_8);
-        final InputStream dataStream = new ByteArrayInputStream(dataBytes);
-
-        final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(dataStream);
-        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
-        exchange.getIn().setHeader(BlobConstants.CREATE_PAGE_BLOB, true);
-
-        // create our page
-        operations.uploadPageBlob(exchange);
-
-        final BlobOperationResponse response = operations.clearPageBlob(exchange);
-
-        // check content
-        final BlobOperationResponse getBlobResponse = operations.getBlob(null);
-
-        assertTrue(IOUtils.toString((InputStream) getBlobResponse.getBody(), StandardCharsets.UTF_8).trim().isEmpty());
-
-        blobClientWrapper.delete(null, null, null);
-    }
-
-    @Test
-    void testGetPageBlobRanges() throws IOException {
-        final BlobClientWrapper blobClientWrapper = blobContainerClientWrapper.getBlobClientWrapper("upload_test_file");
-        final BlobOperations operations = new BlobOperations(configuration, blobClientWrapper);
-
-        byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
-        new SecureRandom().nextBytes(dataBytes);
-        final String data = new String(dataBytes, StandardCharsets.UTF_8);
-        final InputStream dataStream = new ByteArrayInputStream(dataBytes);
-
-        final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(dataStream);
-        exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
-        exchange.getIn().setHeader(BlobConstants.CREATE_PAGE_BLOB, true);
-
-        // create our page
-        operations.uploadPageBlob(exchange);
-
-        final BlobOperationResponse response = operations.getPageBlobRanges(exchange);
-
-        assertNotNull(response);
-
-        final PageList pageList = (PageList) response.getBody();
-
-        assertEquals(pageRange.getStart(), pageList.getPageRange().get(0).getStart());
-        assertEquals(pageRange.getEnd(), pageList.getPageRange().get(0).getEnd());
-
-        blobClientWrapper.delete(null, null, null);
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobProducerITTest.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobProducerITTest.java
deleted file mode 100644
index f4ad930..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/integration/BlobProducerITTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.integration;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.security.SecureRandom;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.azure.storage.blob.BlobContainerClient;
-import com.azure.storage.blob.models.PageRange;
-import org.apache.camel.EndpointInject;
-import org.apache.camel.ProducerTemplate;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.azure.storage.blob.BlobBlock;
-import org.apache.camel.component.azure.storage.blob.BlobConstants;
-import org.apache.camel.component.mock.MockEndpoint;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class BlobProducerITTest extends BaseIT {
-
-    @EndpointInject
-    private ProducerTemplate template;
-
-    @EndpointInject("mock:result")
-    private MockEndpoint result;
-    private String resultName = "mock:result";
-    private BlobContainerClient containerClient;
-
-    @BeforeAll
-    public void prepare() {
-        // create test container
-        containerClient = serviceClient.getBlobContainerClient(containerName);
-        containerClient.create();
-    }
-
-    @Test
-    void testUploadBlockBlob() throws InterruptedException {
-        final String blobName = RandomStringUtils.randomAlphabetic(10);
-
-        result.expectedMessageCount(1);
-
-        template.send("direct:uploadBlockBlob", exchange -> {
-            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
-            exchange.getIn().setBody("Block Blob");
-        });
-
-        result.assertIsSatisfied();
-    }
-
-    @Test
-    void testCommitAndStageBlockBlob() throws InterruptedException, IOException {
-        final String blobName = RandomStringUtils.randomAlphabetic(10);
-
-        result.expectedMessageCount(1);
-
-        result.expectedBodiesReceived(true);
-
-        template.send("direct:stageBlockBlobList", exchange -> {
-            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
-            exchange.getIn().setHeader(BlobConstants.COMMIT_BLOCK_LIST_LATER, false);
-
-            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);
-        });
-
-        result.assertIsSatisfied();
-
-        assertNotNull(result.getExchanges().get(0).getMessage().getHeader(BlobConstants.E_TAG));
-    }
-
-    @Test
-    void testCommitAppendBlobWithError() throws InterruptedException {
-        final String blobName = RandomStringUtils.randomAlphabetic(10);
-
-        template.send("direct:commitAppendBlobWithError", exchange -> {
-            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
-            exchange.getIn().setHeader(BlobConstants.CREATE_APPEND_BLOB, false);
-
-            final String data = "Hello world from my awesome tests!";
-            final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
-
-            exchange.getIn().setBody(dataStream);
-        });
-
-        result.assertIsSatisfied();
-
-        // append blob not created because of the flag
-        assertTrue(result.getExchanges().isEmpty());
-    }
-
-    @Test
-    void testCreateAndUpdateAppendBlob() throws InterruptedException {
-        final String blobName = RandomStringUtils.randomAlphabetic(10);
-
-        result.expectedMessageCount(1);
-
-        result.expectedBodiesReceived(true);
-
-        template.send("direct:commitAppendBlob", exchange -> {
-            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
-
-            final String data = "Hello world from my awesome tests!";
-            final InputStream dataStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
-
-            exchange.getIn().setBody(dataStream);
-        });
-
-        result.assertIsSatisfied();
-
-        assertNotNull(result.getExchanges().get(0).getMessage().getHeader(BlobConstants.E_TAG));
-        assertNotNull(result.getExchanges().get(0).getMessage().getHeader(BlobConstants.COMMITTED_BLOCK_COUNT));
-    }
-
-    @Test
-    void testCreateAndUploadPageBlob() throws InterruptedException {
-        final String blobName = RandomStringUtils.randomAlphabetic(10);
-
-        result.expectedMessageCount(1);
-
-        result.expectedBodiesReceived(true);
-
-        template.send("direct:uploadPageBlob", exchange -> {
-            exchange.getIn().setHeader(BlobConstants.BLOB_NAME, blobName);
-
-            byte[] dataBytes = new byte[512]; // we set range for the page from 0-511
-            new SecureRandom().nextBytes(dataBytes);
-            final InputStream dataStream = new ByteArrayInputStream(dataBytes);
-            final PageRange pageRange = new PageRange().setStart(0).setEnd(511);
-
-            exchange.getIn().setHeader(BlobConstants.PAGE_BLOB_RANGE, pageRange);
-            exchange.getIn().setBody(dataStream);
-        });
-
-        result.assertIsSatisfied();
-
-        assertNotNull(result.getExchanges().get(0).getMessage().getHeader(BlobConstants.E_TAG));
-    }
-
-    @Test
-    void testUploadBlockBlobWithConfigUri() throws InterruptedException {
-        result.expectedMessageCount(1);
-
-        template.send("direct:uploadBlockBlobWithConfigUri",
-                exchange -> exchange.getIn().setBody("Block Blob"));
-
-        result.assertIsSatisfied();
-    }
-
-    @AfterAll
-    public void tearDown() {
-        containerClient.delete();
-    }
-
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
-            @Override
-            public void configure() throws Exception {
-                from("direct:uploadBlockBlob")
-                        .to(componentUri("uploadBlockBlob"))
-                        .to(resultName);
-
-                from("direct:stageBlockBlobList")
-                        .to(componentUri("stageBlockBlobList"))
-                        .to(resultName);
-
-                from("direct:commitAppendBlob")
-                        .to(componentUri("commitAppendBlob"))
-                        .to(resultName);
-
-                from("direct:commitAppendBlobWithError")
-                        .to(componentUri("commitAppendBlob"))
-                        .to(resultName);
-
-                from("direct:uploadPageBlob")
-                        .to(componentUri("uploadPageBlob"))
-                        .to(resultName);
-
-                from("direct:uploadBlockBlobWithConfigUri")
-                        .to(componentUri("uploadBlockBlob") + "&blobName=uploadBlockName")
-                        .to(resultName);
-            }
-        };
-    }
-
-    private String componentUri(final String operation) {
-        return String.format("azure-storage-blob://cameldev/%s?blobServiceClient=#serviceClient&operation=%s", containerName,
-                operation);
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperationsTest.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperationsTest.java
deleted file mode 100644
index d1761e4..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobContainerOperationsTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.operations;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import com.azure.core.http.HttpHeaders;
-import com.azure.storage.blob.models.BlobItem;
-import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
-import org.apache.camel.component.azure.storage.blob.BlobConstants;
-import org.apache.camel.component.azure.storage.blob.client.BlobContainerClientWrapper;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.extension.ExtendWith;
-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.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-@ExtendWith(MockitoExtension.class)
-class BlobContainerOperationsTest {
-
-    private BlobConfiguration configuration;
-
-    @Mock
-    private BlobContainerClientWrapper client;
-
-    @BeforeEach
-    public void setup() {
-        configuration = new BlobConfiguration();
-        configuration.setAccountName("cameldev");
-        configuration.setContainerName("awesome2");
-    }
-
-    @Test
-    void testCreateContainer() {
-        when(client.createContainer(any(), any(), any())).thenReturn(createContainerMock());
-
-        final BlobContainerOperations blobContainerOperations = new BlobContainerOperations(configuration, client);
-        final BlobOperationResponse response = blobContainerOperations.createContainer(null);
-
-        assertNotNull(response);
-        assertNotNull(response.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS));
-        assertTrue((boolean) response.getBody());
-    }
-
-    @Test
-    void testDeleteContainer() {
-        when(client.deleteContainer(any(), any())).thenReturn(deleteContainerMock());
-
-        final BlobContainerOperations blobContainerOperations = new BlobContainerOperations(configuration, client);
-        final BlobOperationResponse response = blobContainerOperations.deleteContainer(null);
-
-        assertNotNull(response);
-        assertNotNull(response.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS));
-        assertTrue((boolean) response.getBody());
-    }
-
-    @Test
-    void testListBlob() {
-        when(client.listBlobs(any(), any())).thenReturn(listBlobsMock());
-
-        final BlobContainerOperations blobContainerOperations = new BlobContainerOperations(configuration, client);
-        final BlobOperationResponse response = blobContainerOperations.listBlobs(null);
-
-        assertNotNull(response);
-
-        @SuppressWarnings("unchecked")
-        final List<BlobItem> body = (List<BlobItem>) response.getBody();
-        final List<String> items = body.stream().map(BlobItem::getName).collect(Collectors.toList());
-
-        assertTrue(items.contains("item-1"));
-        assertTrue(items.contains("item-2"));
-    }
-
-    @Test
-    void testListBlobWithRegex() {
-
-        BlobConfiguration myConfiguration = new BlobConfiguration();
-        myConfiguration.setAccountName("cameldev");
-        myConfiguration.setContainerName("awesome2");
-        myConfiguration.setRegex(".*\\.pdf");
-
-        when(client.listBlobs(any(), any())).thenReturn(listBlobsMockWithRegex());
-
-        final BlobContainerOperations blobContainerOperations = new BlobContainerOperations(myConfiguration, client);
-        final BlobOperationResponse response = blobContainerOperations.listBlobs(null);
-
-        assertNotNull(response);
-
-        @SuppressWarnings("unchecked")
-        final List<BlobItem> body = (List<BlobItem>) response.getBody();
-        final List<String> items = body.stream().map(BlobItem::getName).collect(Collectors.toList());
-        assertEquals(3, items.size());
-        assertTrue(items.contains("invoice1.pdf"));
-        assertTrue(items.contains("invoice2.pdf"));
-        assertTrue(items.contains("invoice5.pdf"));
-    }
-
-    private HttpHeaders createContainerMock() {
-        final HttpHeaders httpHeaders = new HttpHeaders();
-
-        httpHeaders.put("x-ms-request-id", "12345");
-        httpHeaders.put("Server", "Azure-Server");
-
-        return httpHeaders;
-    }
-
-    private HttpHeaders deleteContainerMock() {
-        final HttpHeaders httpHeaders = new HttpHeaders();
-
-        httpHeaders.put("x-ms-request-id", "12345");
-        httpHeaders.put("Server", "Azure-Server");
-        httpHeaders.put("x-ms-delete-type-permanent", "true");
-
-        return httpHeaders;
-    }
-
-    private List<BlobItem> listBlobsMock() {
-        final List<BlobItem> items = new LinkedList<>();
-
-        final BlobItem blobItem1 = new BlobItem().setName("item-1").setVersionId("1").setDeleted(false);
-        final BlobItem blobItem2 = new BlobItem().setName("item-2").setVersionId("2").setDeleted(true);
-
-        items.add(blobItem1);
-        items.add(blobItem2);
-
-        return items;
-    }
-
-    private List<BlobItem> listBlobsMockWithRegex() {
-        final List<BlobItem> items = listBlobsMock();
-
-        final BlobItem blobItemPdf1 = new BlobItem().setName("invoice1.pdf").setVersionId("1").setDeleted(false);
-        final BlobItem blobItemPdf2 = new BlobItem().setName("invoice2.pdf").setVersionId("2").setDeleted(true);
-        final BlobItem blobItemPdf3 = new BlobItem().setName("invoice5.pdf").setVersionId("2").setDeleted(true);
-
-        final BlobItem blobItemExe1 = new BlobItem().setName("office.exe").setVersionId("1").setDeleted(false);
-        final BlobItem blobItemExe2 = new BlobItem().setName("autorun.exe").setVersionId("2").setDeleted(false);
-        final BlobItem blobItemExe3 = new BlobItem().setName("start.exe").setVersionId("2").setDeleted(true);
-
-        items.add(blobItemPdf1);
-        items.add(blobItemPdf2);
-        items.add(blobItemPdf3);
-
-        items.add(blobItemExe1);
-        items.add(blobItemExe2);
-        items.add(blobItemExe3);
-
-        return items;
-    }
-
-}
diff --git a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationsTest.java b/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationsTest.java
deleted file mode 100644
index 8a57b0b..0000000
--- a/components/camel-azure-storage-blob/src/test/java/org/apache/camel/component/azure/storage/blob/operations/BlobOperationsTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.azure.storage.blob.operations;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
-import java.time.OffsetDateTime;
-import java.util.HashMap;
-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.BlobProperties;
-import com.azure.storage.blob.models.BlockBlobItem;
-import org.apache.camel.Exchange;
-import org.apache.camel.component.azure.storage.blob.BlobBlock;
-import org.apache.camel.component.azure.storage.blob.BlobConfiguration;
-import org.apache.camel.component.azure.storage.blob.BlobConstants;
-import org.apache.camel.component.azure.storage.blob.BlobType;
-import org.apache.camel.component.azure.storage.blob.client.BlobClientWrapper;
-import org.apache.camel.support.DefaultExchange;
-import org.apache.camel.test.junit5.CamelTestSupport;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestInstance;
-import org.junit.jupiter.api.extension.ExtendWith;
-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.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.when;
-
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
-@ExtendWith(MockitoExtension.class)
-class BlobOperationsTest extends CamelTestSupport {
-
-    private BlobConfiguration configuration;
-
-    @Mock
-    private BlobClientWrapper client;
-
-    @BeforeEach
-    public void setup() {
-        configuration = new BlobConfiguration();
-        configuration.setAccountName("cameldev");
-        configuration.setContainerName("awesome2");
-    }
-
-    @Test
-    void testGetBlob() throws IOException {
-        // mocking
-        final Map<String, Object> mockedResults = new HashMap<>();
-        mockedResults.put("inputStream", new ByteArrayInputStream("testInput".getBytes(Charset.defaultCharset())));
-        mockedResults.put("properties", createBlobProperties());
-
-        when(client.openInputStream(any(), any())).thenReturn(mockedResults);
-
-        final Exchange exchange = new DefaultExchange(context);
-
-        // first: test with no exchange provided
-        final BlobOperations operations = new BlobOperations(configuration, client);
-
-        final BlobOperationResponse response = operations.getBlob(null);
-
-        assertNotNull(response);
-        assertNotNull(response.getBody());
-        assertNotNull(response.getHeaders());
-        assertNotNull(response.getHeaders().get(BlobConstants.CREATION_TIME));
-        assertEquals("testInput", new BufferedReader(new InputStreamReader((InputStream) response.getBody())).readLine());
-
-        // second: test with exchange provided
-        configuration.setBlobType(BlobType.blockblob);
-        final BlobOperationResponse response2 = operations.getBlob(exchange);
-
-        assertNotNull(response2);
-        assertNotNull(response2.getBody());
-        assertNotNull(response2.getHeaders());
-        assertNotNull(response2.getHeaders().get(BlobConstants.CREATION_TIME));
-
-        // third: test with exchange provided but with outputstream set
-        // mocking
-        final ResponseBase<BlobDownloadHeaders, Void> mockedResults2 = new ResponseBase<>(
-                null, 200, new HttpHeaders().put("x-test-header", "123"), null, new BlobDownloadHeaders().setETag("tag1"));
-        when(client.downloadWithResponse(any(), any(), any(), any(), anyBoolean(), any())).thenReturn(mockedResults2);
-        exchange.getIn().setBody(new ByteArrayOutputStream());
-
-        final BlobOperationResponse response3 = operations.getBlob(exchange);
-
-        assertNotNull(response3);
-        assertNotNull(response3.getBody());
-        assertNotNull(response3.getHeaders());
-        assertEquals("tag1", response3.getHeaders().get(BlobConstants.E_TAG));
-    }
-
-    @Test
-    void testUploadBlockBlob() throws Exception {
-        // mocking
-        final BlockBlobItem blockBlobItem = new BlockBlobItem("testTag", OffsetDateTime.now(), null, false, null);
-        final HttpHeaders httpHeaders = new HttpHeaders().put("x-test-header", "123");
-
-        when(client.uploadBlockBlob(any(), anyLong(), any(), any(), any(), any(), any(), any()))
-                .thenReturn(new ResponseBase<>(null, 200, httpHeaders, blockBlobItem, null));
-
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody(new ByteArrayInputStream("test".getBytes(Charset.defaultCharset())));
-
-        // test upload with input stream
-        final BlobOperations operations = new BlobOperations(configuration, client);
-
-        final BlobOperationResponse operationResponse = operations.uploadBlockBlob(exchange);
-
-        assertNotNull(operationResponse);
-        assertTrue((boolean) operationResponse.getBody());
-        assertNotNull(operationResponse.getHeaders());
-        assertEquals("testTag", operationResponse.getHeaders().get(BlobConstants.E_TAG));
-        assertEquals("123", ((HttpHeaders) operationResponse.getHeaders().get(BlobConstants.RAW_HTTP_HEADERS))
-                .get("x-test-header").getValue());
-    }
-
-    @Test
-    void testStageBlockBlobList() throws Exception {
-        final HttpHeaders httpHeaders = new HttpHeaders().put("x-test-header", "123");
-        when(client.stageBlockBlob(anyString(), any(), anyLong(), any(), any(), any())).thenReturn(httpHeaders);
-
-        final Exchange exchange = new DefaultExchange(context);
-        exchange.getIn().setBody("test");
-        exchange.getIn().setHeader(BlobConstants.COMMIT_BLOCK_LIST_LATER, true);
-
-        // test
-        final BlobOperations operations = new BlobOperations(configuration, client);
-
-        // in case of invalid payload
-        assertThrows(IllegalArgumentException.class, () -> operations.stageBlockBlobList(exchange));
-
-        // in case of correct payload
-        exchange.getIn().setBody(BlobBlock.createBlobBlock("1", new ByteArrayInputStream("test".getBytes())));
-
-        // test again
-        final BlobOperationResponse response = operations.stageBlockBlobList(exchange);
-
-        assertNotNull(response);
-        assertTrue((boolean) response.getBody());
-    }
-
-    private BlobProperties createBlobProperties() {
-        return new BlobProperties(
-                OffsetDateTime.now(), null, null, 0L, null, null, null, null, null,
-                null, null, null, null, null, null, null, null, null, null,
-                null, null, null, null, null, null, null, null,
-                null, null, null, null);
-    }
-}
diff --git a/components/camel-azure-storage-blob/src/test/resources/azurite.properties b/components/camel-azure-storage-blob/src/test/resources/azurite.properties
deleted file mode 100644
index f058f35..0000000
--- a/components/camel-azure-storage-blob/src/test/resources/azurite.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-## ---------------------------------------------------------------------------
-## Licensed to the Apache Software Foundation (ASF) under one or more
-## contributor license agreements.  See the NOTICE file distributed with
-## this work for additional information regarding copyright ownership.
-## The ASF licenses this file to You under the Apache License, Version 2.0
-## (the "License"); you may not use this file except in compliance with
-## the License.  You may obtain a copy of the License at
-##
-##      http://www.apache.org/licenses/LICENSE-2.0
-##
-## Unless required by applicable law or agreed to in writing, software
-## distributed under the License is distributed on an "AS IS" BASIS,
-## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-## See the License for the specific language governing permissions and
-## limitations under the License.
-## ---------------------------------------------------------------------------
-# Default Azurite properties
-# See https://docs.microsoft.com/en-us/azure/storage/common/storage-use-azurite#well-known-storage-account-and-key
-accountName=devstoreaccount1
-accessKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==
\ No newline at end of file
diff --git a/components/camel-azure-storage-blob/src/test/resources/log4j2.properties b/components/camel-azure-storage-blob/src/test/resources/log4j2.properties
deleted file mode 100644
index ae1c0f8f..0000000
--- a/components/camel-azure-storage-blob/src/test/resources/log4j2.properties
+++ /dev/null
@@ -1,27 +0,0 @@
-## ---------------------------------------------------------------------------
-## Licensed to the Apache Software Foundation (ASF) under one or more
-## contributor license agreements.  See the NOTICE file distributed with
-## this work for additional information regarding copyright ownership.
-## The ASF licenses this file to You under the Apache License, Version 2.0
-## (the "License"); you may not use this file except in compliance with
-## the License.  You may obtain a copy of the License at
-##
-##      http://www.apache.org/licenses/LICENSE-2.0
-##
-## Unless required by applicable law or agreed to in writing, software
-## distributed under the License is distributed on an "AS IS" BASIS,
-## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-## See the License for the specific language governing permissions and
-## limitations under the License.
-## ---------------------------------------------------------------------------
-appender.file.type = File
-appender.file.name = file
-appender.file.fileName = target/camel-azure-storage-blob-test.log
-appender.file.layout.type = PatternLayout
-appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
-appender.out.type = Console
-appender.out.name = out
-appender.out.layout.type = PatternLayout
-appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
-rootLogger.level = INFO
-rootLogger.appenderRef.file.ref = file
\ No newline at end of file
diff --git a/components/camel-azure-storage-blob/src/test/resources/upload_test_file b/components/camel-azure-storage-blob/src/test/resources/upload_test_file
deleted file mode 100644
index 582b34d..0000000
--- a/components/camel-azure-storage-blob/src/test/resources/upload_test_file
+++ /dev/null
@@ -1 +0,0 @@
-awesome camel to upload!
\ No newline at end of file
diff --git a/components/camel-azure-storage-datalake/pom.xml b/components/camel-azure-storage-datalake/pom.xml
deleted file mode 100644
index 0c8c1da..0000000
--- a/components/camel-azure-storage-datalake/pom.xml
+++ /dev/null
@@ -1,144 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-         http://www.apache.org/licenses/LICENSE-2.0
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.camel</groupId>
-        <artifactId>components</artifactId>
-        <version>3.9.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>camel-azure-storage-datalake</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Camel :: Azure Datalake Gen2</name>
-    <description>Camel Azure Datalake Gen2 Component</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-support</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>com.azure</groupId>
-            <artifactId>azure-storage-file-datalake</artifactId>
-            <version>${azure-storage-datalake-java-sdk12-version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.azure</groupId>
-            <artifactId>azure-identity</artifactId>
-            <version>${azure-identity-version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-        </dependency>
-
-        <!-- test dependencies -->
-
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test-junit5</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-core</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-slf4j-impl</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mockito</groupId>
-            <artifactId>mockito-junit-jupiter</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <version>${commons-lang3-version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.awaitility</groupId>
-            <artifactId>awaitility</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.assertj</groupId>
-            <artifactId>assertj-core</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test-infra-common</artifactId>
-            <version>${project.version}</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test-infra-azure-common</artifactId>
-            <version>${project.version}</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
... 9200 lines suppressed ...