Partager via


Azure Event Grid client library for Java - version 4.21.0-beta.1

Azure Event Grid allows you to easily build applications with event-based architectures. The Event Grid service fully manages all routing of events from any source, to any destination, for any application. Azure service events and custom events can be published directly to the service, where the events can then be filtered and sent to various recipients, such as built-in handlers or custom webhooks. To learn more about Azure Event Grid: What is Event Grid?

Use the client library for Azure Event Grid to:

  • Publish events to the Event Grid service using the Event Grid Event, Cloud Event 1.0, or custom schemas
  • Consume events that have been delivered to event handlers
  • Generate SAS tokens to authenticate the client publishing events to Azure Event Grid topics

Sources | API Reference Documentation | Product Documentation | Samples

Getting started

Prerequisites

If you use the Azure CLI, replace <your-resource-group-name> and <your-resource-name> with your own unique names and <location> with a valid Azure service location.

Creating a topic (Azure CLI)

az eventgrid topic create --location <location> --resource-group <your-resource-group-name> --name <your-resource-name>

Creating a domain (Azure CLI)

az eventgrid domain create --location <location> --resource-group <your-resource-group-name> --name <your-resource-name>

Include the package

Include the BOM file

Please include the azure-sdk-bom to your project to take dependency on GA version of the library. In the following snippet, replace the {bom_version_to_target} placeholder with the version number. To learn more about the BOM, see the AZURE SDK BOM README.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-sdk-bom</artifactId>
            <version>{bom_version_to_target}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

and then include the direct dependency in the dependencies section without the version tag.

<dependencies>
  <dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-messaging-eventgrid</artifactId>
  </dependency>
</dependencies>

Include direct dependency

If you want to take dependency on a particular version of the library that is not present in the BOM, add the direct dependency to your project as follows.

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-messaging-eventgrid</artifactId>
    <version>4.21.0-beta.1</version>
</dependency>

Authenticate the Client

In order to send events, we need an endpoint to send to and some authentication for the endpoint. The authentication can be a key credential, a shared access signature, or Azure Active Directory token authentication. The endpoint and key can both be obtained through Azure Portal or Azure CLI.

Endpoint

The endpoint is listed on the dashboard of the topic or domain in the Azure Portal, or can be obtained using the following command in Azure CLI.

az eventgrid topic show --name <your-resource-name> --resource-group <your-resource-group-name> --query "endpoint"

Access Key

The keys are listed in the "Access Keys" tab of the Azure Portal, or can be obtained using the following command in Azure CLI. Anyone of the keys listed will work.

az eventgrid topic key list --name <your-resource-name> --resource-group <your-resource-group-name>

Azure Active Directory (AAD) Token authentication

Azure Event Grid provides integration with Azure Active Directory (Azure AD) for identity-based authentication of requests. With Azure AD, you can use role-based access control (RBAC) to grant access to your Azure Event Grid resources to users, groups, or applications. To send events to a topic or domain with a TokenCredential, the authenticated identity should have the "EventGrid Data Sender" role assigned.

Creating the Client

Using endpoint and access key to create the client

Once you have your access key and topic endpoint, you can create the publisher client as follows:

Sync client that works for every Java developer:

// For CloudEvent
EventGridPublisherClient<CloudEvent> cloudEventClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts CloudEvent schema>")
    .credential(new AzureKeyCredential("<key for the endpoint>"))
    .buildCloudEventPublisherClient();
// For EventGridEvent
EventGridPublisherClient<EventGridEvent> eventGridEventClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts EventGridEvent schema>")
    .credential(new AzureKeyCredential("<key for the endpoint>"))
    .buildEventGridEventPublisherClient();
// For custom event
EventGridPublisherClient<BinaryData> customEventClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts custom event schema>")
    .credential(new AzureKeyCredential("<key for the endpoint>"))
    .buildCustomEventPublisherClient();

or async client if your technology stack has reactive programming such as project reactor:

// For CloudEvent
EventGridPublisherAsyncClient<CloudEvent> cloudEventAsyncClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts CloudEvent schema>")
    .credential(new AzureKeyCredential("<key for the endpoint>"))
    .buildCloudEventPublisherAsyncClient();
// For EventGridEvent
EventGridPublisherAsyncClient<EventGridEvent> eventGridEventAsyncClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts EventGridEvent schema>")
    .credential(new AzureKeyCredential("<key for the endpoint>"))
    .buildEventGridEventPublisherAsyncClient();
// For custom event
EventGridPublisherAsyncClient<BinaryData> customEventAsyncClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts custom event schema>")
    .credential(new AzureKeyCredential("<key for the endpoint>"))
    .buildCustomEventPublisherAsyncClient();
Using endpoint and SAS token to create the client

If you have a SAS (Shared Access Signature) that can be used to send events to an Event Grid Topic or Domain for limited time, you can use it to create the publisher client:

Sync client:

EventGridPublisherClient<CloudEvent> cloudEventClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts CloudEvent schema>")
    .credential(new AzureSasCredential("<sas token that can access the endpoint>"))
    .buildCloudEventPublisherClient();

Async client:

EventGridPublisherAsyncClient<CloudEvent> cloudEventAsyncClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts CloudEvent schema>")
    .credential(new AzureSasCredential("<sas token that can access the endpoint>"))
    .buildCloudEventPublisherAsyncClient();
Using endpoint and Azure Active Directory (AAD) token credential to create the client

To use the AAD token credential, include azure-identity artifact as a dependency. Refer to azure-identity README for details.

Sync client:

EventGridPublisherClient<CloudEvent> cloudEventClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts CloudEvent schema>")
    .credential(new DefaultAzureCredentialBuilder().build())
    .buildCloudEventPublisherClient();

Async client:

EventGridPublisherAsyncClient<CloudEvent> cloudEventClient = new EventGridPublisherClientBuilder()
    .endpoint("<endpoint of your event grid topic/domain that accepts CloudEvent schema>")
    .credential(new DefaultAzureCredentialBuilder().build())
    .buildCloudEventPublisherAsyncClient();

Create a SAS token for other people to send events for a limited period of time

If you'd like to give permission to other people to publish events to your Event Grid Topic or Domain for some time, you can create a SAS (Shared Access Signature) for them so they can create an EventGridPublisherClient like the above to use AzureSasCredential to create the publisher client.

Here is sample code to create a shared access signature that expires after 20 minutes:

OffsetDateTime expiration = OffsetDateTime.now().plusMinutes(20);
String sasToken = EventGridPublisherClient
    .generateSas("<your event grid endpoint>", new AzureKeyCredential("<key for the endpoint>"), expiration);

Use BinaryData

This SDK uses com.azure.util.BinaryData to represent the data payload of events. BinaryData supports serializing and deserializing objects through com.azure.core.util.BinaryData.fromObject(Object object) and toObject() methods, which use a default Jackson Json serializer, or fromObject(Object object, ObjectSerializer customSerializer) and toObject(Class<T> clazz, ObjectSerializer serializer) methods, which accept your customized Json serializer. Refer to BinaryData documentation for details.

Key concepts

For information about general Event Grid concepts: Concepts in Azure Event Grid.

EventGridPublisherClient

EventGridPublisherClient is used sending events to an Event Grid Topic or an Event Grid Domain. EventGridPublisherAsyncClient is the async version of EventGridPublisherClient.

Event Schemas

Event Grid supports multiple schemas for encoding events. When an Event Grid Topic or Domain is created, you specify the schema that will be used when publishing events. While you may configure your topic to use a custom schema it is more common to use the already defined EventGridEvent schema or CloudEvent schema. CloudEvent is a Cloud Native Computing Foundation project which produces a specification for describing event data in a common way. Event Grid service is compatible with the CloudEvent specification Regardless of what schema your topic or domain is configured to use, EventGridPublisherClient will be used to publish events to it. However, you must use the correct type to instantiate it:

Event Schema Publisher Client Generic Instantiation
Event Grid Events EventGridPublisherClient<EventGridEvent>
Cloud Events EventGridPublisherClient<CloudEvent>
Custom Events EventGridPublisherClient<BinaryData>

Using the wrong type will result in a BadRequest error from the service and your events will not be published. Use this Azure CLI command to query which schema an Event Grid Topic or Domain accepts:

az eventgrid topic show --name <your-resource-name> --resource-group <your-resource-group-name> --query inputSchema

Event Handlers and event deserialization.

EventGrid doesn't store any events in the Event Grid Topic or Domain itself. You need to create subscriptions to the EventGrid Topic or Domain. The events sent to the topic or domain will be stored into the subscription's endpoint, also known as "Event Handler".

You may use the event handler's SDK to receive the events in Json String and then use the EventGridEvent.fromString() or CloudEvent.fromString() deserialize the events. The data part of the events can be in binary, String, or JSON data.

Examples

Sending Events To Event Grid Topics

Events can be sent in the EventGridEvent, CloudEvent, or a custom schema, as detailed in Event Schemas. The topic or domain must be configured to accept the schema being sent. For simplicity, the synchronous client is used for samples, however the asynchronous client has the same method names.

Note: figure out what schema (cloud event, event grid event, or custom event) the event grid topic accepts before you start sending.

Sending EventGridEvent to a topic that accepts EventGridEvent schema

// Make sure that the event grid topic or domain you're sending to is able to accept the EventGridEvent schema.
List<EventGridEvent> events = new ArrayList<>();
User user = new User("John", "James");
events.add(new EventGridEvent("exampleSubject", "Com.Example.ExampleEventType", BinaryData.fromObject(user), "0.1"));
eventGridEventClient.sendEvents(events);

Sending CloudEvent to a topic that accepts CloudEvent schema

// Make sure that the event grid topic or domain you're sending to is able to accept the CloudEvent schema.
List<CloudEvent> events = new ArrayList<>();
User user = new User("John", "James");
events.add(new CloudEvent("https://source.example.com", "Com.Example.ExampleEventType",
    BinaryData.fromObject(user), CloudEventDataFormat.JSON, "application/json"));
cloudEventClient.sendEvents(events);

Sending Custom Events to a topic that accepts custom event schema

// Make sure that the event grid topic or domain you're sending to is able to accept the custom event schema.
List<BinaryData> events = new ArrayList<>();
events.add(BinaryData.fromObject(new HashMap<String, String>() {
    {
        put("id", UUID.randomUUID().toString());
        put("time", OffsetDateTime.now().toString());
        put("subject", "Test");
        put("foo", "bar");
        put("type", "Microsoft.MockPublisher.TestEvent");
        put("data", "example data");
        put("dataVersion", "0.1");
    }
}));
customEventClient.sendEvents(events);

Sending Events To Event Grid Domain

An Event Grid Domain can have thousands of topics but has a single endpoint. You can use a domain to manage a set of related topics. Sending events to the topics of an Event Grid Domain is the same as sending events to a regular Event Grid Topic except that you need to specify the topic of an EventGridEvent if the domain accepts EventGridEvent schema.

List<EventGridEvent> events = new ArrayList<>();
User user = new User("John", "James");
events.add(new EventGridEvent("com/example", "Com.Example.ExampleEventType", BinaryData.fromObject(user), "1")
    .setTopic("yourtopic"));
eventGridEventClient.sendEvents(events);

If the domain accepts CloudEvent schema, the CloudEvent's attribute that is configured to map the topic when the domain is created must be set. The default mapping attribute is source.

Receiving and Consuming Events

The Event Grid service doesn't store events. So this Event Grid SDK doesn't have an event receiver. Instead, events are stored in the Event Handlers, including ServiceBus, EventHubs, Storage Queue, WebHook endpoint, or many other supported Azure Services. However, currently all events will be sent and stored as encoded JSON data. Here is some basic code that details the deserialization of events after they're received by the event handlers. Again, the handling is different based on the event schema being received from the topic/subscription.

Deserialize EventGridEvent or CloudEvent from a Json String

The Json String can have a single event or an array of events. The returned result is a list of events.

// Deserialize an EventGridEvent
String eventGridEventJsonData = "<your EventGridEvent json String>";
List<EventGridEvent> eventGridEvents = EventGridEvent.fromString(eventGridEventJsonData);

// Deserialize a CloudEvent
String cloudEventJsonData = "<your CloudEvent json String>";
List<CloudEvent> cloudEvents = CloudEvent.fromString(cloudEventJsonData);

Deserialize data from a CloudEvent or EventGridEvent

Once you deserialize the EventGridEvent or CloudEvent from a Json String, you can use getData() of CloudEvent or EventGridEvent to get the payload of the event. It returns a BinaryData object, which has methods to further deserialize the data into usable types:

  • BinaryData.toBytes() gets the data as a byte[]
  • BinaryData.toString() gets the data as a String
  • BinaryData.toObject() gets the data as an object of a specific type. It uses Json deserializer by default. It has an overload to accept your deserializer if you want to use your own.
BinaryData eventData = eventGridEvent.getData();

//Deserialize data to a model class
User dataInModelClass = eventData.toObject(User.class);

//Deserialize data to a Map
Map<String, Object> dataMap = eventData.toObject(new TypeReference<Map<String, Object>>() {
});

//Deserialize Json String to a String
String dataString = eventData.toObject(String.class);

//Deserialize String data to a String
String dataInJsonString = eventData.toString();

//Deserialize data to byte array (byte[])
byte[] dataInBytes = eventData.toBytes();

Deserialize system event data from CloudEvent or EventGridEvent

An event that is sent to a System Topic is called a System Topic Event, or System Event. A system topic in Event Grid represents events published by an Event Source like Azure Storage, Azure Event Hubs, App Configuration and so on. An example is when a blob is created, a system event with event type "Microsoft.Storage.BlobCreated" is sent to the configured System Topic. The system event class for this event type is StorageBlobCreatedEventData defined in package com.azure.messaging.eventgrid.systemevents. EventGrid has system events for:

You can't send a System Event to a System Topic by using this SDK.

Receiving and consuming system events is the same as other events. Additionally, a set of model classes for the various system event data are defined in package com.azure.messaging.eventgrid.systemevents. You can do the following after you deserialize an event by using EventGridEvent.fromString() or CloudEvent.fromString():

  • look up the system event data model class that the System Event data can be deserialized to;
// Look up the System Event data class
Class<?> eventDataClazz = SystemEventNames.getSystemEventMappings().get(event.getEventType());
  • deserialize a system event's data to a model class instance like deserializing any other event data;
// Deserialize the event data to an instance of a specific System Event data class type
BinaryData data = event.getData();
if (data != null) {
    StorageBlobCreatedEventData blobCreatedData = data.toObject(StorageBlobCreatedEventData.class);
    System.out.println(blobCreatedData.getUrl());
}
  • deal with multiple event types.
List<EventGridEvent> eventGridEvents = EventGridEvent.fromString("<Your EventGridEvent Json String>");
for (EventGridEvent eventGridEvent : eventGridEvents) {
    BinaryData binaryData = eventGridEvent.getData();
    switch (eventGridEvent.getEventType()) {
        case SystemEventNames.APP_CONFIGURATION_KEY_VALUE_DELETED:
            AppConfigurationKeyValueDeletedEventData keyValueDeletedEventData =
                binaryData.toObject(TypeReference.createInstance(AppConfigurationKeyValueDeletedEventData.class));
            System.out.println("Processing the AppConfigurationKeyValueDeletedEventData...");
            System.out.printf("The key is: %s%n", keyValueDeletedEventData.getKey());
            break;
        case SystemEventNames.APP_CONFIGURATION_KEY_VALUE_MODIFIED:
            AppConfigurationKeyValueModifiedEventData keyValueModifiedEventData =
                binaryData.toObject(TypeReference.createInstance(AppConfigurationKeyValueModifiedEventData.class));
            System.out.println("Processing the AppConfigurationKeyValueModifiedEventData...");
            System.out.printf("The key is: %s%n", keyValueModifiedEventData.getKey());
            break;
        default:
            System.out.printf("%s isn't an AppConfiguration event data%n", eventGridEvent.getEventType());
            break;
    }
}

More samples

Some additional sample code can be found here.

Troubleshooting

Responses and error codes

Service responses are returned in the form of Http status codes, including a number of error codes. These codes can optionally be returned by the PublisherClient. Unexpected status codes are thrown as HttpResponseException which wraps the error code.

Reference documentation for the event grid service can be found here. This is a good place to start for problems involving configuration of topics/endpoints, as well as for problems involving error codes from the service.

Distributed Tracing

The Event Grid library supports distributing tracing out of the box. In order to adhere to the CloudEvents specification's guidance on distributing tracing, the library will set the traceparent and tracestate on the extensionAttributes of a CloudEvent when distributed tracing is enabled. To learn more about how to enable distributed tracing in your application, take a look at the Azure SDK Java distributed tracing documentation.

Help and Issues

Reference documentation for the SDK can be found here. This is a good first step to understanding the purpose of each method called, as well as possible reasons for errors or unexpected behavior.

If you encounter any bugs with these SDKs, please file issues via Issues or checkout StackOverflow for Azure Java SDK.

Next steps

  • Azure Java SDKs
  • If you don't have a Microsoft Azure subscription you can get a FREE trial account here
  • Some additional sample code can be found here
  • Additional Event Grid tutorials can be found here

Contributing

For details on contributing to this repository, see the contributing guide.

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Impressions