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))); } } } }
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); }
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); } } }
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(); }
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]); } } }
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 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); } }