Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating README and Samples for Event Grid #14568

Merged
merged 33 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fe79722
Updating README
Aug 25, 2020
8097e25
Updated README
Aug 25, 2020
44eff5c
More updates to README and samples
Aug 25, 2020
1e8fc61
Created samples README and sample files
Aug 26, 2020
c94050e
Update README.md
kerri-lee Aug 26, 2020
97b9927
Update README.md
kerri-lee Aug 26, 2020
a5f0ded
More samples
Aug 26, 2020
0584aaa
Merging changes
Aug 26, 2020
fc49727
Update README.md
kerri-lee Aug 26, 2020
d969ae4
Updating README
Aug 25, 2020
dfe28a0
Updated README
Aug 25, 2020
c2333ab
More updates to README and samples
Aug 25, 2020
51e013a
Created samples README and sample files
Aug 26, 2020
bf6c3c4
More samples
Aug 26, 2020
cc3a2f8
Update README.md
kerri-lee Aug 26, 2020
29c38e9
Update README.md
Aug 26, 2020
1e0f6a3
merging
Aug 26, 2020
53d3ded
Merging again?
Aug 26, 2020
3497de6
More updates to README and samples
Aug 25, 2020
5c2fca5
Created samples README and sample files
Aug 26, 2020
726e8f1
More samples
Aug 26, 2020
ce825f1
More merging
Aug 26, 2020
a7a49cd
Removing merge conflict
Aug 26, 2020
0cfe6fe
Updating samples to reflect new BinaryData api
Aug 26, 2020
dbf6cc1
Added async method
Aug 26, 2020
668f0bc
Updating samples
Aug 26, 2020
46e6828
Fixing broken links
Aug 26, 2020
5edc219
More changes to README and samples
Aug 27, 2020
c988efb
Small edits, updated system event types
Aug 31, 2020
9f22b80
Update README.md
kerri-lee Sep 1, 2020
b41759b
Edited sample to match readme snippet
Sep 1, 2020
08d0e3a
Update README.md
kerri-lee Sep 1, 2020
bd06c07
Updating session records
Sep 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Messaging.EventGrid",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Messaging.EventGrid.Tests", "tests\Azure.Messaging.EventGrid.Tests.csproj", "{779EF7D4-B9C1-4177-BAA7-CF7CBDEF6A5C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core.Experimental", "..\..\core\Azure.Core.Experimental\src\Azure.Core.Experimental.csproj", "{31629B85-17F3-4135-9F16-C45D77A636EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Core", "..\..\core\Azure.Core\src\Azure.Core.csproj", "{21CF4B4A-5027-46D0-B50A-976BF8483095}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -27,6 +31,14 @@ Global
{779EF7D4-B9C1-4177-BAA7-CF7CBDEF6A5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{779EF7D4-B9C1-4177-BAA7-CF7CBDEF6A5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{779EF7D4-B9C1-4177-BAA7-CF7CBDEF6A5C}.Release|Any CPU.Build.0 = Release|Any CPU
{31629B85-17F3-4135-9F16-C45D77A636EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31629B85-17F3-4135-9F16-C45D77A636EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31629B85-17F3-4135-9F16-C45D77A636EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31629B85-17F3-4135-9F16-C45D77A636EC}.Release|Any CPU.Build.0 = Release|Any CPU
{21CF4B4A-5027-46D0-B50A-976BF8483095}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21CF4B4A-5027-46D0-B50A-976BF8483095}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21CF4B4A-5027-46D0-B50A-976BF8483095}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21CF4B4A-5027-46D0-B50A-976BF8483095}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
251 changes: 206 additions & 45 deletions sdk/eventgrid/Azure.Messaging.EventGrid/README.md

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions sdk/eventgrid/Azure.Messaging.EventGrid/samples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
page_type: sample
languages:
- csharp
products:
- azure
- azure-event-grid
name: Azure Event Grid samples for .NET
description: Samples for the Azure.Messaging.EventGrid client library
---

# Azure Event Grid SDK Samples
Before starting, take a look at the Azure Event Grid [README](../README.md) for more information on how to create an Event Grid custom topic or domain using the Azure portal/Azure CLI, and retrieving the designated endpoint and credential.

- [Publishing Events to an Event Grid Topic](Sample1_PublishEventsToTopic.md)
- [Publishing Events to an Event Grid Domain](Sample2_PublishEventsToDomain.md)
- [Deserializing Events Delivered to Event Handlers ](Sample3_ParseAndDeserializeEvents.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Publishing Events to an Event Grid Topic

This sample demonstrates how to publish both Event Grid and CloudEvent 1.0 schema events to the Event Grid service. You can publish events from your own application using the `EventGridPublisherClient`.

To begin, create separate custom Event Grid topics accepting events of the Event Grid and CloudEvent 1.0 schema. See the [Prerequisites](../#prerequisites) section of the README for more instructions on creating custom topics.

## Creating and Authenticating `EventGridPublisherClient`
Once you have your access key and topic endpoint, you can create the publisher client using the `AzureKeyCredential` class as follows:
```csharp Snippet:CreateClient
EventGridPublisherClient client = new EventGridPublisherClient(
new Uri(topicEndpoint),
new AzureKeyCredential(topicAccessKey));
```
`EventGridPublisherClient` also accepts a set of configuring options through `EventGridPublisherClientOptions`. For example, specifying a custom serializer used to serialize the event data to JSON:

```csharp Snippet:CreateClientWithOptions
EventGridPublisherClientOptions clientOptions = new EventGridPublisherClientOptions()
{
DataSerializer = myCustomDataSerializer
};

EventGridPublisherClient client = new EventGridPublisherClient(
new Uri(topicEndpoint),
new AzureKeyCredential(topicAccessKey),
clientOptions);
```

## Publishing Events to Azure Event Grid
### Using `EventGridEvent`
After creating the `EventGridPublisherClient` such that the custom topic is configured to accept events of the Event Grid schema, we can now create some events of the `EventGridEvent` type to publish to the topic.

Following that, invoke `SendEvents` or `SendEventsAsync` to publish the events to Azure Event Grid.

Note on `EventGridEvent`: each `EventGridEvent` has a set of required, non-nullable properties, including event data. `EventTime` and `Id` are also required properties that are set by default, but can also be manually set if needed.

```csharp Snippet:SendEGEventsToTopic
// Add EventGridEvents to a list to publish to the topic
List<EventGridEvent> eventsList = new List<EventGridEvent>
{
new EventGridEvent(
"This is the event data",
"ExampleEventSubject",
"Example.EventType",
"1.0")
};

// Send the events
await client.SendEventsAsync(eventsList);
```

### Using `CloudEvent`
The process for publishing events of the CloudEvent schema is very similar to that of Event Grid events. Once again, after creating the `EventGridPublisherClient` such that the custom topic is configured to accept events of the CloudEvent 1.0 schema, we can create events of the `CloudEvent` type.

Following that, invoke `SendEvents` or `SendEventsAsync` to publish the events to Azure Event Grid.

Note on `CloudEvent`: each `CloudEvent` has a set of required, non-nullable properties. However, `Data` is *not required*. `Time` and `SpecVersion` are required properties that are set by default, but can also be manually set if needed. `Time` is also set by default, but not required.

```csharp Snippet:SendCloudEventsToTopic
// Add CloudEvents to a list to publish to the topic
List<CloudEvent> eventsList = new List<CloudEvent>
{
// CloudEvent with populated data
new CloudEvent(
"/cloudevents/example/source",
"Example.EventType",
"This is the event data"),

// CloudEvents also supports sending binary-valued data
new CloudEvent(
"/cloudevents/example/binarydata",
"Example.EventType",
new BinaryData("This is binary data"),
"example/binary")};

// Send the events
await client.SendEventsAsync(eventsList);
```

## Source

To view the full example source, see:
- [Sample1_SendEventsToTopic.cs](../tests/Samples/Sample1_SendEventsToTopicAndDomain.cs)
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Publishing Events to an Event Grid Domain

This sample demonstrates how to publish Event Grid schema events to an Event Grid domain. You can publish events from your own application using the `EventGridPublisherClient`.

## Create an Event Grid Domain

To begin, create an Event Grid domain that accepts events of the Event Grid schema. An *event domain* is a management tool for large numbers of Event Grid topics related to the same application. You can think of it as a meta-topic that can have thousands of individual topics.

See the this [step-by-step tutorial](https://docs.microsoft.com/en-us/azure/event-grid/custom-event-quickstart-portal#create-a-custom-topic) for instructions on creating custom topics using Azure Portal; however, instead of searching for "Event Grid Topics", search for "Event Grid Domains". When you create an event domain, you're given a publishing endpoint and access key similar to if you had created a topic in Event Grid.

## Create and Authenticate `EventGridPublisherClient`

If you have not created an `EventGridPublisherClient`, refer to the sample [Publish Events To Topic](../Sample1_PublishEventsToTopic.md) for more information on creating and authenticating the client. An example is shown below:
```csharp Snippet:CreateDomainClient
// Create the publisher client using an AzureKeyCredential
// Domain should be configured to accept events of the Event Grid schema
EventGridPublisherClient client = new EventGridPublisherClient(
new Uri(domainEndpoint),
new AzureKeyCredential(domainAccessKey));
```

## Publish Events to Azure Event Grid
To publish events to any topic in an Event Domain, push the events to the domain's endpoint the same way you would for a custom topic. The only difference is that you must specify the topic you'd like the event to be delivered to. Use the same `SendEvents` method to publish events to the service.

```csharp Snippet:SendEventsToDomain
// Add EventGridEvents to a list to publish to the domain
// Don't forget to specify the topic you want the event to be delivered to!
List<EventGridEvent> eventsList = new List<EventGridEvent>
{
new EventGridEvent(
"This is the event data",
"ExampleEventSubject",
"Example.EventType",
"1.0")
{
Topic = "MyTopic"
}
};

// Send the events
await client.SendEventsAsync(eventsList);
```

## Source

To view the full example source, see:
- [Sample1_SendEventsToTopic.cs](../tests/Samples/Sample1_SendEventsToTopicAndDomain.cs)
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Deserializing Events Delivered to Event Handlers

This sample will demonstrate how to deserialize events that have been delivered to event handlers. There are several different Azure services that act as [event handlers](https://docs.microsoft.com/en-us/azure/event-grid/event-handlers). Regardless of the event handler, however, events are always sent as UTF-8 encoded JSON.

Note: if using Webhooks to for event delivery, Event Grid requires you to prove ownership of your Webhook endpoint before it starts delivering events to that endpoint. At the time of event subscription creation, Event Grid sends a subscription validation event to your endpoint, as seen below. Learn more about completing the handshake here: [Webhook event delivery](https://docs.microsoft.com/en-us/azure/event-grid/webhook-event-delivery)

Handling events will be different based on which schema the event was delivered as. However, the general pattern will remain the same:
- Parse events from JSON into individual events. Based on the event schema (Event Grid or CloudEvents 1.0), you can now access basic information about the event on the envelope (properties that are present for all events, like event time and type).
- Deserialize the event data. Given an `EventGridEvent` or `CloudEvent`, the user can attempt to access the event payload, or data, by deserializing to a specific type. You can supply a custom serializer at this point to correctly decode the data.

## Parse Events from JSON payload
Once events are delivered to the event handler, parse the JSON payload into list of events.

Using `EventGridEvent`:
```csharp Snippet:EgEventParseJson
// Parse the JSON payload into a list of events using EventGridEvent.Parse
EventGridEvent[] egEvents = EventGridEvent.Parse(jsonPayloadSampleOne);
```

Using `CloudEvent`:
```csharp Snippet:CloudEventParseJson
// Parse the JSON payload into a list of events using CloudEvent.Parse
CloudEvent[] cloudEvents = CloudEvent.Parse(jsonPayloadSampleTwo);
```

## Deserialize Event Data
From here, one can access the event data by deserializing to a specific type using `GetData<T>()` and passing in a custom serializer if necessary. Calling `GetData()` will either return a deserialized system event (an event generated by an Azure service), or the event data wrapped in `BinaryData`, which represents the serialized JSON event data as bytes.

### Using `GetData()`
If expecting mostly system events, it may be cleaner to switch on object `GetData()` and use pattern matching to deserialize events. In the case where there are unrecognized event types, one can use the returned `BinaryData` to deserialize the custom event data.

```csharp Snippet:DeserializePayloadUsingNonGenericGetData
// If the event is a system event, GetData() should return the correct system event type
switch (egEvent.GetData())
{
case SubscriptionValidationEventData subscriptionValidated:
Console.WriteLine(subscriptionValidated.ValidationCode);
break;
case StorageBlobCreatedEventData blobCreated:
Console.WriteLine(blobCreated.BlobType);
break;
case BinaryData unknownType:
// An unrecognized event type - GetData() returns BinaryData with the serialized JSON payload
// You can use BinaryData methods to deserialize the payload
if (egEvent.EventType == "MyApp.Models.CustomEventType")
{
TestPayload deserializedEventData = await unknownType.ToObject<TestPayload>();
Console.WriteLine(deserializedEventData.Name);
}
break;
}
```
### Using `GetData<T>()`
Below is an example calling `GetData<T>()` for CloudEvents. In order to deserialize to the correct type, the `EventType` property (`Type` for CloudEvents) helps distinguish between different events. Custom event data should be deserialized using the generic method `GetData<T>()`. There is also an overload for `GetData<T>()` that accepts a custom `ObjectSerializer` to deserialize the event data.

```csharp Snippet:DeserializePayloadUsingGenericGetData
// If the event is a system event, GetData() should return the correct system event type
switch (cloudEvent.Type)
{
case "Contoso.Items.ItemReceived":
// By default, GetData uses JsonObjectSerializer to deserialize the payload
ContosoItemReceivedEventData itemReceived = cloudEvent.GetData<ContosoItemReceivedEventData>();
Console.WriteLine(itemReceived.ItemSku);
break;
case "MyApp.Models.CustomEventType":
// One can also specify a custom ObjectSerializer as needed to deserialize the payload correctly
TestPayload testPayload = await cloudEvent.GetDataAsync<TestPayload>(myCustomSerializer);
Console.WriteLine(testPayload.Name);
break;
case "Microsoft.EventGrid.SubscriptionValidationEvent":
SubscriptionValidationEventData subscriptionValidated = cloudEvent.GetData<SubscriptionValidationEventData>();
Console.WriteLine(subscriptionValidated.ValidationCode);
break;
}
```

## Source
To view the full example source, see:
- [Sample2_ParseAndDeserializeEvents.cs](../tests/Samples/Sample1_ParseAndDeserializeEvents.cs)
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ public T GetData<T>(ObjectSerializer serializer, CancellationToken cancellationT
}

/// <summary>
/// Deserializes the event payload into a specified event type using the <see cref="JsonObjectSerializer"/>.
/// Deserializes the event payload into a specified event type using the provided <see cref="JsonObjectSerializer"/>.
/// </summary>
/// <typeparam name="T"> Type of event to deserialize to. </typeparam>
/// <param name="cancellationToken"> The cancellation token to use during deserialization. </param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public async Task<T> GetDataAsync<T>(ObjectSerializer serializer, CancellationTo
}

/// <summary>
/// Deserializes the event payload into a specified event type <see cref="ObjectSerializer"/>.
/// Deserializes the event payload into a specified event type using the provided <see cref="ObjectSerializer"/>.
/// </summary>
/// <typeparam name="T"> Type of event to deserialize to. </typeparam>
/// <param name="serializer"> Custom serializer used to deserialize the payload. </param>
Expand All @@ -155,7 +155,7 @@ public T GetData<T>(ObjectSerializer serializer, CancellationToken cancellationT
}

/// <summary>
/// Deserializes the event payload into a specified event type <see cref="JsonObjectSerializer"/>.
/// Deserializes the event payload into a specified event type using the provided <see cref="JsonObjectSerializer"/>.
/// </summary>
/// <typeparam name="T"> Type of event to deserialize to. </typeparam>
/// <param name="cancellationToken"> The cancellation token to use during deserialization. </param>
Expand Down
Loading