{"id":1030,"date":"2021-03-19T12:15:14","date_gmt":"2021-03-19T19:15:14","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sdk\/?p=1030"},"modified":"2021-03-19T12:15:14","modified_gmt":"2021-03-19T19:15:14","slug":"event-grid-ga","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sdk\/event-grid-ga\/","title":{"rendered":"Announcing the new Azure Event Grid Client Libraries"},"content":{"rendered":"<p>We are pleased to announce that the new Azure Event Grid libraries have reached general availability (GA). Version 4 of the <a href=\"https:\/\/docs.microsoft.com\/azure\/event-grid\/overview\">Azure Event Grid<\/a> packages have now been released (<a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/blob\/master\/sdk\/eventgrid\/Azure.Messaging.EventGrid\">.NET<\/a>, <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/tree\/master\/sdk\/eventgrid\/azure-messaging-eventgrid\">Java<\/a>, <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/tree\/master\/sdk\/eventgrid\/azure-eventgrid\">Python<\/a> and <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/blob\/master\/sdk\/eventgrid\/eventgrid\/\">JavaScript\/TypeScript<\/a>), following the new <a href=\"https:\/\/github.com\/Azure\/azure-sdk\/blob\/master\/README.md\">Azure SDK guidelines<\/a>. These guidelines provide consistency across all Azure SDK client libraries while also allowing each language to follow the idioms for their respective languages.<\/p>\n<p>This library is the result of months of development, design discussions, feedback, and observing developers in user studies as they worked with Azure Event Grid. In this release, we&#8217;ve simplified the API surface, added distributed tracing, and added support for publishing using the <a href=\"https:\/\/cloudevents.io\">CloudEvent<\/a> schema and custom event schemas.<\/p>\n<h2>Cross Service SDK improvements<\/h2>\n<p>The new Event Grid client libraries allow Event Grid developers to take advantage of the cross-service improvements made to the Azure development experience, such as:<\/p>\n<ul>\n<li><strong>Core credential types<\/strong> to share a single authentication approach between clients<\/li>\n<li><strong>A unified logging and diagnostics pipeline<\/strong> offering a common view of the activities across each of the client libraries<\/li>\n<\/ul>\n<p>In particular, the new Event Grid libraries use the core <code>AzureKeyCredential<\/code> type for authenticating the service client.<\/p>\n<h3>C&num;<\/h3>\n<pre><code class=\"csharp\">EventGridPublisherClient client = new EventGridPublisherClient(\n    new Uri(\"&lt;endpoint&gt;\"),\n    new AzureKeyCredential(\"&lt;access-key&gt;\"));\n<\/code><\/pre>\n<h3>Java<\/h3>\n<pre><code class=\"java\">EventGridPublisherClient&lt;EventGridEvent&gt; eventGridEventClient = new EventGridPublisherClientBuilder()\n    .endpoint(\"&lt;endpoint&gt;\")\n    .credential(new AzureKeyCredential(\"&lt;access-key&gt;\"))\n    .buildEventGridEventPublisherClient();\n<\/code><\/pre>\n<h3>JavaScript<\/h3>\n<pre><code class=\"js\">const { EventGridPublisherClient, AzureKeyCredential } = require(\"@azure\/eventgrid\");\nconst client = new EventGridPublisherClient(\"&lt;endpoint&gt;\", \"EventGrid\", new AzureKeyCredential(\"&lt;access-key&gt;\"));\n<\/code><\/pre>\n<h3>Python<\/h3>\n<pre><code class=\"python\">from azure.core.credentials import AzureKeyCredential\nfrom azure.eventgrid import EventGridPublisherClient\ncredential = AzureKeyCredential(\"&lt;access-key&gt;\")\nclient = EventGridPublisherClient(\"&lt;endpoint&gt;\", credential)\n<\/code><\/pre>\n<h2>New features<\/h2>\n<p>In addition to the cross-service improvements, Version 4 of the library includes several new features specific to Event Grid: &#8211; <strong>Support for publishing events using the <a href=\"https:\/\/cloudevents.io\">CloudEvent<\/a> schema<\/strong> to topics which are configured to use the CloudEvent V1 schema.<\/p>\n<h3>C&num;<\/h3>\n<pre><code class=\"csharp\">var cloudEvent = new CloudEvent(\n    source: \"\/cloudevents\/example\/source\",\n    type: \"Example.EventType\",\n    data: new MyDataModel() { A = 5, B = true });\n\nawait client.SendEventAsync(cloudEvent);\n<\/code><\/pre>\n<h3>Java<\/h3>\n<pre><code class=\"java\">\/\/ Initialize the client for use with the cloud event schema\nEventGridPublisherClient&lt;CloudEvent&gt; publisherClient = new EventGridPublisherClientBuilder()\n    .endpoint(\"&lt;endpoint&gt;\")\n    .credential(new AzureKeyCredential(\"&lt;access-key&gt;\"))\n    .buildCloudEventPublisherClient();\n\nUser newUser = new User(\"John2\", \"James\");\nCloudEvent cloudEventModel = new CloudEvent(\"https:\/\/com.example.myapp\", \"User.Created.Object\",\nBinaryData.fromObject(newUser), CloudEventDataFormat.JSON, \"application\/json\");\npublisherClient.sendEvents(cloudEventModel);\n<\/code><\/pre>\n<h3>JavaScript<\/h3>\n<pre><code class=\"js\">\/\/ Initialize the client for use with the cloud event schema\nconst client = new EventGridPublisherClient(\n  \"&lt;endpoint&gt;\",\n  \"CloudEvent\",\n  new AzureKeyCredential(\"&lt;access-key&gt;\")\n);\n\n\/\/ Send an event to the Event Grid Service, using the Cloud Event schema.\n\/\/ A random ID will be generated for this event, since one is not provided.\nawait client.send([\n  {\n    type: \"com.example.cloudevent\",\n    source: \"\/azure\/sdk\/eventgrid\/samples\/sendEventSample\",\n    data: {\n      message: \"this is a sample event\"\n    }\n  }\n]);\n<\/code><\/pre>\n<h3>Python<\/h3>\n<pre><code class=\"python\">client.send([\n    CloudEvent(\n        type=\"Contoso.Items.ItemReceived\",\n        source=\"\/contoso\/items\",\n        data={\n            \"itemSku\": \"Contoso Item SKU #1\"\n        },\n        subject=\"Door1\"\n    )\n])\n<\/code><\/pre>\n<ul>\n<li><strong>Support for publishing events using a custom schema<\/strong> to topics which are configured to use a custom schema. <a href=\"https:\/\/docs.microsoft.com\/azure\/event-grid\/input-mappings\">Custom schema<\/a> events are useful in situations where you are dealing with events that do not match either the CloudEvent or the Event Grid schema, but you would still like to use Azure Event Grid. In both Java and .NET, custom events are represented with the <code>BinaryData<\/code> type. This is a common type used across several messaging libraries in Java and .NET, including Service Bus, Event Hubs, and Storage Queues.<\/li>\n<\/ul>\n<h3>C&num;<\/h3>\n<pre><code class=\"csharp\">var customModel = new CustomModel\n{\n    DataVersion = \"1.0\",\n    EventTime = Recording.Now,\n    EventType = \"Microsoft.MockPublisher.TestEvent\",\n    Id = Recording.Random.NewGuid().ToString(),\n    Subject = \"Subject\",\n    Topic = \"Topic\",\n    Data = new MyDataModel() { A = 5, B = true }\n};\nvar customEvent = new BinaryData(customModel);\nawait client.SendEventAsync(cloudEvent);\n<\/code><\/pre>\n<h3>Java<\/h3>\n<pre><code class=\"java\">\/\/ Initialize the client for use with a custom event schema\nEventGridPublisherClient&lt;BinaryData&gt; customEventClient = new EventGridPublisherClientBuilder()\n    .endpoint(\"&lt;endpoint&gt;\")\n    .credential(new AzureKeyCredential(\"&lt;access-key&gt;\"))\n    .buildCustomEventPublisherClient();\n\nList&lt;BinaryData&gt; events = new ArrayList&lt;&gt;();\nevents.add(BinaryData.fromObject(new HashMap&lt;String, String&gt;() {\n    {\n        put(\"id\", UUID.randomUUID().toString());\n        put(\"time\", OffsetDateTime.now().toString());\n        put(\"subject\", \"Test\");\n        put(\"foo\", \"bar\");\n        put(\"type\", \"Microsoft.MockPublisher.TestEvent\");\n        put(\"data\", \"example data\");\n        put(\"dataVersion\", \"0.1\");\n    }\n}));\ncustomEventClient.sendEvents(events);\n<\/code><\/pre>\n<h3>JavaScript<\/h3>\n<pre><code class=\"js\">\/\/ Initialize the client for use with a custom event schema\nconst client = new EventGridPublisherClient(\n  \"&lt;endpoint&gt;\",\n  \"Custom\",\n  new AzureKeyCredential(\"&lt;access-key&gt;\")\n);\n\nawait client.send([\n  {\n    eventType: \"Azure.Sdk.SampleEvent\",\n    subject: \"Event Subject\",\n    dataVersion: \"1.0\",\n    data: {\n      hello: \"world\"\n    }\n  }\n]);\n<\/code><\/pre>\n<h3>Python<\/h3>\n<pre><code class=\"python\">custom_schema_event = {\n    \"customSubject\": \"sample\",\n    \"customEventType\": \"sample.event\",\n    \"customDataVersion\": \"2.0\",\n    \"customId\": uuid.uuid4(),\n    \"customEventTime\": dt.datetime.now(UTC()).isoformat(),\n    \"customData\": \"sample data\"\n}\n\nclient.send(custom_schema_event)\n<\/code><\/pre>\n<ul>\n<li><strong>Helpers to construct SAS (shared access signature) tokens<\/strong> which can be used to provide time-based access for publishing to an Event Grid topic. Generally, the workflow would be that one application would generate the shared string and hand off the string to another application that would consume the string. <\/li>\n<\/ul>\n<h3>C&num;<\/h3>\n<p>Generate the SAS:<\/p>\n<pre><code class=\"csharp\">var builder = new EventGridSasBuilder(new Uri(topicEndpoint), DateTimeOffset.Now.AddHours(1));\nvar keyCredential = new AzureKeyCredential(topicAccessKey);\nstring sasToken = builder.GenerateSas(keyCredential);\n<\/code><\/pre>\n<p>Here is how it would be used from the consumer&#8217;s perspective using the core <code>AzureSasCredential<\/code> type:<\/p>\n<pre><code class=\"csharp\">var sasCredential = new AzureSasCredential(sasToken);\nEventGridPublisherClient client = new EventGridPublisherClient(\n    new Uri(topicEndpoint),\n    sasCredential);\n<\/code><\/pre>\n<h3>Java<\/h3>\n<p>Generate the SAS:<\/p>\n<pre><code class=\"java\">String sasToken = EventGridPublisherClient.generateSas(\n    topicEndpoint,\n    new AzureKeyCredential(topicAccessKey),\n    OffsetDateTime.now().plusMinutes(20));\n<\/code><\/pre>\n<p>Here is how it would be used from the consumer&#8217;s perspective using the core <code>AzureSasCredential<\/code> type:<\/p>\n<pre><code class=\"java\">EventGridPublisherClient&lt;CloudEvent&gt; publisherClient = new EventGridPublisherClientBuilder()\n    .endpoint(topicEndpoint)\n    .credential(new AzureSasCredential(sasToken))\n    .buildCloudEventPublisherClient();\n<\/code><\/pre>\n<h3>JavaScript<\/h3>\n<p>Generate the SAS:<\/p>\n<pre><code class=\"js\">\/\/ Create a SAS Token which expires on 2020-01-01 at Midnight.\nconst token = generateSharedAccessSignature(\n  \"&lt;endpoint&gt;\",\n  new AzureKeyCredential(\"&lt;API key&gt;\"),\n  new Date(\"2020-01-01T00:00:00\")\n);\n<\/code><\/pre>\n<p>Here is how it would be used from the consumer&#8217;s perspective using the core <code>AzureSasCredential<\/code> type:<\/p>\n<pre><code class=\"js\">const client = new EventGridPublisherClient(\n  \"&lt;endpoint&gt;\",\n  \"&lt;endpoint schema&gt;\",\n  new AzureSASCredential(\"&lt;SAS Token&gt;\")\n);\n<\/code><\/pre>\n<h3>Python<\/h3>\n<p>Generate the SAS:<\/p>\n<pre><code class=\"python\">signature = generate_sas(endpoint, topic_key, expiration_date_utc)\n<\/code><\/pre>\n<p>Here is how it would be used from the consumer&#8217;s perspective using the core <code>AzureSasCredential<\/code> type:<\/p>\n<pre><code class=\"python\">credential = AzureSasCredential(signature)\nclient = EventGridPublisherClient(endpoint, credential)\n<\/code><\/pre>\n<ul>\n<li><strong>Bridge library providing integration with the CNCF CloudEvents package for .NET<\/strong> The <a href=\"https:\/\/www.nuget.org\/packages\/CloudNative.CloudEvents\/2.0.0-beta.1\">CloudNative.CloudEvents<\/a> package is the official Cloud Native Computing Foundation SDK for CloudEvents. We have introduced a <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/blob\/master\/sdk\/eventgrid\/Microsoft.Azure.Messaging.EventGrid.CloudNativeCloudEvents\/README.md\">bridge library<\/a> that contains extension methods for the <code>EventGridPublisherClient<\/code> that can be used to send CloudNative CloudEvents:<\/li>\n<\/ul>\n<pre><code class=\"cs\">var cloudEvent =\n    new CloudEvent(\n        type: \"record\",\n        source: new Uri(\"http:\/\/www.contoso.com\"))\n        {\n            Data = new MyDataModel() { A = 5, B = true }\n        };\n\nawait client.SendCloudEventAsync(cloudEvent);\n<\/code><\/pre>\n<h2>Conclusion<\/h2>\n<p>Azure Event Grid is one of Azure&#8217;s core messaging offerings, that can greatly simplify your application. The latest set of packages are our effort to make integrating Event Grid quick and painless, allowing you to quickly jumpstart your applications and get running.<\/p>\n<p>For more information about each language from this article please see the following:<\/p>\n<ul>\n<li>.NET: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/blob\/master\/sdk\/eventgrid\/Azure.Messaging.EventGrid\">github<\/a> | <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/tree\/master\/sdk\/eventgrid\/Azure.Messaging.EventGrid\/samples\">samples<\/a> | <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-net\/blob\/master\/sdk\/eventgrid\/Azure.Messaging.EventGrid\/MigrationGuide.md\">migration guide<\/a><\/li>\n<li>Java: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/tree\/master\/sdk\/eventgrid\/azure-messaging-eventgrid\">github<\/a> | <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/tree\/master\/sdk\/eventgrid\/azure-messaging-eventgrid\/src\/samples\/java\/com\/azure\/messaging\/eventgrid\">samples<\/a> | <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-java\/blob\/master\/sdk\/eventgrid\/azure-messaging-eventgrid\/migration-guide.md\">migration guide<\/a><\/li>\n<li>Python: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/tree\/master\/sdk\/eventgrid\/azure-eventgrid\">github<\/a> | <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/tree\/master\/sdk\/eventgrid\/azure-eventgrid\/samples\">samples<\/a> | <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-python\/blob\/master\/sdk\/eventgrid\/azure-eventgrid\/migration_guide.md\">migration guide<\/a><\/li>\n<li>JavaScript: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/blob\/master\/sdk\/eventgrid\/eventgrid\/\">github<\/a> | <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/blob\/master\/sdk\/eventgrid\/eventgrid\/samples\">samples<\/a> | <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-js\/blob\/master\/sdk\/eventgrid\/eventgrid\/migration.md\">migration guide<\/a><\/li>\n<\/ul>\n<h2>Azure SDK Blog Contributions<\/h2>\n<p>Thank you for reading this Azure SDK blog post! We hope that you learned something new and welcome you to share this post. We are open to Azure SDK blog contributions. Please contact us at <a href=\"&#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x61;z&#115;&#x64;&#107;&#x62;&#108;&#x6f;&#103;&#x40;&#109;&#105;&#x63;&#114;&#x6f;&#115;&#x6f;&#102;&#x74;&#46;&#x63;o&#109;\">&#x61;z&#115;&#x64;&#107;&#x62;&#108;&#x6f;&#103;&#x40;&#109;&#105;&#x63;&#114;&#x6f;&#115;&#x6f;&#102;&#x74;&#46;&#x63;o&#109;<\/a> with your topic and we&#8217;ll get you set up as a guest blogger.<\/p>\n<h2>Azure SDK Links<\/h2>\n<ul>\n<li>Azure SDK Website: <a href=\"https:\/\/aka.ms\/azsdk\">aka.ms\/azsdk<\/a><\/li>\n<li>Azure SDK Intro (3 minute video): <a href=\"https:\/\/aka.ms\/azsdk\/intro\">aka.ms\/azsdk\/intro<\/a><\/li>\n<li>Azure SDK Intro Deck (PowerPoint deck): <a href=\"https:\/\/aka.ms\/azsdk\/intro\/deck\">aka.ms\/azsdk\/intro\/deck<\/a><\/li>\n<li>Azure SDK Releases: <a href=\"https:\/\/aka.ms\/azsdk\/releases\">aka.ms\/azsdk\/releases<\/a><\/li>\n<li>Azure SDK Blog: <a href=\"https:\/\/aka.ms\/azsdk\/blog\">aka.ms\/azsdk\/blog<\/a><\/li>\n<li>Azure SDK Twitter: <a href=\"https:\/\/twitter.com\/AzureSDK\">twitter.com\/AzureSDK<\/a><\/li>\n<li>Azure SDK Design Guidelines: <a href=\"https:\/\/aka.ms\/azsdk\/guide\">aka.ms\/azsdk\/guide<\/a><\/li>\n<li>Azure SDKs &amp; Tools: <a href=\"https:\/\/azure.microsoft.com\/downloads\">azure.microsoft.com\/downloads<\/a><\/li>\n<li>Azure SDK Central Repository: <a href=\"https:\/\/github.com\/azure\/azure-sdk#azure-sdk\">github.com\/azure\/azure-sdk<\/a><\/li>\n<li>Azure SDK for .NET: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-net\">github.com\/azure\/azure-sdk-for-net<\/a><\/li>\n<li>Azure SDK for Java: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-java\">github.com\/azure\/azure-sdk-for-java<\/a><\/li>\n<li>Azure SDK for Python: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-python\">github.com\/azure\/azure-sdk-for-python<\/a><\/li>\n<li>Azure SDK for JavaScript\/TypeScript: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-js\">github.com\/azure\/azure-sdk-for-js<\/a><\/li>\n<li>Azure SDK for Android: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-android\">github.com\/Azure\/azure-sdk-for-android<\/a><\/li>\n<li>Azure SDK for iOS: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-ios\">github.com\/Azure\/azure-sdk-for-ios<\/a><\/li>\n<li>Azure SDK for Go: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\">github.com\/Azure\/azure-sdk-for-go<\/a><\/li>\n<li>Azure SDK for C: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-c\">github.com\/Azure\/azure-sdk-for-c<\/a><\/li>\n<li>Azure SDK for C++: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-cpp\">github.com\/Azure\/azure-sdk-for-cpp<\/a><\/li>\n<\/ul>\n<p><!-- FOOTER: DO NOT EDIT OR REMOVE --><\/p>\n<p><!-- github links --><\/p>\n<p><!-- cloud event links --><\/p>\n<p><!-- sample links --><\/p>\n<p><!-- migration guides --><\/p>\n","protected":false},"excerpt":{"rendered":"<p>New major release of the Azure Event Grid packages for .NET, Java, Python, and JavaScript\/TypeScript.<\/p>\n","protected":false},"author":55909,"featured_media":1038,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[24],"class_list":["post-1030","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sdk","tag-releases"],"acf":[],"blog_post_summary":"<p>New major release of the Azure Event Grid packages for .NET, Java, Python, and JavaScript\/TypeScript.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/1030","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/users\/55909"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/comments?post=1030"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/1030\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media\/1038"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media?parent=1030"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/categories?post=1030"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/tags?post=1030"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}