Merge pull request #4 from clemensv/master

Versioning support for 0.1 and 0.2
This commit is contained in:
Clemens Vasters 2018-11-28 14:06:24 +01:00 committed by GitHub
commit 51ea22ed49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 618 additions and 316 deletions

View File

@ -9,7 +9,6 @@ namespace CloudNative.CloudEvents.Amqp
using System.Dynamic; using System.Dynamic;
using System.IO; using System.IO;
using System.Net.Mime; using System.Net.Mime;
using System.Threading.Tasks;
using global::Amqp; using global::Amqp;
using global::Amqp.Types; using global::Amqp.Types;
@ -17,7 +16,9 @@ namespace CloudNative.CloudEvents.Amqp
{ {
const string AmqpHeaderPrefix = "cloudEvents:"; const string AmqpHeaderPrefix = "cloudEvents:";
const string SpecVersionAmqpHeader = AmqpHeaderPrefix + "specversion"; const string SpecVersionAmqpHeader1 = AmqpHeaderPrefix + "cloudEventsVersion";
const string SpecVersionAmqpHeader2 = AmqpHeaderPrefix + "specversion";
static JsonEventFormatter jsonFormatter = new JsonEventFormatter(); static JsonEventFormatter jsonFormatter = new JsonEventFormatter();
@ -25,7 +26,8 @@ namespace CloudNative.CloudEvents.Amqp
{ {
return ((message.Properties.ContentType != null && return ((message.Properties.ContentType != null &&
message.Properties.ContentType.ToString().StartsWith(CloudEvent.MediaType)) || message.Properties.ContentType.ToString().StartsWith(CloudEvent.MediaType)) ||
message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader)); message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader1) ||
message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader2));
} }
public static CloudEvent ToCloudEvent(this Message message, public static CloudEvent ToCloudEvent(this Message message,
@ -61,7 +63,14 @@ namespace CloudNative.CloudEvents.Amqp
} }
else else
{ {
var cloudEvent = new CloudEvent(extensions); var cloudEvent = new CloudEvent(
message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader1)
? CloudEventsSpecVersion.V0_1
: message.ApplicationProperties.Map.ContainsKey(SpecVersionAmqpHeader2)
? (message.ApplicationProperties.Map[SpecVersionAmqpHeader2] as string == "0.2"
? CloudEventsSpecVersion.V0_2
: CloudEventsSpecVersion.Default)
: CloudEventsSpecVersion.Default, extensions);
var attributes = cloudEvent.GetAttributes(); var attributes = cloudEvent.GetAttributes();
foreach (var prop in message.ApplicationProperties.Map) foreach (var prop in message.ApplicationProperties.Map)
{ {
@ -75,13 +84,14 @@ namespace CloudNative.CloudEvents.Amqp
{ {
exp[props.Key.ToString()] = props.Value; exp[props.Key.ToString()] = props.Value;
} }
attributes[((string)prop.Key).Substring(AmqpHeaderPrefix.Length).ToLowerInvariant()] = attributes[((string)prop.Key).Substring(AmqpHeaderPrefix.Length).ToLowerInvariant()] =
exp; exp;
} }
else else
{ {
attributes[((string)prop.Key).Substring(AmqpHeaderPrefix.Length).ToLowerInvariant()] = attributes[((string)prop.Key).Substring(AmqpHeaderPrefix.Length).ToLowerInvariant()] =
prop.Value; prop.Value;
} }
} }
} }

View File

@ -5,7 +5,6 @@
namespace CloudNative.CloudEvents.Amqp namespace CloudNative.CloudEvents.Amqp
{ {
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.IO; using System.IO;
using global::Amqp; using global::Amqp;
@ -19,7 +18,7 @@ namespace CloudNative.CloudEvents.Amqp
if (contentMode == ContentMode.Structured) if (contentMode == ContentMode.Structured)
{ {
this.BodySection = new Data this.BodySection = new Data
{ Binary = formatter.EncodeStructuredEvent(cloudEvent, out var contentType) }; { Binary = formatter.EncodeStructuredEvent(cloudEvent, out var contentType) };
this.Properties = new Properties() { ContentType = contentType.MediaType }; this.Properties = new Properties() { ContentType = contentType.MediaType };
this.ApplicationProperties = new ApplicationProperties(); this.ApplicationProperties = new ApplicationProperties();
MapHeaders(cloudEvent); MapHeaders(cloudEvent);
@ -57,32 +56,28 @@ namespace CloudNative.CloudEvents.Amqp
{ {
foreach (var attribute in cloudEvent.GetAttributes()) foreach (var attribute in cloudEvent.GetAttributes())
{ {
switch (attribute.Key) if (!attribute.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) &&
!attribute.Key.Equals(CloudEventAttributes.ContentTypeAttributeName(cloudEvent.SpecVersion)))
{ {
case CloudEventAttributes.DataAttributeName: if (attribute.Value is Uri)
case CloudEventAttributes.ContentTypeAttributeName: {
break; this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, attribute.Value.ToString());
default: }
if (attribute.Value is Uri) 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))
{ {
this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, attribute.Value.ToString()); dict.Add(descriptor.Name, descriptor.GetValue(attribute.Value));
} }
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);
}
break;
}
this.ApplicationProperties.Map.Add("cloudEvents:" + attribute.Key, dict);
}
}
} }
} }
} }

View File

@ -15,7 +15,7 @@ namespace CloudNative.CloudEvents
{ {
public const string MediaType = "application/cloudevents"; public const string MediaType = "application/cloudevents";
readonly IDictionary<string, object> attributes; readonly CloudEventAttributes attributes;
/// <summary> /// <summary>
/// Create a new CloudEvent instance. /// Create a new CloudEvent instance.
@ -26,7 +26,21 @@ namespace CloudNative.CloudEvents
/// <param name="time">'time' of the CloudEvent</param> /// <param name="time">'time' of the CloudEvent</param>
/// <param name="extensions">Extensions to be added to this CloudEvents</param> /// <param name="extensions">Extensions to be added to this CloudEvents</param>
public CloudEvent(string type, Uri source, string id = null, DateTime? time = null, public CloudEvent(string type, Uri source, string id = null, DateTime? time = null,
params ICloudEventExtension[] extensions) : this(extensions) params ICloudEventExtension[] extensions) : this(CloudEventsSpecVersion.V0_2, type, source, id, time, extensions)
{
}
/// <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; Type = type;
Source = source; Source = source;
@ -37,11 +51,11 @@ namespace CloudNative.CloudEvents
/// <summary> /// <summary>
/// Create a new CloudEvent instance /// Create a new CloudEvent instance
/// </summary> /// </summary>
/// <param name="specVersion">CloudEvents specification version</param>
/// <param name="extensions">Extensions to be added to this CloudEvents</param> /// <param name="extensions">Extensions to be added to this CloudEvents</param>
internal CloudEvent(IEnumerable<ICloudEventExtension> extensions) internal CloudEvent(CloudEventsSpecVersion specVersion, IEnumerable<ICloudEventExtension> extensions)
{ {
attributes = new CloudEventAttributes(extensions); attributes = new CloudEventAttributes(specVersion, extensions);
SpecVersion = "0.2";
this.Extensions = new Dictionary<Type, ICloudEventExtension>(); this.Extensions = new Dictionary<Type, ICloudEventExtension>();
if (extensions != null) if (extensions != null)
{ {
@ -61,8 +75,8 @@ namespace CloudNative.CloudEvents
/// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#contenttype"/> /// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#contenttype"/>
public ContentType ContentType public ContentType ContentType
{ {
get => attributes[CloudEventAttributes.ContentTypeAttributeName] as ContentType; get => attributes[CloudEventAttributes.ContentTypeAttributeName(attributes.SpecVersion)] as ContentType;
set => attributes[CloudEventAttributes.ContentTypeAttributeName] = value; set => attributes[CloudEventAttributes.ContentTypeAttributeName(attributes.SpecVersion)] = value;
} }
/// <summary> /// <summary>
@ -73,8 +87,8 @@ namespace CloudNative.CloudEvents
/// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#data-1"/> /// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#data-1"/>
public object Data public object Data
{ {
get => attributes[CloudEventAttributes.DataAttributeName]; get => attributes[CloudEventAttributes.DataAttributeName(attributes.SpecVersion)];
set => attributes[CloudEventAttributes.DataAttributeName] = value; set => attributes[CloudEventAttributes.DataAttributeName(attributes.SpecVersion)] = value;
} }
/// <summary> /// <summary>
@ -89,8 +103,8 @@ namespace CloudNative.CloudEvents
/// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#id"/> /// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#id"/>
public string Id public string Id
{ {
get => attributes[CloudEventAttributes.IdAttributeName] as string; get => attributes[CloudEventAttributes.IdAttributeName(attributes.SpecVersion)] as string;
set => attributes[CloudEventAttributes.IdAttributeName] = value; set => attributes[CloudEventAttributes.IdAttributeName(attributes.SpecVersion)] = value;
} }
/// <summary> /// <summary>
@ -101,8 +115,8 @@ namespace CloudNative.CloudEvents
/// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#schemaurl"/> /// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#schemaurl"/>
public Uri SchemaUrl public Uri SchemaUrl
{ {
get => attributes[CloudEventAttributes.SchemaUrlAttributeName] as Uri; get => attributes[CloudEventAttributes.SchemaUrlAttributeName(attributes.SpecVersion)] as Uri;
set => attributes[CloudEventAttributes.SchemaUrlAttributeName] = value; set => attributes[CloudEventAttributes.SchemaUrlAttributeName(attributes.SpecVersion)] = value;
} }
/// <summary> /// <summary>
@ -114,8 +128,8 @@ namespace CloudNative.CloudEvents
/// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#source"/> /// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#source"/>
public Uri Source public Uri Source
{ {
get => attributes[CloudEventAttributes.SourceAttributeName] as Uri; get => attributes[CloudEventAttributes.SourceAttributeName(attributes.SpecVersion)] as Uri;
set => attributes[CloudEventAttributes.SourceAttributeName] = value; set => attributes[CloudEventAttributes.SourceAttributeName(attributes.SpecVersion)] = value;
} }
/// <summary> /// <summary>
@ -123,10 +137,10 @@ namespace CloudNative.CloudEvents
/// specification which the event uses. This enables the interpretation of the context. /// specification which the event uses. This enables the interpretation of the context.
/// </summary> /// </summary>
/// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#specversion"/> /// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#specversion"/>
public string SpecVersion public CloudEventsSpecVersion SpecVersion
{ {
get => attributes[CloudEventAttributes.SpecVersionAttributeName] as string; get => attributes.SpecVersion;
set => attributes[CloudEventAttributes.SpecVersionAttributeName] = value; set => attributes.SpecVersion = value;
} }
/// <summary> /// <summary>
@ -135,8 +149,8 @@ namespace CloudNative.CloudEvents
/// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#time"/> /// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#time"/>
public DateTime? Time public DateTime? Time
{ {
get => (DateTime?)attributes[CloudEventAttributes.TimeAttributeName]; get => (DateTime?)attributes[CloudEventAttributes.TimeAttributeName(attributes.SpecVersion)];
set => attributes[CloudEventAttributes.TimeAttributeName] = value; set => attributes[CloudEventAttributes.TimeAttributeName(attributes.SpecVersion)] = value;
} }
/// <summary> /// <summary>
@ -146,8 +160,8 @@ namespace CloudNative.CloudEvents
/// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#type"/> /// <see cref="https://github.com/cloudevents/spec/blob/master/spec.md#type"/>
public string Type public string Type
{ {
get => attributes[CloudEventAttributes.TypeAttributeName] as string; get => attributes[CloudEventAttributes.TypeAttributeName(attributes.SpecVersion)] as string;
set => attributes[CloudEventAttributes.TypeAttributeName] = value; set => attributes[CloudEventAttributes.TypeAttributeName(attributes.SpecVersion)] = value;
} }
/// <summary> /// <summary>

View File

@ -15,29 +15,17 @@ namespace CloudNative.CloudEvents
/// </summary> /// </summary>
public class CloudEventAttributes : IDictionary<string, object> public class CloudEventAttributes : IDictionary<string, object>
{ {
public const string ContentTypeAttributeName = "contenttype"; readonly CloudEventsSpecVersion specVersion;
public const string DataAttributeName = "data";
public const string IdAttributeName = "id";
public const string SchemaUrlAttributeName = "schemaurl";
public const string SourceAttributeName = "source";
public const string SpecVersionAttributeName = "specversion";
public const string TimeAttributeName = "time";
public const string TypeAttributeName = "type";
IDictionary<string, object> dict = new Dictionary<string, object>(); IDictionary<string, object> dict = new Dictionary<string, object>();
IEnumerable<ICloudEventExtension> extensions; IEnumerable<ICloudEventExtension> extensions;
internal CloudEventAttributes(IEnumerable<ICloudEventExtension> extensions) internal CloudEventAttributes(CloudEventsSpecVersion specVersion, IEnumerable<ICloudEventExtension> extensions)
{ {
this.extensions = extensions; this.extensions = extensions;
this.specVersion = specVersion;
dict[SpecVersionAttributeName(specVersion)] = specVersion == CloudEventsSpecVersion.V0_1 ? "0.1" : "0.2";
} }
int ICollection<KeyValuePair<string, object>>.Count => dict.Count; int ICollection<KeyValuePair<string, object>>.Count => dict.Count;
@ -48,7 +36,85 @@ namespace CloudNative.CloudEvents
ICollection<object> IDictionary<string, object>.Values => dict.Values; ICollection<object> IDictionary<string, object>.Values => dict.Values;
object IDictionary<string, object>.this[string key] public CloudEventsSpecVersion SpecVersion
{
get
{
object val;
if (dict.TryGetValue(SpecVersionAttributeName(CloudEventsSpecVersion.V0_1), out val) ||
dict.TryGetValue(SpecVersionAttributeName(CloudEventsSpecVersion.V0_2), out val))
{
return (val as string) == "0.1" ? CloudEventsSpecVersion.V0_1 : CloudEventsSpecVersion.V0_2;
}
return CloudEventsSpecVersion.V0_2;
}
set
{
var currentSpecVersion = SpecVersion;
object val;
if (dict.TryGetValue(SpecVersionAttributeName(CloudEventsSpecVersion.V0_1), out val))
{
if (value == CloudEventsSpecVersion.V0_1 && (val as string) == "0.1")
{
return;
}
}
else if ( dict.TryGetValue(SpecVersionAttributeName(CloudEventsSpecVersion.V0_2), out val))
{
if (value == CloudEventsSpecVersion.V0_2 && (val as string) == "0.2")
{
return;
}
}
// transform to new version
var copy = new Dictionary<string, object>(dict);
dict.Clear();
dict[SpecVersionAttributeName(value)] = value == CloudEventsSpecVersion.V0_1 ? "0.1" : "0.2";
foreach (var kv in copy)
{
if (SpecVersionAttributeName(currentSpecVersion).Equals(kv.Key))
{
continue;
}
if (ContentTypeAttributeName(currentSpecVersion).Equals(kv.Key))
{
dict[ContentTypeAttributeName(value)] = kv.Value;
}
else if (DataAttributeName(currentSpecVersion).Equals(kv.Key))
{
dict[DataAttributeName(value)] = kv.Value;
}
else if (IdAttributeName(currentSpecVersion).Equals(kv.Key))
{
dict[IdAttributeName(value)] = kv.Value;
}
else if (SchemaUrlAttributeName(currentSpecVersion).Equals(kv.Key))
{
dict[SchemaUrlAttributeName(value)] = kv.Value;
}
else if (SourceAttributeName(currentSpecVersion).Equals(kv.Key))
{
dict[SourceAttributeName(value)] = kv.Value;
}
else if (TimeAttributeName(currentSpecVersion).Equals(kv.Key))
{
dict[TimeAttributeName(value)] = kv.Value;
}
else if (TypeAttributeName(currentSpecVersion).Equals(kv.Key))
{
dict[TypeAttributeName(value)] = kv.Value;
}
else
{
dict[kv.Key] = kv.Value;
}
}
}
}
public object this[string key]
{ {
get => dict[key]; get => dict[key];
set set
@ -58,6 +124,46 @@ namespace CloudNative.CloudEvents
} }
} }
public static string ContentTypeAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
{
return version == CloudEventsSpecVersion.V0_1 ? "contentType" : "contenttype";
}
public static string DataAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
{
return "data";
}
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 SourceAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
{
return "source";
}
public static string SpecVersionAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
{
return version == CloudEventsSpecVersion.V0_1 ? "cloudEventsVersion" : "specversion";
}
public static string TimeAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
{
return version == CloudEventsSpecVersion.V0_1 ? "eventTime" : "time";
}
public static string TypeAttributeName(CloudEventsSpecVersion version = CloudEventsSpecVersion.Default)
{
return version == CloudEventsSpecVersion.V0_1 ? "eventType" : "type";
}
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item) void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
{ {
object value = item.Value; object value = item.Value;
@ -118,114 +224,126 @@ namespace CloudNative.CloudEvents
internal virtual bool ValidateAndNormalize(string key, ref object value) internal virtual bool ValidateAndNormalize(string key, ref object value)
{ {
switch (key) if (key.Equals(TypeAttributeName(this.SpecVersion)))
{ {
case TypeAttributeName: if (value is string)
if (value is string) {
{
return true;
}
throw new InvalidOperationException(Strings.ErrorTypeValueIsNotAString);
case SpecVersionAttributeName:
if (value is string)
{
return true;
}
throw new InvalidOperationException(Strings.ErrorSpecVersionValueIsNotAString);
case IdAttributeName:
if (value is string)
{
return true;
}
throw new InvalidOperationException(Strings.ErrorIdValueIsNotAString);
case TimeAttributeName:
if (value is null || value is DateTime)
{
return true;
}
if (value is string)
{
if (DateTime.TryParseExact((string)value, "o", CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out var dateTimeVal))
{
value = dateTimeVal;
return true;
}
}
throw new InvalidOperationException(Strings.ErrorTimeValueIsNotATimestamp);
case SourceAttributeName:
if (value is Uri)
{
return true;
}
if (value is string)
{
if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out var uriVal))
{
value = uriVal;
return true;
}
}
throw new InvalidOperationException(Strings.ErrorSchemaUrlIsNotAUri);
case SchemaUrlAttributeName:
if (value is null || value is Uri)
{
return true;
}
if (value is string)
{
if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out var uriVal))
{
value = uriVal;
return true;
}
}
throw new InvalidOperationException(Strings.ErrorSchemaUrlIsNotAUri);
case ContentTypeAttributeName:
if (value is null || value is ContentType)
{
return true;
}
if (value is string)
{
try
{
value = new ContentType((string)value);
return true;
}
catch (FormatException fe)
{
throw new InvalidOperationException(Strings.ErrorContentTypeIsNotRFC2046, fe);
}
}
throw new InvalidOperationException(Strings.ErrorContentTypeIsNotRFC2046);
case DataAttributeName:
return true; return true;
default: }
if (extensions != null)
throw new InvalidOperationException(Strings.ErrorTypeValueIsNotAString);
}
else if (key.Equals(SpecVersionAttributeName(this.SpecVersion)))
{
if (value is string)
{
return true;
}
throw new InvalidOperationException(Strings.ErrorSpecVersionValueIsNotAString);
}
else if (key.Equals(IdAttributeName(this.SpecVersion)))
{
if (value is string)
{
return true;
}
throw new InvalidOperationException(Strings.ErrorIdValueIsNotAString);
}
else if (key.Equals(TimeAttributeName(this.SpecVersion)))
{
if (value is null || value is DateTime)
{
return true;
}
if (value is string)
{
if (DateTime.TryParseExact((string)value, "o", CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal, out var dateTimeVal))
{ {
foreach (var extension in extensions) value = dateTimeVal;
return true;
}
}
throw new InvalidOperationException(Strings.ErrorTimeValueIsNotATimestamp);
}
else if (key.Equals(SourceAttributeName(this.SpecVersion)))
{
if (value is Uri)
{
return true;
}
if (value is string)
{
if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out var uriVal))
{
value = uriVal;
return true;
}
}
throw new InvalidOperationException(Strings.ErrorSchemaUrlIsNotAUri);
}
else if (key.Equals(SchemaUrlAttributeName(this.SpecVersion)))
{
if (value is null || value is Uri)
{
return true;
}
if (value is string)
{
if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out var uriVal))
{
value = uriVal;
return true;
}
}
throw new InvalidOperationException(Strings.ErrorSchemaUrlIsNotAUri);
}
else if (key.Equals(ContentTypeAttributeName(this.SpecVersion)))
{
if (value is null || value is ContentType)
{
return true;
}
if (value is string)
{
try
{
value = new ContentType((string)value);
return true;
}
catch (FormatException fe)
{
throw new InvalidOperationException(Strings.ErrorContentTypeIsNotRFC2046, fe);
}
}
throw new InvalidOperationException(Strings.ErrorContentTypeIsNotRFC2046);
}
else if (key.Equals(DataAttributeName(this.SpecVersion)))
{
return true;
}
else
{
if (extensions != null)
{
foreach (var extension in extensions)
{
if (extension.ValidateAndNormalize(key, ref value))
{ {
if (extension.ValidateAndNormalize(key, ref value)) return true;
{
return true;
}
} }
} }
}
break;
} }
return false; return false;

View File

@ -51,7 +51,7 @@ namespace CloudNative.CloudEvents
} }
else else
{ {
inner = new InnerByteArrayContent(formatter.EncodeAttribute(CloudEventAttributes.DataAttributeName, inner = new InnerByteArrayContent(formatter.EncodeAttribute(cloudEvent.SpecVersion, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion),
cloudEvent.Data, cloudEvent.Extensions.Values)); cloudEvent.Data, cloudEvent.Extensions.Values));
} }
@ -79,29 +79,27 @@ namespace CloudNative.CloudEvents
{ {
foreach (var attribute in cloudEvent.GetAttributes()) foreach (var attribute in cloudEvent.GetAttributes())
{ {
switch (attribute.Key) if (!(attribute.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) ||
attribute.Key.Equals(CloudEventAttributes.ContentTypeAttributeName(cloudEvent.SpecVersion))))
{ {
case CloudEventAttributes.DataAttributeName: if (attribute.Value is string)
case CloudEventAttributes.ContentTypeAttributeName: {
break; Headers.Add("ce-" + attribute.Key, attribute.Value.ToString());
default: }
if (attribute.Value is string) else if (attribute.Value is DateTime)
{ {
Headers.Add("ce-" + attribute.Key, attribute.Value.ToString()); Headers.Add("ce-" + attribute.Key, ((DateTime)attribute.Value).ToString("o"));
} }
else if (attribute.Value is DateTime) else if (attribute.Value is Uri || attribute.Value is int)
{ {
Headers.Add("ce-" + attribute.Key, ((DateTime)attribute.Value).ToString("o")); Headers.Add("ce-" + attribute.Key, attribute.Value.ToString());
} }
else if (attribute.Value is Uri || attribute.Value is int) else
{ {
Headers.Add("ce-" + attribute.Key, attribute.Value.ToString()); Headers.Add("ce-" + attribute.Key,
} Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(cloudEvent.SpecVersion, attribute.Key, attribute.Value,
else cloudEvent.Extensions.Values)));
{ }
Headers.Add("ce-" + attribute.Key, Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(attribute.Key, attribute.Value, cloudEvent.Extensions.Values)));
}
break;
} }
} }
} }

View File

@ -0,0 +1,13 @@
// Copyright (c) Cloud Native Foundation.
// Licensed under the Apache 2.0 license.
// See LICENSE file in the project root for full license information.
namespace CloudNative.CloudEvents
{
public enum CloudEventsSpecVersion
{
V0_1,
V0_2,
Default = V0_2
}
}

View File

@ -9,7 +9,6 @@ namespace CloudNative.CloudEvents
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mime; using System.Net.Mime;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -17,8 +16,12 @@ namespace CloudNative.CloudEvents
public static class HttpClientExtension public static class HttpClientExtension
{ {
const string HttpHeaderPrefix = "ce-"; const string HttpHeaderPrefix = "ce-";
const string SpecVersionHttpHeader = HttpHeaderPrefix + "specversion";
const string SpecVersionHttpHeader1 = HttpHeaderPrefix + "cloudEventsVersion";
const string SpecVersionHttpHeader2 = HttpHeaderPrefix + "specversion";
static JsonEventFormatter jsonFormatter = new JsonEventFormatter(); static JsonEventFormatter jsonFormatter = new JsonEventFormatter();
/// <summary> /// <summary>
@ -81,9 +84,10 @@ namespace CloudNative.CloudEvents
/// <returns>true, if the response is a CloudEvent</returns> /// <returns>true, if the response is a CloudEvent</returns>
public static bool IsCloudEvent(this HttpResponseMessage httpResponseMessage) public static bool IsCloudEvent(this HttpResponseMessage httpResponseMessage)
{ {
return ((httpResponseMessage.Content.Headers.ContentType != null && return (httpResponseMessage.Content.Headers.ContentType != null &&
httpResponseMessage.Content.Headers.ContentType.MediaType.StartsWith(CloudEvent.MediaType)) || httpResponseMessage.Content.Headers.ContentType.MediaType.StartsWith(CloudEvent.MediaType)) ||
httpResponseMessage.Headers.Contains(SpecVersionHttpHeader)); httpResponseMessage.Headers.Contains(SpecVersionHttpHeader1) ||
httpResponseMessage.Headers.Contains(SpecVersionHttpHeader2);
} }
/// <summary> /// <summary>
@ -91,9 +95,10 @@ namespace CloudNative.CloudEvents
/// </summary> /// </summary>
public static bool IsCloudEvent(this HttpListenerRequest httpListenerRequest) public static bool IsCloudEvent(this HttpListenerRequest httpListenerRequest)
{ {
return ((httpListenerRequest.Headers["content-type"] != null && return (httpListenerRequest.Headers["content-type"] != null &&
httpListenerRequest.Headers["content-type"].StartsWith(CloudEvent.MediaType)) || httpListenerRequest.Headers["content-type"].StartsWith(CloudEvent.MediaType)) ||
httpListenerRequest.Headers.AllKeys.Contains(SpecVersionHttpHeader)); httpListenerRequest.Headers[SpecVersionHttpHeader1] != null ||
httpListenerRequest.Headers[SpecVersionHttpHeader2] != null;
} }
/// <summary> /// <summary>
@ -169,22 +174,43 @@ namespace CloudNative.CloudEvents
} }
else else
{ {
var cloudEvent = new CloudEvent(extensions); CloudEventsSpecVersion version = CloudEventsSpecVersion.Default;
var attributes = cloudEvent.GetAttributes(); if (httpListenerRequest.Headers[SpecVersionHttpHeader1] != null)
foreach (var httpResponseHeader in httpListenerRequest.Headers.AllKeys)
{ {
if (httpResponseHeader.StartsWith(HttpHeaderPrefix, StringComparison.InvariantCultureIgnoreCase)) version = CloudEventsSpecVersion.V0_1;
}
if (httpListenerRequest.Headers[SpecVersionHttpHeader2] != null)
{
version = httpListenerRequest.Headers[SpecVersionHttpHeader2] == "0.2"
? CloudEventsSpecVersion.V0_2
: 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))
{ {
string headerValue = httpListenerRequest.Headers[httpResponseHeader]; continue;
}
if (httpRequestHeaders.StartsWith(HttpHeaderPrefix, StringComparison.InvariantCultureIgnoreCase))
{
string headerValue = httpListenerRequest.Headers[httpRequestHeaders];
if (headerValue.StartsWith("{") && headerValue.EndsWith("}") || if (headerValue.StartsWith("{") && headerValue.EndsWith("}") ||
headerValue.StartsWith("[") && headerValue.EndsWith("]")) headerValue.StartsWith("[") && headerValue.EndsWith("]"))
{ {
attributes[httpResponseHeader.Substring(3).ToLowerInvariant()] = attributes[httpRequestHeaders.Substring(3).ToLowerInvariant()] =
JsonConvert.DeserializeObject(headerValue); JsonConvert.DeserializeObject(headerValue);
} }
else else
{ {
attributes[httpResponseHeader.Substring(3).ToLowerInvariant()] = headerValue; attributes[httpRequestHeaders.Substring(3).ToLowerInvariant()] = headerValue;
attributes[httpRequestHeaders.Substring(3).ToLowerInvariant()] = headerValue;
} }
} }
} }
@ -201,35 +227,31 @@ namespace CloudNative.CloudEvents
{ {
foreach (var attribute in cloudEvent.GetAttributes()) foreach (var attribute in cloudEvent.GetAttributes())
{ {
switch (attribute.Key) if (!attribute.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) &&
!attribute.Key.Equals(CloudEventAttributes.ContentTypeAttributeName(cloudEvent.SpecVersion)))
{ {
case CloudEventAttributes.DataAttributeName: if (attribute.Value is string)
case CloudEventAttributes.ContentTypeAttributeName: {
break; httpListenerResponse.Headers.Add(HttpHeaderPrefix + attribute.Key,
default: attribute.Value.ToString());
if (attribute.Value is string) }
{ else if (attribute.Value is DateTime)
httpListenerResponse.Headers.Add(HttpHeaderPrefix + attribute.Key, {
attribute.Value.ToString()); httpListenerResponse.Headers.Add(HttpHeaderPrefix + attribute.Key,
} ((DateTime)attribute.Value).ToString("o"));
else if (attribute.Value is DateTime) }
{ else if (attribute.Value is Uri || attribute.Value is int)
httpListenerResponse.Headers.Add(HttpHeaderPrefix + attribute.Key, {
((DateTime)attribute.Value).ToString("o")); httpListenerResponse.Headers.Add(HttpHeaderPrefix + attribute.Key,
} attribute.Value.ToString());
else if (attribute.Value is Uri || attribute.Value is int) }
{ else
httpListenerResponse.Headers.Add(HttpHeaderPrefix + attribute.Key, {
attribute.Value.ToString()); httpListenerResponse.Headers.Add(HttpHeaderPrefix + attribute.Key,
} Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(cloudEvent.SpecVersion, attribute.Key,
else attribute.Value,
{ cloudEvent.Extensions.Values)));
httpListenerResponse.Headers.Add(HttpHeaderPrefix + attribute.Key, }
Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(attribute.Key, attribute.Value,
cloudEvent.Extensions.Values)));
}
break;
} }
} }
} }
@ -238,33 +260,29 @@ namespace CloudNative.CloudEvents
{ {
foreach (var attribute in cloudEvent.GetAttributes()) foreach (var attribute in cloudEvent.GetAttributes())
{ {
switch (attribute.Key) if (!attribute.Key.Equals(CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) &&
!attribute.Key.Equals(CloudEventAttributes.ContentTypeAttributeName(cloudEvent.SpecVersion)))
{ {
case CloudEventAttributes.DataAttributeName: if (attribute.Value is string)
case CloudEventAttributes.ContentTypeAttributeName: {
break; httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key, attribute.Value.ToString());
default: }
if (attribute.Value is string) else if (attribute.Value is DateTime)
{ {
httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key, attribute.Value.ToString()); httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key,
} ((DateTime)attribute.Value).ToString("o"));
else if (attribute.Value is DateTime) }
{ else if (attribute.Value is Uri || attribute.Value is int)
httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key, {
((DateTime)attribute.Value).ToString("o")); httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key, attribute.Value.ToString());
} }
else if (attribute.Value is Uri || attribute.Value is int) else
{ {
httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key, attribute.Value.ToString()); httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key,
} Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(cloudEvent.SpecVersion, attribute.Key,
else attribute.Value,
{ cloudEvent.Extensions.Values)));
httpWebRequest.Headers.Add(HttpHeaderPrefix + attribute.Key, }
Encoding.UTF8.GetString(jsonFormatter.EncodeAttribute(attribute.Key, attribute.Value,
cloudEvent.Extensions.Values)));
}
break;
} }
} }
} }
@ -286,7 +304,8 @@ namespace CloudNative.CloudEvents
} }
else else
{ {
stream = new MemoryStream(formatter.EncodeAttribute(CloudEventAttributes.DataAttributeName, stream = new MemoryStream(formatter.EncodeAttribute(cloudEvent.SpecVersion,
CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion),
cloudEvent.Data, cloudEvent.Extensions.Values)); cloudEvent.Data, cloudEvent.Extensions.Values));
} }
@ -315,29 +334,55 @@ namespace CloudNative.CloudEvents
} }
} }
return formatter.DecodeStructuredEvent(httpResponseMessage.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult(), return formatter.DecodeStructuredEvent(
httpResponseMessage.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult(),
extensions); extensions);
} }
else else
{ {
var cloudEvent = new CloudEvent(extensions); 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
: CloudEventsSpecVersion.Default;
}
var cloudEvent = new CloudEvent(version, extensions);
var attributes = cloudEvent.GetAttributes(); var attributes = cloudEvent.GetAttributes();
foreach (var httpResponseHeader in httpResponseMessage.Headers) 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, if (httpResponseHeader.Key.StartsWith(HttpHeaderPrefix,
StringComparison.InvariantCultureIgnoreCase)) StringComparison.InvariantCultureIgnoreCase))
{ {
string headerValue = httpResponseHeader.Value.First(); string headerValue = httpResponseHeader.Value.First();
if (headerValue.StartsWith("{") && headerValue.EndsWith("}") || var name = httpResponseHeader.Key.Substring(3).ToLowerInvariant();
if (headerValue.StartsWith("\"") && headerValue.EndsWith("\"") ||
headerValue.StartsWith("'") && headerValue.EndsWith("'") ||
headerValue.StartsWith("{") && headerValue.EndsWith("}") ||
headerValue.StartsWith("[") && headerValue.EndsWith("]")) headerValue.StartsWith("[") && headerValue.EndsWith("]"))
{ {
attributes[httpResponseHeader.Key.Substring(3).ToLowerInvariant()] = attributes[name] = jsonFormatter.DecodeAttribute(version, name,
JsonConvert.DeserializeObject(headerValue); Encoding.UTF8.GetBytes(headerValue), extensions);
} }
else else
{ {
attributes[httpResponseHeader.Key.Substring(3).ToLowerInvariant()] = headerValue; attributes[name] = headerValue;
} }
} }
} }

View File

@ -35,6 +35,7 @@ namespace CloudNative.CloudEvents
/// <param name="contentType"></param> /// <param name="contentType"></param>
/// <returns></returns> /// <returns></returns>
byte[] EncodeStructuredEvent(CloudEvent cloudEvent, out ContentType contentType); byte[] EncodeStructuredEvent(CloudEvent cloudEvent, out ContentType contentType);
/// <summary> /// <summary>
/// Decode an attribute from a byte array /// Decode an attribute from a byte array
/// </summary> /// </summary>
@ -42,7 +43,7 @@ namespace CloudNative.CloudEvents
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="extensions"></param> /// <param name="extensions"></param>
/// <returns></returns> /// <returns></returns>
object DecodeAttribute(string name, byte[] data, IEnumerable<ICloudEventExtension> extensions); object DecodeAttribute(CloudEventsSpecVersion specVersion, string name, byte[] data, IEnumerable<ICloudEventExtension> extensions);
/// <summary> /// <summary>
/// Encode an attribute into a byte array /// Encode an attribute into a byte array
/// </summary> /// </summary>
@ -50,6 +51,6 @@ namespace CloudNative.CloudEvents
/// <param name="value"></param> /// <param name="value"></param>
/// <param name="extensions"></param> /// <param name="extensions"></param>
/// <returns></returns> /// <returns></returns>
byte[] EncodeAttribute(string name, object value, IEnumerable<ICloudEventExtension> extensions); byte[] EncodeAttribute(CloudEventsSpecVersion specVersion, string name, object value, IEnumerable<ICloudEventExtension> extensions);
} }
} }

View File

@ -46,11 +46,30 @@ namespace CloudNative.CloudEvents
public CloudEvent DecodeJObject(JObject jObject, IEnumerable<ICloudEventExtension> extensions = null) public CloudEvent DecodeJObject(JObject jObject, IEnumerable<ICloudEventExtension> extensions = null)
{ {
var cloudEvent = new CloudEvent(extensions); CloudEventsSpecVersion specVersion = CloudEventsSpecVersion.Default;
if (jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1)))
{
specVersion = CloudEventsSpecVersion.V0_1;
}
if (jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2)))
{
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(); var attributes = cloudEvent.GetAttributes();
attributes.Clear();
foreach (var keyValuePair in jObject) foreach (var keyValuePair in jObject)
{ {
if (keyValuePair.Key.Equals(
CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1)) ||
keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2)))
{
continue;
}
switch (keyValuePair.Value.Type) switch (keyValuePair.Value.Type)
{ {
case JTokenType.String: case JTokenType.String:
@ -101,23 +120,30 @@ namespace CloudNative.CloudEvents
return Encoding.UTF8.GetBytes(jObject.ToString()); return Encoding.UTF8.GetBytes(jObject.ToString());
} }
public object DecodeAttribute(string name, byte[] data, IEnumerable<ICloudEventExtension> extensions = null) public object DecodeAttribute(CloudEventsSpecVersion specVersion, string name, byte[] data, IEnumerable<ICloudEventExtension> extensions = null)
{ {
switch (name) if (name.Equals(CloudEventAttributes.IdAttributeName(specVersion)) ||
name.Equals(CloudEventAttributes.TypeAttributeName(specVersion)))
{ {
case CloudEventAttributes.SpecVersionAttributeName: return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(string));
case CloudEventAttributes.IdAttributeName: }
case CloudEventAttributes.TypeAttributeName:
return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(string)); if (name.Equals(CloudEventAttributes.TimeAttributeName(specVersion)))
case CloudEventAttributes.TimeAttributeName: {
return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(DateTime)); return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(DateTime));
case CloudEventAttributes.SourceAttributeName: }
case CloudEventAttributes.SchemaUrlAttributeName:
var uri = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(string)) as string; if (name.Equals(CloudEventAttributes.SourceAttributeName(specVersion)) ||
return new Uri(uri); name.Equals(CloudEventAttributes.SchemaUrlAttributeName(specVersion)))
case CloudEventAttributes.ContentTypeAttributeName: {
var s = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(string)) as string; var uri = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(string)) as string;
return new ContentType(s); return new Uri(uri);
}
if (name.Equals(CloudEventAttributes.ContentTypeAttributeName(specVersion)))
{
var s = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(string)) as string;
return new ContentType(s);
} }
if (extensions != null) if (extensions != null)
@ -131,13 +157,12 @@ namespace CloudNative.CloudEvents
} }
} }
} }
return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data)); return JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data));
} }
public byte[] EncodeAttribute(string name, object value, IEnumerable<ICloudEventExtension> extensions = null) public byte[] EncodeAttribute(CloudEventsSpecVersion specVersion, string name, object value, IEnumerable<ICloudEventExtension> extensions = null)
{ {
if (name.Equals(CloudEventAttributes.DataAttributeName)) if (name.Equals(CloudEventAttributes.DataAttributeName(specVersion)))
{ {
if (value is Stream) if (value is Stream)
{ {

View File

@ -41,7 +41,7 @@ namespace CloudNative.CloudEvents.UnitTests
Assert.True(message1.IsCloudEvent()); Assert.True(message1.IsCloudEvent());
var receivedCloudEvent = message1.ToCloudEvent(); var receivedCloudEvent = message1.ToCloudEvent();
Assert.Equal("0.2", receivedCloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, receivedCloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", receivedCloudEvent.Type); Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
Assert.Equal("A234-1234-1234", receivedCloudEvent.Id); Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);
@ -84,7 +84,7 @@ namespace CloudNative.CloudEvents.UnitTests
Assert.True(message1.IsCloudEvent()); Assert.True(message1.IsCloudEvent());
var receivedCloudEvent = message1.ToCloudEvent(); var receivedCloudEvent = message1.ToCloudEvent();
Assert.Equal("0.2", receivedCloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, receivedCloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", receivedCloudEvent.Type); Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
Assert.Equal("A234-1234-1234", receivedCloudEvent.Id); Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);

View File

@ -26,7 +26,7 @@ namespace CloudNative.CloudEvents.UnitTests
attrs["comexampleextension1"] = "value"; attrs["comexampleextension1"] = "value";
attrs["comexampleextension2"] = new { othervalue = 5 }; attrs["comexampleextension2"] = new { othervalue = 5 };
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -57,7 +57,7 @@ namespace CloudNative.CloudEvents.UnitTests
attrs["comexampleextension1"] = "value"; attrs["comexampleextension1"] = "value";
attrs["comexampleextension2"] = new { othervalue = 5 }; attrs["comexampleextension2"] = new { othervalue = 5 };
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -71,6 +71,71 @@ namespace CloudNative.CloudEvents.UnitTests
Assert.Equal(5, (int)((dynamic)attr["comexampleextension2"]).othervalue); Assert.Equal(5, (int)((dynamic)attr["comexampleextension2"]).othervalue);
} }
[Fact]
public void CreateV0_1()
{
var cloudEvent = new CloudEvent(CloudEventsSpecVersion.V0_1, "com.github.pull.create",
new Uri("https://github.com/cloudevents/spec/pull/123"))
{
Id = "A234-1234-1234",
Time = new DateTime(2018, 4, 5, 17, 31, 0, DateTimeKind.Utc),
ContentType = new ContentType(MediaTypeNames.Text.Xml),
Data = "<much wow=\"xml\"/>"
};
var attrs = cloudEvent.GetAttributes();
attrs["comexampleextension1"] = "value";
attrs["comexampleextension2"] = new { othervalue = 5 };
Assert.Equal(CloudEventsSpecVersion.V0_1, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id);
Assert.Equal(DateTime.Parse("2018-04-05T17:31:00Z").ToUniversalTime(),
cloudEvent.Time.Value.ToUniversalTime());
Assert.Equal(new ContentType(MediaTypeNames.Text.Xml), cloudEvent.ContentType);
Assert.Equal("<much wow=\"xml\"/>", cloudEvent.Data);
var attr = cloudEvent.GetAttributes();
Assert.Equal("value", (string)attr["comexampleextension1"]);
Assert.Equal(5, (int)((dynamic)attr["comexampleextension2"]).othervalue);
}
[Fact]
public void CreateV0_1ConvertToV0_2()
{
var cloudEvent = new CloudEvent(CloudEventsSpecVersion.V0_1, "com.github.pull.create",
new Uri("https://github.com/cloudevents/spec/pull/123"))
{
Id = "A234-1234-1234",
Time = new DateTime(2018, 4, 5, 17, 31, 0, DateTimeKind.Utc),
ContentType = new ContentType(MediaTypeNames.Text.Xml),
Data = "<much wow=\"xml\"/>"
};
var attrs = cloudEvent.GetAttributes();
attrs["comexampleextension1"] = "value";
attrs["comexampleextension2"] = new { othervalue = 5 };
cloudEvent.SpecVersion = CloudEventsSpecVersion.V0_2;
Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id);
Assert.Equal(DateTime.Parse("2018-04-05T17:31:00Z").ToUniversalTime(),
cloudEvent.Time.Value.ToUniversalTime());
Assert.Equal(new ContentType(MediaTypeNames.Text.Xml), cloudEvent.ContentType);
Assert.Equal("<much wow=\"xml\"/>", cloudEvent.Data);
var attr = cloudEvent.GetAttributes();
Assert.Equal("value", (string)attr["comexampleextension1"]);
Assert.Equal(5, (int)((dynamic)attr["comexampleextension2"]).othervalue);
}
[Fact] [Fact]
public void CreateEventWithExtensions() public void CreateEventWithExtensions()
{ {
@ -95,7 +160,7 @@ namespace CloudNative.CloudEvents.UnitTests
Data = "<much wow=\"xml\"/>" Data = "<much wow=\"xml\"/>"
}; };
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);

View File

@ -55,7 +55,7 @@ namespace CloudNative.CloudEvents.UnitTests
{ {
var jsonFormatter = new JsonEventFormatter(); var jsonFormatter = new JsonEventFormatter();
var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonDistTrace), new DistributedTracingExtension()); var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonDistTrace), new DistributedTracingExtension());
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -74,7 +74,7 @@ namespace CloudNative.CloudEvents.UnitTests
var jsonData = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType); var jsonData = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType);
var cloudEvent = jsonFormatter.DecodeStructuredEvent(jsonData, new DistributedTracingExtension()); var cloudEvent = jsonFormatter.DecodeStructuredEvent(jsonData, new DistributedTracingExtension());
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -90,7 +90,7 @@ namespace CloudNative.CloudEvents.UnitTests
{ {
var jsonFormatter = new JsonEventFormatter(); var jsonFormatter = new JsonEventFormatter();
var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSequence), new SequenceExtension()); var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSequence), new SequenceExtension());
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -109,7 +109,7 @@ namespace CloudNative.CloudEvents.UnitTests
var jsonData = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType); var jsonData = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType);
var cloudEvent = jsonFormatter.DecodeStructuredEvent(jsonData, new SequenceExtension()); var cloudEvent = jsonFormatter.DecodeStructuredEvent(jsonData, new SequenceExtension());
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -125,7 +125,7 @@ namespace CloudNative.CloudEvents.UnitTests
{ {
var jsonFormatter = new JsonEventFormatter(); var jsonFormatter = new JsonEventFormatter();
var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSequence), new IntegerSequenceExtension()); var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSequence), new IntegerSequenceExtension());
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -143,7 +143,7 @@ namespace CloudNative.CloudEvents.UnitTests
var jsonData = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType); var jsonData = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType);
var cloudEvent = jsonFormatter.DecodeStructuredEvent(jsonData, new IntegerSequenceExtension()); var cloudEvent = jsonFormatter.DecodeStructuredEvent(jsonData, new IntegerSequenceExtension());
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -158,7 +158,7 @@ namespace CloudNative.CloudEvents.UnitTests
{ {
var jsonFormatter = new JsonEventFormatter(); var jsonFormatter = new JsonEventFormatter();
var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSampledRate), new SamplingExtension()); var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(jsonSampledRate), new SamplingExtension());
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -176,7 +176,7 @@ namespace CloudNative.CloudEvents.UnitTests
var jsonData = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType); var jsonData = jsonFormatter.EncodeStructuredEvent(cloudEvent1, out var contentType);
var cloudEvent = jsonFormatter.DecodeStructuredEvent(jsonData, new SamplingExtension()); var cloudEvent = jsonFormatter.DecodeStructuredEvent(jsonData, new SamplingExtension());
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);

View File

@ -107,7 +107,7 @@ namespace CloudNative.CloudEvents.UnitTests
Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal(HttpStatusCode.OK, result.StatusCode);
var receivedCloudEvent = result.ToCloudEvent(); var receivedCloudEvent = result.ToCloudEvent();
Assert.Equal("0.2", receivedCloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, receivedCloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", receivedCloudEvent.Type); Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
Assert.Equal("A234-1234-1234", receivedCloudEvent.Id); Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);
@ -152,7 +152,7 @@ namespace CloudNative.CloudEvents.UnitTests
var receivedCloudEvent = context.Request.ToCloudEvent(new JsonEventFormatter()); var receivedCloudEvent = context.Request.ToCloudEvent(new JsonEventFormatter());
Assert.Equal("0.2", receivedCloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, receivedCloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", receivedCloudEvent.Type); Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
Assert.Equal("A234-1234-1234", receivedCloudEvent.Id); Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);
@ -234,7 +234,7 @@ namespace CloudNative.CloudEvents.UnitTests
Assert.True(result.IsCloudEvent()); Assert.True(result.IsCloudEvent());
var receivedCloudEvent = result.ToCloudEvent(); var receivedCloudEvent = result.ToCloudEvent();
Assert.Equal("0.2", receivedCloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, receivedCloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", receivedCloudEvent.Type); Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
Assert.Equal("A234-1234-1234", receivedCloudEvent.Id); Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);
@ -274,7 +274,7 @@ namespace CloudNative.CloudEvents.UnitTests
{ {
var receivedCloudEvent = context.Request.ToCloudEvent(new JsonEventFormatter()); var receivedCloudEvent = context.Request.ToCloudEvent(new JsonEventFormatter());
Assert.Equal("0.2", receivedCloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, receivedCloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", receivedCloudEvent.Type); Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
Assert.Equal("A234-1234-1234", receivedCloudEvent.Id); Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);
@ -336,7 +336,7 @@ namespace CloudNative.CloudEvents.UnitTests
{ {
var receivedCloudEvent = context.Request.ToCloudEvent(new JsonEventFormatter()); var receivedCloudEvent = context.Request.ToCloudEvent(new JsonEventFormatter());
Assert.Equal("0.2", receivedCloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, receivedCloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", receivedCloudEvent.Type); Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
Assert.Equal("A234-1234-1234", receivedCloudEvent.Id); Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);

View File

@ -43,12 +43,30 @@ namespace CloudNative.CloudEvents.UnitTests
Assert.Equal(cloudEvent2.Data, cloudEvent.Data); Assert.Equal(cloudEvent2.Data, cloudEvent.Data);
} }
[Fact]
public void ReserializeTestV0_2toV0_1()
{
var jsonFormatter = new JsonEventFormatter();
var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(json));
cloudEvent.SpecVersion = CloudEventsSpecVersion.V0_1;
var jsonData = jsonFormatter.EncodeStructuredEvent(cloudEvent, out var contentType);
var cloudEvent2 = jsonFormatter.DecodeStructuredEvent(jsonData);
Assert.Equal(cloudEvent2.SpecVersion, cloudEvent.SpecVersion);
Assert.Equal(cloudEvent2.Type, cloudEvent.Type);
Assert.Equal(cloudEvent2.Source, cloudEvent.Source);
Assert.Equal(cloudEvent2.Id, cloudEvent.Id);
Assert.Equal(cloudEvent2.Time.Value.ToUniversalTime(), cloudEvent.Time.Value.ToUniversalTime());
Assert.Equal(cloudEvent2.ContentType, cloudEvent.ContentType);
Assert.Equal(cloudEvent2.Data, cloudEvent.Data);
}
[Fact] [Fact]
public void StructuredParseSuccess() public void StructuredParseSuccess()
{ {
var jsonFormatter = new JsonEventFormatter(); var jsonFormatter = new JsonEventFormatter();
var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(json)); var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(json));
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);
@ -68,7 +86,7 @@ namespace CloudNative.CloudEvents.UnitTests
var jsonFormatter = new JsonEventFormatter(); var jsonFormatter = new JsonEventFormatter();
var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(json), new ComExampleExtension1Extension(), var cloudEvent = jsonFormatter.DecodeStructuredEvent(Encoding.UTF8.GetBytes(json), new ComExampleExtension1Extension(),
new ComExampleExtension2Extension()); new ComExampleExtension2Extension());
Assert.Equal("0.2", cloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, cloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", cloudEvent.Type); Assert.Equal("com.github.pull.create", cloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), cloudEvent.Source);
Assert.Equal("A234-1234-1234", cloudEvent.Id); Assert.Equal("A234-1234-1234", cloudEvent.Id);

View File

@ -74,7 +74,7 @@ namespace CloudNative.CloudEvents.UnitTests
await client.PublishAsync(new MqttCloudEventMessage(cloudEvent, new JsonEventFormatter()) { Topic = "abc" }); await client.PublishAsync(new MqttCloudEventMessage(cloudEvent, new JsonEventFormatter()) { Topic = "abc" });
var receivedCloudEvent = await tcs.Task; var receivedCloudEvent = await tcs.Task;
Assert.Equal("0.2", receivedCloudEvent.SpecVersion); Assert.Equal(CloudEventsSpecVersion.V0_2, receivedCloudEvent.SpecVersion);
Assert.Equal("com.github.pull.create", receivedCloudEvent.Type); Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source); Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
Assert.Equal("A234-1234-1234", receivedCloudEvent.Id); Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);