public CloudEvent GetCloudEvent(byte[] cEventBytes)
        {
            CloudEvent cEvent = null;

            if (cEventBytes != null && cEventBytes.Length > 0)
            {
                try
                {
                    cEvent = _cEventsFormatter.DecodeStructuredEvent(cEventBytes, null);
                    // info
                    _logger.LogInformation($"GetCloudEvent: CloudEvents envelope specversion='{cEvent.SpecVersion}' type='{cEvent.Type}' source='{cEvent.Source.ToString()}' id='{cEvent.Id}' subject='{cEvent.Subject ?? "NA"}' content-type='{cEvent.DataContentType.MediaType}'");
                }
                catch (Exception ex)
                {
                    // err
                    _logger.LogError($"GetCloudEvent: failed with exception '{ex.Message}', of type '{ex.GetType().Name}'");
                    throw new CloudEventReaderException("GetCloudEvent", ex);
                }
            }
            else
            {
                // warn
                _logger.LogWarning("GetCloudEvent: specified byte array is empty");
            }

            return(cEvent);
        }
Beispiel #2
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);
        }
        /// <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);
            }
        }
        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 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));
 }
Beispiel #8
0
        public static CloudEvent ToCloudEvent(this Message message,
                                              ICloudEventFormatter formatter = null,
                                              params ICloudEventExtension[] extensions)
        {
            string contentType = message.Properties.ContentType?.ToString();

            if (contentType != null &&
                contentType.StartsWith(CloudEvent.MediaType, StringComparison.InvariantCultureIgnoreCase))
            {
                // handle structured mode
                if (formatter == null)
                {
                    // if we didn't get a formatter, pick one
                    if (contentType.EndsWith(JsonEventFormatter.MediaTypeSuffix,
                                             StringComparison.InvariantCultureIgnoreCase))
                    {
                        formatter = jsonFormatter;
                    }
                    else
                    {
                        throw new InvalidOperationException("Unsupported CloudEvents encoding");
                    }
                }

                return(formatter.DecodeStructuredEvent(new MemoryStream((byte[])message.Body), extensions));
            }
            else
            {
                var specVersion = message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader1)
                        ? CloudEventsSpecVersion.V0_1
                        : message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader2)
                            ? (message.ApplicationProperties.Map[SpecVersionAmqpHeader2] as string == "0.2"
                                ? CloudEventsSpecVersion.V0_2 :
                               (message.ApplicationProperties.Map[SpecVersionAmqpHeader2] as string == "0.3"
                                    ? CloudEventsSpecVersion.V0_3
                                : CloudEventsSpecVersion.Default))
                            : CloudEventsSpecVersion.Default;

                var cloudEvent = new CloudEvent(specVersion, extensions);
                var attributes = cloudEvent.GetAttributes();
                foreach (var prop in message.ApplicationProperties.Map)
                {
                    if (prop.Key is string &&
                        ((string)prop.Key).StartsWith(AmqpHeaderPrefix, StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (cloudEvent.SpecVersion != CloudEventsSpecVersion.V1_0 && prop.Value is Map)
                        {
                            IDictionary <string, object> exp = new ExpandoObject();
                            foreach (var props in (Map)prop.Value)
                            {
                                exp[props.Key.ToString()] = props.Value;
                            }

                            attributes[((string)prop.Key).Substring(AmqpHeaderPrefix.Length).ToLowerInvariant()] =
                                exp;
                        }
                        else
                        {
                            attributes[((string)prop.Key).Substring(AmqpHeaderPrefix.Length).ToLowerInvariant()] =
                                prop.Value;
                        }
                    }
                }

                cloudEvent.DataContentType = message.Properties.ContentType != null
                    ? new ContentType(message.Properties.ContentType)
                    : null;
                cloudEvent.Data = message.Body;
                return(cloudEvent);
            }
        }
Beispiel #9
0
        public static CloudEvent ToCloudEvent(this Message message,
                                              ICloudEventFormatter formatter = null,
                                              params ICloudEventExtension[] extensions)
        {
            string contentType = message.Properties.ContentType?.ToString();

            if (contentType != null &&
                contentType.StartsWith(CloudEvent.MediaType, StringComparison.InvariantCultureIgnoreCase))
            {
                // handle structured mode
                if (formatter == null)
                {
                    // if we didn't get a formatter, pick one
                    if (contentType.EndsWith(JsonEventFormatter.MediaTypeSuffix,
                                             StringComparison.InvariantCultureIgnoreCase))
                    {
                        formatter = jsonFormatter;
                    }
                    else
                    {
                        throw new InvalidOperationException("Unsupported CloudEvents encoding");
                    }
                }

                return(formatter.DecodeStructuredEvent(new MemoryStream((byte[])message.Body), extensions));
            }
            else
            {
                var specVersion = message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader1)
                        ? CloudEventsSpecVersion.V0_1
                        : message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader2)
                            ? (message.ApplicationProperties.Map[SpecVersionAmqpHeader2] as string == "0.2"
                                ? CloudEventsSpecVersion.V0_2 :
                               (message.ApplicationProperties.Map[SpecVersionAmqpHeader2] as string == "0.3"
                                    ? CloudEventsSpecVersion.V0_3
                                : CloudEventsSpecVersion.Default))
                            : CloudEventsSpecVersion.Default;

                var cloudEvent = new CloudEvent(specVersion, extensions);
                var attributes = cloudEvent.GetAttributes();
                foreach (var prop in message.ApplicationProperties.Map)
                {
                    if (prop.Key is string key &&
                        key.StartsWith(AmqpHeaderPrefix, StringComparison.InvariantCultureIgnoreCase))
                    {
                        string attrName = key.Substring(AmqpHeaderPrefix.Length).ToLowerInvariant();
                        if (cloudEvent.SpecVersion != CloudEventsSpecVersion.V1_0 && prop.Value is Map)
                        {
                            IDictionary <string, object> exp = new ExpandoObject();
                            foreach (var props in (Map)prop.Value)
                            {
                                exp[props.Key.ToString()] = props.Value;
                            }

                            attributes[attrName] = exp;
                        }
                        else if (prop.Value is DateTime dt)
                        {
                            if (dt.Kind != DateTimeKind.Utc)
                            {
                                // This should only happen for MinValue and MaxValue...
                                // just respecify as UTC. (We could add validation that it really
                                // *is* MinValue or MaxValue if we wanted to.)
                                dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
                            }
                            attributes[attrName] = (DateTimeOffset)dt;
                        }
                        else
                        {
                            attributes[attrName] = prop.Value;
                        }
                    }
                }

                cloudEvent.DataContentType = message.Properties.ContentType != null
                    ? new ContentType(message.Properties.ContentType)
                    : null;
                cloudEvent.Data = message.Body;
                return(cloudEvent);
            }
        }