author | ms.service | ms.topic | ms.date | ms.author |
---|---|---|---|---|
craigshoemaker |
azure-functions |
include |
03/05/2019 |
cshoe |
Use the function trigger to respond to an event sent to an event hub event stream. You must have read access to the underlying event hub to set up the trigger. When the function is triggered, the message passed to the function is typed as a string.
Each instance of an event triggered function is backed by a single EventProcessorHost instance. The trigger (powered by Event Hubs) ensures that only one EventProcessorHost instance can get a lease on a given partition.
For example, consider an Event Hub as follows:
- 10 partitions
- 1,000 events distributed evenly across all partitions, with 100 messages in each partition
When your function is first enabled, there is only one instance of the function. Let's call the first function instance Function_0
. The Function_0
function has a single instance of EventProcessorHost that holds a lease on all ten partitions. This instance is reading events from partitions 0-9. From this point forward, one of the following happens:
-
New function instances are not needed:
Function_0
is able to process all 1,000 events before the Functions scaling logic take effect. In this case, all 1,000 messages are processed byFunction_0
. -
An additional function instance is added: If the Functions scaling logic determines that
Function_0
has more messages than it can process, a new function app instance (Function_1
) is created. This new function also has an associated instance of EventProcessorHost. As the underlying Event Hubs detect that a new host instance is trying read messages, it load balances the partitions across the host instances. For example, partitions 0-4 may be assigned toFunction_0
and partitions 5-9 toFunction_1
. -
N more function instances are added: If the Functions scaling logic determines that both
Function_0
andFunction_1
have more messages than they can process, newFunctions_N
function app instances are created. Apps are created to the point whereN
is greater than the number of event hub partitions. In our example, Event Hubs again load balances the partitions, in this case across the instancesFunction_0
...Functions_9
.
As scaling occurs, N
instances is a number greater than the number of event hub partitions. This pattern is used to ensure EventProcessorHost instances are available to obtain locks on partitions as they become available from other instances. You are only charged for the resources used when the function instance executes. In other words, you are not charged for this over-provisioning.
When all function execution completes (with or without errors), checkpoints are added to the associated storage account. When check-pointing succeeds, all 1,000 messages are never retrieved again.
The following example shows a C# function that logs the message body of the event hub trigger.
[FunctionName("EventHubTriggerCSharp")]
public static void Run([EventHubTrigger("samples-workitems", Connection = "EventHubConnectionAppSetting")] string myEventHubMessage, ILogger log)
{
log.LogInformation($"C# function triggered to process a message: {myEventHubMessage}");
}
To get access to event metadata in function code, bind to an EventData object (requires a using statement for Microsoft.Azure.EventHubs
). You can also access the same properties by using binding expressions in the method signature. The following example shows both ways to get the same data:
[FunctionName("EventHubTriggerCSharp")]
public static void Run(
[EventHubTrigger("samples-workitems", Connection = "EventHubConnectionAppSetting")] EventData myEventHubMessage,
DateTime enqueuedTimeUtc,
Int64 sequenceNumber,
string offset,
ILogger log)
{
log.LogInformation($"Event: {Encoding.UTF8.GetString(myEventHubMessage.Body)}");
// Metadata accessed by binding to EventData
log.LogInformation($"EnqueuedTimeUtc={myEventHubMessage.SystemProperties.EnqueuedTimeUtc}");
log.LogInformation($"SequenceNumber={myEventHubMessage.SystemProperties.SequenceNumber}");
log.LogInformation($"Offset={myEventHubMessage.SystemProperties.Offset}");
// Metadata accessed by using binding expressions in method parameters
log.LogInformation($"EnqueuedTimeUtc={enqueuedTimeUtc}");
log.LogInformation($"SequenceNumber={sequenceNumber}");
log.LogInformation($"Offset={offset}");
}
To receive events in a batch, make string
or EventData
an array.
Note
When receiving in a batch you cannot bind to method parameters like in the above example with DateTime enqueuedTimeUtc
and must receive these from each EventData
object
[FunctionName("EventHubTriggerCSharp")]
public static void Run([EventHubTrigger("samples-workitems", Connection = "EventHubConnectionAppSetting")] EventData[] eventHubMessages, ILogger log)
{
foreach (var message in eventHubMessages)
{
log.LogInformation($"C# function triggered to process a message: {Encoding.UTF8.GetString(message.Body)}");
log.LogInformation($"EnqueuedTimeUtc={message.SystemProperties.EnqueuedTimeUtc}");
}
}
The following example shows an event hub trigger binding in a function.json file and a C# script function that uses the binding. The function logs the message body of the event hub trigger.
The following examples show Event Hubs binding data in the function.json file.
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"eventHubName": "MyEventHub",
"connection": "myEventHubReadConnectionAppSetting"
}
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"path": "MyEventHub",
"connection": "myEventHubReadConnectionAppSetting"
}
Here's the C# script code:
using System;
public static void Run(string myEventHubMessage, TraceWriter log)
{
log.Info($"C# function triggered to process a message: {myEventHubMessage}");
}
To get access to event metadata in function code, bind to an EventData object (requires a using statement for Microsoft.Azure.EventHubs
). You can also access the same properties by using binding expressions in the method signature. The following example shows both ways to get the same data:
#r "Microsoft.Azure.EventHubs"
using System.Text;
using System;
using Microsoft.ServiceBus.Messaging;
using Microsoft.Azure.EventHubs;
public static void Run(EventData myEventHubMessage,
DateTime enqueuedTimeUtc,
Int64 sequenceNumber,
string offset,
TraceWriter log)
{
log.Info($"Event: {Encoding.UTF8.GetString(myEventHubMessage.Body)}");
log.Info($"EnqueuedTimeUtc={myEventHubMessage.SystemProperties.EnqueuedTimeUtc}");
log.Info($"SequenceNumber={myEventHubMessage.SystemProperties.SequenceNumber}");
log.Info($"Offset={myEventHubMessage.SystemProperties.Offset}");
// Metadata accessed by using binding expressions
log.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");
log.Info($"SequenceNumber={sequenceNumber}");
log.Info($"Offset={offset}");
}
To receive events in a batch, make string
or EventData
an array:
public static void Run(string[] eventHubMessages, TraceWriter log)
{
foreach (var message in eventHubMessages)
{
log.Info($"C# function triggered to process a message: {message}");
}
}
The following example shows an event hub trigger binding in a function.json file and a JavaScript function that uses the binding. The function reads event metadata and logs the message.
The following examples show Event Hubs binding data in the function.json file.
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"eventHubName": "MyEventHub",
"connection": "myEventHubReadConnectionAppSetting"
}
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"path": "MyEventHub",
"connection": "myEventHubReadConnectionAppSetting"
}
Here's the JavaScript code:
module.exports = function (context, myEventHubMessage) {
context.log('Function triggered to process a message: ', myEventHubMessage);
context.log('EnqueuedTimeUtc =', context.bindingData.enqueuedTimeUtc);
context.log('SequenceNumber =', context.bindingData.sequenceNumber);
context.log('Offset =', context.bindingData.offset);
context.done();
};
To receive events in a batch, set cardinality
to many
in the function.json file, as shown in the following examples.
{
"type": "eventHubTrigger",
"name": "eventHubMessages",
"direction": "in",
"eventHubName": "MyEventHub",
"cardinality": "many",
"connection": "myEventHubReadConnectionAppSetting"
}
{
"type": "eventHubTrigger",
"name": "eventHubMessages",
"direction": "in",
"path": "MyEventHub",
"cardinality": "many",
"connection": "myEventHubReadConnectionAppSetting"
}
Here's the JavaScript code:
module.exports = function (context, eventHubMessages) {
context.log(`JavaScript eventhub trigger function called for message array ${eventHubMessages}`);
eventHubMessages.forEach((message, index) => {
context.log(`Processed message ${message}`);
context.log(`EnqueuedTimeUtc = ${context.bindingData.enqueuedTimeUtcArray[index]}`);
context.log(`SequenceNumber = ${context.bindingData.sequenceNumberArray[index]}`);
context.log(`Offset = ${context.bindingData.offsetArray[index]}`);
});
context.done();
};
The following example shows an event hub trigger binding in a function.json file and a Python function that uses the binding. The function reads event metadata and logs the message.
The following examples show Event Hubs binding data in the function.json file.
{
"type": "eventHubTrigger",
"name": "event",
"direction": "in",
"eventHubName": "MyEventHub",
"connection": "myEventHubReadConnectionAppSetting"
}
Here's the Python code:
import logging
import azure.functions as func
def main(event: func.EventHubEvent):
logging.info('Function triggered to process a message: ', event.get_body())
logging.info(' EnqueuedTimeUtc =', event.enqueued_time)
logging.info(' SequenceNumber =', event.sequence_number)
logging.info(' Offset =', event.offset)
The following example shows an Event Hub trigger binding which logs the message body of the Event Hub trigger.
@FunctionName("ehprocessor")
public void eventHubProcessor(
@EventHubTrigger(name = "msg",
eventHubName = "myeventhubname",
connection = "myconnvarname") String message,
final ExecutionContext context )
{
context.getLogger().info(message);
}
In the Java functions runtime library, use the EventHubTrigger
annotation on parameters whose value would come from Event Hub. Parameters with these annotations cause the function to run when an event arrives. This annotation can be used with native Java types, POJOs, or nullable values using Optional<T>
.
In C# class libraries, use the EventHubTriggerAttribute attribute.
The attribute's constructor takes the name of the event hub, the name of the consumer group, and the name of an app setting that contains the connection string. For more information about these settings, see the trigger configuration section. Here's an EventHubTriggerAttribute
attribute example:
[FunctionName("EventHubTriggerCSharp")]
public static void Run([EventHubTrigger("samples-workitems", Connection = "EventHubConnectionAppSetting")] string myEventHubMessage, ILogger log)
{
...
}
For a complete example, see Trigger - C# example.
Attributes are not supported by C# Script.
Attributes are not supported by JavaScript.
Attributes are not supported by Python.
From the Java functions runtime library, use the EventHubTrigger annotation on parameters whose value would come from Event Hub. Parameters with these annotations cause the function to run when an event arrives. This annotation can be used with native Java types, POJOs, or nullable values using Optional<T>
.
The following table explains the binding configuration properties that you set in the function.json file and the EventHubTrigger
attribute.
function.json property | Attribute property | Description |
---|---|---|
type | n/a | Must be set to eventHubTrigger . This property is set automatically when you create the trigger in the Azure portal. |
direction | n/a | Must be set to in . This property is set automatically when you create the trigger in the Azure portal. |
name | n/a | The name of the variable that represents the event item in function code. |
path | EventHubName | Functions 1.x only. The name of the event hub. When the event hub name is also present in the connection string, that value overrides this property at runtime. |
eventHubName | EventHubName | Functions 2.x and higher. The name of the event hub. When the event hub name is also present in the connection string, that value overrides this property at runtime. Can be referenced via app settings %eventHubName% |
consumerGroup | ConsumerGroup | An optional property that sets the consumer group used to subscribe to events in the hub. If omitted, the $Default consumer group is used. |
cardinality | n/a | Used for all non-C# languages. Set to many in order to enable batching. If omitted or set to one , a single message is passed to the function.In C#, this property is automatically assigned whenever the trigger has an array for the type. |
connection | Connection | The name of an app setting that contains the connection string to the event hub's namespace. Copy this connection string by clicking the Connection Information button for the namespace, not the event hub itself. This connection string must have at least read permissions to activate the trigger. |
[!INCLUDE app settings to local.settings.json]
The Event Hubs trigger provides several metadata properties. Metadata properties can be used as part of binding expressions in other bindings or as parameters in your code. The properties come from the EventData class.
Property | Type | Description |
---|---|---|
PartitionContext |
PartitionContext | The PartitionContext instance. |
EnqueuedTimeUtc |
DateTime |
The enqueued time in UTC. |
Offset |
string |
The offset of the data relative to the Event Hub partition stream. The offset is a marker or identifier for an event within the Event Hubs stream. The identifier is unique within a partition of the Event Hubs stream. |
PartitionKey |
string |
The partition to which event data should be sent. |
Properties |
IDictionary<String,Object> |
The user properties of the event data. |
SequenceNumber |
Int64 |
The logical sequence number of the event. |
SystemProperties |
IDictionary<String,Object> |
The system properties, including the event data. |
See code examples that use these properties earlier in this article.
The host.json file contains settings that control Event Hubs trigger behavior. The configuration is different depending on the Azure Functions version.
[!INCLUDE functions-host-json-event-hubs]