Service Bus Integration¶
This recipe demonstrates Java Service Bus queue and topic triggers with output bindings, dead-letter behavior, and host tuning.
Architecture¶
flowchart TD
PROD[Producers] --> SBQ[(Service Bus Queue/Topic)]
SBQ --> TRIG[ServiceBusQueueTrigger worker]
TRIG --> FA[Function App]
FA --> DLQ[(Dead-Letter Queue)]
FA --> OUT[ServiceBusQueueOutput] Prerequisites¶
Provide the connection in app settings. A connection-string setting or an identity-based connection is supported. Identity-based connections use a setting prefix with __fullyQualifiedNamespace:
az functionapp config appsettings set \
--name $APP_NAME \
--resource-group $RG \
--settings "ServiceBusConnection__fullyQualifiedNamespace=$NAMESPACE.servicebus.windows.net"
| CLI element | Explanation |
|---|---|
| Command(s) | az functionapp config appsettings set |
| Key flags | --name, --resource-group, --settings |
| Variables | $APP_NAME, $RG, $NAMESPACE |
| Expected result | Azure CLI returns the updated app settings as JSON; confirm the setting is present before continuing. |
When using an identity-based connection, grant the function app's managed identity the Azure Service Bus Data Receiver (and Data Sender for output) role on the namespace.
Java Implementation¶
package com.contoso.functions;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;
public class ServiceBusFunctions {
@FunctionName("processOrder")
public void processOrder(
@ServiceBusQueueTrigger(
name = "message",
queueName = "orders",
connection = "ServiceBusConnection"
) String message,
final ExecutionContext context
) {
context.getLogger().info("Processing Service Bus message: " + message);
// Throwing abandons the message; after maxDeliveryCount it is
// moved to the dead-letter queue automatically.
}
@FunctionName("processEvent")
public void processEvent(
@ServiceBusTopicTrigger(
name = "message",
topicName = "events",
subscriptionName = "billing",
connection = "ServiceBusConnection"
) String message,
final ExecutionContext context
) {
context.getLogger().info("Subscription message: " + message);
}
@FunctionName("enqueue")
@ServiceBusQueueOutput(name = "output", queueName = "orders", connection = "ServiceBusConnection")
public String enqueue(
@HttpTrigger(
name = "request",
methods = {HttpMethod.POST},
authLevel = AuthorizationLevel.FUNCTION,
route = "servicebus/enqueue"
) HttpRequestMessage<String> request
) {
return request.getBody();
}
}
Host Configuration¶
{
"version": "2.0",
"extensions": {
"serviceBus": {
"maxConcurrentCalls": 16,
"prefetchCount": 0,
"maxAutoLockRenewalDuration": "00:05:00"
}
}
}
| Setting | Description |
|---|---|
maxConcurrentCalls | Maximum concurrent message handlers per instance |
prefetchCount | Number of messages the client prefetches to reduce latency |
maxAutoLockRenewalDuration | How long the runtime keeps renewing the message lock during processing |
Sessions and ordering
Set isSessionsEnabled = true on the trigger to process session-enabled queues/subscriptions, which guarantees ordered, single-consumer processing per session ID.