static void MapAttributesToWebRequest(CloudEvent cloudEvent, HttpWebRequest httpWebRequest)
 {
     foreach (var attribute in cloudEvent.GetAttributes())
     {
         if (!attribute.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) &&
             !attribute.Key.Equals(CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion)))
         {
             if (attribute.Value is string)
             {
                 httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key, attribute.Value.ToString());
             }
             else if (attribute.Value is DateTime)
             {
                 httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key,
                                            ((DateTime)attribute.Value).ToString("u"));
             }
             else if (attribute.Value is Uri || attribute.Value is int)
             {
                 httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key, attribute.Value.ToString());
             }
             else
             {
                 httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key,
                                            Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(cloudEvent.SpecVersion, attribute.Key,
                                                                                                  attribute.Value,
                                                                                                  cloudEvent.Extensions.Values)));
             }
         }
     }
 }
Example #2
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 #3
0
 void MapHeaders(CloudEvent cloudEvent)
 {
     foreach (var attribute in cloudEvent.GetAttributes())
     {
         if (!(attribute.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) ||
               attribute.Key.Equals(CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion))))
         {
             if (attribute.Value is string)
             {
                 Headers.Add("ce-" + attribute.Key, WebUtility.UrlEncode(attribute.Value.ToString()));
             }
             else if (attribute.Value is DateTime)
             {
                 Headers.Add("ce-" + attribute.Key, ((DateTime)attribute.Value).ToString("u"));
             }
             else if (attribute.Value is Uri || attribute.Value is int)
             {
                 Headers.Add("ce-" + attribute.Key, attribute.Value.ToString());
             }
             else
             {
                 Headers.Add("ce-" + attribute.Key,
                             WebUtility.UrlEncode(
                                 Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(cloudEvent.SpecVersion, attribute.Key, attribute.Value,
                                                                                       cloudEvent.Extensions.Values))));
             }
         }
     }
 }
        public byte[] EncodeStructuredEvent(CloudEvent cloudEvent, out ContentType contentType)
        {
            contentType = new ContentType("application/cloudevents+json")
            {
                CharSet = Encoding.UTF8.WebName
            };

            JObject jObject    = new JObject();
            var     attributes = cloudEvent.GetAttributes();

            foreach (var keyValuePair in attributes)
            {
                if (keyValuePair.Value == null)
                {
                    continue;
                }

                if (keyValuePair.Value is ContentType && !string.IsNullOrEmpty(((ContentType)keyValuePair.Value).MediaType))
                {
                    jObject[keyValuePair.Key] = JToken.FromObject(((ContentType)keyValuePair.Value).ToString());
                }
                else
                {
                    jObject[keyValuePair.Key] = JToken.FromObject(keyValuePair.Value);
                }
            }
            return(Encoding.UTF8.GetBytes(jObject.ToString()));
        }
        public byte[] EncodeStructuredEvent(CloudEvent cloudEvent, out ContentType contentType)
        {
            contentType = new ContentType(CloudEvent.MediaType + AvroEventFormatter.MediaTypeSuffix);

            GenericRecord record           = new GenericRecord(avroSchema);
            var           recordAttributes = new Dictionary <string, object>();
            var           attributes       = cloudEvent.GetAttributes();

            foreach (var keyValuePair in attributes)
            {
                if (keyValuePair.Value == null)
                {
                    continue;
                }

                if (keyValuePair.Value is ContentType && !string.IsNullOrEmpty(((ContentType)keyValuePair.Value).MediaType))
                {
                    recordAttributes[keyValuePair.Key] = ((ContentType)keyValuePair.Value).ToString();
                }
                else if (keyValuePair.Value is Uri)
                {
                    recordAttributes[keyValuePair.Key] = ((Uri)keyValuePair.Value).ToString();
                }
                else if (keyValuePair.Value is DateTime)
                {
                    recordAttributes[keyValuePair.Key] = ((DateTime)keyValuePair.Value).ToString("o");
                }
                else if (cloudEvent.SpecVersion == CloudEventsSpecVersion.V1_0 &&
                         keyValuePair.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)))
                {
                    if (keyValuePair.Value is Stream)
                    {
                        using (var sr = new BinaryReader((Stream)keyValuePair.Value))
                        {
                            record.Add("data", sr.ReadBytes((int)sr.BaseStream.Length));
                        }
                    }
                    else
                    {
                        record.Add("data", keyValuePair.Value);
                    }
                }
                else
                {
                    recordAttributes[keyValuePair.Key] = keyValuePair.Value;
                }
            }
            record.Add("attribute", recordAttributes);
            MemoryStream  memStream = new MemoryStream();
            BinaryEncoder encoder   = new BinaryEncoder(memStream);

            avroWriter.Write(record, encoder);
            return(new Span <byte>(memStream.GetBuffer(), 0, (int)memStream.Length).ToArray());
        }
 static void MapAttributesToWebRequest(CloudEvent cloudEvent, HttpWebRequest httpWebRequest)
 {
     foreach (var attribute in cloudEvent.GetAttributes())
     {
         if (!attribute.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) &&
             !attribute.Key.Equals(CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion)))
         {
             string headerValue = UrlEncodeAttributeAsHeaderValue(
                 attribute.Key, attribute.Value, cloudEvent.SpecVersion, cloudEvent.Extensions.Values);
             httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key, headerValue);
         }
     }
 }
Example #7
0
        public byte[] EncodeStructuredEvent(CloudEvent cloudEvent, out ContentType contentType)
        {
            contentType = new ContentType("application/cloudevents+json")
            {
                CharSet = Encoding.UTF8.WebName
            };

            JObject jObject    = new JObject();
            var     attributes = cloudEvent.GetAttributes();

            foreach (var keyValuePair in attributes)
            {
                if (keyValuePair.Value == null)
                {
                    continue;
                }

                if (keyValuePair.Value is ContentType && !string.IsNullOrEmpty(((ContentType)keyValuePair.Value).MediaType))
                {
                    jObject[keyValuePair.Key] = JToken.FromObject(((ContentType)keyValuePair.Value).ToString());
                }
                else if (cloudEvent.SpecVersion == CloudEventsSpecVersion.V1_0 &&
                         keyValuePair.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)))
                {
                    if (keyValuePair.Value is Stream)
                    {
                        using (var sr = new BinaryReader((Stream)keyValuePair.Value))
                        {
                            jObject["data_base64"] = Convert.ToBase64String(sr.ReadBytes((int)sr.BaseStream.Length));
                        }
                    }
                    else if (keyValuePair.Value is IEnumerable <byte> )
                    {
                        jObject["data_base64"] =
                            Convert.ToBase64String(((IEnumerable <byte>)keyValuePair.Value).ToArray());
                    }
                    else
                    {
                        jObject["data"] = JToken.FromObject(keyValuePair.Value);
                    }
                }
                else
                {
                    jObject[keyValuePair.Key] = JToken.FromObject(keyValuePair.Value);
                }
            }
            return(Encoding.UTF8.GetBytes(jObject.ToString()));
        }
        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);
        }
        public byte[] EncodeStructuredEvent(CloudEvent cloudEvent, out ContentType contentType)
        {
            contentType = new ContentType(CloudEvent.MediaType + AvroEventFormatter.MediaTypeSuffix);

            GenericRecord record           = new GenericRecord(avroSchema);
            var           recordAttributes = new Dictionary <string, object>();
            var           attributes       = cloudEvent.GetAttributes();

            foreach (var keyValuePair in attributes)
            {
                if (keyValuePair.Value == null)
                {
                    continue;
                }

                if (keyValuePair.Value is ContentType valueContentType && !string.IsNullOrEmpty(valueContentType.MediaType))
                {
                    recordAttributes[keyValuePair.Key] = valueContentType.ToString();
                }
Example #10
0
        void MapHeaders(CloudEvent cloudEvent, bool includeDataContentType)
        {
            string specVersionAttributeName     = CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion);
            string dataContentTypeAttributeName = CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion);

            foreach (var attribute in cloudEvent.GetAttributes())
            {
                string key        = attribute.Key;
                string headerName = "ce-" + key;
                object value      = attribute.Value;

                // Never map the spec attribute to a header
                if (key == specVersionAttributeName)
                {
                    continue;
                }
                // Only map the data content type attribute to a header if we've been asked to
                else if (key == dataContentTypeAttributeName && !includeDataContentType)
                {
                    continue;
                }
                else
                {
                    string headerValue = attribute.Value switch
                    {
                        string text => WebUtility.UrlEncode(text),
                        ContentType contentType => contentType.ToString(),
                        DateTime dt => XmlConvert.ToString(dt, XmlDateTimeSerializationMode.Utc),
                        Uri uri => uri.ToString(),
                        int integer => integer.ToString(),
                        _ => WebUtility.UrlEncode(Encoding.UTF8.GetString(
                                                      jsonFormatter.EncodeAttribute(cloudEvent.SpecVersion, key, value, cloudEvent.Extensions.Values)))
                    };
                    Headers.Add(headerName, headerValue);
                }
            }
        }
        public async Task SetsTraceParentExtension(bool inclTraceparent, bool inclTracestate)
        {
            var mockTransport = new MockTransport(new MockResponse(200));
            var options       = new EventGridPublisherClientOptions
            {
                Transport = mockTransport
            };
            EventGridPublisherClient client =
                new EventGridPublisherClient(
                    new Uri("http://localHost"),
                    new AzureKeyCredential("fakeKey"),
                    options);
            var activity = new Activity($"{nameof(EventGridPublisherClient)}.{nameof(EventGridPublisherClient.SendEvents)}");

            activity.SetW3CFormat();
            activity.Start();
            List <CloudEvent> eventsList = new List <CloudEvent>();

            for (int i = 0; i < 10; i++)
            {
                var cloudEvent =
                    new CloudEvent(
                        "record",
                        new Uri("http://localHost"),
                        Guid.NewGuid().ToString(),
                        DateTime.Now);

                if (inclTraceparent && inclTracestate && i % 2 == 0)
                {
                    cloudEvent.GetAttributes().Add("traceparent", "traceparentValue");
                }
                if (inclTracestate && i % 2 == 0)
                {
                    cloudEvent.GetAttributes().Add("tracestate", "param:value");
                }
                eventsList.Add(cloudEvent);
            }
            await client.SendCloudEventsAsync(eventsList);

            activity.Stop();
            List <CloudEvent>        cloudEvents = DeserializeRequest(mockTransport.SingleRequest);
            IEnumerator <CloudEvent> cloudEnum   = eventsList.GetEnumerator();

            foreach (CloudEvent cloudEvent in cloudEvents)
            {
                cloudEnum.MoveNext();
                IDictionary <string, object> cloudEventAttr = cloudEnum.Current.GetAttributes();
                if (cloudEventAttr.ContainsKey(TraceParentHeaderName) &&
                    cloudEventAttr.ContainsKey(TraceStateHeaderName))
                {
                    Assert.AreEqual(
                        cloudEventAttr[TraceParentHeaderName],
                        cloudEvent.GetAttributes()[TraceParentHeaderName]);

                    Assert.AreEqual(
                        cloudEventAttr[TraceStateHeaderName],
                        cloudEvent.GetAttributes()[TraceStateHeaderName]);
                }
                else if (cloudEventAttr.ContainsKey(TraceParentHeaderName))
                {
                    Assert.AreEqual(
                        cloudEventAttr[TraceParentHeaderName],
                        cloudEvent.GetAttributes()[TraceParentHeaderName]);
                }
                else if (cloudEventAttr.ContainsKey(TraceStateHeaderName))
                {
                    Assert.AreEqual(
                        cloudEventAttr[TraceStateHeaderName],
                        cloudEvent.GetAttributes()[TraceStateHeaderName]);
                }
                else
                {
                    Assert.AreEqual(
                        activity.Id,
                        cloudEvent.GetAttributes()[TraceParentHeaderName]);
                }
            }
        }
Example #12
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);
            }
        }
Example #13
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);
            }
        }
        /// <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 #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);
        }
        /// <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"></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 = null,
                                                                       params ICloudEventExtension[] extensions)
        {
            if (httpRequest.ContentType != null &&
                httpRequest.ContentType.StartsWith(CloudEvent.MediaType,
                                                   StringComparison.InvariantCultureIgnoreCase))
            {
                // handle structured mode
                if (formatter == null)
                {
                    // if we didn't get a formatter, pick one
                    var contentType = httpRequest.ContentType.Split(';')[0].Trim();
                    if (contentType.EndsWith(JsonEventFormatter.MediaTypeSuffix,
                                             StringComparison.InvariantCultureIgnoreCase))
                    {
                        formatter = jsonFormatter;
                    }
                    else
                    {
                        throw new InvalidOperationException("Unsupported CloudEvents encoding");
                    }
                }

                return(await formatter.DecodeStructuredEventAsync(httpRequest.Body, extensions));
            }
            else
            {
                CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
                if (httpRequest.Headers[SpecVersionHttpHeader1] != StringValues.Empty)
                {
                    version = CloudEventsSpecVersion.V0_1;
                }

                if (httpRequest.Headers[SpecVersionHttpHeader2] != StringValues.Empty)
                {
                    switch (httpRequest.Headers[SpecVersionHttpHeader2])
                    {
                    case "0.2":
                        version = CloudEventsSpecVersion.V0_2;
                        break;

                    case "0.3":
                        version = CloudEventsSpecVersion.V0_3;
                        break;

                    default:
                        version = CloudEventsSpecVersion.Default;
                        break;
                    }
                }

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

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

                cloudEvent.DataContentType = httpRequest.ContentType != null
                    ? new ContentType(httpRequest.ContentType)
                    : null;
                cloudEvent.Data = await new StreamReader(httpRequest.Body, Encoding.UTF8).ReadToEndAsync();
                return(cloudEvent);
            }
        }