public byte[] GetBytes(CloudEvent cEvent) { byte[] cEventBytes = null; ContentType formatterContentType; if (cEvent != null) { try { cEventBytes = _cEventsFormatter.EncodeStructuredEvent(cEvent, out formatterContentType); // no async // info _logger.LogInformation($"GetBytes: generated {cEventBytes.Length} bytes with formatter content type {formatterContentType.MediaType}"); // debug/ max verbosity _logger.LogDebug($"GetBytes: CloudEvent with envelope and full content {Environment.NewLine}{Encoding.UTF8.GetString(cEventBytes)}"); } catch (Exception ex) { // err _logger.LogError($"GetBytes: failed with exception '{ex.Message}', of type '{ex.GetType().Name}'"); throw new CloudEventWriterException("GetBytes", ex); } } else { // warn _logger.LogWarning("GetBytes: specified CloudEvent is empty"); } return(cEventBytes); }
/// <summary> /// Executes the function with the specified CloudEvent, which is converted /// to an HTTP POST request using structured encoding. This method asserts that the /// request completed successfully. /// </summary> public async Task ExecuteCloudEventRequestAsync(CloudEvent cloudEvent) { var bytes = s_eventFormatter.EncodeStructuredEvent(cloudEvent, out var contentType); contentType ??= s_applicationJsonContentType; var mediaContentType = new MediaTypeHeaderValue(contentType.MediaType) { CharSet = contentType.CharSet }; var request = new HttpRequestMessage { // Any URI RequestUri = new Uri("uri", UriKind.Relative), // CloudEvent headers Content = new ByteArrayContent(bytes) { Headers = { ContentType = mediaContentType } }, Method = HttpMethod.Post }; using var client = Server.CreateClient(); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); }
/// <summary> /// Constructor /// </summary> /// <param name="cloudEvent">CloudEvent</param> /// <param name="contentMode">Content mode. Structured or binary.</param> /// <param name="formatter">Event formatter</param> public CloudEventContent(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { if (contentMode == ContentMode.Structured) { inner = new InnerByteArrayContent(formatter.EncodeStructuredEvent(cloudEvent, out var contentType)); Headers.ContentType = new MediaTypeHeaderValue(contentType.MediaType); MapHeaders(cloudEvent); return; } if (cloudEvent.Data is byte[]) { inner = new InnerByteArrayContent((byte[])cloudEvent.Data); } else if (cloudEvent.Data is string) { inner = new InnerStringContent((string)cloudEvent.Data); } else if (cloudEvent.Data is Stream) { inner = new InnerStreamContent((Stream)cloudEvent.Data); } else { inner = new InnerByteArrayContent(formatter.EncodeAttribute(cloudEvent.SpecVersion, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion), cloudEvent.Data, cloudEvent.Extensions.Values)); } Headers.ContentType = new MediaTypeHeaderValue(cloudEvent.DataContentType?.MediaType); MapHeaders(cloudEvent); }
public AmqpCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { ApplicationProperties = new ApplicationProperties(); MapHeaders(cloudEvent); if (contentMode == ContentMode.Structured) { BodySection = new Data { Binary = formatter.EncodeStructuredEvent(cloudEvent, out var contentType) }; Properties = new Properties { ContentType = contentType.MediaType }; ApplicationProperties = new ApplicationProperties(); MapHeaders(cloudEvent); return; } else { BodySection = SerializeData(cloudEvent.Data); Properties = new Properties { ContentType = cloudEvent.DataContentType }; } }
/// <summary> /// Constructor /// </summary> /// <param name="cloudEvent">CloudEvent</param> /// <param name="contentMode">Content mode. Structured or binary.</param> /// <param name="formatter">Event formatter</param> public CloudEventContent(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { if (contentMode == ContentMode.Structured) { inner = new InnerByteArrayContent(formatter.EncodeStructuredEvent(cloudEvent, out var contentType)); // This is optional in the specification, but can be useful. MapHeaders(cloudEvent, includeDataContentType: true); Headers.ContentType = new MediaTypeHeaderValue(contentType.MediaType); return; } if (cloudEvent.Data is byte[]) { inner = new InnerByteArrayContent((byte[])cloudEvent.Data); } else if (cloudEvent.Data is string) { inner = new InnerStringContent((string)cloudEvent.Data); } else if (cloudEvent.Data is Stream) { inner = new InnerStreamContent((Stream)cloudEvent.Data); } else { inner = new InnerByteArrayContent(formatter.EncodeAttribute(cloudEvent.SpecVersion, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion), cloudEvent.Data, cloudEvent.Extensions.Values)); } var mediaType = cloudEvent.DataContentType?.MediaType ?? throw new ArgumentException(Strings.ErrorContentTypeUnspecified, nameof(cloudEvent)); Headers.ContentType = new MediaTypeHeaderValue(mediaType); MapHeaders(cloudEvent, includeDataContentType: false); }
public KafkaCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { // TODO: Is this appropriate? Why can't we transport a CloudEvent without data in Kafka? if (cloudEvent.Data == null) { throw new ArgumentNullException(nameof(cloudEvent.Data)); } Headers = new Headers { { SpecVersionKafkaHeader, Encoding.UTF8.GetBytes(cloudEvent.SpecVersion.VersionId) } }; Key = (string)cloudEvent[Partitioning.PartitionKeyAttribute]; if (contentMode == ContentMode.Structured) { Value = formatter.EncodeStructuredEvent(cloudEvent, out var contentType); Headers.Add(KafkaContentTypeAttributeName, Encoding.UTF8.GetBytes(contentType.MediaType)); } else { if (cloudEvent.Data is byte[] byteData) { Value = byteData; } else if (cloudEvent.Data is Stream dataStream) { // TODO: Extract this common code somewhere if (dataStream is MemoryStream dataMemoryStream) { Value = dataMemoryStream.ToArray(); } else { var buffer = new MemoryStream(); dataStream.CopyTo(buffer); Value = buffer.ToArray(); } } else { throw new InvalidOperationException($"{cloudEvent.Data.GetType()} type is not supported for Cloud Event's Value."); } if (cloudEvent.DataContentType is string dataContentType) { Headers.Add(KafkaContentTypeAttributeName, Encoding.UTF8.GetBytes(dataContentType)); } } MapHeaders(cloudEvent, formatter); }
/// <summary> /// Constructor /// </summary> /// <param name="cloudEvent">CloudEvent</param> /// <param name="contentMode">Content mode. Structured or binary.</param> /// <param name="formatter">Event formatter</param> public CloudEventHttpContent(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { if (contentMode == ContentMode.Structured) { inner = new InnerByteArrayContent(formatter.EncodeStructuredEvent(cloudEvent, out var contentType)); // This is optional in the specification, but can be useful. MapHeaders(cloudEvent, includeDataContentType: true); Headers.ContentType = new MediaTypeHeaderValue(contentType.MediaType); return; } // TODO: Shouldn't we use the formatter in all cases? If I have a JSON formatter and // If we specify that the the data is a byte array, I'd expect to end up with a base64-encoded representation... if (cloudEvent.Data is byte[]) { inner = new InnerByteArrayContent((byte[])cloudEvent.Data); } else if (cloudEvent.Data is string) { inner = new InnerStringContent((string)cloudEvent.Data); } else if (cloudEvent.Data is Stream) { inner = new InnerStreamContent((Stream)cloudEvent.Data); } else { inner = new InnerByteArrayContent(formatter.EncodeData(cloudEvent.Data)); } // We don't require a data content type if there isn't any data. // We may not be able to tell whether the data is empty or not, but we're lenient // in that case. var dataContentType = cloudEvent.DataContentType; if (dataContentType is object) { var mediaType = new ContentType(dataContentType).MediaType; Headers.ContentType = new MediaTypeHeaderValue(mediaType); } else if (TryComputeLength(out var length) && length != 0L) { throw new ArgumentException(Strings.ErrorContentTypeUnspecified, nameof(cloudEvent)); } MapHeaders(cloudEvent, includeDataContentType: false); }
public ServiceBusCloudEventMessage(CloudEvent cloudEvent, ICloudEventFormatter formatter) { if (cloudEvent == null) { throw new ArgumentNullException(nameof(cloudEvent)); } if (formatter == null) { throw new ArgumentNullException(nameof(formatter)); } Body = formatter.EncodeStructuredEvent(cloudEvent, out var contentType); ContentType = contentType.MediaType; MessageId = cloudEvent.Id; MapHeaders(cloudEvent); }
public KafkaCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { if (cloudEvent.Data == null) { throw new ArgumentNullException(nameof(cloudEvent.Data)); } Headers = new Headers(); Key = ExtractPartitionKey(cloudEvent); if (contentMode == ContentMode.Structured) { Value = formatter.EncodeStructuredEvent(cloudEvent, out var contentType); Headers.Add(KafkaContentTypeAttributeName, Encoding.UTF8.GetBytes(contentType.MediaType)); } else { if (cloudEvent.Data is byte[] byteData) { Value = byteData; } else if (cloudEvent.Data is Stream dataStream) { if (dataStream is MemoryStream dataMemoryStream) { Value = dataMemoryStream.ToArray(); } else { var buffer = new MemoryStream(); dataStream.CopyTo(buffer); Value = buffer.ToArray(); } } else { throw new InvalidOperationException($"{cloudEvent.Data.GetType()} type is not supported for Cloud Event's Value."); } Headers.Add(KafkaContentTypeAttributeName, Encoding.UTF8.GetBytes(cloudEvent.DataContentType?.MediaType)); } MapHeaders(cloudEvent, formatter); }
/// <summary> /// Copies the CloudEvent into this HttpListenerResponse instance /// </summary> /// <param name="httpListenerResponse">this</param> /// <param name="cloudEvent">CloudEvent to copy</param> /// <param name="contentMode">Content mode (structured or binary)</param> /// <param name="formatter">Formatter</param> /// <returns>Task</returns> public static Task CopyFromAsync(this HttpListenerResponse httpListenerResponse, CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { if (contentMode == ContentMode.Structured) { var buffer = formatter.EncodeStructuredEvent(cloudEvent, out var contentType); httpListenerResponse.ContentType = contentType.ToString(); MapAttributesToListenerResponse(cloudEvent, httpListenerResponse); return(httpListenerResponse.OutputStream.WriteAsync(buffer, 0, buffer.Length)); } Stream stream = MapDataAttributeToStream(cloudEvent, formatter); httpListenerResponse.ContentType = cloudEvent.DataContentType.ToString(); MapAttributesToListenerResponse(cloudEvent, httpListenerResponse); return(stream.CopyToAsync(httpListenerResponse.OutputStream)); }
// TODO: Check the pattern here. I suspect that cloudEvent.CopyToAsync(response) would be more natural. /// <summary> /// Copies the CloudEvent into this HttpListenerResponse instance /// </summary> /// <param name="httpListenerResponse">this</param> /// <param name="cloudEvent">CloudEvent to copy</param> /// <param name="contentMode">Content mode (structured or binary)</param> /// <param name="formatter">Formatter</param> /// <returns>Task</returns> public static Task CopyFromAsync(this HttpListenerResponse httpListenerResponse, CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { if (contentMode == ContentMode.Structured) { var buffer = formatter.EncodeStructuredEvent(cloudEvent, out var contentType); httpListenerResponse.ContentType = contentType.ToString(); MapAttributesToListenerResponse(cloudEvent, httpListenerResponse); return(httpListenerResponse.OutputStream.WriteAsync(buffer, 0, buffer.Length)); } Stream stream = HttpUtilities.MapDataAttributeToStream(cloudEvent, formatter); // TODO: Check the defaulting to JSON here... httpListenerResponse.ContentType = cloudEvent.DataContentType?.ToString() ?? "application/json"; MapAttributesToListenerResponse(cloudEvent, httpListenerResponse); return(stream.CopyToAsync(httpListenerResponse.OutputStream)); }
/// <summary> /// Copies the CloudEvent into this HttpWebRequest instance /// </summary> /// <param name="httpWebRequest">this</param> /// <param name="cloudEvent">CloudEvent to copy</param> /// <param name="contentMode">Content mode (structured or binary)</param> /// <param name="formatter">Formatter</param> /// <returns>Task</returns> public static async Task CopyFromAsync(this HttpWebRequest httpWebRequest, CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { if (contentMode == ContentMode.Structured) { var buffer = formatter.EncodeStructuredEvent(cloudEvent, out var contentType); httpWebRequest.ContentType = contentType.ToString(); await(httpWebRequest.GetRequestStream()).WriteAsync(buffer, 0, buffer.Length); return; } Stream stream = MapDataAttributeToStream(cloudEvent, formatter); httpWebRequest.ContentType = cloudEvent.DataContentType?.ToString() ?? "application/json"; MapAttributesToWebRequest(cloudEvent, httpWebRequest); await stream.CopyToAsync(httpWebRequest.GetRequestStream()); }
public MqttCloudEventMessage(CloudEvent cloudEvent, ICloudEventFormatter formatter) { this.Payload = formatter.EncodeStructuredEvent(cloudEvent, out var contentType); }
public AmqpCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { if (contentMode == ContentMode.Structured) { this.BodySection = new Data { Binary = formatter.EncodeStructuredEvent(cloudEvent, out var contentType) }; this.Properties = new Properties() { ContentType = contentType.MediaType }; this.ApplicationProperties = new ApplicationProperties(); MapHeaders(cloudEvent); return; } if (cloudEvent.Data is byte[]) { this.BodySection = new Data { Binary = (byte[])cloudEvent.Data }; } else if (cloudEvent.Data is Stream) { if (cloudEvent.Data is MemoryStream) { this.BodySection = new Data { Binary = ((MemoryStream)cloudEvent.Data).ToArray() }; } else { var buffer = new MemoryStream(); ((Stream)cloudEvent.Data).CopyTo(buffer); this.BodySection = new Data { Binary = buffer.ToArray() }; } } else if (cloudEvent.Data is string) { this.BodySection = new AmqpValue() { Value = cloudEvent.Data }; } this.Properties = new Properties() { ContentType = cloudEvent.DataContentType?.MediaType }; this.ApplicationProperties = new ApplicationProperties(); MapHeaders(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 Uri) { this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, attribute.Value.ToString()); } else if (attribute.Value is DateTime || attribute.Value is DateTime || attribute.Value is string) { this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, attribute.Value); } else { Map dict = new Map(); foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(attribute.Value)) { dict.Add(descriptor.Name, descriptor.GetValue(attribute.Value)); } this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, dict); } } } } }
public AmqpCloudEventMessage(CloudEvent cloudEvent, ContentMode contentMode, ICloudEventFormatter formatter) { if (contentMode == ContentMode.Structured) { this.BodySection = new Data { Binary = formatter.EncodeStructuredEvent(cloudEvent, out var contentType) }; this.Properties = new Properties() { ContentType = contentType.MediaType }; this.ApplicationProperties = new ApplicationProperties(); MapHeaders(cloudEvent); return; } if (cloudEvent.Data is byte[]) { this.BodySection = new Data { Binary = (byte[])cloudEvent.Data }; } else if (cloudEvent.Data is Stream) { if (cloudEvent.Data is MemoryStream) { this.BodySection = new Data { Binary = ((MemoryStream)cloudEvent.Data).ToArray() }; } else { var buffer = new MemoryStream(); ((Stream)cloudEvent.Data).CopyTo(buffer); this.BodySection = new Data { Binary = buffer.ToArray() }; } } else if (cloudEvent.Data is string) { this.BodySection = new AmqpValue() { Value = cloudEvent.Data }; } this.Properties = new Properties() { ContentType = cloudEvent.DataContentType?.MediaType }; this.ApplicationProperties = new ApplicationProperties(); MapHeaders(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))) { string key = "cloudEvents:" + attribute.Key; if (attribute.Value is Uri) { this.ApplicationProperties.Map.Add(key, attribute.Value.ToString()); } else if (attribute.Value is DateTimeOffset dto) { // AMQPNetLite doesn't support DateTimeOffset values, so convert to UTC. // That means we can't roundtrip events with non-UTC timestamps, but that's not awful. this.ApplicationProperties.Map.Add(key, dto.UtcDateTime); } else if (attribute.Value is string) { this.ApplicationProperties.Map.Add(key, attribute.Value); } else { Map dict = new Map(); foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(attribute.Value)) { dict.Add(descriptor.Name, descriptor.GetValue(attribute.Value)); } this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, dict); } } } } }