= Azure Event Hubs Component
:doctitle: Azure Event Hubs
:shortname: azure-eventhubs
:artifactid: camel-azure-eventhubs
:description: Send and receive events to/from Azure Event Hubs using AMQP protocol.
:since: 3.5
:supportlevel: Stable
:tabs-sync-option:
:component-header: Both producer and consumer are supported
//Manually maintained attributes
:group: Azure
:camel-spring-boot-name: azure-eventhubs

*Since Camel {since}*

*{component-header}*

The Azure Event Hubs component provides the capability to produce and consume events with https://azure.microsoft.com/en-us/services/event-hubs/[Azure Event Hubs] using the 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.

*Prerequisites*

You must have a valid Microsoft Azure Event Hubs account. More information is available at the
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]
------------------------------

When providing a `connectionString`, the `namespace` and `eventHubName` options are not required as they are already included
in the `connectionString`


// component-configure options: START

// component-configure options: END

// component options: START
include::partial$component-configure-options.adoc[]
include::partial$component-endpoint-options.adoc[]
// component options: END

// endpoint options: START

// endpoint options: END

// component headers: START
include::partial$component-endpoint-headers.adoc[]
// component headers: END

== Usage

=== Authentication Information

There are three different Credential Types: `AZURE_IDENTITY`, `TOKEN_CREDENTIAL` and `CONNECTION_STRING`.

*CONNECTION_STRING*:

You can either:

- Provide the `connectionString` option. Using this options means that you don't need to specify additional options `namespace`, `eventHubName`, `sharedAccessKey` and `sharedAccessName`
, as this data is already included within the `connectionString`. Learn more https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-get-connection-string[here] on how to generate the connection string.

Or

- Provide  `sharedAccessName` and `sharedAccessKey` options for your Azure Event Hubs account. The `sharedAccessKey` can be generated through the Event Hubs Azure portal.
The connection String will then be generated automatically for you by the azure-eventhubs component.

*TOKEN_CREDENTIAL*:

- Bind an implementation of `com.azure.core.credential.TokenCredential` to the Camel Registry (see example below).
See the documentation https://docs.microsoft.com/en-us/azure/active-directory/authentication/overview-authentication[here about Azure-AD authentication].

*AZURE_IDENTITY*:
- This will use an `com.azure.identity.DefaultAzureCredentialBuilder().build()` instance. This will follow the Default Azure Credential Chain.
See the documentation https://docs.microsoft.com/en-us/azure/active-directory/authentication/overview-authentication[here about Azure-AD authentication].

*Client instance*:

- Provide a https://docs.microsoft.com/en-us/java/api/com.azure.messaging.eventhubs.eventhubproducerasyncclient?view=azure-java-stable[EventHubProducerAsyncClient] instance which can be
used for the `producerAsyncClient` option. However, this is *only supported for azure-eventhubs producer*, for the consumer, it is not possible to inject the client due to some design constraints in 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 a `CheckpointStore`.
Users are expected to choose existing implementations of this interface, instantiate it, and pass it to the component through the `checkpointStore` option.

When no `CheckpointStore` implementation is provided, the azure-eventhubs component will fall back to use https://docs.microsoft.com/en-us/javascript/api/@azure/eventhubs-checkpointstore-blob/blobcheckpointstore?view=azure-node-latest[`BlobCheckpointStore`] to store the checkpoint information in the Azure Blob Storage account.
If you chose to use the default `BlobCheckpointStore`, you will need to supply the following options:

- `blobAccountName`: The Azure account name to be used for authentication with azure blob services.
- `blobAccessKey`: The access key for the associated azure account name to be used for authentication with azure blob services.
- `blobContainerName`: The name of the blob container that shall be used by the BlobCheckpointStore to store the checkpoint offsets.

=== Message body type

The azure-eventhubs producer expects the data in the message body to be of type `byte[]`. This allows the simple messages (E.g. `String` based ones) to be marshalled /unmarshalled with ease.
The same is true for the azure-eventhubs consumer, it will set the encoded data as `byte[]` in the message body.

=== Automatic detection of EventHubProducerAsyncClient client in the Camel 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 the client, and you won't have to define it as uri parameter, like the example above.
This may be really useful for smarter configuration of the endpoint.

== Examples

=== Consumer Example

To consume events:

[source,java]
--------------------------------------------------------------------------------
from("azure-eventhubs:/camel/camelHub?sharedAccessName=SASaccountName&sharedAccessKey=SASaccessKey&blobAccountName=accountName&blobAccessKey=accessKey&blobContainerName=containerName")
    .to("file://queuedirectory");
--------------------------------------------------------------------------------

=== Producer Example

To produce events:

[source,java]
----
from("direct:start")
    .process(exchange -> {
        exchange.getIn().setHeader(EventHubsConstants.PARTITION_ID, firstPartition);
        exchange.getIn().setBody("test event");
    })
    .to("azure-eventhubs:?connectionString=RAW({{connectionString}})"
----

The azure-eventhubs producer supports sending sending events as an `Iterable` (E.g. as a `List`). For example:

[source,java]
----
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}})"
----

=== Azure-AD Authentication example

The example below makes use of the Azure-AD authentication. See https://docs.microsoft.com/en-us/java/api/overview/azure/identity-readme?view=azure-java-stable#environment-variables[here]
about what environment variables you need to set for this to work:

[source,java]
----
@BindToRegistry("myTokenCredential")
public com.azure.core.credential.TokenCredential myTokenCredential() {
    return com.azure.identity.DefaultAzureCredentialBuilder().build();
}

from("direct:start")
    .to("azure-eventhubs:namespace/eventHubName?tokenCredential=#myTokenCredential&credentialType=TOKEN_CREDENTIAL)"
----

== Important Development Notes

When developing on this component, you will need to obtain your Azure accessKey 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:

[source,bash]
----
mvn verify -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::spring-boot:partial$starter.adoc[]
