/// <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);
        }
Beispiel #2
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);
        }
        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
                };
            }
        }
        public static void Update <T>(this IBasicProperties self, MotorCloudEvent <byte[]> cloudEvent,
                                      RabbitMQPublisherConfig <T> config, ICloudEventFormatter cloudEventFormatter)
        {
            var messagePriority = cloudEvent.Extension <RabbitMQPriorityExtension>()?.Priority ??
                                  config.DefaultPriority;

            if (messagePriority.HasValue)
            {
                self.Priority = messagePriority.Value;
            }
            var dictionary = new Dictionary <string, object>();

            foreach (var attr in cloudEvent.GetAttributes())
            {
                if (string.Equals(attr.Key, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) ||
                    string.Equals(attr.Key,
                                  CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion)) ||
                    string.Equals(attr.Key, RabbitMQPriorityExtension.PriorityAttributeName) ||
                    string.Equals(attr.Key, RabbitMQBindingConfigExtension.ExchangeAttributeName) ||
                    string.Equals(attr.Key, RabbitMQBindingConfigExtension.RoutingKeyAttributeName))
                {
                    continue;
                }
                dictionary.Add($"{CloudEventPrefix}{attr.Key}",
                               cloudEventFormatter.EncodeAttribute(cloudEvent.SpecVersion, attr.Key, attr.Value,
                                                                   cloudEvent.GetExtensions().Values));
            }

            self.Headers = dictionary;
        }
Beispiel #5
0
        public static CloudEvent ToCloudEvent(this Message <string, byte[]> message,
                                              ICloudEventFormatter eventFormatter = null, params ICloudEventExtension[] extensions)
        {
            if (!IsCloudEvent(message))
            {
                throw new InvalidOperationException();
            }

            var contentType = ExtractContentType(message);

            CloudEvent cloudEvent;

            if (!string.IsNullOrEmpty(contentType) &&
                contentType.StartsWith(CloudEvent.MediaType, StringComparison.InvariantCultureIgnoreCase))
            {
                // structured mode
                if (eventFormatter == null)
                {
                    if (contentType.EndsWith(JsonEventFormatter.MediaTypeSuffix, StringComparison.InvariantCultureIgnoreCase))
                    {
                        eventFormatter = _jsonFormatter;
                    }
                    else
                    {
                        throw new InvalidOperationException("Not supported CloudEvents media formatter.");
                    }
                }

                cloudEvent = _jsonFormatter.DecodeStructuredEvent(message.Value, extensions);
            }
            else
            {
                // binary mode
                var specVersion = ExtractVersion(message);

                cloudEvent = new CloudEvent(specVersion, extensions);
                var attributes        = cloudEvent.GetAttributes();
                var cloudEventHeaders = message.Headers.Where(h => h.Key.StartsWith(KafkaCloudEventMessage.KafkaHeaderPerfix));

                foreach (var header in cloudEventHeaders)
                {
                    if (string.Equals(header.Key, SpecVersionKafkaHeader1, StringComparison.InvariantCultureIgnoreCase) ||
                        string.Equals(header.Key, SpecVersionKafkaHeader2, StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    var attributeName = header.Key.Substring(KafkaCloudEventMessage.KafkaHeaderPerfix.Length);
                    attributes.Add(attributeName,
                                   eventFormatter.DecodeAttribute(specVersion, attributeName, header.GetValueBytes(), extensions));
                }

                cloudEvent.DataContentType = contentType != null ? new ContentType(contentType) : null;
                cloudEvent.Data            = message.Value;
            }

            InitPartitioningKey(message, cloudEvent);

            return(cloudEvent);
        }
 public RabbitMQMessagePublisher(IRabbitMQConnectionFactory connectionFactory,
                                 IOptions <RabbitMQPublisherConfig <T> > config, ICloudEventFormatter cloudEventFormatter)
 {
     _connectionFactory   = connectionFactory;
     _cloudEventFormatter = cloudEventFormatter;
     _config = config.Value;
 }
Beispiel #7
0
 public KafkaMessagePublisher(IOptions <KafkaPublisherConfig <T> > options,
                              ICloudEventFormatter cloudEventFormatter)
 {
     _cloudEventFormatter = cloudEventFormatter;
     config   = options.Value ?? throw new ArgumentNullException(nameof(options));
     producer = new ProducerBuilder <string, byte[]>(config).Build();
 }
        static Stream MapDataAttributeToStream(CloudEvent cloudEvent, ICloudEventFormatter formatter)
        {
            Stream stream;

            if (cloudEvent.Data is byte[])
            {
                stream = new MemoryStream((byte[])cloudEvent.Data);
            }
            else if (cloudEvent.Data is string)
            {
                stream = new MemoryStream(Encoding.UTF8.GetBytes((string)cloudEvent.Data));
            }
            else if (cloudEvent.Data is Stream)
            {
                stream = (Stream)cloudEvent.Data;
            }
            else
            {
                stream = new MemoryStream(formatter.EncodeAttribute(cloudEvent.SpecVersion,
                                                                    CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion),
                                                                    cloudEvent.Data, cloudEvent.Extensions.Values));
            }

            return(stream);
        }
Beispiel #9
0
        public static CloudEvent ToCloudEvent(this Message message, ICloudEventFormatter formatter, params ICloudEventExtension[] extensions)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            return(InternalToCloudEvent(message, formatter, extensions));
        }
        public CloudEventJsonInputFormatter(ICloudEventFormatter formatter)
        {
            _formatter = formatter;
            SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
            SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/cloudevents+json"));

            SupportedEncodings.Add(Encoding.UTF8);
            SupportedEncodings.Add(Encoding.Unicode);
        }
Beispiel #11
0
        public static CloudEvent ToCloudEvent(this Message <string, byte[]> message,
                                              ICloudEventFormatter eventFormatter, IEnumerable <CloudEventAttribute> extensionAttributes)
        {
            if (!IsCloudEvent(message))
            {
                throw new InvalidOperationException();
            }

            var contentType = ExtractContentType(message);

            CloudEvent cloudEvent;

            // Structured mode
            if (contentType?.StartsWith(CloudEvent.MediaType, StringComparison.InvariantCultureIgnoreCase) == true)
            {
                cloudEvent = eventFormatter.DecodeStructuredEvent(message.Value, extensionAttributes);
            }
            else
            {
                // Binary mode
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (GetHeaderValue(message, KafkaCloudEventMessage.SpecVersionKafkaHeader) is byte[] versionIdBytes)
                {
                    string versionId = Encoding.UTF8.GetString(versionIdBytes);
                    version = CloudEventsSpecVersion.FromVersionId(versionId);
                }

                cloudEvent = new CloudEvent(version, extensionAttributes)
                {
                    Data            = message.Value,
                    DataContentType = contentType
                };
                foreach (var header in message.Headers.Where(h => h.Key.StartsWith(KafkaCloudEventMessage.KafkaHeaderPrefix)))
                {
                    var attributeName = header.Key.Substring(KafkaCloudEventMessage.KafkaHeaderPrefix.Length).ToLowerInvariant();
                    if (attributeName == CloudEventsSpecVersion.SpecVersionAttribute.Name)
                    {
                        continue;
                    }
                    // TODO: Is this feasible?
                    var headerValue = header.GetValueBytes();
                    if (headerValue is null)
                    {
                        continue;
                    }
                    string attributeValue = Encoding.UTF8.GetString(headerValue);

                    cloudEvent.SetAttributeFromString(attributeName, attributeValue);
                }
            }

            InitPartitioningKey(message, cloudEvent);
            return(cloudEvent);
        }
Beispiel #12
0
 public RabbitMQMessageConsumer(ILogger <RabbitMQMessageConsumer <T> > logger,
                                IRabbitMQConnectionFactory connectionFactory, IOptions <RabbitMQConsumerConfig <T> > config,
                                IHostApplicationLifetime applicationLifetime, IApplicationNameService applicationNameService,
                                ICloudEventFormatter cloudEventFormatter)
 {
     _logger                 = logger;
     _connectionFactory      = connectionFactory;
     _config                 = config.Value;
     _applicationLifetime    = applicationLifetime;
     _applicationNameService = applicationNameService;
     _cloudEventFormatter    = cloudEventFormatter;
 }
 private void MapHeaders(CloudEvent cloudEvent, ICloudEventFormatter formatter)
 {
     foreach (var pair in cloudEvent.GetPopulatedAttributes())
     {
         var attribute = pair.Key;
         if (attribute == cloudEvent.SpecVersion.DataContentTypeAttribute ||
             attribute.Name == Partitioning.PartitionKeyAttribute.Name)
         {
             continue;
         }
         var value = attribute.Format(pair.Value);
         Headers.Add(KafkaHeaderPrefix + attribute.Name, Encoding.UTF8.GetBytes(value));
     }
 }
Beispiel #14
0
 public KafkaMessageConsumer(ILogger <KafkaMessageConsumer <TData> > logger,
                             IOptions <KafkaConsumerConfig <TData> > config,
                             IMetricsFactory <KafkaMessageConsumer <TData> >?metricsFactory,
                             IApplicationNameService applicationNameService,
                             ICloudEventFormatter cloudEventFormatter)
 {
     _logger = logger ?? throw new ArgumentNullException(nameof(logger));
     _applicationNameService = applicationNameService ?? throw new ArgumentNullException(nameof(config));
     _cloudEventFormatter    = cloudEventFormatter;
     _config             = config?.Value ?? throw new ArgumentNullException(nameof(config));
     _consumerLagSummary = metricsFactory?.CreateSummary("consumer_lag_distribution",
                                                         "Contains a summary of current consumer lag of each partition", new [] { "topic", "partition" });
     _consumerLagGauge = metricsFactory?.CreateGauge("consumer_lag",
                                                     "Contains current number consumer lag of each partition", false, "topic", "partition");
 }
        private void MapHeaders(CloudEvent cloudEvent, ICloudEventFormatter formatter)
        {
            foreach (var attr in cloudEvent.GetAttributes())
            {
                if (string.Equals(attr.Key, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) ||
                    string.Equals(attr.Key, CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion)) ||
                    string.Equals(attr.Key, PartitioningExtension.PartitioningKeyAttributeName))
                {
                    continue;
                }

                Headers.Add(KafkaHeaderPerfix + attr.Key,
                            formatter.EncodeAttribute(cloudEvent.SpecVersion, attr.Key, attr.Value, cloudEvent.Extensions.Values));
            }
        }
        /// <summary>
        /// Converts this HTTP request into a CloudEvent object, with the given extensions,
        /// overriding the formatter.
        /// </summary>
        /// <param name="httpRequest">HTTP request</param>
        /// <param name="formatter">The event formatter to use to process the request body.</param>
        /// <param name="extensions">List of extension instances</param>
        /// <returns>A CloudEvent instance or 'null' if the request message doesn't hold a CloudEvent</returns>
        public static async ValueTask <CloudEvent> ReadCloudEventAsync(this HttpRequest httpRequest,
                                                                       ICloudEventFormatter formatter,
                                                                       params CloudEventAttribute[] extensionAttributes)
        {
            if (HasCloudEventsContentType(httpRequest))
            {
                // TODO: Handle formatter being null
                return(await formatter.DecodeStructuredEventAsync(httpRequest.Body, extensionAttributes).ConfigureAwait(false));
            }
            else
            {
                var headers = httpRequest.Headers;
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (headers.TryGetValue(HttpUtilities.SpecVersionHttpHeader, out var values))
                {
                    string versionId = values.First();
                    version = CloudEventsSpecVersion.FromVersionId(versionId);
                }

                var cloudEvent = new CloudEvent(version, extensionAttributes);
                foreach (var header in headers)
                {
                    string attributeName = HttpUtilities.GetAttributeNameFromHeaderName(header.Key);
                    if (attributeName is null || attributeName == CloudEventsSpecVersion.SpecVersionAttribute.Name)
                    {
                        continue;
                    }
                    string attributeValue = HttpUtilities.DecodeHeaderValue(header.Value.First());

                    cloudEvent.SetAttributeFromString(attributeName, attributeValue);
                }

                cloudEvent.DataContentType = httpRequest.ContentType;
                if (httpRequest.Body is Stream body)
                {
                    // TODO: This is a bit ugly.
                    var memoryStream = new MemoryStream();
                    await body.CopyToAsync(memoryStream).ConfigureAwait(false);

                    if (memoryStream.Length != 0)
                    {
                        cloudEvent.Data = formatter.DecodeData(memoryStream.ToArray(), cloudEvent.DataContentType);
                    }
                }
                return(cloudEvent);
            }
        }
        /// <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 CloudEventReader(Dictionary <string, Type> typeMappings, ILogger <CloudEventReader> logger)
        {
            #region Check arguments
            if (typeMappings == null || typeMappings.Count == 0)
            {
                throw new ArgumentNullException("typeMappings");
            }
            #endregion

            this._typeMappings    = typeMappings;
            this._logger          = logger;
            this._pLoadFormatters = new List <IPayloadDeserializationFormatter>()
            {
                new JsonPayloadDeserializationFormatter()
            };
            this._cEventsFormatter = new JsonEventFormatter();
        }
        /// <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));
        }
        // 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));
        }
        /// <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());
        }
        /// <summary>
        /// Converts this listener request into a CloudEvent object, with the given extension attributes.
        /// </summary>
        /// <param name="httpListenerRequest">Listener request</param>
        /// <param name="formatter"></param>
        /// <param name="extensions">List of extension instances</param>
        /// <returns>A CloudEvent instance or 'null' if the request message doesn't hold a CloudEvent</returns>
        public static CloudEvent ToCloudEvent(this HttpListenerRequest httpListenerRequest,
                                              ICloudEventFormatter formatter, params CloudEventAttribute[] extensionAttributes)
        {
            if (HasCloudEventsContentType(httpListenerRequest))
            {
                // FIXME: Handle no formatter being specified.
                return(formatter.DecodeStructuredEvent(httpListenerRequest.InputStream, extensionAttributes));
            }
            else
            {
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (httpListenerRequest.Headers[HttpUtilities.SpecVersionHttpHeader] is string versionId)
                {
                    version = CloudEventsSpecVersion.FromVersionId(versionId);
                }

                var cloudEvent = new CloudEvent(version, extensionAttributes);
                var headers    = httpListenerRequest.Headers;
                foreach (var key in headers.AllKeys)
                {
                    string attributeName = HttpUtilities.GetAttributeNameFromHeaderName(key);
                    if (attributeName is null || attributeName == CloudEventsSpecVersion.SpecVersionAttribute.Name)
                    {
                        continue;
                    }
                    string attributeValue = HttpUtilities.DecodeHeaderValue(headers[key]);
                    cloudEvent.SetAttributeFromString(attributeName, attributeValue);
                }

                // TODO: Check that this doesn't come through as a header already
                cloudEvent.DataContentType = httpListenerRequest.ContentType;

                // TODO: This is a bit ugly.
                var memoryStream = new MemoryStream();
                httpListenerRequest.InputStream.CopyTo(memoryStream);
                if (memoryStream.Length != 0)
                {
                    cloudEvent.Data = formatter.DecodeData(memoryStream.ToArray(), cloudEvent.DataContentType);
                }
                return(cloudEvent);
            }
        }
Beispiel #24
0
        private static async Task <CloudEvent> ToCloudEventInternalAsync(HttpHeaders headers, HttpContent content,
                                                                         ICloudEventFormatter formatter, IEnumerable <CloudEventAttribute> extensionAttributes)
        {
            if (HasCloudEventsContentType(content))
            {
                // FIXME: Handle no formatter being specified.
                var stream = await content.ReadAsStreamAsync().ConfigureAwait(false);

                return(await formatter.DecodeStructuredEventAsync(stream, extensionAttributes).ConfigureAwait(false));
            }
            else
            {
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (headers.Contains(HttpUtilities.SpecVersionHttpHeader))
                {
                    string versionId = headers.GetValues(HttpUtilities.SpecVersionHttpHeader).First();
                    version = CloudEventsSpecVersion.FromVersionId(versionId);
                }

                var cloudEvent = new CloudEvent(version, extensionAttributes);
                foreach (var header in headers)
                {
                    string attributeName = HttpUtilities.GetAttributeNameFromHeaderName(header.Key);
                    if (attributeName is null || attributeName == CloudEventsSpecVersion.SpecVersionAttribute.Name)
                    {
                        continue;
                    }
                    string attributeValue = HttpUtilities.DecodeHeaderValue(header.Value.First());

                    cloudEvent.SetAttributeFromString(attributeName, attributeValue);
                }
                if (content is object)
                {
                    // TODO: Should this just be the media type? We probably need to take a full audit of this...
                    cloudEvent.DataContentType = content.Headers?.ContentType?.ToString();
                    var data = await content.ReadAsByteArrayAsync().ConfigureAwait(false);

                    cloudEvent.Data = formatter.DecodeData(data, cloudEvent.DataContentType);
                }
                return(cloudEvent);
            }
        }
        public CloudEventWriter(string eventTypeUrnAuthority, Uri eventSource, ILogger <CloudEventWriter> logger)
        {
            #region Check arguments
            if (String.IsNullOrWhiteSpace(eventTypeUrnAuthority))
            {
                throw new ArgumentNullException("eventTypeUrnAuthority");
            }
            if (eventSource == null)
            {
                throw new ArgumentNullException("eventSource");
            }
            #endregion

            this._pLoadFormatters = new List <IPayloadSerializationFormatter>()
            {
                new JsonPayloadSerializationFormatter()
            };
            this._declarativeTypeMapper = Utils.ConvertPascalToKebabCase;
            this._eventTypeUrnAuthority = eventTypeUrnAuthority.ToLower();
            this._eventSource           = eventSource;
            this._cEventsFormatter      = new JsonEventFormatter();
            this._logger = logger;
        }
        static CloudEvent ToCloudEventInternal(HttpResponseMessage httpResponseMessage,
                                               ICloudEventFormatter formatter, ICloudEventExtension[] extensions)
        {
            if (httpResponseMessage.Content?.Headers.ContentType != null &&
                httpResponseMessage.Content.Headers.ContentType.MediaType.StartsWith("application/cloudevents",
                                                                                     StringComparison.InvariantCultureIgnoreCase))
            {
                // handle structured mode
                if (formatter == null)
                {
                    // if we didn't get a formatter, pick one
                    if (httpResponseMessage.Content.Headers.ContentType.MediaType.EndsWith("+json",
                                                                                           StringComparison.InvariantCultureIgnoreCase))
                    {
                        formatter = jsonFormatter;
                    }
                    else
                    {
                        throw new InvalidOperationException("Unsupported CloudEvents encoding");
                    }
                }

                return(formatter.DecodeStructuredEvent(
                           httpResponseMessage.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult(),
                           extensions));
            }
            else
            {
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (httpResponseMessage.Headers.Contains(SpecVersionHttpHeader1))
                {
                    version = CloudEventsSpecVersion.V0_1;
                }

                if (httpResponseMessage.Headers.Contains(SpecVersionHttpHeader2))
                {
                    version = httpResponseMessage.Headers.GetValues(SpecVersionHttpHeader2).First() == "0.2"
                        ? CloudEventsSpecVersion.V0_2 : httpResponseMessage.Headers.GetValues(SpecVersionHttpHeader2).First() == "0.3"
                            ? CloudEventsSpecVersion.V0_3 : CloudEventsSpecVersion.Default;
                }

                var cloudEvent = new CloudEvent(version, extensions);
                var attributes = cloudEvent.GetAttributes();
                foreach (var httpResponseHeader in httpResponseMessage.Headers)
                {
                    if (httpResponseHeader.Key.Equals(SpecVersionHttpHeader1,
                                                      StringComparison.InvariantCultureIgnoreCase) ||
                        httpResponseHeader.Key.Equals(SpecVersionHttpHeader2,
                                                      StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    if (httpResponseHeader.Key.StartsWith(HttpHeaderPrefix,
                                                          StringComparison.InvariantCultureIgnoreCase))
                    {
                        string headerValue = httpResponseHeader.Value.First();
                        var    name        = httpResponseHeader.Key.Substring(3);

                        // abolished structures in headers in 1.0
                        if (version != CloudEventsSpecVersion.V1_0 && (headerValue.StartsWith("\"") && headerValue.EndsWith("\"") ||
                                                                       headerValue.StartsWith("'") && headerValue.EndsWith("'") ||
                                                                       headerValue.StartsWith("{") && headerValue.EndsWith("}") ||
                                                                       headerValue.StartsWith("[") && headerValue.EndsWith("]")))
                        {
                            attributes[name] = jsonFormatter.DecodeAttribute(version, name,
                                                                             Encoding.UTF8.GetBytes(headerValue), extensions);
                        }
                        else
                        {
                            attributes[name] = headerValue;
                        }
                    }
                }

                cloudEvent.DataContentType = httpResponseMessage.Content?.Headers.ContentType != null
                    ? new ContentType(httpResponseMessage.Content.Headers.ContentType.ToString())
                    : null;
                cloudEvent.Data = httpResponseMessage.Content?.ReadAsStreamAsync().GetAwaiter().GetResult();
                return(cloudEvent);
            }
        }
        /// <summary>
        /// Converts this listener request into a CloudEvent object, with the given extensions,
        /// overriding the formatter.
        /// </summary>
        /// <param name="httpListenerRequest">Listener request</param>
        /// <param name="formatter"></param>
        /// <param name="extensions">List of extension instances</param>
        /// <returns>A CloudEvent instance or 'null' if the request message doesn't hold a CloudEvent</returns>
        public static CloudEvent ToCloudEvent(this HttpRequestMessage httpListenerRequest,
                                              ICloudEventFormatter formatter = null,
                                              params ICloudEventExtension[] extensions)
        {
            if (httpListenerRequest.Content != null && httpListenerRequest.Content.Headers.ContentType != null &&
                httpListenerRequest.Content.Headers.ContentType.MediaType.StartsWith(CloudEvent.MediaType,
                                                                                     StringComparison.InvariantCultureIgnoreCase))
            {
                // handle structured mode
                if (formatter == null)
                {
                    // if we didn't get a formatter, pick one
                    if (httpListenerRequest.Content.Headers.ContentType.MediaType.EndsWith(
                            JsonEventFormatter.MediaTypeSuffix,
                            StringComparison.InvariantCultureIgnoreCase))
                    {
                        formatter = jsonFormatter;
                    }
                    else
                    {
                        throw new InvalidOperationException("Unsupported CloudEvents encoding");
                    }
                }

                return(formatter.DecodeStructuredEvent(
                           httpListenerRequest.Content.ReadAsStreamAsync().GetAwaiter().GetResult(), extensions));
            }
            else
            {
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (httpListenerRequest.Headers.Contains(SpecVersionHttpHeader1))
                {
                    version = CloudEventsSpecVersion.V0_1;
                }

                if (httpListenerRequest.Headers.Contains(SpecVersionHttpHeader2))
                {
                    version = httpListenerRequest.Headers.GetValues(SpecVersionHttpHeader2).First() == "0.2"
                        ? CloudEventsSpecVersion.V0_2
                        : CloudEventsSpecVersion.Default;
                }

                var cloudEvent = new CloudEvent(version, extensions);
                var attributes = cloudEvent.GetAttributes();
                foreach (var httpRequestHeaders in httpListenerRequest.Headers)
                {
                    if (httpRequestHeaders.Key.Equals(SpecVersionHttpHeader1,
                                                      StringComparison.InvariantCultureIgnoreCase) ||
                        httpRequestHeaders.Key.Equals(SpecVersionHttpHeader2,
                                                      StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    if (httpRequestHeaders.Key.StartsWith(HttpHeaderPrefix,
                                                          StringComparison.InvariantCultureIgnoreCase))
                    {
                        string headerValue = httpListenerRequest.Headers.GetValues(httpRequestHeaders.Key).First();
                        // maps in headers have been abolished in version 1.0
                        if (version != CloudEventsSpecVersion.V1_0 &&
                            (headerValue.StartsWith("{") && headerValue.EndsWith("}") ||
                             headerValue.StartsWith("[") && headerValue.EndsWith("]")))
                        {
                            attributes[httpRequestHeaders.Key.Substring(3)] =
                                JsonConvert.DeserializeObject(headerValue);
                        }
                        else
                        {
                            attributes[httpRequestHeaders.Key.Substring(3)] = headerValue;
                        }
                    }
                }

                cloudEvent.DataContentType = httpListenerRequest.Content?.Headers.ContentType != null
                    ? new ContentType(httpListenerRequest.Content.Headers.ContentType.MediaType)
                    : null;
                cloudEvent.Data = httpListenerRequest.Content?.ReadAsStreamAsync().GetAwaiter().GetResult();
                return(cloudEvent);
            }
        }
 /// <summary>
 /// Converts this response message into a CloudEvent object, with the given extensions and
 /// overriding the default formatter.
 /// </summary>
 /// <param name="httpResponseMessage">Response message</param>
 /// <param name="formatter"></param>
 /// <param name="extensions">List of extension instances</param>
 /// <returns>A CloudEvent instance or 'null' if the response message doesn't hold a CloudEvent</returns>
 public static CloudEvent ToCloudEvent(this HttpResponseMessage httpResponseMessage,
                                       ICloudEventFormatter formatter, params ICloudEventExtension[] extensions)
 {
     return(ToCloudEventInternal(httpResponseMessage, formatter, extensions));
 }
        /// <summary>
        /// Converts this listener request into a CloudEvent object, with the given extensions,
        /// overriding the formatter.
        /// </summary>
        /// <param name="httpListenerRequest">Listener request</param>
        /// <param name="formatter"></param>
        /// <param name="extensions">List of extension instances</param>
        /// <returns>A CloudEvent instance or 'null' if the response message doesn't hold a CloudEvent</returns>
        public static CloudEvent ToCloudEvent(this HttpListenerRequest httpListenerRequest,
                                              ICloudEventFormatter formatter = null,
                                              params ICloudEventExtension[] extensions)
        {
            if (httpListenerRequest.ContentType != null &&
                httpListenerRequest.ContentType.StartsWith(CloudEvent.MediaType,
                                                           StringComparison.InvariantCultureIgnoreCase))
            {
                // handle structured mode
                if (formatter == null)
                {
                    // if we didn't get a formatter, pick one
                    if (httpListenerRequest.ContentType.EndsWith(JsonEventFormatter.MediaTypeSuffix,
                                                                 StringComparison.InvariantCultureIgnoreCase))
                    {
                        formatter = jsonFormatter;
                    }
                    else
                    {
                        throw new InvalidOperationException("Unsupported CloudEvents encoding");
                    }
                }

                return(formatter.DecodeStructuredEvent(httpListenerRequest.InputStream, extensions));
            }
            else
            {
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (httpListenerRequest.Headers[SpecVersionHttpHeader1] != null)
                {
                    version = CloudEventsSpecVersion.V0_1;
                }

                if (httpListenerRequest.Headers[SpecVersionHttpHeader2] != null)
                {
                    version = httpListenerRequest.Headers[SpecVersionHttpHeader2] == "0.2"
                        ? CloudEventsSpecVersion.V0_2 : httpListenerRequest.Headers[SpecVersionHttpHeader2] == "0.3"
                            ? CloudEventsSpecVersion.V0_3 : CloudEventsSpecVersion.Default;
                }

                var cloudEvent = new CloudEvent(version, extensions);
                var attributes = cloudEvent.GetAttributes();
                foreach (var httpRequestHeaders in httpListenerRequest.Headers.AllKeys)
                {
                    if (httpRequestHeaders.Equals(SpecVersionHttpHeader1,
                                                  StringComparison.InvariantCultureIgnoreCase) ||
                        httpRequestHeaders.Equals(SpecVersionHttpHeader2, StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    if (httpRequestHeaders.StartsWith(HttpHeaderPrefix, StringComparison.InvariantCultureIgnoreCase))
                    {
                        string headerValue = httpListenerRequest.Headers[httpRequestHeaders];
                        if (headerValue.StartsWith("{") && headerValue.EndsWith("}") ||
                            headerValue.StartsWith("[") && headerValue.EndsWith("]"))
                        {
                            attributes[httpRequestHeaders.Substring(3)] =
                                JsonConvert.DeserializeObject(headerValue);
                        }
                        else
                        {
                            attributes[httpRequestHeaders.Substring(3)] = headerValue;
                            attributes[httpRequestHeaders.Substring(3)] = headerValue;
                        }
                    }
                }

                cloudEvent.DataContentType = httpListenerRequest.ContentType != null
                    ? new ContentType(httpListenerRequest.ContentType)
                    : null;
                cloudEvent.Data = httpListenerRequest.InputStream;
                return(cloudEvent);
            }
        }
 public static CloudEvent ToCloudEvent(this MqttApplicationMessage message,
                                       ICloudEventFormatter eventFormatter, params ICloudEventExtension[] extensions)
 {
     return(eventFormatter.DecodeStructuredEvent(message.Payload, extensions));
 }