How To Build A Reactive Solution With Azure Event Grid
Tags: azure, serverless, eventgrid
Published: 2019-08-14 06:10:59

<p>Author Credits: <a href="https://www.serverless360.com/blog/author/steef">Steef-Jan Wiggers</a>, Azure MVP</p>
<p>Originally published at <a href="https://www.serverless360.com/blog">Serverless360 Blogs</a></p>
<p>Azure <span style="text-decoration: underline;"><a href="https://azure.microsoft.com/en-us/services/event-grid/" target="_blank" rel="noopener noreferrer">Event Grid</a></span> was the missing piece for messaging in the cloud. Instead of extensive polling or ‘hammer-polling,’ a very resource intensive process, you now get ‘tap on the shoulder’ – here’s an event ‘an image is available for processing.’ Event Grid is a service in Azure that enables central management of events. It provides intelligent routing with filters and standardizes on an <span style="text-decoration: underline;"><a href="https://docs.microsoft.com/en-us/azure/event-grid/event-schema" target="_blank" rel="noopener noreferrer">event schema</a>.</span></p>
<h2 style="padding: 5px 0 0px; margin-bottom: 10px; border-bottom: 3px solid #3081ed; display: inline-block;"><strong>Event Grid</strong></h2>
<p>With Event, Grid offers a mechanism for reactive event handling. An application can subscribe to events and handle them accordingly – for instance, handle events like storage blob events, provisioning notifications in an Azure subscription, IoT device signals, or even custom event.</p>
<p>Event Grid handles events, not messages. A message has an intent and requires an action – for instance, an order that needs to be fulfilled. An event is a fact, something that has happened and you can react to it or not. Hence there is a clear distinction between messaging and events. Thus, there are services for both available in the Azure Platform - Clemens Vasters explains this in the blog post from last year: <a href="https://azure.microsoft.com/en-us/blog/events-data-points-and-messages-choosing-the-right-azure-messaging-service-for-your-data/" target="_blank" rel="noopener noreferrer"><span style="text-decoration: underline;">Events, Data Points, and Messages</span> - <span style="text-decoration: underline;">Choosing the right Azure messaging service for your data</span></a>.</p>
<h2 style="padding: 5px 0 0px; margin-bottom: 10px; border-bottom: 3px solid #3081ed; display: inline-block;"><strong>Pub-Sub Model</strong></h2>
<p>The concept of Azure Event Grid is simple – it is a pub-sub model. An event source pushes events to Azure Event Grid, and event handlers subscribe to events. An event source or publisher - an Azure service like Storage, IoT Hub, or a third party source emits an event, for instance, <strong>blobCreated</strong> or <strong>blobDeleted</strong>. You can send the event to a topic.  Each topic can have one or multiple subscribers (event handlers).  You can configure an Azure Service, if supported, as an event publisher or you create a custom Azure Event Grid Topic. Subsequently, the event handlers in Azure like Functions, WebHook, and Event Hubs can react to the events and process them.</p>
<p><img class="alignnone size-full wp-image-116" src="https://serverless360.wpengine.com/wp-content/uploads/2018/07/Event-Grid-concepts.png" alt="It is a pub-sub model. An event source pushes events to Azure Event Grid, and event handlers subscribe to events." /></p>
<p>The pub-sub model of Azure Event Grid is not similar to service bus Topics and subscriptions. Moreover, Topics and subscription are push-pull, while Azure Event Grid is push-push. Furthermore, there are other differences too, as shown in the picture below.</p>
<p><img class="alignnone size-full wp-image-117" src="https://serverless360.wpengine.com/wp-content/uploads/2018/07/Cloud-Pub-Sub-Models.png" alt="Pub-sub model of Azure Event Grid is not similar to service bus Topics and subscriptions" /></p>
<p>Consider a function listening to a blob storage container and each time a new blob is created it will send a message to a message queue. Subsequently, you can listen to the queue with another function, process the blob with the function and call two other functions (or place a queue between that function and the other two functions). The diagram below shows how pull-push would work using a Service Bus Queue.</p>
<p><img class="alignnone size-full wp-image-130" src="https://serverless360.wpengine.com/wp-content/uploads/2018/07/Building-reactive-solution-with-Azure-Event-Grid-Picture-3.png" alt="pull-push would work using a Service Bus Queue" /></p>
<p>With Event Grid, you can have a different approach as shown in the diagram below.</p>
<p><img class="alignnone size-full wp-image-132" src="https://serverless360.wpengine.com/wp-content/uploads/2018/07/Building-reactive-solution-with-Azure-Event-Grid-Picture-4.png" alt="With Event Grid, you can have a different approach" /></p>
<p>You can view Event Grid as the backbone of event-driven computing in Microsoft Azure - and it brings a few benefits to the enterprise. With the push-push pub-sub model you can be more efficient with resources. Event Grid delivers besides efficiency:</p>
<ul>
	<li>Native integrations (point and click) in a serverless way;</li>
	<li>Fan out to multiple places;</li>
	<li>Reliable delivery of events within 24 hours;</li>
	<li>Intelligent routing of events with types and filters.</li>
</ul>
<p>These benefits will become apparent in this blog post.</p>
<h2 style="padding: 5px 0 0px; margin-bottom: 10px; border-bottom: 3px solid #3081ed; display: inline-block;"><strong>Reversal of dependencies</strong></h2>
<p>With Event Grid in Azure, you can use as a developer can or adopt reverse dependencies in an existing cloud solution – where services are supporting business processes by depending on each other. In this type of solution, each service has some logic to communicate with others across the architecture. Moreover, the solution or architecture becomes complex or spaghetti of services.</p>
<p><img class="alignnone size-full wp-image-133" src="https://serverless360.wpengine.com/wp-content/uploads/2018/07/Building-reactive-solution-with-Azure-Event-Grid-Picture-5.png" alt="with leveraging Event Grid, you can loosen these dependencies by making the services more event-driven. " /></p>
<p>However, with leveraging Event Grid, you can loosen these dependencies by making the services more event-driven. The services communicate by pushing events to a central place, i.e., Event Grid.</p>
<p><img class="alignnone size-full wp-image-134" src="https://serverless360.wpengine.com/wp-content/uploads/2018/07/Building-reactive-solution-with-Azure-Event-Grid-Picture-6.png" alt="By pushing events to a central place you fundamentally unify the communication between services." /></p>
<p>By pushing events to a central place you fundamentally unify the communication between services. Tom Kerhove discusses this in his blog <span style="text-decoration: underline;"><a href="https://blog.tomkerkhove.be/2017/08/22/exploring-azure-event-grid/" target="_blank" rel="noopener noreferrer">Exploring Event Grid</a>.</span></p>
<h2 style="padding: 5px 0 0px; margin-bottom: 10px; border-bottom: 3px solid #3081ed; display: inline-block;"><strong>Toll booth Scenario</strong></h2>
<p>A typical use-case or sample of Event Grid is processing an image leveraging the Vision API. Azure Blob Storage emits an event <strong>blobCreated</strong>, which is subsequently handled by a function or Logic App subscribing to that event. In the following scenario, the event grid plays a crucial role in handling <strong>blobCreated</strong> events where several functions subscribe to that event.</p>
<p><img class="alignnone size-full wp-image-122" src="https://serverless360.wpengine.com/wp-content/uploads/2018/07/Toll-booth-license-plate-recognition-scenario.png" alt="Azure Event Grid and its Toll booth Scenario" /></p>
<p>In the above scenario, a camera registers every car going through a toll booth. The picture of the vehicle includes a license plate. These images are uploaded in batches to an Azure Storage account – configured as event publisher. Every image is stored as a blob and thus results in an event being emitted to the Event Grid topic. Subsequently, several functions subscribe to the events:</p>
<ul>
	<li>A function to push the blob (image) to a Computer Vision API – extracting license plate number through Optical Character Recognition (OCR) feature. The function will push the result as an event to another Event Grid Topic.</li>
	<li>A Function to save the license plate (the result of the Vision API) to Cosmos DB.</li>
	<li>A Function to save a reference of the image in the storage account to Cosmos DB.</li>
</ul>
<p>The above scenario shows how a developer can build several functions to handle the events. Moreover, the developer is a part of making reactive components, i.e., functions (tasks) in this case. The process of managing events (car passing a toll booth) is through a loosely coupled, scalable, and serverless type of solution. In the following paragraphs, we will further discuss some of the critical concepts of Event Grid with the given scenario.</p>
<h2 style="padding: 5px 0 0px; margin-bottom: 10px; border-bottom: 3px solid #3081ed; display: inline-block;"><strong>Azure Event Grid Schema</strong></h2>
<p>The events in Event Grid adhere to a predefined schema – a JSON schema with several properties. Furthermore, events are sent as a JSON array to Event Grid with a maximum size of 1 MB – each event in the array is limited to 64 KB. In case you send an array of an event exceeding the limits – you will receive the HTTP response 413 Payload Too Large. Note that even a single event is sent as an array.</p>
<p>The following schema shows the properties of an event:</p>
<pre class="lang:default decode:true ">[
 {
  "topic": string,
  "subject": string,
  "id": string,
  "eventType": string,
  "eventTime": string,
  "data":{
  object-unique-to-each-publisher
  },
  "dataVersion": string,
  "metadataVersion": string
 }
]</pre>
<p>For example, the schema published for an Azure Blob storage event in our scenario:</p>
<pre class="lang:default decode:true ">[{
"topic": "/subscriptions/0bf166ac-9aa8-4597-bb2a-a845afe01415/resourceGroups/RG_LicensePlates_Demo/providers/Microsoft.Storage/storageAccounts/licenseplatesstorage",
"subject": "/blobServices/default/containers/images/blobs/LicensePlate1.png",
"eventType": "Microsoft.Storage.BlobCreated",
"eventTime": "2018-06-05T08:35:26.2778593Z",
"id": "2c6f7c22-201e-00b7-0aa8-fca7ce06e319",
"data": {
"api": "PutBlob",
"clientRequestId": "32a51839-6bf5-44d6-acfe-7d284229988c",
"requestId": "2c6f7c22-201e-00b7-0aa8-fca7ce000000",
"eTag": "0x8D5CABF497519C6",
"contentType": "application/octet-stream",
"contentLength": 41860,
"blobType": "BlockBlob",
"url": "https://licenseplatesstorage.blob.core.windows.net/images/LicensePlate1.png",
"sequencer": "000000000000000000000000000008BC0000000003fd850f",
"storageDiagnostics": {
"batchId": "fbb4e831-82b2-4e64-b0e5-0735449f9cb7"
}
},
"dataVersion": "",
"metadataVersion": "1"
}]</pre>
<p>The image processing function in our scenario can handle the event and use the URL in the data payload to download the image from the storage account container. The Rest Call pushes the downloaded image to the Computer Vision endpoint. Finally, this function will read the JSON result and push to another Event Grid topic as an event.</p>
<p><img class="alignnone size-full wp-image-123" src="https://serverless360.wpengine.com/wp-content/uploads/2018/07/Tollbooth-license-plate-recognition-scenario1.png" alt="SON result and push to another Event Grid topic as an event." /></p>
<h2 style="padding: 5px 0 0px; margin-bottom: 10px; border-bottom: 3px solid #3081ed; display: inline-block;"><strong>Security</strong></h2>
<p>The security of Event Grid consists of several parts. The first part is the Role-based Access Control (RBAC) on the Event Grid resource - where the person creating a new subscription needs to have the <strong>Microsoft.EventGrid/EventSubscriptions/Write</strong> permissions. Second, there is a validation on WebHooks – the first and foremost mechanism for listening to events – every newly registered WebHook needs to be validated by Event Grid first. This is what is implicitly happening when creating subscriptions to events in an event resource like Storage Account V2 – you can hook events to a Function or Logic App using the events feature in the storage account. In our scenario, the arrangement of subscriptions to events is implicit.</p>
<p>In case you want to subscribe to events using custom code, i.e., the on-premise client you will need to respond to the validation token the Event Grid will send out. The validation request Event Grid will send to the client will look like below:</p>
<pre class="lang:default decode:true ">[{
"id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66",
"topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"subject": "",
"data": {
"validationCode": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6"
},
"eventType": "Microsoft.EventGrid.SubscriptionValidationEvent",
"eventTime": "2018-01-25T22:12:19.4556811Z",
"metadataVersion": "1",
"dataVersion": "1"
}]</pre>
<p>The client will respond with the validation code in the response with a 200-OK. If you want to send custom events, use SAS tokens or key authentication to publish an event to a topic. For more details on security and authentication of Event Grid, see <span style="text-decoration: underline;"><a href="https://docs.microsoft.com/en-us/azure/event-grid/security-authentication" target="_blank" rel="noopener noreferrer">https://docs.microsoft.com/en-us/azure/event-grid/security-authentication</a></span></p>
<h2 style="padding: 5px 0 0px; margin-bottom: 10px; border-bottom: 3px solid #3081ed; display: inline-block;"><strong>Guaranteed delivery of events</strong></h2>
<p>A key aspect of the scenario is the guaranteed delivery of events. The default behavior of Event Grid is that it will try at least once to deliver the event and retry using exponential backoff - Event Grid will keep on sending events to the Event Handler until it acknowledges the request with either an HTTP 200 OK or HTTP 202 Accepted. The back-off mechanism will use progressively longer waits between retries for following error responses. Furthermore, it will last until 24 hours have passed - after 24 hours the Event Grid will delete the event. See also <span style="text-decoration: underline;"><a href="https://docs.microsoft.com/en-us/azure/event-grid/delivery-and-retry" target="_blank" rel="noopener noreferrer">https://docs.microsoft.com/en-us/azure/event-grid/delivery-and-retry</a>.</span></p>
<h2 style="padding: 5px 0 0px; margin-bottom: 10px; border-bottom: 3px solid #3081ed; display: inline-block;"><strong>Fan-in fan-out Scenario</strong></h2>
<p>You can view Event Grid as serverless that is you do not have to manage any infrastructure, you pay per operation, and Microsoft handles the scaling for you. Event Grid leverages Service Fabric under the hood and thus scales when the workload increases.</p>
<p>Event Hubs and Event Grid together work seamlessly in ingestion (fan-in) and push (fan-out) scenarios. Both scale easily when workloads increases and do not require you manage infrastructure. In the following situation, the capture feature will send the wind farm data (per turbine) to the event hub.</p>
<p><img class="alignnone size-full wp-image-124" src="https://serverless360.wpengine.com/wp-content/uploads/2018/07/Ingestion-and-migration-of-event-data.png" alt="Azure Event Grid and its fan-in and fan-out scenario" /></p>
<p>The <span style="text-decoration: underline;"><a href="https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-capture-overview" target="_blank" rel="noopener noreferrer">Event Hubs Capture</a> </span>pulls the data from the stream of windfarm data and generates storage blobs with the data in <span style="text-decoration: underline;"><a href="https://en.wikipedia.org/wiki/Apache_Avro" target="_blank" rel="noopener noreferrer">Avro</a></span> format. Subsequently, when Capture creates the blob (1), the blobCreated event is generated and emitted to Event Grid (2). Subscribers to the event will receive it and handle it accordingly, in this case, an Azure Function (3) will get the event. Furthermore, the function will retrieve the file (URL to the Avro file) from the blob storage (4) and store it into a SQL Data Warehouse (5). This sample is available on the Microsoft docs: <span style="text-decoration: underline;"><a href="https://docs.microsoft.com/en-gb/azure/event-grid/event-grid-event-hubs-integration" target="_blank" rel="noopener noreferrer">https://docs.microsoft.com/en-gb/azure/event-grid/event-grid-event-hubs-integration</a></span></p>
<h2 style="padding: 5px 0 0px; margin-bottom: 10px; border-bottom: 3px solid #3081ed; display: inline-block;"><strong>Wrap up</strong></h2>
<p>This blog discusses Event Grid scenarios where Event Grid plays a central role, and how developers can leverage this service. Another scenario showed how Event Grid could collaborate with Event Hubs in high volume ingestion and migration of event data.</p>
<p>Event Grid is globally available in several Azure regions of the U.S., Europe, and Asia, with more to come soon. For pricing of Event Grid, details see the <span style="text-decoration: underline;"><a href="https://azure.microsoft.com/en-us/pricing/details/event-grid/" target="_blank" rel="noopener noreferrer">pricing page</a></span>. Furthermore, the full documentation on the Azure Event Grid service is available on the <span style="text-decoration: underline;"><a href="https://docs.microsoft.com/en-us/azure/event-grid/" target="_blank" rel="noopener noreferrer">Microsoft Documentation site</a></span>.</p>