UPDATE: we have decided to use a non-Functions approach, so this is no longer urgent.
The problem
I have an Azure Function in Java that I am trying to migrate from an Event Hub trigger to a Kafka trigger. For testing purposes, I create an Event Hub with Kafka surface enabled to test against before deploying to use the real Kafka instance from Confluent.
When I deploy the Event Hub on Azure and run the function locally (mvn azure-functions:run) with my personal account, it consumes messages from a local producer correctly every time. But when the same function is deployed to Azure and assigned a managed identity, it (mostly) ignores messages.
This is a consumption plan Function, with "functionTimeout": "00:04:30" set in host.json.
Code
The Function:
@FunctionName("KafkaLicensesConsumer")
public void consumeKafka(
@KafkaTrigger(
name = "KafkaLicensesConsumer",
brokerList = "BOOTSTRAPSERVERS",
topic = "<TOPICS>_NAME",
consumerGroup = "<TOPIC>_CONSUMER_GROUP",
dataType = "binary",
protocol = BrokerProtocol.SASLSSL,
authenticationMode = BrokerAuthenticationMode.PLAIN,
username = "SASL_USERNAME",
password = "SASL_PASSWORD"
) byte[] eventData,
final ExecutionContext context
) {
//doStuff
}
}
Event Hub namespace, hub, and authorization rule in Bicep:
resource eventHub_namespace 'Microsoft.EventHub/namespaces@2021-11-01' = {
name: eventHub.namespace
location: location
sku: {
name: 'Standard'
tier: 'Standard'
capacity: 1
}
properties: {
zoneRedundant: false
isAutoInflateEnabled: true
maximumThroughputUnits: 1
kafkaEnabled: true
}
}
resource eventHub_namespace_eventHub_licensesTopic 'Microsoft.EventHub/namespaces/eventhubs@2021-11-01' = {
name: '${eventHub.namespace}/${eventHub.licensesTopic}'
location: location
properties: {
messageRetentionInDays: 7
partitionCount: 1
status: 'Active'
}
dependsOn: [
eventHub_namespace
]
}
resource eventHub_namespace_eventHub_licensesTopic_eventHub_authorizationRule 'Microsoft.EventHub/namespaces/eventhubs/authorizationRules@2021-11-01' = {
name: '${eventHub.namespace}/${eventHub.licensesTopic}/${eventHub.authorizationRule}'
location: location
properties: {
rights: [
'Listen'
'Send'
'Manage'
]
}
dependsOn: [
eventHub_namespace_eventHub_licensesTopic
]
}
resource functionApp 'Microsoft.Web/sites@2021-03-01' = {
name: functionAppName
location: location
kind: 'functionapp,linux'
tags: resourceTags
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${myFunctionAppMsiResourceId}': {
}
}
}
properties: {
httpsOnly: 'true'
serverFarmId: serverfarm.id
siteConfig: {
linuxFxVersion: 'Java|8'
functionAppScaleLimit: 100
appSettings: [
//settings here ]
}
}
dependsOn: [
storageAccount
]
}
I am expecting the Function to trigger when an event is published to the Event Hub that it is configured to listen to using Kafka protocol.
Things I have confirmed:
- BrokerList, topic and auth config is identical locally and in Azure.
- The local and deployed functions use different consumer groups to not interfere with each other.
- Setting partition count on the Event Hub to 1 let the function receive 4 messages (the 3rd with 10 minutes delay), then it began ignoring them again.
- The identity used by the function has Send, Receive and Owner rights to the Event Hub.
- When I used a regular Kafka broker deployed in Azure Container Instances instead of an Event Hub with Kafka surface, the deployed function SOMETIMES received messages as it should. However, due to the existing test setup in the project, this is not a viable option. In later tests using a Confluent Cloud broker, this did not work either.
- When deployed, the old Event Hub trigger is triggered by every message in the same Hub that the Kafka trigger is (mostly) ignoring.
- After the Functions of the project are deployed, they are restarted and synced programmatically.
The Event Hub sometimes shows more outgoing than incoming messages, which I assume should indicate that more than one consumer is listening, but the Function is not triggering: