Ejemplo n.º 1
0
        public void Dictionary_Add_NullValue()
        {
            IDictionary <string, object> attributes = new CloudEventAttributes(CloudEventsSpecVersion.Default, emptyExtensions);
            string attributeName = CloudEventAttributes.TypeAttributeName();

            Assert.Throws <ArgumentNullException>(() => attributes.Add(attributeName, null));
        }
Ejemplo n.º 2
0
        public void Dictionary_Remove_SpecVersion()
        {
            IDictionary <string, object> attributes = new CloudEventAttributes(CloudEventsSpecVersion.Default, emptyExtensions);
            string specVersionAttributeName         = CloudEventAttributes.SpecVersionAttributeName();

            Assert.Throws <InvalidOperationException>(() => attributes.Remove(specVersionAttributeName));
        }
        private void MapHeaders(CloudEvent cloudEvent)
        {
            var ignoreKeys = new List <string>(3)
            {
                CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion),
                CloudEventAttributes.IdAttributeName(cloudEvent.SpecVersion),
                CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion),
            };

            foreach (var attribute in cloudEvent.GetAttributes())
            {
                if (!ignoreKeys.Contains(attribute.Key))
                {
                    var key = Constants.PropertyKeyPrefix + attribute.Key;
                    switch (attribute.Value)
                    {
                    case Uri uri:
                        UserProperties.Add(key, uri.ToString());
                        break;

                    default:
                        UserProperties.Add(key, attribute.Value);
                        break;
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public void Indexer_SetToNullValue_SpecVersion()
        {
            var    attributes    = new CloudEventAttributes(CloudEventsSpecVersion.Default, emptyExtensions);
            string attributeName = CloudEventAttributes.SpecVersionAttributeName();

            Assert.Throws <InvalidOperationException>(() => attributes[attributeName] = null);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Determines if a given JSON <paramref name="jObject"/> is considered a <see cref="CloudEvent"/>.
        /// </summary>
        /// <param name="jObject">The raw JSON object.</param>
        /// <returns>
        ///     [true] if the specified <paramref name="jObject"/> is considered a valid <see cref="CloudEvent"/>; [false] otherwise.
        /// </returns>
        public static bool IsCloudEvent(this JObject jObject)
        {
            Guard.NotNull(jObject, nameof(jObject));

            return(jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName()) ||
                   jObject.ContainsKey(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_1)));
        }
        public static void Update <T>(this IBasicProperties self, MotorCloudEvent <byte[]> cloudEvent,
                                      RabbitMQPublisherConfig <T> config, ICloudEventFormatter cloudEventFormatter)
        {
            var messagePriority = cloudEvent.Extension <RabbitMQPriorityExtension>()?.Priority ??
                                  config.DefaultPriority;

            if (messagePriority.HasValue)
            {
                self.Priority = messagePriority.Value;
            }
            var dictionary = new Dictionary <string, object>();

            foreach (var attr in cloudEvent.GetAttributes())
            {
                if (string.Equals(attr.Key, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) ||
                    string.Equals(attr.Key,
                                  CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion)) ||
                    string.Equals(attr.Key, RabbitMQPriorityExtension.PriorityAttributeName) ||
                    string.Equals(attr.Key, RabbitMQBindingConfigExtension.ExchangeAttributeName) ||
                    string.Equals(attr.Key, RabbitMQBindingConfigExtension.RoutingKeyAttributeName))
                {
                    continue;
                }
                dictionary.Add($"{CloudEventPrefix}{attr.Key}",
                               cloudEventFormatter.EncodeAttribute(cloudEvent.SpecVersion, attr.Key, attr.Value,
                                                                   cloudEvent.GetExtensions().Values));
            }

            self.Headers = dictionary;
        }
Ejemplo n.º 7
0
        public void Collection_Add_NullValue()
        {
            ICollection <KeyValuePair <string, object> > attributes = new CloudEventAttributes(CloudEventsSpecVersion.Default, emptyExtensions);
            string attributeName = CloudEventAttributes.TypeAttributeName();
            var    pair          = KeyValuePair.Create(attributeName, default(object));

            Assert.Throws <InvalidOperationException>(() => attributes.Add(pair));
        }
Ejemplo n.º 8
0
        public void Collection_Remove_SpecVersion()
        {
            ICollection <KeyValuePair <string, object> > attributes = new CloudEventAttributes(CloudEventsSpecVersion.Default, emptyExtensions);
            string specVersionAttributeName = CloudEventAttributes.SpecVersionAttributeName();
            // The value part is irrelevant; we throw on any attempt to remove a pair with a key that's the spec attribute version.
            var pair = KeyValuePair.Create(specVersionAttributeName, new object());

            Assert.Throws <InvalidOperationException>(() => attributes.Remove(pair));
        }
Ejemplo n.º 9
0
        public void Indexer_SetToNullValue_RegularAttribute()
        {
            var    attributes    = new CloudEventAttributes(CloudEventsSpecVersion.Default, emptyExtensions);
            string attributeName = CloudEventAttributes.TypeAttributeName();

            attributes[attributeName] = "some event type";
            attributes[attributeName] = null;
            Assert.Null(attributes[attributeName]);
        }
Ejemplo n.º 10
0
        private void MapHeaders(CloudEvent cloudEvent, ICloudEventFormatter formatter)
        {
            foreach (var attr in cloudEvent.GetAttributes())
            {
                if (string.Equals(attr.Key, CloudEventAttributes.DataAttributeName(cloudEvent.SpecVersion)) ||
                    string.Equals(attr.Key, CloudEventAttributes.DataContentTypeAttributeName(cloudEvent.SpecVersion)) ||
                    string.Equals(attr.Key, PartitioningExtension.PartitioningKeyAttributeName))
                {
                    continue;
                }

                Headers.Add(KafkaHeaderPerfix + attr.Key,
                            formatter.EncodeAttribute(cloudEvent.SpecVersion, attr.Key, attr.Value, cloudEvent.Extensions.Values));
            }
        }
        public static MotorCloudEvent <byte[]> ExtractCloudEvent <T>(this IBasicProperties self,
                                                                     IApplicationNameService applicationNameService, ICloudEventFormatter cloudEventFormatter,
                                                                     ReadOnlyMemory <byte> body,
                                                                     IReadOnlyCollection <ICloudEventExtension> extensions)
        {
            var specVersion = CloudEventsSpecVersion.V1_0;
            var attributes  = new Dictionary <string, object>();
            IDictionary <string, object> headers = new Dictionary <string, object>();

            if (self.IsHeadersPresent() && self.Headers != null)
            {
                headers = self.Headers;
            }

            foreach (var header in headers
                     .Where(t => t.Key.StartsWith(CloudEventPrefix))
                     .Select(t =>
                             new KeyValuePair <string, object>(
                                 t.Key.Substring(CloudEventPrefix.Length),
                                 t.Value)))
            {
                if (string.Equals(header.Key, CloudEventAttributes.DataContentTypeAttributeName(specVersion),
                                  StringComparison.InvariantCultureIgnoreCase) ||
                    string.Equals(header.Key, CloudEventAttributes.SpecVersionAttributeName(specVersion),
                                  StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }

                attributes.Add(header.Key, header.Value);
            }

            if (attributes.Count == 0)
            {
                return(new MotorCloudEvent <byte[]>(applicationNameService, body.ToArray(), typeof(T).Name,
                                                    new Uri("rabbitmq://notset"), extensions: extensions.ToArray()));
            }

            var cloudEvent = new MotorCloudEvent <byte[]>(applicationNameService, body.ToArray(), extensions);

            foreach (var attribute in attributes)
            {
                cloudEvent.GetAttributes().Add(attribute.Key, cloudEventFormatter.DecodeAttribute(
                                                   cloudEvent.SpecVersion, attribute.Key, (byte[])attribute.Value, extensions));
            }

            return(cloudEvent);
        }
Ejemplo n.º 12
0
        public void Clear_PreservesSpecVersion()
        {
            IDictionary <string, object> attributes = new CloudEventAttributes(CloudEventsSpecVersion.Default, emptyExtensions);
            string specVersionAttributeName         = CloudEventAttributes.SpecVersionAttributeName();
            string specVersionValue = (string)attributes[specVersionAttributeName];

            attributes[CloudEventAttributes.TypeAttributeName()] = "some event type";
            Assert.Equal(2, attributes.Count);
            attributes.Clear();

            // We'd normally expect an empty dictionary now, but CloudEventAttributes always preserves the spec version.
            var entry = Assert.Single(attributes);

            Assert.Equal(CloudEventAttributes.SpecVersionAttributeName(), entry.Key);
            Assert.Equal(specVersionValue, entry.Value);
        }
Ejemplo n.º 13
0
        private static CloudEvent BinaryToCloudEvent(Message message, ICloudEventExtension[] extensions)
        {
            var specVersion      = GetCloudEventsSpecVersion(message);
            var cloudEventType   = GetAttribute(message, CloudEventAttributes.TypeAttributeName(specVersion));
            var cloudEventSource = new Uri(GetAttribute(message, CloudEventAttributes.SourceAttributeName(specVersion)));
            var cloudEvent       = new CloudEvent(specVersion, cloudEventType, cloudEventSource, id: message.MessageId, extensions: extensions);
            var attributes       = cloudEvent.GetAttributes();

            foreach (var property in message.UserProperties)
            {
                if (property.Key.StartsWith(Constants.PropertyKeyPrefix, StringComparison.InvariantCultureIgnoreCase))
                {
#pragma warning disable CA1308 // Normalize strings to uppercase
                    var key = property.Key.Substring(Constants.PropertyKeyPrefix.Length).ToLowerInvariant();
#pragma warning restore CA1308 // Normalize strings to uppercase

                    attributes[key] = property.Value;
                }
            }

            cloudEvent.DataContentType = message.ContentType == null ? null : new ContentType(message.ContentType);
            cloudEvent.Data            = message.Body;
            return(cloudEvent);
        }
Ejemplo n.º 14
0
        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);
                    }
                }
            }
        }
    }
        public CloudEvent DecodeJObject(JObject jObject, IEnumerable <ICloudEventExtension> extensions)
        {
            if (jObject == null)
            {
                throw new ArgumentNullException(nameof(jObject));
            }

            var specVersion = GetSpecVersion(jObject);
            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.OrdinalIgnoreCase) ||
                    keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V0_2), StringComparison.OrdinalIgnoreCase) ||
                    keyValuePair.Key.Equals(CloudEventAttributes.SpecVersionAttributeName(CloudEventsSpecVersion.V1_0), StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                if (
                    specVersion == CloudEventsSpecVersion.V1_0 &&
                    keyValuePair.Key.Equals("data_base64", StringComparison.OrdinalIgnoreCase)
                    )
                {
                    attributes["data"] = Convert.FromBase64String(keyValuePair.Value.ToString());
                    continue;
                }

                if (keyValuePair.Key.Equals(CloudEventAttributes.DataAttributeName(specVersion), StringComparison.OrdinalIgnoreCase))
                {
                    try
                    {
                        attributes[keyValuePair.Key] = keyValuePair.Value.ToObject <T>(_serializer);
                        continue;
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException($"Failed to deserialize data of type {typeof(T).FullName}", ex);
                    }
                }

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

                case JTokenType.Date:
                    var timeValue = ((JValue)keyValuePair.Value).Value;     // The value type may be DateTime or DateTimeOffset
                    if (keyValuePair.Key.Equals(CloudEventAttributes.TimeAttributeName(specVersion), StringComparison.OrdinalIgnoreCase) &&
                        timeValue is DateTimeOffset dateTimeOffset)
                    {
                        attributes[keyValuePair.Key] = dateTimeOffset.UtcDateTime;
                    }
                    else
                    {
                        attributes[keyValuePair.Key] = timeValue;
                    }

                    break;

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

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

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

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

            return(cloudEvent);
        }