Пример #1
0
        public byte[] GetBytes(CloudEvent cEvent)
        {
            byte[]      cEventBytes = null;
            ContentType formatterContentType;

            if (cEvent != null)
            {
                try
                {
                    cEventBytes = _cEventsFormatter.EncodeStructuredEvent(cEvent, out formatterContentType); // no async
                    // info
                    _logger.LogInformation($"GetBytes: generated {cEventBytes.Length} bytes with formatter content type {formatterContentType.MediaType}");
                    // debug/ max verbosity
                    _logger.LogDebug($"GetBytes: CloudEvent with envelope and full content {Environment.NewLine}{Encoding.UTF8.GetString(cEventBytes)}");
                }
                catch (Exception ex)
                {
                    // err
                    _logger.LogError($"GetBytes: failed with exception '{ex.Message}', of type '{ex.GetType().Name}'");
                    throw new CloudEventWriterException("GetBytes", ex);
                }
            }
            else
            {
                // warn
                _logger.LogWarning("GetBytes: specified CloudEvent is empty");
            }

            return(cEventBytes);
        }
Пример #2
0
        /// <summary>
        /// Executes the function with the specified CloudEvent, which is converted
        /// to an HTTP POST request using structured encoding. This method asserts that the
        /// request completed successfully.
        /// </summary>
        public async Task ExecuteCloudEventRequestAsync(CloudEvent cloudEvent)
        {
            var bytes = s_eventFormatter.EncodeStructuredEvent(cloudEvent, out var contentType);

            contentType ??= s_applicationJsonContentType;
            var mediaContentType = new MediaTypeHeaderValue(contentType.MediaType)
            {
                CharSet = contentType.CharSet
            };
            var request = new HttpRequestMessage
            {
                // Any URI
                RequestUri = new Uri("uri", UriKind.Relative),
                // CloudEvent headers
                Content = new ByteArrayContent(bytes)
                {
                    Headers = { ContentType = mediaContentType }
                },
                Method = HttpMethod.Post
            };

            using var client   = Server.CreateClient();
            using var response = await client.SendAsync(request);

            response.EnsureSuccessStatusCode();
        }
Пример #3
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="cloudEvent">CloudEvent</param>
        /// <param name="contentMode">Content mode. Structured or binary.</param>
        /// <param name="formatter">Event formatter</param>
        public CloudEventContent(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter)
        {
            if (contentMode == ContentMode.Structured)
            {
                inner = new InnerByteArrayContent(formatter.EncodeStructuredEvent(cloudEvent, out var contentType));
                Headers.ContentType = new MediaTypeHeaderValue(contentType.MediaType);
                MapHeaders(cloudEvent);
                return;
            }

            if (cloudEvent.Data is byte[])
            {
                inner = new InnerByteArrayContent((byte[])cloudEvent.Data);
            }
            else if (cloudEvent.Data is string)
            {
                inner = new InnerStringContent((string)cloudEvent.Data);
            }
            else if (cloudEvent.Data is Stream)
            {
                inner = new InnerStreamContent((Stream)cloudEvent.Data);
            }
            else
            {
                inner = new InnerByteArrayContent(formatter.EncodeAttribute(cloudEvent.SpecVersion, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion),
                                                                            cloudEvent.Data, cloudEvent.Extensions.Values));
            }

            Headers.ContentType = new MediaTypeHeaderValue(cloudEvent.DataContentType?.MediaType);
            MapHeaders(cloudEvent);
        }
Пример #4
0
        public AmqpCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter)
        {
            ApplicationProperties = new ApplicationProperties();
            MapHeaders(cloudEvent);

            if (contentMode == ContentMode.Structured)
            {
                BodySection = new Data
                {
                    Binary = formatter.EncodeStructuredEvent(cloudEvent, out var contentType)
                };
                Properties = new Properties {
                    ContentType = contentType.MediaType
                };
                ApplicationProperties = new ApplicationProperties();
                MapHeaders(cloudEvent);
                return;
            }
            else
            {
                BodySection = SerializeData(cloudEvent.Data);
                Properties  = new Properties {
                    ContentType = cloudEvent.DataContentType
                };
            }
        }
Пример #5
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="cloudEvent">CloudEvent</param>
        /// <param name="contentMode">Content mode. Structured or binary.</param>
        /// <param name="formatter">Event formatter</param>
        public CloudEventContent(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter)
        {
            if (contentMode == ContentMode.Structured)
            {
                inner = new InnerByteArrayContent(formatter.EncodeStructuredEvent(cloudEvent, out var contentType));
                // This is optional in the specification, but can be useful.
                MapHeaders(cloudEvent, includeDataContentType: true);
                Headers.ContentType = new MediaTypeHeaderValue(contentType.MediaType);
                return;
            }

            if (cloudEvent.Data is byte[])
            {
                inner = new InnerByteArrayContent((byte[])cloudEvent.Data);
            }
            else if (cloudEvent.Data is string)
            {
                inner = new InnerStringContent((string)cloudEvent.Data);
            }
            else if (cloudEvent.Data is Stream)
            {
                inner = new InnerStreamContent((Stream)cloudEvent.Data);
            }
            else
            {
                inner = new InnerByteArrayContent(formatter.EncodeAttribute(cloudEvent.SpecVersion, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion),
                                                                            cloudEvent.Data, cloudEvent.Extensions.Values));
            }

            var mediaType = cloudEvent.DataContentType?.MediaType
                            ?? throw new ArgumentException(Strings.ErrorContentTypeUnspecified, nameof(cloudEvent));

            Headers.ContentType = new MediaTypeHeaderValue(mediaType);
            MapHeaders(cloudEvent, includeDataContentType: false);
        }
Пример #6
0
        public KafkaCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter)
        {
            // TODO: Is this appropriate? Why can't we transport a CloudEvent without data in Kafka?
            if (cloudEvent.Data == null)
            {
                throw new ArgumentNullException(nameof(cloudEvent.Data));
            }

            Headers = new Headers
            {
                { SpecVersionKafkaHeader, Encoding.UTF8.GetBytes(cloudEvent.SpecVersion.VersionId) }
            };
            Key = (string)cloudEvent[Partitioning.PartitionKeyAttribute];

            if (contentMode == ContentMode.Structured)
            {
                Value = formatter.EncodeStructuredEvent(cloudEvent, out var contentType);
                Headers.Add(KafkaContentTypeAttributeName, Encoding.UTF8.GetBytes(contentType.MediaType));
            }
            else
            {
                if (cloudEvent.Data is byte[] byteData)
                {
                    Value = byteData;
                }
                else if (cloudEvent.Data is Stream dataStream)
                {
                    // TODO: Extract this common code somewhere
                    if (dataStream is MemoryStream dataMemoryStream)
                    {
                        Value = dataMemoryStream.ToArray();
                    }
                    else
                    {
                        var buffer = new MemoryStream();
                        dataStream.CopyTo(buffer);
                        Value = buffer.ToArray();
                    }
                }
                else
                {
                    throw new InvalidOperationException($"{cloudEvent.Data.GetType()} type is not supported for Cloud Event's Value.");
                }
                if (cloudEvent.DataContentType is string dataContentType)
                {
                    Headers.Add(KafkaContentTypeAttributeName, Encoding.UTF8.GetBytes(dataContentType));
                }
            }

            MapHeaders(cloudEvent, formatter);
        }
Пример #7
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="cloudEvent">CloudEvent</param>
        /// <param name="contentMode">Content mode. Structured or binary.</param>
        /// <param name="formatter">Event formatter</param>
        public CloudEventHttpContent(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter)
        {
            if (contentMode == ContentMode.Structured)
            {
                inner = new InnerByteArrayContent(formatter.EncodeStructuredEvent(cloudEvent, out var contentType));
                // This is optional in the specification, but can be useful.
                MapHeaders(cloudEvent, includeDataContentType: true);
                Headers.ContentType = new MediaTypeHeaderValue(contentType.MediaType);
                return;
            }

            // TODO: Shouldn't we use the formatter in all cases? If I have a JSON formatter and
            // If we specify that the the data is a byte array, I'd expect to end up with a base64-encoded representation...
            if (cloudEvent.Data is byte[])
            {
                inner = new InnerByteArrayContent((byte[])cloudEvent.Data);
            }
            else if (cloudEvent.Data is string)
            {
                inner = new InnerStringContent((string)cloudEvent.Data);
            }
            else if (cloudEvent.Data is Stream)
            {
                inner = new InnerStreamContent((Stream)cloudEvent.Data);
            }
            else
            {
                inner = new InnerByteArrayContent(formatter.EncodeData(cloudEvent.Data));
            }

            // We don't require a data content type if there isn't any data.
            // We may not be able to tell whether the data is empty or not, but we're lenient
            // in that case.
            var dataContentType = cloudEvent.DataContentType;

            if (dataContentType is object)
            {
                var mediaType = new ContentType(dataContentType).MediaType;
                Headers.ContentType = new MediaTypeHeaderValue(mediaType);
            }
            else if (TryComputeLength(out var length) && length != 0L)
            {
                throw new ArgumentException(Strings.ErrorContentTypeUnspecified, nameof(cloudEvent));
            }
            MapHeaders(cloudEvent, includeDataContentType: false);
        }
        public ServiceBusCloudEventMessage(CloudEvent cloudEvent, ICloudEventFormatter formatter)
        {
            if (cloudEvent == null)
            {
                throw new ArgumentNullException(nameof(cloudEvent));
            }

            if (formatter == null)
            {
                throw new ArgumentNullException(nameof(formatter));
            }

            Body        = formatter.EncodeStructuredEvent(cloudEvent, out var contentType);
            ContentType = contentType.MediaType;
            MessageId   = cloudEvent.Id;
            MapHeaders(cloudEvent);
        }
        public KafkaCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter)
        {
            if (cloudEvent.Data == null)
            {
                throw new ArgumentNullException(nameof(cloudEvent.Data));
            }

            Headers = new Headers();

            Key = ExtractPartitionKey(cloudEvent);

            if (contentMode == ContentMode.Structured)
            {
                Value = formatter.EncodeStructuredEvent(cloudEvent, out var contentType);
                Headers.Add(KafkaContentTypeAttributeName, Encoding.UTF8.GetBytes(contentType.MediaType));
            }
            else
            {
                if (cloudEvent.Data is byte[] byteData)
                {
                    Value = byteData;
                }
                else if (cloudEvent.Data is Stream dataStream)
                {
                    if (dataStream is MemoryStream dataMemoryStream)
                    {
                        Value = dataMemoryStream.ToArray();
                    }
                    else
                    {
                        var buffer = new MemoryStream();
                        dataStream.CopyTo(buffer);
                        Value = buffer.ToArray();
                    }
                }
                else
                {
                    throw new InvalidOperationException($"{cloudEvent.Data.GetType()} type is not supported for Cloud Event's Value.");
                }

                Headers.Add(KafkaContentTypeAttributeName, Encoding.UTF8.GetBytes(cloudEvent.DataContentType?.MediaType));
            }

            MapHeaders(cloudEvent, formatter);
        }
Пример #10
0
        /// <summary>
        /// Copies the CloudEvent into this HttpListenerResponse instance
        /// </summary>
        /// <param name="httpListenerResponse">this</param>
        /// <param name="cloudEvent">CloudEvent to copy</param>
        /// <param name="contentMode">Content mode (structured or binary)</param>
        /// <param name="formatter">Formatter</param>
        /// <returns>Task</returns>
        public static Task CopyFromAsync(this HttpListenerResponse httpListenerResponse, CloudEvent cloudEvent,
                                         ContentMode contentMode, ICloudEventFormatter formatter)
        {
            if (contentMode == ContentMode.Structured)
            {
                var buffer =
                    formatter.EncodeStructuredEvent(cloudEvent, out var contentType);
                httpListenerResponse.ContentType = contentType.ToString();
                MapAttributesToListenerResponse(cloudEvent, httpListenerResponse);
                return(httpListenerResponse.OutputStream.WriteAsync(buffer, 0, buffer.Length));
            }

            Stream stream = MapDataAttributeToStream(cloudEvent, formatter);

            httpListenerResponse.ContentType = cloudEvent.DataContentType.ToString();
            MapAttributesToListenerResponse(cloudEvent, httpListenerResponse);
            return(stream.CopyToAsync(httpListenerResponse.OutputStream));
        }
Пример #11
0
        // TODO: Check the pattern here. I suspect that cloudEvent.CopyToAsync(response) would be more natural.

        /// <summary>
        /// Copies the CloudEvent into this HttpListenerResponse instance
        /// </summary>
        /// <param name="httpListenerResponse">this</param>
        /// <param name="cloudEvent">CloudEvent to copy</param>
        /// <param name="contentMode">Content mode (structured or binary)</param>
        /// <param name="formatter">Formatter</param>
        /// <returns>Task</returns>
        public static Task CopyFromAsync(this HttpListenerResponse httpListenerResponse, CloudEvent cloudEvent,
                                         ContentMode contentMode, ICloudEventFormatter formatter)
        {
            if (contentMode == ContentMode.Structured)
            {
                var buffer = formatter.EncodeStructuredEvent(cloudEvent, out var contentType);
                httpListenerResponse.ContentType = contentType.ToString();
                MapAttributesToListenerResponse(cloudEvent, httpListenerResponse);
                return(httpListenerResponse.OutputStream.WriteAsync(buffer, 0, buffer.Length));
            }

            Stream stream = HttpUtilities.MapDataAttributeToStream(cloudEvent, formatter);

            // TODO: Check the defaulting to JSON here...
            httpListenerResponse.ContentType = cloudEvent.DataContentType?.ToString() ?? "application/json";
            MapAttributesToListenerResponse(cloudEvent, httpListenerResponse);
            return(stream.CopyToAsync(httpListenerResponse.OutputStream));
        }
Пример #12
0
        /// <summary>
        /// Copies the CloudEvent into this HttpWebRequest instance
        /// </summary>
        /// <param name="httpWebRequest">this</param>
        /// <param name="cloudEvent">CloudEvent to copy</param>
        /// <param name="contentMode">Content mode (structured or binary)</param>
        /// <param name="formatter">Formatter</param>
        /// <returns>Task</returns>
        public static async Task CopyFromAsync(this HttpWebRequest httpWebRequest, CloudEvent cloudEvent,
                                               ContentMode contentMode, ICloudEventFormatter formatter)
        {
            if (contentMode == ContentMode.Structured)
            {
                var buffer =
                    formatter.EncodeStructuredEvent(cloudEvent, out var contentType);
                httpWebRequest.ContentType = contentType.ToString();
                await(httpWebRequest.GetRequestStream()).WriteAsync(buffer, 0, buffer.Length);
                return;
            }

            Stream stream = MapDataAttributeToStream(cloudEvent, formatter);

            httpWebRequest.ContentType = cloudEvent.DataContentType?.ToString() ?? "application/json";
            MapAttributesToWebRequest(cloudEvent, httpWebRequest);
            await stream.CopyToAsync(httpWebRequest.GetRequestStream());
        }
Пример #13
0
 public MqttCloudEventMessage(CloudEvent cloudEvent, ICloudEventFormatter formatter)
 {
     this.Payload = formatter.EncodeStructuredEvent(cloudEvent, out var contentType);
 }
Пример #14
0
        public AmqpCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter)
        {
            if (contentMode == ContentMode.Structured)
            {
                this.BodySection = new Data
                {
                    Binary = formatter.EncodeStructuredEvent(cloudEvent, out var contentType)
                };
                this.Properties = new Properties()
                {
                    ContentType = contentType.MediaType
                };
                this.ApplicationProperties = new ApplicationProperties();
                MapHeaders(cloudEvent);
                return;
            }

            if (cloudEvent.Data is byte[])
            {
                this.BodySection = new Data {
                    Binary = (byte[])cloudEvent.Data
                };
            }
            else if (cloudEvent.Data is Stream)
            {
                if (cloudEvent.Data is MemoryStream)
                {
                    this.BodySection = new Data {
                        Binary = ((MemoryStream)cloudEvent.Data).ToArray()
                    };
                }
                else
                {
                    var buffer = new MemoryStream();
                    ((Stream)cloudEvent.Data).CopyTo(buffer);
                    this.BodySection = new Data {
                        Binary = buffer.ToArray()
                    };
                }
            }
            else if (cloudEvent.Data is string)
            {
                this.BodySection = new AmqpValue()
                {
                    Value = cloudEvent.Data
                };
            }

            this.Properties = new Properties()
            {
                ContentType = cloudEvent.DataContentType?.MediaType
            };
            this.ApplicationProperties = new ApplicationProperties();
            MapHeaders(cloudEvent);
        }

        void MapHeaders(CloudEvent cloudEvent)
        {
            foreach (var attribute in cloudEvent.GetAttributes())
            {
                if (!attribute.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) &&
                    !attribute.Key.Equals(CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion)))
                {
                    if (attribute.Value is Uri)
                    {
                        this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, attribute.Value.ToString());
                    }
                    else if (attribute.Value is DateTime || attribute.Value is DateTime || attribute.Value is string)
                    {
                        this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, attribute.Value);
                    }
                    else
                    {
                        Map dict = new Map();
                        foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(attribute.Value))
                        {
                            dict.Add(descriptor.Name, descriptor.GetValue(attribute.Value));
                        }

                        this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, dict);
                    }
                }
            }
        }
    }
        public AmqpCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter)
        {
            if (contentMode == ContentMode.Structured)
            {
                this.BodySection = new Data
                {
                    Binary = formatter.EncodeStructuredEvent(cloudEvent, out var contentType)
                };
                this.Properties = new Properties()
                {
                    ContentType = contentType.MediaType
                };
                this.ApplicationProperties = new ApplicationProperties();
                MapHeaders(cloudEvent);
                return;
            }

            if (cloudEvent.Data is byte[])
            {
                this.BodySection = new Data {
                    Binary = (byte[])cloudEvent.Data
                };
            }
            else if (cloudEvent.Data is Stream)
            {
                if (cloudEvent.Data is MemoryStream)
                {
                    this.BodySection = new Data {
                        Binary = ((MemoryStream)cloudEvent.Data).ToArray()
                    };
                }
                else
                {
                    var buffer = new MemoryStream();
                    ((Stream)cloudEvent.Data).CopyTo(buffer);
                    this.BodySection = new Data {
                        Binary = buffer.ToArray()
                    };
                }
            }
            else if (cloudEvent.Data is string)
            {
                this.BodySection = new AmqpValue()
                {
                    Value = cloudEvent.Data
                };
            }

            this.Properties = new Properties()
            {
                ContentType = cloudEvent.DataContentType?.MediaType
            };
            this.ApplicationProperties = new ApplicationProperties();
            MapHeaders(cloudEvent);
        }

        void MapHeaders(CloudEvent cloudEvent)
        {
            foreach (var attribute in cloudEvent.GetAttributes())
            {
                if (!attribute.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) &&
                    !attribute.Key.Equals(CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion)))
                {
                    string key = "cloudEvents:" + attribute.Key;
                    if (attribute.Value is Uri)
                    {
                        this.ApplicationProperties.Map.Add(key, attribute.Value.ToString());
                    }
                    else if (attribute.Value is DateTimeOffset dto)
                    {
                        // AMQPNetLite doesn't support DateTimeOffset values, so convert to UTC.
                        // That means we can't roundtrip events with non-UTC timestamps, but that's not awful.
                        this.ApplicationProperties.Map.Add(key, dto.UtcDateTime);
                    }
                    else if (attribute.Value is string)
                    {
                        this.ApplicationProperties.Map.Add(key, attribute.Value);
                    }
                    else
                    {
                        Map dict = new Map();
                        foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(attribute.Value))
                        {
                            dict.Add(descriptor.Name, descriptor.GetValue(attribute.Value));
                        }

                        this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, dict);
                    }
                }
            }
        }
    }