コード例 #1
0
        /// <summary>
        /// Given a single JSON-encoded event, parses the event envelope and returns a CloudEvent.
        /// </summary>
        /// <param name="binaryData"> Specifies the instance of <see cref="BinaryData"/>. </param>
        /// <returns> A <see cref="CloudEvent"/>. </returns>
        public static CloudEvent ToCloudEvent(this BinaryData binaryData)
        {
            // Deserialize JsonElement to single event, parse event envelope properties
            JsonDocument       requestDocument    = JsonDocument.Parse(binaryData.ToMemory());
            CloudEventInternal cloudEventInternal = CloudEventInternal.DeserializeCloudEventInternal(requestDocument.RootElement);

            CloudEvent cloudEvent = new CloudEvent(
                cloudEventInternal.Id,
                cloudEventInternal.Source,
                cloudEventInternal.Type,
                cloudEventInternal.Time,
                cloudEventInternal.Dataschema,
                cloudEventInternal.Datacontenttype,
                cloudEventInternal.Subject,
                cloudEventInternal.Data,
                cloudEventInternal.DataBase64);

            if (cloudEventInternal.AdditionalProperties != null)
            {
                foreach (KeyValuePair <string, object> kvp in cloudEventInternal.AdditionalProperties)
                {
                    cloudEvent.ExtensionAttributes.Add(kvp.Key, kvp.Value);
                }
            }

            return(cloudEvent);
        }
コード例 #2
0
        /// <summary>
        /// Given a single JSON-encoded event, parses the event envelope and returns a CloudEvent.
        /// </summary>
        /// <param name="binaryData"> Specifies the instance of <see cref="BinaryData"/>. </param>
        /// <returns> A <see cref="CloudEvent"/>. </returns>
        public static CloudEvent ToCloudEvent(this BinaryData binaryData)
        {
            // Deserialize JsonElement to single event, parse event envelope properties
            JsonDocument       requestDocument    = JsonDocument.Parse(binaryData.Bytes);
            CloudEventInternal cloudEventInternal = CloudEventInternal.DeserializeCloudEventInternal(requestDocument.RootElement);

            // Case where Data and Type are null - cannot pass null Type into CloudEvent constructor
            if (cloudEventInternal.Type == null)
            {
                cloudEventInternal.Type = "";
            }

            CloudEvent cloudEvent = new CloudEvent(
                cloudEventInternal.Source,
                cloudEventInternal.Type)
            {
                Id              = cloudEventInternal.Id,
                Time            = cloudEventInternal.Time,
                DataBase64      = cloudEventInternal.DataBase64,
                DataSchema      = cloudEventInternal.Dataschema,
                DataContentType = cloudEventInternal.Datacontenttype,
                Subject         = cloudEventInternal.Subject,
                SerializedData  = cloudEventInternal.Data
            };

            if (cloudEventInternal.AdditionalProperties != null)
            {
                foreach (KeyValuePair <string, object> kvp in cloudEventInternal.AdditionalProperties)
                {
                    cloudEvent.ExtensionAttributes.Add(kvp.Key, kvp.Value);
                }
            }

            return(cloudEvent);
        }
コード例 #3
0
        /// <summary>
        /// Given JSON-encoded events, parses the event envelope and returns an array of CloudEvents.
        /// </summary>
        /// <param name="requestContent"> The JSON-encoded representation of either a single event or an array or events, in the CloudEvent schema. </param>
        /// <returns> A list of <see cref="CloudEvent"/>. </returns>
        public static CloudEvent[] Parse(string requestContent)
        {
            List <CloudEventInternal> cloudEventsInternal = new List <CloudEventInternal>();
            List <CloudEvent>         cloudEvents         = new List <CloudEvent>();
            JsonDocument requestDocument = JsonDocument.Parse(requestContent);

            // Parse JsonElement into separate events, deserialize event envelope properties
            if (requestDocument.RootElement.ValueKind == JsonValueKind.Object)
            {
                cloudEventsInternal.Add(CloudEventInternal.DeserializeCloudEventInternal(requestDocument.RootElement));
            }
            else if (requestDocument.RootElement.ValueKind == JsonValueKind.Array)
            {
                foreach (JsonElement property in requestDocument.RootElement.EnumerateArray())
                {
                    cloudEventsInternal.Add(CloudEventInternal.DeserializeCloudEventInternal(property));
                }
            }

            foreach (CloudEventInternal cloudEventInternal in cloudEventsInternal)
            {
                cloudEvents.Add(new CloudEvent(cloudEventInternal));
            }

            return(cloudEvents.ToArray());
        }
コード例 #4
0
        /// <summary>
        /// Given JSON-encoded events, parses the event envelope and returns an array of CloudEvents.
        /// </summary>
        /// <param name="requestContent"> The JSON-encoded representation of either a single event or an array or events, in the CloudEvent schema. </param>
        /// <returns> A list of <see cref="CloudEvent"/>. </returns>
        public static CloudEvent[] Parse(string requestContent)
        {
            List <CloudEventInternal> cloudEventsInternal = new List <CloudEventInternal>();
            List <CloudEvent>         cloudEvents         = new List <CloudEvent>();
            JsonDocument requestDocument = JsonDocument.Parse(requestContent);

            // Parse JsonElement into separate events, deserialize event envelope properties
            if (requestDocument.RootElement.ValueKind == JsonValueKind.Object)
            {
                cloudEventsInternal.Add(CloudEventInternal.DeserializeCloudEventInternal(requestDocument.RootElement));
            }
            else if (requestDocument.RootElement.ValueKind == JsonValueKind.Array)
            {
                foreach (JsonElement property in requestDocument.RootElement.EnumerateArray())
                {
                    cloudEventsInternal.Add(CloudEventInternal.DeserializeCloudEventInternal(property));
                }
            }

            foreach (CloudEventInternal cloudEventInternal in cloudEventsInternal)
            {
                // Case where Data and Type are null - cannot pass null Type into CloudEvent constructor
                if (cloudEventInternal.Type == null)
                {
                    cloudEventInternal.Type = "";
                }

                CloudEvent cloudEvent = new CloudEvent(
                    cloudEventInternal.Source,
                    cloudEventInternal.Type)
                {
                    Id              = cloudEventInternal.Id,
                    Time            = cloudEventInternal.Time,
                    DataBase64      = cloudEventInternal.DataBase64,
                    DataSchema      = cloudEventInternal.Dataschema,
                    DataContentType = cloudEventInternal.Datacontenttype,
                    Subject         = cloudEventInternal.Subject,
                    SerializedData  = cloudEventInternal.Data
                };

                if (cloudEventInternal.AdditionalProperties != null)
                {
                    foreach (KeyValuePair <string, object> kvp in cloudEventInternal.AdditionalProperties)
                    {
                        cloudEvent.ExtensionAttributes.Add(kvp.Key, kvp.Value);
                    }
                }

                cloudEvents.Add(cloudEvent);
            }

            return(cloudEvents.ToArray());
        }
コード例 #5
0
        internal CloudEvent(CloudEventInternal cloudEventInternal)
        {
            // we only validate that the type is required when deserializing since the service allows sending a CloudEvent without a Source.
            Argument.AssertNotNull(cloudEventInternal.Type, nameof(cloudEventInternal.Type));

            Id                  = cloudEventInternal.Id;
            Source              = cloudEventInternal.Source;
            Type                = cloudEventInternal.Type;
            Time                = cloudEventInternal.Time;
            DataSchema          = cloudEventInternal.Dataschema;
            DataContentType     = cloudEventInternal.Datacontenttype;
            Subject             = cloudEventInternal.Subject;
            SerializedData      = cloudEventInternal.Data;
            DataBase64          = cloudEventInternal.DataBase64;
            ExtensionAttributes = new Dictionary <string, object>(cloudEventInternal.AdditionalProperties);
        }
コード例 #6
0
        /// <summary>
        /// Given JSON-encoded events, parses the event envelope and returns an array of CloudEvents.
        /// </summary>
        /// <param name="requestContent"> The JSON-encoded representation of either a single event or an array or events, in the CloudEvent schema. </param>
        /// <returns> A list of <see cref="CloudEvent"/>. </returns>
        public static CloudEvent[] Parse(string requestContent)
        {
            List <CloudEventInternal> cloudEventsInternal = new List <CloudEventInternal>();
            List <CloudEvent>         cloudEvents         = new List <CloudEvent>();
            JsonDocument requestDocument = JsonDocument.Parse(requestContent);

            // Parse JsonElement into separate events, deserialize event envelope properties
            if (requestDocument.RootElement.ValueKind == JsonValueKind.Object)
            {
                cloudEventsInternal.Add(CloudEventInternal.DeserializeCloudEventInternal(requestDocument.RootElement));
            }
            else if (requestDocument.RootElement.ValueKind == JsonValueKind.Array)
            {
                foreach (JsonElement property in requestDocument.RootElement.EnumerateArray())
                {
                    cloudEventsInternal.Add(CloudEventInternal.DeserializeCloudEventInternal(property));
                }
            }

            foreach (CloudEventInternal cloudEventInternal in cloudEventsInternal)
            {
                CloudEvent cloudEvent = new CloudEvent(
                    cloudEventInternal.Id,
                    cloudEventInternal.Source,
                    cloudEventInternal.Type,
                    cloudEventInternal.Time,
                    cloudEventInternal.Dataschema,
                    cloudEventInternal.Datacontenttype,
                    cloudEventInternal.Subject,
                    cloudEventInternal.Data,
                    cloudEventInternal.DataBase64);

                if (cloudEventInternal.AdditionalProperties != null)
                {
                    foreach (KeyValuePair <string, object> kvp in cloudEventInternal.AdditionalProperties)
                    {
                        cloudEvent.ExtensionAttributes.Add(kvp.Key, kvp.Value);
                    }
                }

                cloudEvents.Add(cloudEvent);
            }

            return(cloudEvents.ToArray());
        }
コード例 #7
0
        private static List <CloudEvent> DeserializeRequest(Request request)
        {
            var content = request.Content as Utf8JsonRequestContent;
            var stream  = new MemoryStream();

            content.WriteTo(stream, CancellationToken.None);
            stream.Position = 0;
            JsonDocument requestDocument = JsonDocument.Parse(stream);
            var          cloudEvents     = new List <CloudEvent>();

            // Parse JsonElement into separate events, deserialize event envelope properties
            if (requestDocument.RootElement.ValueKind == JsonValueKind.Object)
            {
                cloudEvents.Add(new CloudEvent(CloudEventInternal.DeserializeCloudEventInternal(requestDocument.RootElement)));
            }
            else if (requestDocument.RootElement.ValueKind == JsonValueKind.Array)
            {
                foreach (JsonElement property in requestDocument.RootElement.EnumerateArray())
                {
                    cloudEvents.Add(new CloudEvent(CloudEventInternal.DeserializeCloudEventInternal(property)));
                }
            }
            return(cloudEvents);
        }
コード例 #8
0
        /// <summary>
        /// Given JSON-encoded events, parses the event envelope and returns an array of CloudEvents.
        /// </summary>
        /// <param name="requestContent"> The JSON-encoded representation of either a single event or an array or events, in the CloudEvent schema. </param>
        /// <returns> A list of <see cref="CloudEvent"/>. </returns>
        public static CloudEvent[] Parse(string requestContent)
        {
            Argument.AssertNotNull(requestContent, nameof(requestContent));

            CloudEvent[] cloudEvents     = null;
            JsonDocument requestDocument = JsonDocument.Parse(requestContent);

            // Parse JsonElement into separate events, deserialize event envelope properties
            if (requestDocument.RootElement.ValueKind == JsonValueKind.Object)
            {
                cloudEvents    = new CloudEvent[1];
                cloudEvents[0] = (new CloudEvent(CloudEventInternal.DeserializeCloudEventInternal(requestDocument.RootElement)));
            }
            else if (requestDocument.RootElement.ValueKind == JsonValueKind.Array)
            {
                cloudEvents = new CloudEvent[requestDocument.RootElement.GetArrayLength()];
                int i = 0;
                foreach (JsonElement property in requestDocument.RootElement.EnumerateArray())
                {
                    cloudEvents[i++] = new CloudEvent(CloudEventInternal.DeserializeCloudEventInternal(property));
                }
            }
            return(cloudEvents ?? Array.Empty <CloudEvent>());
        }
コード例 #9
0
        /// <summary> Publishes a batch of CloudEvents to an Azure Event Grid topic. </summary>
        /// <param name="events"> An array of events to be published to Event Grid. </param>
        /// <param name="async">Whether to invoke the operation asynchronously.</param>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        private async Task <Response> SendCloudEventsInternal(IEnumerable <CloudEvent> events, bool async, CancellationToken cancellationToken = default)
        {
            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(EventGridPublisherClient)}.{nameof(SendEvents)}");
            scope.Start();

            try
            {
                // List of events cannot be null
                Argument.AssertNotNull(events, nameof(events));

                List <CloudEventInternal> eventsWithSerializedPayloads = new List <CloudEventInternal>();
                foreach (CloudEvent cloudEvent in events)
                {
                    // Individual events cannot be null
                    Argument.AssertNotNull(cloudEvent, nameof(cloudEvent));

                    CloudEventInternal newCloudEvent = new CloudEventInternal(
                        cloudEvent.Id,
                        cloudEvent.Source,
                        cloudEvent.Type,
                        "1.0")
                    {
                        Time            = cloudEvent.Time,
                        DataBase64      = cloudEvent.DataBase64,
                        Datacontenttype = cloudEvent.DataContentType,
                        Dataschema      = cloudEvent.DataSchema,
                        Subject         = cloudEvent.Subject
                    };

                    foreach (KeyValuePair <string, object> kvp in cloudEvent.ExtensionAttributes)
                    {
                        newCloudEvent.Add(kvp.Key, new CustomModelSerializer(kvp.Value, _dataSerializer, cancellationToken));
                    }

                    // The 'Data' property is optional for CloudEvents
                    // Additionally, if the type of data is binary, 'Data' will not be populated (data will be stored in 'DataBase64' instead)
                    if (cloudEvent.Data != null)
                    {
                        JsonDocument data = SerializeObjectToJsonDocument(cloudEvent.Data, cloudEvent.Data.GetType(), cancellationToken);
                        newCloudEvent.Data = data.RootElement;
                    }
                    eventsWithSerializedPayloads.Add(newCloudEvent);
                }
                if (async)
                {
                    // Publish asynchronously if called via an async path
                    return(await _serviceRestClient.PublishCloudEventEventsAsync(
                               _hostName,
                               eventsWithSerializedPayloads,
                               cancellationToken).ConfigureAwait(false));
                }
                else
                {
                    return(_serviceRestClient.PublishCloudEventEvents(
                               _hostName,
                               eventsWithSerializedPayloads,
                               cancellationToken));
                }
            }
            catch (Exception e)
            {
                scope.Failed(e);
                throw;
            }
        }
コード例 #10
0
        /// <summary> Publishes a batch of CloudEvents to an Azure Event Grid topic. </summary>
        /// <param name="events"> An array of events to be published to Event Grid. </param>
        /// <param name="async">Whether to invoke the operation asynchronously</param>
        /// <param name="cancellationToken"> The cancellation token to use. </param>
        private async Task <Response> PublishCloudEventsInternal(IEnumerable <CloudEvent> events, bool async, CancellationToken cancellationToken = default)
        {
            using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(EventGridPublisherClient)}.{nameof(PublishCloudEvents)}");
            scope.Start();

            try
            {
                // List of events cannot be null
                Argument.AssertNotNull(events, nameof(events));

                List <CloudEventInternal> eventsWithSerializedPayloads = new List <CloudEventInternal>();
                foreach (CloudEvent cloudEvent in events)
                {
                    // Individual events cannot be null
                    Argument.AssertNotNull(cloudEvent, nameof(cloudEvent));

                    CloudEventInternal newCloudEvent = new CloudEventInternal(
                        cloudEvent.Id,
                        cloudEvent.Source,
                        cloudEvent.Type,
                        cloudEvent.SpecVersion)
                    {
                        Time            = cloudEvent.Time,
                        Datacontenttype = cloudEvent.DataContentType,
                        Dataschema      = cloudEvent.DataSchema,
                        Subject         = cloudEvent.Subject
                    };

                    foreach (KeyValuePair <string, object> kvp in cloudEvent.ExtensionAttributes)
                    {
                        newCloudEvent.Add(kvp.Key, new EventGridSerializer(kvp.Value, _serializer, cancellationToken));
                    }

                    // The 'Data' property is optional for CloudEvents
                    if (cloudEvent.Data != null)
                    {
                        if (cloudEvent.Data is IEnumerable <byte> enumerable)
                        {
                            newCloudEvent.DataBase64 = Convert.ToBase64String(enumerable.ToArray());
                        }
                        else if (cloudEvent.Data is ReadOnlyMemory <byte> memory)
                        {
                            newCloudEvent.DataBase64 = Convert.ToBase64String(memory.ToArray());
                        }
                        else
                        {
                            newCloudEvent.Data = new EventGridSerializer(
                                cloudEvent.Data,
                                _serializer,
                                cancellationToken);
                        }
                    }
                    eventsWithSerializedPayloads.Add(newCloudEvent);
                }
                if (async)
                {
                    // Publish asynchronously if called via an async path
                    return(await _serviceRestClient.PublishCloudEventEventsAsync(
                               _hostName,
                               eventsWithSerializedPayloads,
                               cancellationToken).ConfigureAwait(false));
                }
                else
                {
                    return(_serviceRestClient.PublishCloudEventEvents(
                               _hostName,
                               eventsWithSerializedPayloads,
                               cancellationToken));
                }
            }
            catch (Exception e)
            {
                scope.Failed(e);
                throw;
            }
        }
コード例 #11
0
        private async Task <CloudEvent[]> DeserializeCloudEventsInternal(string requestContent, bool async, CancellationToken cancellationToken = default)
        {
            List <CloudEventInternal> cloudEventsInternal = new List <CloudEventInternal>();
            List <CloudEvent>         cloudEvents         = new List <CloudEvent>();

            // Deserialize raw JSON string into separate events, deserialize event envelope properties
            JsonDocument requestDocument = await ParseJsonToDocument(requestContent, async, cancellationToken).ConfigureAwait(false);

            foreach (JsonElement property in requestDocument.RootElement.EnumerateArray())
            {
                cloudEventsInternal.Add(CloudEventInternal.DeserializeCloudEventInternal(property));
            }

            // Deserialize 'Data' property from JsonElement for each event
            foreach (CloudEventInternal cloudEventInternal in cloudEventsInternal)
            {
                object cloudEventData = null;
                if (cloudEventInternal.DataBase64 != null)
                {
                    cloudEventData = Convert.FromBase64String(cloudEventInternal.DataBase64);
                }
                else
                {
                    JsonElement?dataElement = cloudEventInternal.Data;

                    if (dataElement.HasValue && dataElement.Value.ValueKind != JsonValueKind.Null)
                    {
                        // Reserialize JsonElement to stream
                        MemoryStream dataStream = SerializePayloadToStream(dataElement, cancellationToken);

                        // First, let's attempt to find the mapping for the event type in the custom event mapping.
                        if (_customEventTypeMappings.TryGetValue(cloudEventInternal.Type, out Type typeOfEventData))
                        {
                            if (!TryGetPrimitiveFromJsonElement(dataElement.Value, out cloudEventData))
                            {
                                if (async)
                                {
                                    cloudEventData = await _dataSerializer.DeserializeAsync(dataStream, typeOfEventData, cancellationToken).ConfigureAwait(false);
                                }
                                else
                                {
                                    cloudEventData = _dataSerializer.Deserialize(dataStream, typeOfEventData, cancellationToken);
                                }
                            }
                        }
                        // If a custom mapping doesn't exist, let's attempt to find the mapping for the deserialization function in the system event type mapping.
                        else if (SystemEventTypeMappings.SystemEventDeserializers.TryGetValue(cloudEventInternal.Type, out Func <JsonElement, object> systemDeserializationFunction))
                        {
                            cloudEventData = systemDeserializationFunction(dataElement.Value);
                        }
                        // If no custom mapping was added, either return a primitive/string, or an object wrapped as BinaryData
                        else
                        {
                            // If event data is not a primitive/string, return as BinaryData
                            if (!TryGetPrimitiveFromJsonElement(dataElement.Value, out cloudEventData))
                            {
                                cloudEventData = BinaryData.FromStream(dataStream);
                            }
                        }
                    }
                    else // Event has null data
                    {
                        cloudEventData          = null;
                        cloudEventInternal.Type = "";
                    }
                }

                cloudEvents.Add(new CloudEvent(
                                    cloudEventInternal.Source,
                                    cloudEventInternal.Type)
                {
                    Id              = cloudEventInternal.Id,
                    Data            = cloudEventData,
                    Time            = cloudEventInternal.Time,
                    DataSchema      = cloudEventInternal.Dataschema,
                    DataContentType = cloudEventInternal.Datacontenttype,
                    Subject         = cloudEventInternal.Subject
                });
            }

            return(cloudEvents.ToArray());
        }