Example #1
0
 /// <summary>
 /// Creates a new instance, using the specified <see cref="CloudEventsSpecVersion"/>
 /// and the specified initial extension attributes.
 /// </summary>
 /// <param name="specVersion">CloudEvents Specification version for this instance. Must not be null.</param>
 /// <param name="extensionAttributes">Initial extension attributes. May be null, which is equivalent
 /// to an empty sequence.</param>
 public CloudEvent(CloudEventsSpecVersion specVersion, IEnumerable <CloudEventAttribute> extensionAttributes)
 {
     // TODO: Work out how to be more efficient, e.g. not creating a dictionary at all if there are no
     // extension attributes.
     SpecVersion = Validation.CheckNotNull(specVersion, nameof(specVersion));
     if (extensionAttributes is object)
     {
         foreach (var extension in extensionAttributes)
         {
             Validation.CheckArgument(
                 extension is object,
                 nameof(extensionAttributes),
                 "Extension attribute collection cannot contain null elements");
             Validation.CheckArgument(
                 extension.Name != CloudEventsSpecVersion.SpecVersionAttributeName,
                 nameof(extensionAttributes),
                 "The 'specversion' attribute cannot be specified as an extension attribute");
             Validation.CheckArgument(
                 SpecVersion.GetAttributeByName(extension.Name) is null,
                 nameof(extensionAttributes),
                 "'{0}' cannot be specified as the name of an extension attribute; it is already a context attribute",
                 extension.Name);
             Validation.CheckArgument(
                 extension.IsExtension,
                 nameof(extensionAttributes),
                 "'{0}' is not an extension attribute",
                 extension.Name);
             Validation.CheckArgument(
                 !this.extensionAttributes.ContainsKey(extension.Name),
                 nameof(extensionAttributes),
                 "'{0}' cannot be specified more than once as an extension attribute");
             this.extensionAttributes.Add(extension.Name, extension);
         }
     }
 }
Example #2
0
        public byte[] EncodeAttribute(CloudEventsSpecVersion specVersion, string name, object value, IEnumerable <ICloudEventExtension> extensions = null)
        {
            if (name.Equals(CloudEventAttributes.DataAttributeName(specVersion)))
            {
                if (value is Stream)
                {
                    using (var buffer = new MemoryStream())
                    {
                        ((Stream)value).CopyTo(buffer);
                        return(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(buffer.ToArray())));
                    }
                }
            }

            if (extensions != null)
            {
                foreach (var extension in extensions)
                {
                    Type type = extension.GetAttributeType(name);
                    if (type != null)
                    {
                        return(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(Convert.ChangeType(value, type))));
                    }
                }
            }

            return(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)));
        }
 internal CloudEventAttributes(CloudEventsSpecVersion specVersion, IEnumerable <ICloudEventExtension> extensions)
 {
     this.extensions  = extensions;
     this.specVersion = specVersion;
     dict[SpecVersionAttributeName(specVersion)] = (specVersion == CloudEventsSpecVersion.V0_1 ? "0.1" :
                                                    (specVersion == CloudEventsSpecVersion.V0_2 ? "0.2" : (specVersion == CloudEventsSpecVersion.V0_3 ? "0.3" : "1.0")));
 }
Example #4
0
        public CloudEvent DecodeJObject(JObject jObject, IEnumerable <ICloudEventExtension> extensions = null)
        {
            CloudEventsSpecVersion specVersion = CloudEventsSpecVersion.Default;

            if (jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1)) ||
                jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1).ToLowerInvariant()))
            {
                specVersion = CloudEventsSpecVersion.V0_1;
            }
            if (jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2)) ||
                jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2).ToLowerInvariant()))
            {
                specVersion =
                    ((string)jObject[CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2)] ==
                     "0.2")
                        ? CloudEventsSpecVersion.V0_2
                        : CloudEventsSpecVersion.Default;
            }
            var cloudEvent = new CloudEvent(specVersion, extensions);
            var attributes = cloudEvent.GetAttributes();

            foreach (var keyValuePair in jObject)
            {
                if (keyValuePair.Key.Equals(
                        CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1), StringComparison.InvariantCultureIgnoreCase) ||
                    keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2), StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }

                switch (keyValuePair.Value.Type)
                {
                case JTokenType.String:
                    attributes[keyValuePair.Key] = keyValuePair.Value.ToObject <string>();
                    break;

                case JTokenType.Date:
                    attributes[keyValuePair.Key] = keyValuePair.Value.ToObject <DateTime>();
                    break;

                case JTokenType.Uri:
                    attributes[keyValuePair.Key] = keyValuePair.Value.ToObject <Uri>();
                    break;

                case JTokenType.Null:
                    attributes[keyValuePair.Key] = null;
                    break;

                case JTokenType.Integer:
                    attributes[keyValuePair.Key] = keyValuePair.Value.ToObject <int>();
                    break;

                default:
                    attributes[keyValuePair.Key] = (dynamic)keyValuePair.Value;
                    break;
                }
            }

            return(cloudEvent);
        }
Example #5
0
 /// <summary>
 /// Create a new CloudEvent instance.
 /// </summary>
 /// <param name="specVersion">CloudEvents specification version</param>
 /// <param name="type">'type' of the CloudEvent</param>
 /// <param name="source">'source' of the CloudEvent</param>
 /// <param name="id">'id' of the CloudEvent</param>
 /// <param name="time">'time' of the CloudEvent</param>
 /// <param name="extensions">Extensions to be added to this CloudEvents</param>
 public CloudEvent(CloudEventsSpecVersion specVersion, string type, Uri source, string id = null, DateTime?time = null,
                   params ICloudEventExtension[] extensions) : this(specVersion, extensions)
 {
     Type   = type;
     Source = source;
     Id     = id ?? Guid.NewGuid().ToString();
     Time   = time ?? DateTime.UtcNow;
 }
        private CloudEvent DecodeGenericRecord(GenericRecord record, IEnumerable <CloudEventAttribute> extensionAttributes)
        {
            if (!record.TryGetValue(AttributeName, out var attrObj))
            {
                throw new ArgumentException($"Record has no '{AttributeName}' field");
            }
            IDictionary <string, object> recordAttributes = (IDictionary <string, object>)attrObj;

            if (!recordAttributes.TryGetValue(CloudEventsSpecVersion.SpecVersionAttribute.Name, out var versionId) ||
                !(versionId is string versionIdString))
            {
                throw new ArgumentException("Specification version attribute is missing");
            }
            CloudEventsSpecVersion version = CloudEventsSpecVersion.FromVersionId(versionIdString);

            if (version is null)
            {
                throw new ArgumentException($"Unsupported CloudEvents spec version '{versionIdString}'");
            }

            var cloudEvent = new CloudEvent(version, extensionAttributes);

            cloudEvent.Data = record.TryGetValue(DataName, out var data) ? data : null;

            foreach (var keyValuePair in recordAttributes)
            {
                string key   = keyValuePair.Key;
                object value = keyValuePair.Value;
                if (value is null)
                {
                    continue;
                }

                if (key == CloudEventsSpecVersion.SpecVersionAttribute.Name || key == DataName)
                {
                    continue;
                }

                // The Avro schema allows the value to be a Boolean, integer, string or bytes.
                // Timestamps and URIs are represented as strings, so we just use SetAttributeFromString to handle those.
                // TODO: This does mean that any extensions of these types must have been registered beforehand.
                if (value is bool || value is int || value is byte[])
                {
                    cloudEvent[key] = value;
                }
                else if (value is string)
                {
                    cloudEvent.SetAttributeFromString(key, (string)value);
                }
                else
                {
                    throw new ArgumentException($"Invalid value type from Avro record: {value.GetType()}");
                }
            }

            return(Validation.CheckCloudEventArgument(cloudEvent, nameof(record)));
        }
Example #7
0
 /// <summary>
 /// Create a new CloudEvent instance
 /// </summary>
 /// <param name="specVersion">CloudEvents specification version</param>
 /// <param name="extensions">Extensions to be added to this CloudEvents</param>
 public CloudEvent(CloudEventsSpecVersion specVersion, IEnumerable <ICloudEventExtension> extensions)
 {
     attributes      = new CloudEventAttributes(specVersion, extensions);
     this.Extensions = new Dictionary <Type, ICloudEventExtension>();
     if (extensions != null)
     {
         foreach (var extension in extensions)
         {
             this.Extensions.Add(extension.GetType(), extension);
             extension.Attach(this);
         }
     }
 }
Example #8
0
        public CloudEvent DecodeGenericRecord(GenericRecord record, IEnumerable <CloudEventAttribute> extensionAttributes)
        {
            if (!record.TryGetValue("attribute", out var attrObj))
            {
                return(null);
            }
            IDictionary <string, object> recordAttributes = (IDictionary <string, object>)attrObj;

            CloudEventsSpecVersion specVersion = CloudEventsSpecVersion.Default;

            if (recordAttributes.TryGetValue(CloudEventsSpecVersion.SpecVersionAttribute.Name, out var versionId) &&
                versionId is string versionIdString)
            {
                specVersion = CloudEventsSpecVersion.FromVersionId(versionIdString);
            }
            var cloudEvent = new CloudEvent(specVersion, extensionAttributes);

            cloudEvent.Data = record.TryGetValue(DataName, out var data) ? data : null;

            foreach (var keyValuePair in recordAttributes)
            {
                string key   = keyValuePair.Key;
                object value = keyValuePair.Value;
                if (value is null)
                {
                    continue;
                }

                if (key == CloudEventsSpecVersion.SpecVersionAttribute.Name || key == DataName)
                {
                    continue;
                }

                // The Avro schema allows the value to be a Boolean, integer, string or bytes.
                // Timestamps and URIs are represented as strings, so we just use SetAttributeFromString to handle those.
                if (value is bool || value is int || value is byte[])
                {
                    cloudEvent[key] = value;
                }
                else if (value is string)
                {
                    cloudEvent.SetAttributeFromString(key, (string)value);
                }
                else
                {
                    throw new ArgumentException($"Invalid value type from Avro record: {value.GetType()}");
                }
            }

            return(cloudEvent);
        }
Example #9
0
        // TODO: Consider exposing publicly.
        internal CloudEventAttributes WithSpecVersion(CloudEventsSpecVersion newVersion)
        {
            var newAttributes = new CloudEventAttributes(newVersion, extensions);

            foreach (var kv in dict)
            {
                // The constructor will have populated the spec version, so we can skip it.
                if (!kv.Key.Equals(SpecVersionAttributeName(this.SpecVersion), StringComparison.InvariantCultureIgnoreCase))
                {
                    string newAttributeName = ConvertAttributeName(kv.Key, SpecVersion, newVersion);
                    newAttributes[newAttributeName] = kv.Value;
                }
            }
            return(newAttributes);
        }
        /// <summary>
        /// Converts this HTTP request into a CloudEvent object.
        /// </summary>
        /// <param name="httpRequest">The HTTP request to decode. Must not be null.</param>
        /// <param name="formatter">The event formatter to use to process the request body. Must not be null.</param>
        /// <param name="extensions">The extension attributes to use when populating the CloudEvent. May be null.</param>
        /// <returns>The decoded CloudEvent.</returns>
        /// <exception cref="ArgumentException">The request does not contain a CloudEvent.</exception>
        public static async ValueTask <CloudEvent> ReadCloudEventAsync(this HttpRequest httpRequest,
                                                                       CloudEventFormatter formatter,
                                                                       params CloudEventAttribute[] extensionAttributes)
        {
            if (HasCloudEventsContentType(httpRequest))
            {
                // TODO: Handle formatter being null
                return(await formatter.DecodeStructuredModeMessageAsync(httpRequest.Body, MimeUtilities.CreateContentTypeOrNull(httpRequest.ContentType), extensionAttributes).ConfigureAwait(false));
            }
            else
            {
                var headers = httpRequest.Headers;
                if (!headers.TryGetValue(HttpUtilities.SpecVersionHttpHeader, out var versionId))
                {
                    throw new ArgumentException("Request is not a CloudEvent");
                }
                var version = CloudEventsSpecVersion.FromVersionId(versionId.First());
                if (version is null)
                {
                    throw new ArgumentException($"Unsupported CloudEvents spec version '{versionId.First()}'");
                }

                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. We have code in BinaryDataUtilities to handle this, but
                    // we'd rather not expose it...
                    var memoryStream = new MemoryStream();
                    await body.CopyToAsync(memoryStream).ConfigureAwait(false);

                    formatter.DecodeBinaryModeEventData(memoryStream.ToArray(), cloudEvent);
                }
                return(cloudEvent);
            }
        }
        /// <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);
            }
        }
        public CloudEvent DecodeGenericRecord(GenericRecord record, IEnumerable <ICloudEventExtension> extensions = null)
        {
            if (!record.TryGetValue("attribute", out var attrObj))
            {
                return(null);
            }
            IDictionary <string, object> recordAttributes = (IDictionary <string, object>)attrObj;
            object data = null;

            if (!record.TryGetValue("data", out data))
            {
                data = null;
            }

            CloudEventsSpecVersion specVersion = CloudEventsSpecVersion.Default;
            var cloudEvent = new CloudEvent(specVersion, extensions);

            cloudEvent.Data = data;

            var attributes = cloudEvent.GetAttributes();

            foreach (var keyValuePair in recordAttributes)
            {
                // skip the version since we set that above
                if (keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1), StringComparison.InvariantCultureIgnoreCase) ||
                    keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2), StringComparison.InvariantCultureIgnoreCase) ||
                    keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V1_0), StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }
                if (keyValuePair.Key == CloudEventAttributes.SourceAttributeName(specVersion) ||
                    keyValuePair.Key == CloudEventAttributes.DataSchemaAttributeName(specVersion))
                {
                    attributes[keyValuePair.Key] = new Uri((string)keyValuePair.Value);
                }
                else if (keyValuePair.Key == CloudEventAttributes.TimeAttributeName(specVersion))
                {
                    attributes[keyValuePair.Key] = Timestamps.Parse((string)keyValuePair.Value);
                }
                else
                {
                    attributes[keyValuePair.Key] = keyValuePair.Value;
                }
            }

            return(cloudEvent);
        }
Example #13
0
        public object DecodeAttribute(CloudEventsSpecVersion specVersion, string name, byte[] data, IEnumerable <ICloudEventExtension> extensions = null)
        {
            if (name.Equals(CloudEventAttributes.IdAttributeName(specVersion)) ||
                name.Equals(CloudEventAttributes.TypeAttributeName(specVersion)) ||
                name.Equals(CloudEventAttributes.SubjectAttributeName(specVersion)))
            {
                return(JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(string)));
            }

            if (name.Equals(CloudEventAttributes.TimeAttributeName(specVersion)))
            {
                return(JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(DateTime)));
            }

            if (name.Equals(CloudEventAttributes.SourceAttributeName(specVersion)) ||
                name.Equals(CloudEventAttributes.DataSchemaAttributeName(specVersion)))
            {
                var uri = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(string)) as string;
                return(new Uri(uri));
            }

            if (name.Equals(CloudEventAttributes.DataContentTypeAttributeName(specVersion)))
            {
                var s = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(string)) as string;
                return(new ContentType(s));
            }

            if (extensions != null)
            {
                foreach (var extension in extensions)
                {
                    Type type = extension.GetAttributeType(name);
                    if (type != null)
                    {
                        return(JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), type));
                    }
                }
            }
            return(JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data)));
        }
Example #14
0
        static string UrlEncodeAttributeAsHeaderValue(string key, object attributeValue,
                                                      CloudEventsSpecVersion specVersion, IEnumerable <ICloudEventExtension> extensions)
        {
            return(WebUtility.UrlEncode(ConvertToString()));

            string ConvertToString()
            {
                switch (attributeValue)
                {
                case string text: return(text);

                case DateTime dateTime: return(dateTime.ToString("u"));

                case Uri uri: return(uri.ToString());

                case int integer: return(integer.ToString(CultureInfo.InvariantCulture));

                default:
                    byte[] binaryValue = jsonFormatter.EncodeAttribute(specVersion, key, attributeValue, extensions);
                    return(Encoding.UTF8.GetString(binaryValue));
                }
            };
        }
Example #15
0
        public CloudEvent DecodeJObject(JObject jObject, IEnumerable <ICloudEventExtension> extensions = null)
        {
            CloudEventsSpecVersion specVersion = CloudEventsSpecVersion.Default;

            if (jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1)) ||
                jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1).ToLowerInvariant()))
            {
                specVersion = CloudEventsSpecVersion.V0_1;
            }
            if (jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2)) ||
                jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2).ToLowerInvariant()))
            {
                specVersion =
                    ((string)jObject[CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2)] ==
                     "0.2")
                        ? CloudEventsSpecVersion.V0_2 :
                    ((string)jObject[CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_3)] ==
                     "0.3")
                            ? CloudEventsSpecVersion.V0_3 : CloudEventsSpecVersion.Default;
            }

            var cloudEvent = new CloudEvent(specVersion, extensions);
            var attributes = cloudEvent.GetAttributes();

            foreach (var keyValuePair in jObject)
            {
                // skip the version since we set that above
                if (keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1), StringComparison.InvariantCultureIgnoreCase) ||
                    keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2), StringComparison.InvariantCultureIgnoreCase) ||
                    keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V1_0), StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }

                if (specVersion == CloudEventsSpecVersion.V1_0)
                {
                    // handle base64 encoded binaries
                    if (keyValuePair.Key.Equals("data_base64"))
                    {
                        attributes["data"] = Convert.FromBase64String(keyValuePair.Value.ToString());
                        continue;
                    }
                }

                switch (keyValuePair.Value.Type)
                {
                case JTokenType.String:
                    attributes[keyValuePair.Key] = keyValuePair.Value.ToObject <string>();
                    break;

                case JTokenType.Date:
                    attributes[keyValuePair.Key] = keyValuePair.Value.ToObject <DateTime>();
                    break;

                case JTokenType.Uri:
                    attributes[keyValuePair.Key] = keyValuePair.Value.ToObject <Uri>();
                    break;

                case JTokenType.Null:
                    attributes[keyValuePair.Key] = null;
                    break;

                case JTokenType.Integer:
                    attributes[keyValuePair.Key] = keyValuePair.Value.ToObject <int>();
                    break;

                default:
                    attributes[keyValuePair.Key] = (dynamic)keyValuePair.Value;
                    break;
                }
            }

            return(cloudEvent);
        }
 public byte[] EncodeAttribute(CloudEventsSpecVersion specVersion, string name, object value, IEnumerable <ICloudEventExtension> extensions = null)
 {
     throw new NotSupportedException("Encoding invidual attributes is not supported for Apache Avro");
 }
Example #17
0
 /// <summary>
 /// Creates a new instance, using the specified <see cref="CloudEventsSpecVersion"/>
 /// and no initial extension attributes.
 /// </summary>
 /// <param name="specVersion">CloudEvents Specification version for this instance. Must not be null.</param>
 public CloudEvent(CloudEventsSpecVersion specVersion) : this(specVersion, null)
 {
 }
        /// <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);
            }
        }
Example #19
0
 /// <summary>
 /// Create a new CloudEvent instance.
 /// </summary>
 /// <param name="specVersion">CloudEvents specification version</param>
 /// <param name="type">'type' of the CloudEvent</param>
 /// <param name="source">'source' of the CloudEvent</param>
 /// <param name="subject">'subject' of the CloudEvent</param>
 /// <param name="id">'id' of the CloudEvent</param>
 /// <param name="time">'time' of the CloudEvent</param>
 /// <param name="extensions">Extensions to be added to this CloudEvents</param>
 public CloudEvent(CloudEventsSpecVersion specVersion, string type, Uri source, string subject, string id = null, DateTime?time = null,
                   params ICloudEventExtension[] extensions) : this(specVersion, type, source, id, time, extensions)
 {
     Subject = subject;
 }
 public static string IdAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
 {
     return(version == CloudEventsSpecVersion.V0_1 ? "eventID" : "id");
 }
 public static string SchemaUrlAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
 {
     return(version == CloudEventsSpecVersion.V0_1 ? "schemaUrl" : "schemaurl");
 }
 public static string DataContentTypeAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
 {
     return(version == CloudEventsSpecVersion.V0_1 ? "contentType" :
            (version == CloudEventsSpecVersion.V0_2 ? "contenttype" : "datacontenttype"));
 }
Example #23
0
        /// <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);
            }
        }
 public static string SpecVersionAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
 {
     return(version == CloudEventsSpecVersion.V0_1 ? "cloudEventsVersion" : "specversion");
 }
 public static string SourceAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
 {
     return("source");
 }
 public static string DataSchemaAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
 {
     return(version == CloudEventsSpecVersion.V0_1 ? "schemaUrl" :
            (version == CloudEventsSpecVersion.V0_2 || version == CloudEventsSpecVersion.V0_3 ? "schemaurl" : "dataschema"));
 }
 public static string SubjectAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
 {
     return("subject");
 }
 public static string DataAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
 {
     return("data");
 }
Example #29
0
        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);
            }
        }
 public static string TypeAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
 {
     return(version == CloudEventsSpecVersion.V0_1 ? "eventType" : "type");
 }