diff --git a/eventgrid/data-plane/src/main/java/com/microsoft/azure/eventgrid/customization/EventGridSubscriber.java b/eventgrid/data-plane/src/main/java/com/microsoft/azure/eventgrid/customization/EventGridSubscriber.java new file mode 100644 index 0000000000000..419b4c514b8fe --- /dev/null +++ b/eventgrid/data-plane/src/main/java/com/microsoft/azure/eventgrid/customization/EventGridSubscriber.java @@ -0,0 +1,185 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ +package com.microsoft.azure.eventgrid.customization; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.azure.eventgrid.models.EventGridEvent; +import com.microsoft.azure.management.apigeneration.Beta; +import com.microsoft.azure.serializer.AzureJacksonAdapter; +import com.microsoft.rest.protocol.SerializerAdapter; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * The type that can be used to de-serialize eventgrid events. + */ +@Beta +public class EventGridSubscriber { + /** + * The default adapter to be used for de-serializing the events. + */ + private final AzureJacksonAdapter defaultSerializerAdapter; + /** + * The map containing user defined mapping of eventType to Java model type. + */ + private Map eventTypeToEventDataMapping; + + /** + * Creates EventGridSubscriber with default de-serializer. + */ + @Beta + public EventGridSubscriber() { + this.defaultSerializerAdapter = new AzureJacksonAdapter(); + this.eventTypeToEventDataMapping = new HashMap<>(); + } + + /** + * Add a custom event mapping. If a mapping with same eventType exists then the old eventDataType is replaced by + * the specified eventDataType. + * + * @param eventType the event type name. + * @param eventDataType type of the Java model that the event type name mapped to. + */ + @Beta + public void putCustomEventMapping(final String eventType, final Type eventDataType) { + if (eventType == null || eventType.isEmpty()) { + throw new IllegalArgumentException("eventType parameter is required and cannot be null or empty"); + } + if (eventDataType == null) { + throw new IllegalArgumentException("eventDataType parameter is required and cannot be null"); + } + this.eventTypeToEventDataMapping.put(canonicalizeEventType(eventType), eventDataType); + } + + /** + * Get type of the Java model that is mapped to the given eventType. + * + * @param eventType the event type name. + * @return type of the Java model if mapping exists, null otherwise. + */ + @Beta + public Type getCustomEventMapping(final String eventType) { + if (!containsCustomEventMappingFor(eventType)) { + return null; + } else { + return this.eventTypeToEventDataMapping.get(canonicalizeEventType(eventType)); + } + } + + /** + * @return get all registered custom event mappings. + */ + @Beta + public Set> getAllCustomEventMappings() { + return Collections.unmodifiableSet(this.eventTypeToEventDataMapping.entrySet()); + } + + /** + * Removes the mapping with the given eventType. + * + * @param eventType the event type name. + * @return true if the mapping exists and removed, false if mapping does not exists. + */ + @Beta + public boolean removeCustomEventMapping(final String eventType) { + if (!containsCustomEventMappingFor(eventType)) { + return false; + } else { + this.eventTypeToEventDataMapping.remove(canonicalizeEventType(eventType)); + return true; + } + } + + /** + * Checks if an event mapping with the given eventType exists. + * + * @param eventType the event type name. + * @return true if the mapping exists, false otherwise. + */ + @Beta + public boolean containsCustomEventMappingFor(final String eventType) { + if (eventType == null || eventType.isEmpty()) { + return false; + } else { + return this.eventTypeToEventDataMapping.containsKey(canonicalizeEventType(eventType)); + } + } + + /** + * De-serialize the events in the given requested content using default de-serializer. + * + * @param requestContent the request content in string format. + * @return De-serialized events. + * + * @throws IOException + */ + @Beta + public EventGridEvent[] deserializeEventGridEvents(final String requestContent) throws IOException { + return this.deserializeEventGridEvents(requestContent, this.defaultSerializerAdapter); + } + + /** + * De-serialize the events in the given requested content using the provided de-serializer. + * + * @param requestContent the request content as string. + * @param serializerAdapter the de-serializer. + * @return de-serialized events. + * @throws IOException + */ + @Beta + public EventGridEvent[] deserializeEventGridEvents(final String requestContent, final SerializerAdapter serializerAdapter) throws IOException { + EventGridEvent[] eventGridEvents = serializerAdapter.deserialize(requestContent, EventGridEvent[].class); + for (EventGridEvent receivedEvent : eventGridEvents) { + if (receivedEvent.data() == null) { + continue; + } else { + final String eventType = receivedEvent.eventType(); + final Type eventDataType; + if (SystemEventTypeMappings.containsMappingFor(eventType)) { + eventDataType = SystemEventTypeMappings.getMapping(eventType); + } else if (containsCustomEventMappingFor(eventType)) { + eventDataType = getCustomEventMapping(eventType); + } else { + eventDataType = null; + } + if (eventDataType != null) { + final String eventDataAsString = serializerAdapter.serializeRaw(receivedEvent.data()); + final Object eventData = serializerAdapter.deserialize(eventDataAsString, eventDataType); + setEventData(receivedEvent, eventData); + } + } + } + return eventGridEvents; + } + + private static void setEventData(EventGridEvent event, final Object data) { + // This reflection based way to set the data field needs to be removed once + // we expose a wither in EventGridEvent to set the data. (Check swagger + codegen) + try { + Field dataField = event.getClass().getDeclaredField("data"); + dataField.setAccessible(true); + dataField.set(event, data); + } catch (NoSuchFieldException nsfe) { + throw new RuntimeException(nsfe); + } catch (IllegalAccessException iae) { + throw new RuntimeException(iae); + } + } + + private static String canonicalizeEventType(final String eventType) { + if (eventType == null) { + return null; + } else { + return eventType.toLowerCase(); + } + } +} \ No newline at end of file diff --git a/eventgrid/data-plane/src/main/java/com/microsoft/azure/eventgrid/customization/SystemEventTypeMappings.java b/eventgrid/data-plane/src/main/java/com/microsoft/azure/eventgrid/customization/SystemEventTypeMappings.java new file mode 100644 index 0000000000000..13e5eaaf79b01 --- /dev/null +++ b/eventgrid/data-plane/src/main/java/com/microsoft/azure/eventgrid/customization/SystemEventTypeMappings.java @@ -0,0 +1,127 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ +package com.microsoft.azure.eventgrid.customization; + +import com.microsoft.azure.eventgrid.models.ContainerRegistryImageDeletedEventData; +import com.microsoft.azure.eventgrid.models.ContainerRegistryImagePushedEventData; +import com.microsoft.azure.eventgrid.models.EventHubCaptureFileCreatedEventData; +import com.microsoft.azure.eventgrid.models.IotHubDeviceConnectedEventData; +import com.microsoft.azure.eventgrid.models.IotHubDeviceCreatedEventData; +import com.microsoft.azure.eventgrid.models.IotHubDeviceDeletedEventData; +import com.microsoft.azure.eventgrid.models.IotHubDeviceDisconnectedEventData; +import com.microsoft.azure.eventgrid.models.MediaJobStateChangeEventData; +import com.microsoft.azure.eventgrid.models.ResourceActionCancelData; +import com.microsoft.azure.eventgrid.models.ResourceActionFailureData; +import com.microsoft.azure.eventgrid.models.ResourceActionSuccessData; +import com.microsoft.azure.eventgrid.models.ResourceDeleteCancelData; +import com.microsoft.azure.eventgrid.models.ResourceDeleteFailureData; +import com.microsoft.azure.eventgrid.models.ResourceDeleteSuccessData; +import com.microsoft.azure.eventgrid.models.ResourceWriteCancelData; +import com.microsoft.azure.eventgrid.models.ResourceWriteFailureData; +import com.microsoft.azure.eventgrid.models.ResourceWriteSuccessData; +import com.microsoft.azure.eventgrid.models.ServiceBusActiveMessagesAvailableWithNoListenersEventData; +import com.microsoft.azure.eventgrid.models.ServiceBusDeadletterMessagesAvailableWithNoListenersEventData; +import com.microsoft.azure.eventgrid.models.StorageBlobCreatedEventData; +import com.microsoft.azure.eventgrid.models.StorageBlobDeletedEventData; +import com.microsoft.azure.eventgrid.models.SubscriptionDeletedEventData; +import com.microsoft.azure.eventgrid.models.SubscriptionValidationEventData; +import com.microsoft.azure.management.apigeneration.Beta; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +/** + * Mapping of system event type name to corresponding type of the Java model. + */ +@Beta +final class SystemEventTypeMappings { + /** + * The map containing system eventType to Java model type mapping. + */ + private static Map systemEventMappings; + + static { + systemEventMappings = new HashMap<>(); // key: eventType, Value:eventDataType + // + // ContainerRegistry events. + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.CONTAINER_REGISTRY_IMAGE_PUSHED_EVENT), ContainerRegistryImagePushedEventData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.CONTAINER_REGISTRY_IMAGE_DELETED_EVENT), ContainerRegistryImageDeletedEventData.class); + // + // Device events. + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.IOT_HUB_DEVICE_CREATED_EVENT), IotHubDeviceCreatedEventData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.IOT_HUB_DEVICE_DELETED_EVENT), IotHubDeviceDeletedEventData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.IOT_HUB_DEVICE_CONNECTED_EVENT), IotHubDeviceConnectedEventData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.IOT_HUB_DEVICE_DISCONNECTED_EVENT), IotHubDeviceDisconnectedEventData.class); + // + // EventGrid events. + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.EVENT_GRID_SUBSCRIPTION_VALIDATION_EVENT), SubscriptionValidationEventData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.EVENT_GRID_SUBSCRIPTION_DELETED_EVENT), SubscriptionDeletedEventData.class); + // + // Event Hub Events. + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.EVENT_HUB_CAPTURE_FILE_CREATED_EVENT), EventHubCaptureFileCreatedEventData.class); + // + // Media Services events. + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.MEDIA_JOB_STATE_CHANGE_EVENT), MediaJobStateChangeEventData.class); + // + // Resource Manager (Azure Subscription/Resource Group) events. + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.RESOURCE_WRITE_SUCCESS_EVENT), ResourceWriteSuccessData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.RESOURCE_WRITE_FAILURE_EVENT), ResourceWriteFailureData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.RESOURCE_WRITE_CANCEL_EVENT), ResourceWriteCancelData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.RESOURCE_DELETE_SUCCESS_EVENT), ResourceDeleteSuccessData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.RESOURCE_DELETE_FAILURE_EVENT), ResourceDeleteFailureData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.RESOURCE_DELETE_CANCEL_EVENT), ResourceDeleteCancelData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.RESOURCE_ACTION_SUCCESS_EVENT), ResourceActionSuccessData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.RESOURCE_ACTION_FAILURE_EVENT), ResourceActionFailureData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.RESOURCE_ACTION_CANCEL_EVENT), ResourceActionCancelData.class); + // + // ServiceBus events. + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.SERVICE_BUS_ACTIVE_MESSAGES_AVAILABLE_WITH_NO_LISTENERS_EVENT), ServiceBusActiveMessagesAvailableWithNoListenersEventData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.SERVICE_BUS_DEADLETTER_MESSAGES_AVAILABLE_WITH_NO_LISTENER_EVENT), ServiceBusDeadletterMessagesAvailableWithNoListenersEventData.class); + // + // Storage events. + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.STORAGE_BLOB_CREATED_EVENT), StorageBlobCreatedEventData.class); + systemEventMappings.put(canonicalizeEventType(SystemEventTypes.STORAGE_BLOB_DELETED_EVENT), StorageBlobDeletedEventData.class); + } + + /** + * Checks if a mapping exists for the given type. + * + * @param eventType the event type. + * @return true if mapping exists, false otherwise. + */ + @Beta + public static boolean containsMappingFor(final String eventType) { + if (eventType == null || eventType.isEmpty()) { + return false; + } else { + return systemEventMappings.containsKey(canonicalizeEventType(eventType)); + } + } + + /** + * Get Java model type for the given event type. + * + * @param eventType the event type. + * @return the Java model type if mapping exists, null otherwise. + */ + @Beta + public static Type getMapping(final String eventType) { + if (!containsMappingFor(eventType)) { + return null; + } else { + return systemEventMappings.get(canonicalizeEventType(eventType)); + } + } + + private static String canonicalizeEventType(final String eventType) { + if (eventType == null) { + return null; + } else { + return eventType.toLowerCase(); + } + } +} diff --git a/eventgrid/data-plane/src/main/java/com/microsoft/azure/eventgrid/customization/SystemEventTypes.java b/eventgrid/data-plane/src/main/java/com/microsoft/azure/eventgrid/customization/SystemEventTypes.java new file mode 100644 index 0000000000000..49e7a7bd8b962 --- /dev/null +++ b/eventgrid/data-plane/src/main/java/com/microsoft/azure/eventgrid/customization/SystemEventTypes.java @@ -0,0 +1,119 @@ +package com.microsoft.azure.eventgrid.customization; + +import com.microsoft.azure.management.apigeneration.Beta; + +/** + * Represents the names of the various event types for the system events published to Azure Event Grid. + */ +@Beta +public class SystemEventTypes { + // Keep this sorted by the name of the service publishing the events. + + // ContainerRegistry events. + /** + * indicate an event of pushing an image to container registry. + */ + public final static String CONTAINER_REGISTRY_IMAGE_PUSHED_EVENT = "Microsoft.ContainerRegistry.ImagePushed"; + /** + * indicate an event of deleting an image to container registry. + */ + public final static String CONTAINER_REGISTRY_IMAGE_DELETED_EVENT = "Microsoft.ContainerRegistry.ImageDeleted"; + + // Device events. + /** + * indicate an event of creating an IoT hub device. + */ + public final static String IOT_HUB_DEVICE_CREATED_EVENT = "Microsoft.Devices.DeviceCreated"; + /** + * indicate an event of deleting an IoT hub device. + */ + public final static String IOT_HUB_DEVICE_DELETED_EVENT = "Microsoft.Devices.DeviceDeleted"; + /** + * indicate an event of connecting an IoT hub device. + */ + public final static String IOT_HUB_DEVICE_CONNECTED_EVENT = "Microsoft.Devices.DeviceConnected"; + /** + * indicate an event of disconnecting an IoT hub device. + */ + public final static String IOT_HUB_DEVICE_DISCONNECTED_EVENT = "Microsoft.Devices.DeviceDisconnected"; + + // EventGrid events. + /** + * indicate an event of validating eventgrid subscription. + */ + public final static String EVENT_GRID_SUBSCRIPTION_VALIDATION_EVENT = "Microsoft.EventGrid.SubscriptionValidationEvent"; + /** + * indicate an event of deleting eventgrid subscription. + */ + public final static String EVENT_GRID_SUBSCRIPTION_DELETED_EVENT = "Microsoft.EventGrid.SubscriptionDeletedEvent"; + + // Event Hub Events. + /** + * indicate an event of creation of capture file in eventhub. + */ + public final static String EVENT_HUB_CAPTURE_FILE_CREATED_EVENT = "Microsoft.EventHub.CaptureFileCreated"; + + // Media Services events. + /** + * indicate an event of change of media service job state. + */ + public final static String MEDIA_JOB_STATE_CHANGE_EVENT = "Microsoft.Media.JobStateChange"; + + // Resource Manager (Azure Subscription/Resource Group) events + /** + * indicate an event of successful write of a resource. + */ + public final static String RESOURCE_WRITE_SUCCESS_EVENT = "Microsoft.Resources.ResourceWriteSuccess"; + /** + * indicate an event of write failure of a resource. + */ + public final static String RESOURCE_WRITE_FAILURE_EVENT = "Microsoft.Resources.ResourceWriteFailure"; + /** + * indicate an event of write cancellation of a resource. + */ + public final static String RESOURCE_WRITE_CANCEL_EVENT = "Microsoft.Resources.ResourceWriteCancel"; + /** + * indicate an event of successful deletion of a resource. + */ + public final static String RESOURCE_DELETE_SUCCESS_EVENT = "Microsoft.Resources.ResourceDeleteSuccess"; + /** + * indicate an event of failure in deleting a resource. + */ + public final static String RESOURCE_DELETE_FAILURE_EVENT = "Microsoft.Resources.ResourceDeleteFailure"; + /** + * indicate an event of cancellation of resource deletion. + */ + public final static String RESOURCE_DELETE_CANCEL_EVENT = "Microsoft.Resources.ResourceDeleteCancel"; + /** + * indicate an event of successful action on a resource. + */ + public final static String RESOURCE_ACTION_SUCCESS_EVENT = "Microsoft.Resources.ResourceActionSuccess"; + /** + * indicate an event of failure in performing an action on a resource. + */ + public final static String RESOURCE_ACTION_FAILURE_EVENT = "Microsoft.Resources.ResourceActionFailure"; + /** + * indicate an event of cancellation of resource action. + */ + public final static String RESOURCE_ACTION_CANCEL_EVENT = "Microsoft.Resources.ResourceActionCancel"; + + // ServiceBus events. + /** + * indicate an event of active messages with no listener for them. + */ + public final static String SERVICE_BUS_ACTIVE_MESSAGES_AVAILABLE_WITH_NO_LISTENERS_EVENT = "Microsoft.ServiceBus.ActiveMessagesAvailableWithNoListeners"; + /** + * indicate an event of deadletter messages with no listener for them. + */ + public final static String SERVICE_BUS_DEADLETTER_MESSAGES_AVAILABLE_WITH_NO_LISTENER_EVENT = "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListener"; + + // Storage events. + /** + * indicates an event of blob creation. + */ + public final static String STORAGE_BLOB_CREATED_EVENT = "Microsoft.Storage.BlobCreated"; + /** + * indicates an event of blob deletion. + */ + public final static String STORAGE_BLOB_DELETED_EVENT = "Microsoft.Storage.BlobDeleted"; +} diff --git a/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/CustomizationTests.java b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/CustomizationTests.java new file mode 100644 index 0000000000000..7ffc235f8a74d --- /dev/null +++ b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/CustomizationTests.java @@ -0,0 +1,511 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ +package com.microsoft.azure.eventgrid.customization; + +import com.microsoft.azure.eventgrid.customization.models.ContosoItemReceivedEventData; +import com.microsoft.azure.eventgrid.customization.models.ContosoItemSentEventData; +import com.microsoft.azure.eventgrid.customization.models.DroneShippingInfo; +import com.microsoft.azure.eventgrid.customization.models.RocketShippingInfo; +import com.microsoft.azure.eventgrid.models.ContainerRegistryImageDeletedEventData; +import com.microsoft.azure.eventgrid.models.ContainerRegistryImagePushedEventData; +import com.microsoft.azure.eventgrid.models.EventGridEvent; +import com.microsoft.azure.eventgrid.models.EventHubCaptureFileCreatedEventData; +import com.microsoft.azure.eventgrid.models.IotHubDeviceConnectedEventData; +import com.microsoft.azure.eventgrid.models.IotHubDeviceCreatedEventData; +import com.microsoft.azure.eventgrid.models.IotHubDeviceDeletedEventData; +import com.microsoft.azure.eventgrid.models.IotHubDeviceDisconnectedEventData; +import com.microsoft.azure.eventgrid.models.JobState; +import com.microsoft.azure.eventgrid.models.MediaJobStateChangeEventData; +import com.microsoft.azure.eventgrid.models.ResourceActionCancelData; +import com.microsoft.azure.eventgrid.models.ResourceActionFailureData; +import com.microsoft.azure.eventgrid.models.ResourceActionSuccessData; +import com.microsoft.azure.eventgrid.models.ResourceDeleteCancelData; +import com.microsoft.azure.eventgrid.models.ResourceDeleteFailureData; +import com.microsoft.azure.eventgrid.models.ResourceDeleteSuccessData; +import com.microsoft.azure.eventgrid.models.ResourceWriteCancelData; +import com.microsoft.azure.eventgrid.models.ResourceWriteFailureData; +import com.microsoft.azure.eventgrid.models.ResourceWriteSuccessData; +import com.microsoft.azure.eventgrid.models.ServiceBusActiveMessagesAvailableWithNoListenersEventData; +import com.microsoft.azure.eventgrid.models.ServiceBusDeadletterMessagesAvailableWithNoListenersEventData; +import com.microsoft.azure.eventgrid.models.StorageBlobCreatedEventData; +import com.microsoft.azure.eventgrid.models.StorageBlobDeletedEventData; +import com.microsoft.azure.eventgrid.models.SubscriptionDeletedEventData; +import com.microsoft.azure.eventgrid.models.SubscriptionValidationEventData; +import org.junit.Assert; +import org.junit.Test; +import sun.misc.IOUtils; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Map; +import java.util.Set; + +public class CustomizationTests { + + @Test + public void consumeStorageBlobDeletedEventWithExtraProperty() throws IOException { + String jsonData = getTestPayloadFromFile("StorageBlobDeletedEventWithExtraProperty.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof StorageBlobDeletedEventData); + StorageBlobDeletedEventData eventData = (StorageBlobDeletedEventData)events[0].data(); + Assert.assertEquals("https://example.blob.core.windows.net/testcontainer/testfile.txt", eventData.url()); + } + + @Test + public void ConsumeCustomEvents() throws IOException { + String jsonData = getTestPayloadFromFile("CustomEvents.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + eventGridSubscriber.putCustomEventMapping("Contoso.Items.ItemReceived", ContosoItemSentEventData.class); + eventGridSubscriber.putCustomEventMapping("Contoso.Items.ItemReceived", ContosoItemReceivedEventData.class); + + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertEquals(1, events.length); + Assert.assertTrue(events[0].data() instanceof ContosoItemReceivedEventData); + ContosoItemReceivedEventData eventData = (ContosoItemReceivedEventData) events[0].data(); + Assert.assertEquals("512d38b6-c7b8-40c8-89fe-f46f9e9622b6", eventData.itemSku()); + } + + @Test + public void consumeCustomEventWithArrayData() throws IOException { + String jsonData = getTestPayloadFromFile("CustomEventWithArrayData.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + + ContosoItemReceivedEventData[] arr = { new ContosoItemReceivedEventData() }; + eventGridSubscriber.putCustomEventMapping("Contoso.Items.ItemReceived", arr.getClass()); + + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertEquals(1, events.length); + Assert.assertTrue(events[0].data() instanceof ContosoItemReceivedEventData[]); + ContosoItemReceivedEventData[] eventData = (ContosoItemReceivedEventData[]) events[0].data(); + Assert.assertEquals("512d38b6-c7b8-40c8-89fe-f46f9e9622b6", (eventData[0]).itemSku()); + } + + @Test + public void consumeCustomEventWithBooleanData() throws IOException { + String jsonData = getTestPayloadFromFile("CustomEventWithBooleanData.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + + eventGridSubscriber.putCustomEventMapping("Contoso.Items.ItemReceived", Boolean.class); + + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertEquals(1, events.length); + Assert.assertTrue(events[0].data() instanceof Boolean); + Boolean eventData = (Boolean) events[0].data(); + Assert.assertTrue(eventData); + } + + @Test + public void consumeCustomEventWithStringData() throws IOException { + String jsonData = getTestPayloadFromFile("CustomEventWithStringData.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertEquals(1, events.length); + Assert.assertTrue(events[0].data() instanceof String); + String eventData = (String) events[0].data(); + Assert.assertEquals("stringdata", eventData); + } + + @Test + public void consumeCustomEventWithPolymorphicData() throws IOException { + String jsonData = getTestPayloadFromFile("CustomEventWithPolymorphicData.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + + eventGridSubscriber.putCustomEventMapping("Contoso.Items.ItemSent", ContosoItemSentEventData.class); + + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertEquals(2, events.length); + Assert.assertTrue(events[0].data() instanceof ContosoItemSentEventData); + Assert.assertTrue(events[1].data() instanceof ContosoItemSentEventData); + ContosoItemSentEventData eventData0 = (ContosoItemSentEventData)events[0].data(); + Assert.assertTrue(eventData0.shippingInfo() instanceof DroneShippingInfo); + ContosoItemSentEventData eventData1 = (ContosoItemSentEventData)events[1].data(); + Assert.assertTrue(eventData1.shippingInfo() instanceof RocketShippingInfo); + } + + @Test + public void testCustomEventMappings() { + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + eventGridSubscriber.putCustomEventMapping("Contoso.Items.ItemSent", ContosoItemSentEventData.class); + eventGridSubscriber.putCustomEventMapping("Contoso.Items.ItemReceived", ContosoItemReceivedEventData.class); + + Set> mappings = eventGridSubscriber.getAllCustomEventMappings(); + + Assert.assertEquals(2, mappings.size()); + + Type mapping = eventGridSubscriber.getCustomEventMapping("Contoso.Items.ItemSent"); + Assert.assertNotNull(mapping); + // Ensure lookup is case-insensitive + mapping = eventGridSubscriber.getCustomEventMapping("contoso.Items.Itemsent"); + Assert.assertNotNull(mapping); + + mapping = eventGridSubscriber.getCustomEventMapping("Contoso.Items.NotExists"); + Assert.assertNull(mapping); + + boolean removed = eventGridSubscriber.removeCustomEventMapping("Contoso.Items.ItemReceived"); + Assert.assertTrue(removed); + Assert.assertEquals(1, mappings.size()); + + boolean contains = eventGridSubscriber.containsCustomEventMappingFor("Contoso.Items.ItemSent"); + Assert.assertTrue(contains); + } + + @Test + public void consumeMultipleEventsInSameBatch() throws IOException { + String jsonData = getTestPayloadFromFile("MultipleEventsInSameBatch.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertEquals(4, events.length); + Assert.assertTrue(events[0].data() instanceof StorageBlobCreatedEventData); + Assert.assertTrue(events[1].data() instanceof StorageBlobDeletedEventData); + Assert.assertTrue(events[2].data() instanceof StorageBlobDeletedEventData); + Assert.assertTrue(events[3].data() instanceof ServiceBusDeadletterMessagesAvailableWithNoListenersEventData); + StorageBlobDeletedEventData eventData = (StorageBlobDeletedEventData)events[2].data(); + Assert.assertEquals("https://example.blob.core.windows.net/testcontainer/testfile.txt", eventData.url()); + } + + // ContainerRegistry events + @Test + public void consumeContainerRegistryImagePushedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ContainerRegistryImagePushedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ContainerRegistryImagePushedEventData); + ContainerRegistryImagePushedEventData eventData = (ContainerRegistryImagePushedEventData)events[0].data(); + Assert.assertEquals("127.0.0.1", eventData.request().addr()); + } + + @Test + public void consumeContainerRegistryImageDeletedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ContainerRegistryImageDeletedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ContainerRegistryImageDeletedEventData); + ContainerRegistryImageDeletedEventData eventData = (ContainerRegistryImageDeletedEventData)events[0].data(); + Assert.assertEquals("testactor", eventData.actor().name()); + } + + // IoTHub Device events + @Test + public void consumeIoTHubDeviceCreatedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("IoTHubDeviceCreatedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof IotHubDeviceCreatedEventData); + IotHubDeviceCreatedEventData eventData = (IotHubDeviceCreatedEventData)events[0].data(); + Assert.assertEquals("enabled", eventData.twin().status()); + } + + @Test + public void consumeIoTHubDeviceDeletedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("IoTHubDeviceDeletedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof IotHubDeviceDeletedEventData); + IotHubDeviceDeletedEventData eventData = (IotHubDeviceDeletedEventData)events[0].data(); + Assert.assertEquals("AAAAAAAAAAE=", eventData.twin().etag()); + } + + @Test + public void consumeIoTHubDeviceConnectedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("IoTHubDeviceConnectedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof IotHubDeviceConnectedEventData); + IotHubDeviceConnectedEventData eventData = (IotHubDeviceConnectedEventData)events[0].data(); + Assert.assertEquals("EGTESTHUB1", eventData.hubName()); + } + + @Test + public void consumeIoTHubDeviceDisconnectedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("IoTHubDeviceDisconnectedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof IotHubDeviceDisconnectedEventData); + IotHubDeviceDisconnectedEventData eventData = (IotHubDeviceDisconnectedEventData)events[0].data(); + Assert.assertEquals("000000000000000001D4132452F67CE200000002000000000000000000000002", eventData.deviceConnectionStateEventInfo().sequenceNumber()); + } + + // EventGrid events + @Test + public void ConsumeEventGridSubscriptionValidationEvent() throws IOException { + String jsonData = getTestPayloadFromFile("EventGridSubscriptionValidationEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof SubscriptionValidationEventData); + SubscriptionValidationEventData eventData = (SubscriptionValidationEventData)events[0].data(); + Assert.assertEquals("512d38b6-c7b8-40c8-89fe-f46f9e9622b6", eventData.validationCode()); + } + + @Test + public void consumeEventGridSubscriptionDeletedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("EventGridSubscriptionDeletedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof SubscriptionDeletedEventData); + SubscriptionDeletedEventData eventData = (SubscriptionDeletedEventData)events[0].data(); + Assert.assertEquals("/subscriptions/id/resourceGroups/rg/providers/Microsoft.EventGrid/topics/topic1/providers/Microsoft.EventGrid/eventSubscriptions/eventsubscription1", eventData.eventSubscriptionId()); + } + + // Event Hub Events + @Test + public void consumeEventHubCaptureFileCreatedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("EventHubCaptureFileCreatedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof EventHubCaptureFileCreatedEventData); + EventHubCaptureFileCreatedEventData eventData = (EventHubCaptureFileCreatedEventData)events[0].data(); + Assert.assertEquals("AzureBlockBlob", eventData.fileType()); + } + + @Test + public void consumeMediaServicesJobStateChangedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("MediaServicesJobStateChangedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof MediaJobStateChangeEventData); + MediaJobStateChangeEventData eventData = (MediaJobStateChangeEventData)events[0].data(); + Assert.assertEquals(JobState.FINISHED, eventData.state()); + } + + // Resource Manager (Azure Subscription/Resource Group) events + @Test + public void consumeResourceWriteFailureEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ResourceWriteFailureEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ResourceWriteFailureData); + ResourceWriteFailureData eventData = (ResourceWriteFailureData)events[0].data(); + Assert.assertEquals("72f988bf-86f1-41af-91ab-2d7cd011db47", eventData.tenantId()); + } + + @Test + public void consumeResourceWriteCancelEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ResourceWriteCancelEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ResourceWriteCancelData); + ResourceWriteCancelData eventData = (ResourceWriteCancelData) events[0].data(); + Assert.assertEquals("72f988bf-86f1-41af-91ab-2d7cd011db47", eventData.tenantId()); + } + + @Test + public void consumeResourceDeleteSuccessEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ResourceDeleteSuccessEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ResourceDeleteSuccessData); + ResourceDeleteSuccessData eventData = (ResourceDeleteSuccessData) events[0].data(); + Assert.assertEquals("72f988bf-86f1-41af-91ab-2d7cd011db47", eventData.tenantId()); + } + + @Test + public void consumeResourceDeleteFailureEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ResourceDeleteFailureEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ResourceDeleteFailureData); + ResourceDeleteFailureData eventData = (ResourceDeleteFailureData) events[0].data(); + Assert.assertEquals("72f988bf-86f1-41af-91ab-2d7cd011db47", eventData.tenantId()); + } + + @Test + public void consumeResourceDeleteCancelEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ResourceDeleteCancelEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ResourceDeleteCancelData); + ResourceDeleteCancelData eventData = (ResourceDeleteCancelData)events[0].data(); + Assert.assertEquals("72f988bf-86f1-41af-91ab-2d7cd011db47", eventData.tenantId()); + } + + @Test + public void consumeResourceActionSuccessEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ResourceActionSuccessEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ResourceActionSuccessData); + ResourceActionSuccessData eventData = (ResourceActionSuccessData)events[0].data(); + Assert.assertEquals("72f988bf-86f1-41af-91ab-2d7cd011db47", eventData.tenantId()); + } + + @Test + public void consumeResourceActionFailureEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ResourceActionFailureEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ResourceActionFailureData); + ResourceActionFailureData eventData = (ResourceActionFailureData)events[0].data(); + Assert.assertEquals("72f988bf-86f1-41af-91ab-2d7cd011db47", eventData.tenantId()); + } + + @Test + public void consumeResourceActionCancelEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ResourceActionCancelEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ResourceActionCancelData); + ResourceActionCancelData eventData = (ResourceActionCancelData)events[0].data(); + Assert.assertEquals("72f988bf-86f1-41af-91ab-2d7cd011db47", eventData.tenantId()); + } + + // ServiceBus events + @Test + public void consumeServiceBusActiveMessagesAvailableWithNoListenersEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ServiceBusActiveMessagesAvailableWithNoListenersEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ServiceBusActiveMessagesAvailableWithNoListenersEventData); + ServiceBusActiveMessagesAvailableWithNoListenersEventData eventData = (ServiceBusActiveMessagesAvailableWithNoListenersEventData) events[0].data(); + Assert.assertEquals("testns1", eventData.namespaceName()); + } + + @Test + public void consumeServiceBusDeadletterMessagesAvailableWithNoListenersEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ServiceBusDeadletterMessagesAvailableWithNoListenersEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ServiceBusDeadletterMessagesAvailableWithNoListenersEventData); + ServiceBusDeadletterMessagesAvailableWithNoListenersEventData eventData = (ServiceBusDeadletterMessagesAvailableWithNoListenersEventData)events[0].data(); + Assert.assertEquals("testns1", eventData.namespaceName()); + } + + // Storage events + @Test + public void consumeStorageBlobCreatedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("StorageBlobCreatedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof StorageBlobCreatedEventData); + StorageBlobCreatedEventData eventData = (StorageBlobCreatedEventData) events[0].data(); + Assert.assertEquals("https://myaccount.blob.core.windows.net/testcontainer/file1.txt", eventData.url()); + } + + @Test + public void consumeStorageBlobDeletedEvent() throws IOException { + String jsonData = getTestPayloadFromFile("StorageBlobDeletedEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof StorageBlobDeletedEventData); + StorageBlobDeletedEventData eventData = (StorageBlobDeletedEventData)events[0].data(); + Assert.assertEquals("https://example.blob.core.windows.net/testcontainer/testfile.txt", eventData.url()); + } + + // Resource Manager (Azure Subscription/Resource Group) events + @Test + public void consumeResourceWriteSuccessEvent() throws IOException { + String jsonData = getTestPayloadFromFile("ResourceWriteSuccessEvent.json"); + // + EventGridSubscriber eventGridSubscriber = new EventGridSubscriber(); + EventGridEvent[] events = eventGridSubscriber.deserializeEventGridEvents(jsonData); + + Assert.assertNotNull(events); + Assert.assertTrue(events[0].data() instanceof ResourceWriteSuccessData); + ResourceWriteSuccessData eventData = (ResourceWriteSuccessData)events[0].data(); + Assert.assertEquals("72f988bf-86f1-41af-91ab-2d7cd011db47", eventData.tenantId()); + } + + // TODO: When new event types are introduced, add one test here for each event type + + private String getTestPayloadFromFile(String fileName) { + ClassLoader classLoader = getClass().getClassLoader(); + try { + byte[] bytes = IOUtils.readFully(classLoader.getResourceAsStream("customization\\" + fileName), -1, true); + return new String(bytes); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/ContosoItemReceivedEventData.java b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/ContosoItemReceivedEventData.java new file mode 100644 index 0000000000000..7029fbf145186 --- /dev/null +++ b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/ContosoItemReceivedEventData.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ +package com.microsoft.azure.eventgrid.customization.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ContosoItemReceivedEventData { + @JsonProperty(value = "itemSku", access = JsonProperty.Access.WRITE_ONLY) + private String itemSku; + + @JsonProperty(value = "itemUri", access = JsonProperty.Access.WRITE_ONLY) + private String itemUri; + + public String itemSku() { + return this.itemSku; + } + + public String itemUri() { + return this.itemUri; + } +} + diff --git a/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/ContosoItemSentEventData.java b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/ContosoItemSentEventData.java new file mode 100644 index 0000000000000..80e8d6995f7ee --- /dev/null +++ b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/ContosoItemSentEventData.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ +package com.microsoft.azure.eventgrid.customization.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ContosoItemSentEventData { + @JsonProperty(value = "shippingInfo", access = JsonProperty.Access.WRITE_ONLY) + private ShippingInfo shippingInfo; + + /** + * @return the shipping info. + */ + public ShippingInfo shippingInfo() { + return this.shippingInfo; + } +} diff --git a/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/DroneShippingInfo.java b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/DroneShippingInfo.java new file mode 100644 index 0000000000000..7bfa721d1dce2 --- /dev/null +++ b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/DroneShippingInfo.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ +package com.microsoft.azure.eventgrid.customization.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "shippingType") +@JsonTypeName("Drone") +public class DroneShippingInfo extends ShippingInfo { + @JsonProperty(value = "droneId", access = JsonProperty.Access.WRITE_ONLY) + private String droneId; + + /** + * @return the drone id. + */ + public String droneId() { + return this.droneId; + } +} diff --git a/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/RocketShippingInfo.java b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/RocketShippingInfo.java new file mode 100644 index 0000000000000..9ff4c09994c73 --- /dev/null +++ b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/RocketShippingInfo.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ +package com.microsoft.azure.eventgrid.customization.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "shippingType") +@JsonTypeName("Rocket") +public class RocketShippingInfo extends ShippingInfo { + @JsonProperty(value = "rocketNumber", access = JsonProperty.Access.WRITE_ONLY) + private String rocketNumber; + + /** + * @return the rocket number. + */ + public String rocketNumber() { + return this.rocketNumber; + } +} diff --git a/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/ShippingInfo.java b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/ShippingInfo.java new file mode 100644 index 0000000000000..c6deb5cd446d6 --- /dev/null +++ b/eventgrid/data-plane/src/test/java/com/microsoft/azure/eventgrid/customization/models/ShippingInfo.java @@ -0,0 +1,29 @@ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for + * license information. + */ +package com.microsoft.azure.eventgrid.customization.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeName; + +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "shippingType") +@JsonTypeName("JobOutput") +@JsonSubTypes({ + @JsonSubTypes.Type(name = "Drone", value = DroneShippingInfo.class), + @JsonSubTypes.Type(name = "Rocket", value = RocketShippingInfo.class) +}) +public class ShippingInfo { + @JsonProperty(value = "shipmentId", access = JsonProperty.Access.WRITE_ONLY) + private String shipmentId; + + /** + * @return the shipment id. + */ + public String shipmentId() { + return this.shipmentId; + } +} diff --git a/eventgrid/data-plane/src/test/resources/customization/ContainerRegistryImageDeletedEvent.json b/eventgrid/data-plane/src/test/resources/customization/ContainerRegistryImageDeletedEvent.json new file mode 100644 index 0000000000000..21258c6f216fc --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ContainerRegistryImageDeletedEvent.json @@ -0,0 +1,39 @@ +[ + { + "id": "56afc886-767b-d359-d59e-0da7877166b2", + "topic": "/SUBSCRIPTIONS/ID/RESOURCEGROUPS/rg/PROVIDERS/MICROSOFT.ContainerRegistry/test1", + "subject": "test1", + "eventType": "Microsoft.ContainerRegistry.ImageDeleted", + "eventTime": "2018-01-02T19:17:44.4383997Z", + "data": { + "id": "eventID", + "timestamp": "2018-06-20T12:00:33.6125843-07:00", + "action": "testaction", + "target": { + "mediaType": "test", + "size": 20, + "digest": "digest1", + "length": 20, + "repository": "test", + "url": "url1", + "tag": "test" + }, + "request": { + "id": "id", + "addr": "127.0.0.1", + "host": "test", + "method": "method1", + "useragent": "useragent1" + }, + "actor": { + "name": "testactor" + }, + "source": { + "addr": "127.0.0.1", + "instanceID": "id" + } + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ContainerRegistryImagePushedEvent.json b/eventgrid/data-plane/src/test/resources/customization/ContainerRegistryImagePushedEvent.json new file mode 100644 index 0000000000000..6de3420add1d4 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ContainerRegistryImagePushedEvent.json @@ -0,0 +1,39 @@ +[ + { + "id": "56afc886-767b-d359-d59e-0da7877166b2", + "topic": "/SUBSCRIPTIONS/ID/RESOURCEGROUPS/rg/PROVIDERS/MICROSOFT.ContainerRegistry/test1", + "subject": "test1", + "eventType": "Microsoft.ContainerRegistry.ImagePushed", + "eventTime": "2018-01-02T19:17:44.4383997Z", + "data": { + "id": "eventID", + "timestamp": "2018-06-20T12:00:33.6125843-07:00", + "action": "testaction", + "target": { + "mediaType": "test", + "size": 20, + "digest": "digest1", + "length": 20, + "repository": "test", + "url": "url1", + "tag": "test" + }, + "request": { + "id": "id", + "addr": "127.0.0.1", + "host": "test", + "method": "method1", + "useragent": "useragent1" + }, + "actor": { + "name": "testactor" + }, + "source": { + "addr": "127.0.0.1", + "instanceID": "id" + } + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/CustomEventWithArrayData.json b/eventgrid/data-plane/src/test/resources/customization/CustomEventWithArrayData.json new file mode 100644 index 0000000000000..475c713b4b533 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/CustomEventWithArrayData.json @@ -0,0 +1,17 @@ +[ + { + "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66", + "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "subject": "", + "data": [ + { + "itemSku": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6", + "itemUri": "https://rp-eastus2.eventgrid.azure.net:553" + } + ], + "eventType": "Contoso.Items.ItemReceived", + "eventTime": "2018-01-25T22:12:19.4556811Z", + "metadataVersion": "1", + "dataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/CustomEventWithBooleanData.json b/eventgrid/data-plane/src/test/resources/customization/CustomEventWithBooleanData.json new file mode 100644 index 0000000000000..aadb734092d7a --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/CustomEventWithBooleanData.json @@ -0,0 +1,12 @@ +[ + { + "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66", + "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "subject": "", + "data": true, + "eventType": "Contoso.Items.ItemReceived", + "eventTime": "2018-01-25T22:12:19.4556811Z", + "metadataVersion": "1", + "dataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/CustomEventWithPolymorphicData.json b/eventgrid/data-plane/src/test/resources/customization/CustomEventWithPolymorphicData.json new file mode 100644 index 0000000000000..44e593212cba5 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/CustomEventWithPolymorphicData.json @@ -0,0 +1,34 @@ +[ + { + "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66", + "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "subject": "", + "data": { + "shippingInfo": { + "shippingType": "Drone", + "droneId": "Drone1", + "shipmentId": "1" + } + }, + "eventType": "Contoso.Items.ItemSent", + "eventTime": "2018-01-25T22:12:19.4556811Z", + "metadataVersion": "1", + "dataVersion": "1" + }, + { + "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66", + "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "subject": "", + "data": { + "shippingInfo": { + "shippingType": "Rocket", + "rocketNumber": 1, + "shipmentId": "1" + } + }, + "eventType": "Contoso.Items.ItemSent", + "eventTime": "2018-01-25T22:12:19.4556811Z", + "metadataVersion": "1", + "dataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/CustomEventWithStringData.json b/eventgrid/data-plane/src/test/resources/customization/CustomEventWithStringData.json new file mode 100644 index 0000000000000..36045761e1f44 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/CustomEventWithStringData.json @@ -0,0 +1,12 @@ +[ + { + "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66", + "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "subject": "", + "data": "stringdata", + "eventType": "Contoso.Items.ItemReceived", + "eventTime": "2018-01-25T22:12:19.4556811Z", + "metadataVersion": "1", + "dataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/CustomEvents.json b/eventgrid/data-plane/src/test/resources/customization/CustomEvents.json new file mode 100644 index 0000000000000..5999548a30ac1 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/CustomEvents.json @@ -0,0 +1,15 @@ +[ + { + "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66", + "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "subject": "", + "data": { + "itemSku": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6", + "itemUri": "https://rp-eastus2.eventgrid.azure.net:553/eventsubscriptions/estest/validate?id=B2E34264-7D71-453A-B5FB-B62D0FDC85EE&t=2018-04-26T20:30:54.4538837Z&apiVersion=2018-05-01-preview&token=1BNqCxBBSSE9OnNSfZM4%2b5H9zDegKMY6uJ%2fO2DFRkwQ%3d" + }, + "eventType": "Contoso.Items.ItemReceived", + "eventTime": "2018-01-25T22:12:19.4556811Z", + "metadataVersion": "1", + "dataVersion": "1" + } +] \ No newline at end of file diff --git a/eventgrid/data-plane/src/test/resources/customization/EventGridSubscriptionDeletedEvent.json b/eventgrid/data-plane/src/test/resources/customization/EventGridSubscriptionDeletedEvent.json new file mode 100644 index 0000000000000..c9d01ac0211eb --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/EventGridSubscriptionDeletedEvent.json @@ -0,0 +1,14 @@ +[ + { + "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66", + "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "subject": "", + "data": { + "eventSubscriptionId": "/subscriptions/id/resourceGroups/rg/providers/Microsoft.EventGrid/topics/topic1/providers/Microsoft.EventGrid/eventSubscriptions/eventsubscription1" + }, + "eventType": "Microsoft.EventGrid.SubscriptionDeletedEvent", + "eventTime": "2018-01-25T22:12:19.4556811Z", + "metadataVersion": "1", + "dataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/EventGridSubscriptionValidationEvent.json b/eventgrid/data-plane/src/test/resources/customization/EventGridSubscriptionValidationEvent.json new file mode 100644 index 0000000000000..de91404d1296d --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/EventGridSubscriptionValidationEvent.json @@ -0,0 +1,15 @@ +[ + { + "id": "2d1781af-3a4c-4d7c-bd0c-e34b19da4e66", + "topic": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "subject": "", + "data": { + "validationCode": "512d38b6-c7b8-40c8-89fe-f46f9e9622b6", + "validationUrl": "https://rp-eastus2.eventgrid.azure.net:553/eventsubscriptions/estest/validate?id=B2E34264-7D71-453A-B5FB-B62D0FDC85EE&t=2018-04-26T20:30:54.4538837Z&apiVersion=2018-05-01-preview&token=1BNqCxBBSSE9OnNSfZM4%2b5H9zDegKMY6uJ%2fO2DFRkwQ%3d" + }, + "eventType": "Microsoft.EventGrid.SubscriptionValidationEvent", + "eventTime": "2018-01-25T22:12:19.4556811Z", + "metadataVersion": "1", + "dataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/EventHubCaptureFileCreatedEvent.json b/eventgrid/data-plane/src/test/resources/customization/EventHubCaptureFileCreatedEvent.json new file mode 100644 index 0000000000000..52b58e9c41f66 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/EventHubCaptureFileCreatedEvent.json @@ -0,0 +1,22 @@ +[ + { + "topic": "/subscriptions/guid/resourcegroups/rgDataMigrationSample/providers/Microsoft.EventHub/namespaces/tfdatamigratens", + "subject": "eventhubs/hubdatamigration", + "eventType": "microsoft.EventHUB.CaptureFileCreated", + "eventTime": "2017-08-31T19:12:46.0498024Z", + "id": "14e87d03-6fbf-4bb2-9a21-92bd1281f247", + "data": { + "fileUrl": "https://tf0831datamigrate.blob.core.windows.net/windturbinecapture/tfdatamigratens/hubdatamigration/1/2017/08/31/19/11/45.avro", + "fileType": "AzureBlockBlob", + "partitionId": "1", + "sizeInBytes": 249168, + "eventCount": 1500, + "firstSequenceNumber": 2400, + "lastSequenceNumber": 3899, + "firstEnqueueTime": "2017-08-31T19:12:14.674Z", + "lastEnqueueTime": "2017-08-31T19:12:44.309Z" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceConnectedEvent.json b/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceConnectedEvent.json new file mode 100644 index 0000000000000..a8fefeb6aa0a4 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceConnectedEvent.json @@ -0,0 +1,19 @@ +[ + { + "id": "fbfd8ee1-cf78-74c6-dbcf-e1c58638ccbd", + "topic": "/SUBSCRIPTIONS/BDF55CDD-8DAB-4CF4-9B2F-C21E8A780472/RESOURCEGROUPS/EGTESTRG/PROVIDERS/MICROSOFT.DEVICES/IOTHUBS/EGTESTHUB1", + "subject": "devices/48e44e11-1437-4907-83b1-4a8d7e89859e", + "eventType": "Microsoft.Devices.DeviceConnected", + "eventTime": "2018-07-03T23:20:11.6921933+00:00", + "data": { + "deviceConnectionStateEventInfo": { + "sequenceNumber": "000000000000000001D4132452F67CE200000002000000000000000000000001" + }, + "hubName": "EGTESTHUB1", + "deviceId": "48e44e11-1437-4907-83b1-4a8d7e89859e", + "moduleId": "" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] \ No newline at end of file diff --git a/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceCreatedEvent.json b/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceCreatedEvent.json new file mode 100644 index 0000000000000..81eb23a9ec8a6 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceCreatedEvent.json @@ -0,0 +1,46 @@ +[ + { + "id": "56afc886-767b-d359-d59e-0da7877166b2", + "topic": "/SUBSCRIPTIONS/ID/RESOURCEGROUPS/rg/PROVIDERS/MICROSOFT.DEVICES/IOTHUBS/hub1", + "subject": "devices/LogicAppTestDevice", + "eventType": "Microsoft.Devices.DeviceCreated", + "eventTime": "2018-01-02T19:17:44.4383997Z", + "data": { + "twin": { + "deviceId": "LogicAppTestDevice", + "etag": "AAAAAAAAAAE=", + "status": "enabled", + "statusUpdateTime": "0001-01-01T00:00:00", + "connectionState": "Disconnected", + "lastActivityTime": "0001-01-01T00:00:00", + "cloudToDeviceMessageCount": 0, + "authenticationType": "sas", + "x509Thumbprint": { + "primaryThumbprint": null, + "secondaryThumbprint": null + }, + "version": 2, + "properties": { + "desired": { + "$metadata": { + "$lastUpdated": "2018-01-02T19:17:44.4383997Z" + }, + "$version": 1 + }, + "reported": { + "$metadata": { + "$lastUpdated": "2018-01-02T19:17:44.4383997Z" + }, + "$version": 1 + } + } + }, + "hubName": "egtesthub1", + "deviceId": "LogicAppTestDevice", + "operationTimestamp": "2018-01-02T19:17:44.4383997Z", + "opType": "DeviceCreated" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceDeletedEvent.json b/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceDeletedEvent.json new file mode 100644 index 0000000000000..d96fed94ade56 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceDeletedEvent.json @@ -0,0 +1,46 @@ +[ + { + "id": "56afc886-767b-d359-d59e-0da7877166b2", + "topic": "/SUBSCRIPTIONS/id/RESOURCEGROUPS/rg/PROVIDERS/MICROSOFT.DEVICES/IOTHUBS/hub1", + "subject": "devices/LogicAppTestDevice", + "eventType": "Microsoft.Devices.DeviceDeleted", + "eventTime": "2018-01-02T19:17:44.4383997Z", + "data": { + "twin": { + "deviceId": "LogicAppTestDevice", + "etag": "AAAAAAAAAAE=", + "status": "enabled", + "statusUpdateTime": "0001-01-01T00:00:00", + "connectionState": "Disconnected", + "lastActivityTime": "0001-01-01T00:00:00", + "cloudToDeviceMessageCount": 0, + "authenticationType": "sas", + "x509Thumbprint": { + "primaryThumbprint": null, + "secondaryThumbprint": null + }, + "version": 2, + "properties": { + "desired": { + "$metadata": { + "$lastUpdated": "2018-01-02T19:17:44.4383997Z" + }, + "$version": 1 + }, + "reported": { + "$metadata": { + "$lastUpdated": "2018-01-02T19:17:44.4383997Z" + }, + "$version": 1 + } + } + }, + "hubName": "egtesthub1", + "deviceId": "LogicAppTestDevice", + "operationTimestamp": "2018-01-02T19:17:44.4383997Z", + "opType": "DeviceCreated" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceDisconnectedEvent.json b/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceDisconnectedEvent.json new file mode 100644 index 0000000000000..cf2dbff4cf8ec --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/IoTHubDeviceDisconnectedEvent.json @@ -0,0 +1,19 @@ +[ + { + "id": "877f0b10-a086-98ec-27b8-6ae2dfbf5f67", + "topic": "/SUBSCRIPTIONS/BDF55CDD-8DAB-4CF4-9B2F-C21E8A780472/RESOURCEGROUPS/EGTESTRG/PROVIDERS/MICROSOFT.DEVICES/IOTHUBS/EGTESTHUB1", + "subject": "devices/48e44e11-1437-4907-83b1-4a8d7e89859e", + "eventType": "Microsoft.Devices.DeviceDisconnected", + "eventTime": "2018-07-03T23:20:52.646434+00:00", + "data": { + "deviceConnectionStateEventInfo": { + "sequenceNumber": "000000000000000001D4132452F67CE200000002000000000000000000000002" + }, + "hubName": "EGTESTHUB1", + "deviceId": "48e44e11-1437-4907-83b1-4a8d7e89859e", + "moduleId": "" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/MediaServicesJobStateChangedEvent.json b/eventgrid/data-plane/src/test/resources/customization/MediaServicesJobStateChangedEvent.json new file mode 100644 index 0000000000000..8e0611788e058 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/MediaServicesJobStateChangedEvent.json @@ -0,0 +1,15 @@ +[ + { + "topic": "/subscriptions/{subscription id}/resourceGroups/amsResourceGroup/providers/Microsoft.Media/mediaservices/amsaccount", + "subject": "transforms/VideoAnalyzerTransform/jobs/{job id}", + "eventType": "Microsoft.Media.JobStateChange", + "eventTime": "2018-04-20T21:26:13.8978772", + "id": "", + "data": { + "previousState": "Processing", + "state": "Finished" + }, + "dataVersion": "1.0", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/MultipleEventsInSameBatch.json b/eventgrid/data-plane/src/test/resources/customization/MultipleEventsInSameBatch.json new file mode 100644 index 0000000000000..536bd2e57a9b6 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/MultipleEventsInSameBatch.json @@ -0,0 +1,79 @@ +[ + { + "topic": "/subscriptions/319a9601-1ec0-0000-aebc-8fe82724c81e/resourceGroups/testrg/providers/Microsoft.Storage/storageAccounts/myaccount", + "subject": "/blobServices/default/containers/testcontainer/blobs/file1.txt", + "eventType": "Microsoft.Storage.BlobCreated", + "eventTime": "2017-08-16T01:57:26.005121Z", + "id": "602a88ef-0001-00e6-1233-1646070610ea", + "data": { + "api": "PutBlockList", + "clientRequestId": "799304a4-bbc5-45b6-9849-ec2c66be800a", + "requestId": "602a88ef-0001-00e6-1233-164607000000", + "eTag": "0x8D4E44A24ABE7F1", + "contentType": "text/plain", + "contentLength": 447, + "blobType": "BlockBlob", + "url": "https://myaccount.blob.core.windows.net/testcontainer/file1.txt", + "sequencer": "00000000000000EB000000000000C65A" + }, + "dataVersion": "", + "metadataVersion": "1" + }, + { + "topic": "/subscriptions/id/resourceGroups/Storage/providers/Microsoft.Storage/storageAccounts/xstoretestaccount", + "subject": "/blobServices/default/containers/testcontainer/blobs/testfile.txt", + "eventType": "Microsoft.Storage.BlobDeleted", + "eventTime": "2017-11-07T20:09:22.5674003Z", + "id": "4c2359fe-001e-00ba-0e04-58586806d298", + "data": { + "api": "DeleteBlob", + "requestId": "4c2359fe-001e-00ba-0e04-585868000000", + "contentType": "text/plain", + "blobType": "BlockBlob", + "url": "https://example.blob.core.windows.net/testcontainer/testfile.txt", + "sequencer": "0000000000000281000000000002F5CA", + "storageDiagnostics": { + "batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0" + } + }, + "dataVersion": "", + "metadataVersion": "1" + }, + { + "topic": "/subscriptions/id/resourceGroups/Storage/providers/Microsoft.Storage/storageAccounts/xstoretestaccount", + "subject": "/blobServices/default/containers/testcontainer/blobs/testfile.txt", + "eventType": "Microsoft.Storage.BlobDeleted", + "eventTime": "2017-11-07T20:09:22.5674003Z", + "id": "4c2359fe-001e-00ba-0e04-58586806d298", + "data": { + "api": "DeleteBlob", + "requestId": "4c2359fe-001e-00ba-0e04-585868000000", + "contentType": "text/plain", + "blobType": "BlockBlob", + "url": "https://example.blob.core.windows.net/testcontainer/testfile.txt", + "sequencer": "0000000000000281000000000002F5CA", + "storageDiagnostics": { + "batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0" + } + }, + "dataVersion": "", + "metadataVersion": "1" + }, + { + "topic": "/subscriptions/id/resourcegroups/rg/providers/Microsoft.ServiceBus/namespaces/testns1", + "subject": "topics/topic1/subscriptions/sub1", + "eventType": "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListener", + "eventTime": "2018-02-14T05:12:53.4133526Z", + "id": "dede87b0-3656-419c-acaf-70c95ddc60f5", + "data": { + "namespaceName": "testns1", + "requestUri": "https://testns1.servicebus.windows.net/t1/subscriptions/sub1/messages/head", + "entityType": "subscriber", + "queueName": "queue1", + "topicName": "topic1", + "subscriptionName": "sub1" + }, + "dataVersion": "1", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ResourceActionCancelEvent.json b/eventgrid/data-plane/src/test/resources/customization/ResourceActionCancelEvent.json new file mode 100644 index 0000000000000..48c4f902a9bcf --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ResourceActionCancelEvent.json @@ -0,0 +1,23 @@ +[ + { + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceActionCancel", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "{request-operation}", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ResourceActionFailureEvent.json b/eventgrid/data-plane/src/test/resources/customization/ResourceActionFailureEvent.json new file mode 100644 index 0000000000000..1b7bd2d75f513 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ResourceActionFailureEvent.json @@ -0,0 +1,23 @@ +[ + { + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceActionFailure", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "{request-operation}", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ResourceActionSuccessEvent.json b/eventgrid/data-plane/src/test/resources/customization/ResourceActionSuccessEvent.json new file mode 100644 index 0000000000000..ff88ad7960e15 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ResourceActionSuccessEvent.json @@ -0,0 +1,23 @@ +[ + { + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceActionSuccess", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "{request-operation}", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ResourceDeleteCancelEvent.json b/eventgrid/data-plane/src/test/resources/customization/ResourceDeleteCancelEvent.json new file mode 100644 index 0000000000000..90d898be4f84a --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ResourceDeleteCancelEvent.json @@ -0,0 +1,23 @@ +[ + { + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceDeleteCancel", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "{request-operation}", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ResourceDeleteFailureEvent.json b/eventgrid/data-plane/src/test/resources/customization/ResourceDeleteFailureEvent.json new file mode 100644 index 0000000000000..6e9f91e58bb9c --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ResourceDeleteFailureEvent.json @@ -0,0 +1,23 @@ +[ + { + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceDeleteFailure", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "{request-operation}", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ResourceDeleteSuccessEvent.json b/eventgrid/data-plane/src/test/resources/customization/ResourceDeleteSuccessEvent.json new file mode 100644 index 0000000000000..068c14c4d4abd --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ResourceDeleteSuccessEvent.json @@ -0,0 +1,23 @@ +[ + { + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceDeleteSuccess", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "{request-operation}", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ResourceWriteCancelEvent.json b/eventgrid/data-plane/src/test/resources/customization/ResourceWriteCancelEvent.json new file mode 100644 index 0000000000000..6d383f41a1915 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ResourceWriteCancelEvent.json @@ -0,0 +1,23 @@ +[ + { + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceWriteCancel", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "{request-operation}", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ResourceWriteFailureEvent.json b/eventgrid/data-plane/src/test/resources/customization/ResourceWriteFailureEvent.json new file mode 100644 index 0000000000000..c8912cc97f0b6 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ResourceWriteFailureEvent.json @@ -0,0 +1,23 @@ +[ + { + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceWriteFailure", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "{request-operation}", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ResourceWriteSuccessEvent.json b/eventgrid/data-plane/src/test/resources/customization/ResourceWriteSuccessEvent.json new file mode 100644 index 0000000000000..e4dee418fea57 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ResourceWriteSuccessEvent.json @@ -0,0 +1,23 @@ +[ + { + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceWriteSuccess", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "{request-operation}", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ServiceBusActiveMessagesAvailableWithNoListenersEvent.json b/eventgrid/data-plane/src/test/resources/customization/ServiceBusActiveMessagesAvailableWithNoListenersEvent.json new file mode 100644 index 0000000000000..af12bc4404e3a --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ServiceBusActiveMessagesAvailableWithNoListenersEvent.json @@ -0,0 +1,19 @@ +[ + { + "topic": "/subscriptions/id/resourcegroups/rg/providers/Microsoft.ServiceBus/namespaces/testns1", + "subject": "topics/topic1/subscriptions/sub1", + "eventType": "Microsoft.ServiceBus.ActiveMessagesAvailableWithNoListeners", + "eventTime": "2018-02-14T05:12:53.4133526Z", + "id": "dede87b0-3656-419c-acaf-70c95ddc60f5", + "data": { + "namespaceName": "testns1", + "requestUri": "https: //testns1.servicebus.windows.net/t1/subscriptions/sub1/messages/head", + "entityType": "subscriber", + "queueName": "queue1", + "topicName": "topic1", + "subscriptionName": "sub1" + }, + "dataVersion": "1", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/ServiceBusDeadletterMessagesAvailableWithNoListenersEvent.json b/eventgrid/data-plane/src/test/resources/customization/ServiceBusDeadletterMessagesAvailableWithNoListenersEvent.json new file mode 100644 index 0000000000000..a85f575cdf618 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/ServiceBusDeadletterMessagesAvailableWithNoListenersEvent.json @@ -0,0 +1,19 @@ +[ + { + "topic": "/subscriptions/id/resourcegroups/rg/providers/Microsoft.ServiceBus/namespaces/testns1", + "subject": "topics/topic1/subscriptions/sub1", + "eventType": "Microsoft.ServiceBus.DeadletterMessagesAvailableWithNoListener", + "eventTime": "2018-02-14T05:12:53.4133526Z", + "id": "dede87b0-3656-419c-acaf-70c95ddc60f5", + "data": { + "namespaceName": "testns1", + "requestUri": "https://testns1.servicebus.windows.net/t1/subscriptions/sub1/messages/head", + "entityType": "subscriber", + "queueName": "queue1", + "topicName": "topic1", + "subscriptionName": "sub1" + }, + "dataVersion": "1", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/StorageBlobCreatedEvent.json b/eventgrid/data-plane/src/test/resources/customization/StorageBlobCreatedEvent.json new file mode 100644 index 0000000000000..f051ee38c58d1 --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/StorageBlobCreatedEvent.json @@ -0,0 +1,22 @@ +[ + { + "topic": "/subscriptions/319a9601-1ec0-0000-aebc-8fe82724c81e/resourceGroups/testrg/providers/Microsoft.Storage/storageAccounts/myaccount", + "subject": "/blobServices/default/containers/testcontainer/blobs/file1.txt", + "eventType": "Microsoft.Storage.BlobCreated", + "eventTime": "2017-08-16T01:57:26.005121Z", + "id": "602a88ef-0001-00e6-1233-1646070610ea", + "data": { + "api": "PutBlockList", + "clientRequestId": "799304a4-bbc5-45b6-9849-ec2c66be800a", + "requestId": "602a88ef-0001-00e6-1233-164607000000", + "eTag": "0x8D4E44A24ABE7F1", + "contentType": "text/plain", + "contentLength": 447, + "blobType": "BlockBlob", + "url": "https://myaccount.blob.core.windows.net/testcontainer/file1.txt", + "sequencer": "00000000000000EB000000000000C65A" + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/StorageBlobDeletedEvent.json b/eventgrid/data-plane/src/test/resources/customization/StorageBlobDeletedEvent.json new file mode 100644 index 0000000000000..d163e0931bbba --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/StorageBlobDeletedEvent.json @@ -0,0 +1,22 @@ +[ + { + "topic": "/subscriptions/id/resourceGroups/Storage/providers/Microsoft.Storage/storageAccounts/xstoretestaccount", + "subject": "/blobServices/default/containers/testcontainer/blobs/testfile.txt", + "eventType": "Microsoft.Storage.BlobDeleted", + "eventTime": "2017-11-07T20:09:22.5674003Z", + "id": "4c2359fe-001e-00ba-0e04-58586806d298", + "data": { + "api": "DeleteBlob", + "requestId": "4c2359fe-001e-00ba-0e04-585868000000", + "contentType": "text/plain", + "blobType": "BlockBlob", + "url": "https://example.blob.core.windows.net/testcontainer/testfile.txt", + "sequencer": "0000000000000281000000000002F5CA", + "storageDiagnostics": { + "batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0" + } + }, + "dataVersion": "", + "metadataVersion": "1" + } +] diff --git a/eventgrid/data-plane/src/test/resources/customization/StorageBlobDeletedEventWithExtraProperty.json b/eventgrid/data-plane/src/test/resources/customization/StorageBlobDeletedEventWithExtraProperty.json new file mode 100644 index 0000000000000..3758afecd568a --- /dev/null +++ b/eventgrid/data-plane/src/test/resources/customization/StorageBlobDeletedEventWithExtraProperty.json @@ -0,0 +1,24 @@ +[ + { + "topic": "/subscriptions/id/resourceGroups/Storage/providers/Microsoft.Storage/storageAccounts/xstoretestaccount", + "subject": "/blobServices/default/containers/testcontainer/blobs/testfile.txt", + "eventType": "Microsoft.Storage.BlobDeleted", + "eventTime": "2017-11-07T20:09:22.5674003Z", + "id": "4c2359fe-001e-00ba-0e04-58586806d298", + "data": { + "api": "DeleteBlob", + "requestId": "4c2359fe-001e-00ba-0e04-585868000000", + "contentType": "text/plain", + "blobType": "BlockBlob", + "url": "https://example.blob.core.windows.net/testcontainer/testfile.txt", + "sequencer": "0000000000000281000000000002F5CA", + "brandNewProperty": "0000000000000281000000000002F5CA", + "storageDiagnostics": { + "batchId": "b68529f3-68cd-4744-baa4-3c0498ec19f0" + } + }, + "dataVersion": "", + "metadataVersion": "1" + } +] +