Building an Azure Event Grid app. Part 1: Event Grid Topic and a .NET Core custom app event publisher.

In order to have a sample “data feed” for an application I wanted to use Azure Event Grid to create a topic that events could be published to and clients could subscribe to in order to process the events.

The generic scenario is that of alarms (of whatever sort you’d imagine; car, house, IoT device) for which the events represent status updates.

This is the first post about getting started but in my next posts I will cover consuming the events in an Azure Logic App and turning the custom event publishing app into a Docker image.

Creating an Event Grid Topic

The first step is to create the Event Grid Topic. As Event Grid is serverless, this is as easy as you might expect (no thinking about infrastructure, sizing or scaling). The step by step how to is here but you simply give it a name, a resource group and choose the region to run it in. Wait a few seconds and that’s it, the Topic is created:

Creating a publisher (custom app)

I wanted to create an app that would keep generating events, representing alarms and their status, and publishing these to the Event Grid Topic created above.

Publishing an event is simply performing an HTTP Post, and although I chose to implement this in .NET Core, you could choose almost any language.

The data object in an Azure Event Grid event is a JSON payload, and therefore I started by thinking about what that data would consist of:

 {
    "properties": {
        "deviceId": {
            "type": "number"
        },
        "image": {
            "type": "string"
        },
        "latitude": {
            "type": "number"
        },
        "longitude": {
            "type": "number"
        },
        "status": {
            "type": "string"
        }
    },
    "type": "object"
}

 

For my purposes I wanted the alarm to include the device id, an image sent by the alarm (in fact a URL to an image in blob storage), the location of the alarm (longitude and latitude) and the status (green, amber, red).

To create the app I simply used

 dotnet new console

and then started editing it in Visual Studio Code

 code .

A good reference for getting started with exactly this can be found here.

The key point for me that I’d call out is that if you’re used to the .NET HttpClient then in .NET Core HttpClient doesn’t have a PostAsJsonAsync method. Instead what I’ve ended up doing is create a class as follows:

 public class JsonContent : StringContent

{

public JsonContent(object obj) :

base(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json"){ }

}

Then call the PostAsync method but passing in the JSON content:

 _client.PostAsync(_eventTopicEndpoint, new JsonContent(alarmEvents));

This requires that the Newtonsoft.Json package is added to the csproj file:

 <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />

At it’s core publishing to an event Grid Topic is then:

Set the headers including the Event Grid Topic key:

 _client.DefaultRequestHeaders.Accept.Clear();

_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

_client.DefaultRequestHeaders.Add("aeg-sas-key", _eventAegSasKey);

Create an event with a payload of an object that matches the JSON schema you want:

 AlarmEvent alarmEvent = new AlarmEvent {topic = _eventTopicResource, subject = "Alarm", id = Guid.NewGuid().ToString(), eventType = "recordInserted", eventTime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFK"), data = payload };

AlarmEvent[] alarmEvents = { alarmEvent };

Post the event:

 HttpResponseMessage response = await _client.PostAsync(_eventTopicEndpoint, new JsonContent(alarmEvents));

There are other ways of doing all of this of course but if you want it then all my code can be found in GitHub. A reasonable amount of the code is my attempt at setting configurable boundaries for the geographical location for the devices, but it’s not relevant here so I won’t go into it.

Before you commit to Git, make sure you have an appropriate .gitignore file to ensure you’re only staging the files you need. For .NET Core I used this one:

https://github.com/dotnet/core/blob/master/.gitignore

This reduced the number of files I needed to stage and commit from 20 to 4. There are a wide range of .gitignore files here for most languages.

I didn’t want to hardcode some of the key Event Grid information both so that keys didn’t end up in GitHub and also to make it reusable for other Topics. Therefore I can now run my console app from the command line providing some key arguments:

 dotnet run <EventTopicURL> <EventResourcePath> <EventKey>

where:

  • EventTopicURL: the endpoint for the Event Grid Topic and can be copied from the Overview blade in the Azure Portal.
  • EventResourcePath: the path to the resource and is of the form: /subscriptions/< Azure subscription id>/resourceGroups/<Event Grid Topic resource group name>/providers/Microsoft.EventGrid/topics/<Event Grid Topic name>.
  • EventKey: the key for the Event Grid Topic and can be copied from the Access Keys blade in the Azure Portal.

In the next post I’ll look at how to subscribe to the Topic with a Logic App to both test and consume the events.

Cheers,
Giles

Building an Azure Event Grid app. Part 1: Event Grid Topic and a .NET Core custom app event publisher.

Building an Azure Event Grid app. Part 2: Adding a Logic App subscriber to the Event Grid Topic.

Building an Azure Event Grid app. Part 3: Turning the publisher app into a Docker image.

Building an Azure Event Grid app. Part 4: Adding a Service Principal to the Event Grid Topic.

Building an Azure Event Grid app. Part 5: CI and pushing to DockerHub with VSTS.