Develop Event-Based Solutions
This guide covers the AZ-204 exam topics for developing event-based solutions using Azure Event Grid and Azure Event Hub. We'll enhance our TaskManagerWeb
(WebApp) and TaskManagerFunctions
(Function App) to handle events, integrating with our existing setup (including Cosmos DB and API Management). We'll use Event Grid to trigger actions on task creation and Event Hub to stream task updates for processing.
Prerequisites
- Azure Subscription (Free tier or $200 credit recommended).
- Existing Resource Group (
az204exam
). - Deployed Apps:
- WebApp:
taskmanagerweb-yourname
(ASP.NET Core MVC, Free F1 tier). - Function App:
taskmanagerfunc-yourname
(.NET 8 isolated, Consumption plan). - Cosmos DB:
taskmanagercosmos
withTasksDB/Tasks
. - API Management:
taskmanagerapim-yourname
. - Tools:
- .NET SDK 8.0:
winget install Microsoft.DotNet.SDK.8
. - Azure CLI.
- Azure Functions Core Tools.
Implement Solutions that Use Azure Event Grid
We'll use Event Grid to trigger a new Function when a task is created in Cosmos DB, sending a notification via a webhook (simulated by another Function).
Steps
Create an Event Grid Trigger Function
Follow these steps to create an Event Grid Trigger Function:
-
Create the function in the
TaskManagerFunctions
directory and update its code. -
Set up an Event Grid Topic in the Azure Portal.
-
Configure Cosmos DB as an Event Grid event source.
-
Subscribe to the Event Grid Topic using the Azure Function as the endpoint.
-
Deploy the updated Function App.
-
Test the Event Grid integration by triggering a task creation.
Step 1: Create and Update the Event Grid Trigger Function
In the TaskManagerFunctions
directory, create the function and update TaskCreatedNotification.cs
.
cd TaskManagerFunctions
func new --template "Azure Event Grid Trigger" --name TaskCreatedNotification
Update TaskCreatedNotification.cs
:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace TaskManagerFunctions
{
public class TaskCreatedNotification
{
private readonly ILogger<TaskCreatedNotification> _logger;
public TaskCreatedNotification(ILogger<TaskCreatedNotification> logger)
{
_logger = logger;
}
public class TaskItem
{
public string id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string DueDate { get; set; }
}
[Function("TaskCreatedNotification")]
public async Task Run([EventGridTrigger] object eventGridEvent)
{
_logger.LogInformation("Event Grid trigger fired: {event}", JsonSerializer.Serialize(eventGridEvent));
// Extract task data (simplified for exam prep)
var eventData = JsonSerializer.Deserialize<JsonElement>(JsonSerializer.Serialize(eventGridEvent));
if (eventData.TryGetProperty("data", out var data))
{
var task = JsonSerializer.Deserialize<TaskItem>(data.GetRawText());
_logger.LogInformation($"Task created: {task.Title}, ID: {task.id}");
// Simulate notification (e.g., call a webhook)
// In exam context, logging is enough to show event handling
}
}
}
}
Step 2: Set Up Event Grid Topic
In the Azure Portal, go to Create a resource > Event Grid Topic > Create. Configure as follows:
- Resource group:
az204exam
. - Name:
taskcreatedtopic
. - Location: Same as apps (e.g., West US 3).
Step 3: Configure Cosmos DB Event Source
In taskmanagercosmos
> Events > Add Event Grid integration. Select:
- Topic:
taskcreatedtopic
. - Event types:
Microsoft.Azure.CosmosDB.DocumentCreated
. - Container:
TasksDB/Tasks
.
Save.
Step 4: Subscribe to Event Grid Topic
In the Azure Portal, go to Event Grid Topics > taskcreatedtopic
> + Event Subscription. Configure:
- Name:
taskcreatedsub
. - Event type:
DocumentCreated
. - Endpoint type: Azure Function.
- Endpoint: Select
taskmanagerfunc-yourname
>TaskCreatedNotification
.
Step 5: Deploy the Function
Deploy the updated Function App.
func azure functionapp publish taskmanagerfunc-yourname
Step 6: Test Event Grid
Trigger a task creation via APIM (as set up in apimanagement.md
).
curl -X POST https://taskmanagerapim-yourname.azure-api.net/functions/managetask -H "Ocp-Apim-Subscription-Key: [your-key]" -H "Content-Type: application/json" -d '{"Title":"Event Grid Task","Description":"Test","DueDate":"2025-04-15"}'
Verify:
- In the Azure Portal, go to
taskmanagerfunc-yourname
> Functions >TaskCreatedNotification
> Monitor > Logs. - Look for
Task created: Event Grid Task, ID: [guid]
. - Check Cosmos DB >
TasksDB/Tasks
to confirm the task exists.
Implement Solutions that Use Azure Event Hub
We'll use Event Hub to stream task updates from the WebApp, processing them with a new Function to log or analyze changes.
Steps
Follow these steps to implement Event Hub:
-
Create an Event Hub Namespace and Hub.
-
Get the Event Hub connection string and add it to the Function App.
-
Update the WebApp to send events to Event Hub.
-
Create an Event Hub Trigger Function to process events.
-
Test locally (optional).
-
Deploy and test the solution in Azure.
Step 1: Create Event Hub Namespace and Hub
In the Azure Portal, go to Create a resource > Event Hubs > Create. Configure:
- Resource group:
az204exam
. - Namespace name:
taskmanagerhub-yourname
. - Location: West US 3.
- Pricing tier: Basic (exam-friendly).
Inside the namespace, create an Event Hub:
- Name:
taskevents
. - Partition count: 2 (minimal for exam).
- Message retention: 1 day.
Step 2: Get Connection String and Add to Function App
In taskmanagerhub-yourname
> Shared access policies > RootManageSharedAccessKey, copy the Primary Connection String.
Add it to the Function App:
- In
taskmanagerfunc-yourname
> Settings > Environment Variables. - Add:
- Name:
EventHubConnection
. - Value:
[your-connection-string]
. - Save.
Step 3: Update WebApp to Send Events
In TaskManagerWeb
, add the Event Hubs SDK and update the controller to send events.
cd TaskManagerWeb
dotnet add package Azure.Messaging.EventHubs
Update Controllers/HomeController.cs
:
using Microsoft.AspNetCore.Mvc;
using TaskManagerWeb.Models;
using System.Collections.Generic;
using Azure.Messaging.EventHubs;
using Azure.Messaging.EventHubs.Producer;
using System.Text;
using System.Text.Json;
namespace TaskManagerWeb.Controllers
{
public class HomeController : Controller
{
private static List<TaskItem> _tasks = new List<TaskItem>();
private readonly EventHubProducerClient _eventHubClient;
public HomeController()
{
// Use environment variable in Azure; fallback for local testing
var connectionString = Environment.GetEnvironmentVariable("EventHubConnection") ?? "your-local-connection-string";
_eventHubClient = new EventHubProducerClient(connectionString, "taskevents");
}
public IActionResult Index()
{
return View(_tasks);
}
[HttpPost]
public async Task<IActionResult> Create(string title, string description, string dueDate)
{
var task = new TaskItem
{
Title = title,
Description = description,
DueDate = dueDate
};
_tasks.Add(task);
// Send event to Event Hub
var eventData = new EventData(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(task)));
await _eventHubClient.SendAsync(new[] { eventData });
return RedirectToAction("Index");
}
}
}
Add to appsettings.json
:
{
"EventHubConnection": ""
}
Deploy the WebApp and add the environment variable:
az webapp up --name taskmanagerweb-yourname --resource-group az204exam
In taskmanagerweb-yourname
> Settings > Environment Variables, add:
- Name:
EventHubConnection
. - Value:
[your-connection-string]
.
Step 4: Create Event Hub Trigger Function
In TaskManagerFunctions
, create the Event Hub Trigger Function and update its code.
func new --template "Event Hub Trigger" --name ProcessTaskEvents
Update ProcessTaskEvents.cs
:
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using System.Text;
namespace TaskManagerFunctions
{
public class ProcessTaskEvents
{
private readonly ILogger<ProcessTaskEvents> _logger;
public ProcessTaskEvents(ILogger<ProcessTaskEvents> logger)
{
_logger = logger;
}
[Function("ProcessTaskEvents")]
public void Run([EventHubTrigger("taskevents", Connection = "EventHubConnection")] string[] events)
{
foreach (var eventData in events)
{
_logger.LogInformation($"Event Hub message: {eventData}");
}
}
}
}
Step 5: Test Locally (Optional)
Update local.settings.json
in TaskManagerFunctions
:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"CosmosDBConnection": "[your-cosmos-connection]",
"EventHubConnection": "[your-eventhub-connection]"
}
}
Run the WebApp and Function locally to test:
cd TaskManagerWeb
dotnet run
Create a task via https://localhost:5001
.
Run the Function in a separate terminal:
cd ../TaskManagerFunctions
func start
Check the Function's console for Event Hub message: {"id":"[guid]","Title":"Test Task",...}
.
Step 6: Deploy and Test
Deploy the Function and test in Azure.
func azure functionapp publish taskmanagerfunc-yourname
Test:
- Access
https://taskmanagerweb-yourname.azurewebsites.net
and create a task. - In the Azure Portal, go to
taskmanagerfunc-yourname
> Functions >ProcessTaskEvents
> Monitor > Logs. - Verify logs show
Event Hub message
with task data. - Check Event Hub metrics in
taskmanagerhub-yourname
> Metrics; look forIncoming Messages
.
Verify All Topics
- Event Grid: Triggered
TaskCreatedNotification
on Cosmos DB task creation. - Event Hub: Streamed WebApp task updates to
ProcessTaskEvents
.
Clean Up (Optional)
To avoid costs, delete all resources:
az group delete -n az204exam --no-wait --yes
Next Steps
- Enhance
TaskCreatedNotification
to call an external webhook (e.g., via HTTP request). - Scale Event Hub processing with multiple partitions for exam scenarios.
- Move to the final topic: message-based solutions (e.g., Azure Service Bus, Queue Storage).