/// <summary> /// Builds an <see cref="EventData" /> from an <see cref="AmqpMessage" />. /// </summary> /// /// <param name="source">The message to use as the source of the event.</param> /// /// <returns>The <see cref="EventData" /> constructed from the source message.</returns> /// private static EventData BuildEventFromAmqpMessage(AmqpMessage source) { ReadOnlyMemory <byte> body = (source.BodyType.HasFlag(SectionFlag.Data)) ? ReadStreamToMemory(source.BodyStream) : ReadOnlyMemory <byte> .Empty; ParsedAnnotations systemAnnotations = ParseSystemAnnotations(source); // If there were application properties associated with the message, translate them // to the event. var properties = default(Dictionary <string, object>); if (source.Sections.HasFlag(SectionFlag.ApplicationProperties)) { properties = new Dictionary <string, object>(); foreach (KeyValuePair <MapKey, object> pair in source.ApplicationProperties.Map) { if (TryCreateEventPropertyForAmqpProperty(pair.Value, out object propertyValue)) { properties[pair.Key.ToString()] = propertyValue; } } } return(new EventData( eventBody: body, properties: properties, systemProperties: systemAnnotations.ServiceAnnotations, sequenceNumber: systemAnnotations.SequenceNumber ?? long.MinValue, offset: systemAnnotations.Offset ?? long.MinValue, enqueuedTime: systemAnnotations.EnqueuedTime ?? default, partitionKey: systemAnnotations.PartitionKey, lastPartitionSequenceNumber: systemAnnotations.LastSequenceNumber, lastPartitionOffset: systemAnnotations.LastOffset, lastPartitionEnqueuedTime: systemAnnotations.LastEnqueuedTime, lastPartitionPropertiesRetrievalTime: systemAnnotations.LastReceivedTime)); }
/// <summary> /// Parses the annotations set by the Event Hubs service on the <see cref="AmqpMessage"/> /// associated with an event, extracting them into a consumable form. /// </summary> /// /// <param name="source">The message to use as the source of the event.</param> /// /// <returns>The <see cref="ParsedAnnotations" /> parsed from the source message.</returns> /// private static ParsedAnnotations ParseSystemAnnotations(AmqpMessage source) { var systemProperties = new ParsedAnnotations { ServiceAnnotations = new Dictionary <string, object>() }; object amqpValue; object propertyValue; // Process the message annotations. if (source.Sections.HasFlag(SectionFlag.MessageAnnotations)) { Annotations annotations = source.MessageAnnotations.Map; var processed = new HashSet <string>(); if ((annotations.TryGetValue(AmqpProperty.EnqueuedTime, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue))) { systemProperties.EnqueuedTime = propertyValue switch { DateTime dateValue => new DateTimeOffset(dateValue, TimeSpan.Zero), long longValue => new DateTimeOffset(longValue, TimeSpan.Zero), _ => (DateTimeOffset)propertyValue }; processed.Add(AmqpProperty.EnqueuedTime.ToString()); } if ((annotations.TryGetValue(AmqpProperty.SequenceNumber, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue))) { systemProperties.SequenceNumber = (long)propertyValue; processed.Add(AmqpProperty.SequenceNumber.ToString()); } if ((annotations.TryGetValue(AmqpProperty.Offset, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue)) && (long.TryParse((string)propertyValue, out var offset))) { systemProperties.Offset = offset; processed.Add(AmqpProperty.Offset.ToString()); } if ((annotations.TryGetValue(AmqpProperty.PartitionKey, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue))) { systemProperties.PartitionKey = (string)propertyValue; processed.Add(AmqpProperty.PartitionKey.ToString()); } string key; foreach (KeyValuePair <MapKey, object> pair in annotations) { key = pair.Key.ToString(); if ((!processed.Contains(key)) && (TryCreateEventPropertyForAmqpProperty(pair.Value, out propertyValue))) { systemProperties.ServiceAnnotations.Add(key, propertyValue); processed.Add(key); } } } // Process the delivery annotations. if (source.Sections.HasFlag(SectionFlag.DeliveryAnnotations)) { if ((source.DeliveryAnnotations.Map.TryGetValue(AmqpProperty.PartitionLastEnqueuedTimeUtc, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue))) { systemProperties.LastEnqueuedTime = propertyValue switch { DateTime dateValue => new DateTimeOffset(dateValue, TimeSpan.Zero), long longValue => new DateTimeOffset(longValue, TimeSpan.Zero), _ => (DateTimeOffset)propertyValue }; } if ((source.DeliveryAnnotations.Map.TryGetValue(AmqpProperty.PartitionLastEnqueuedSequenceNumber, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue))) { systemProperties.LastSequenceNumber = (long)propertyValue; } if ((source.DeliveryAnnotations.Map.TryGetValue(AmqpProperty.PartitionLastEnqueuedOffset, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue)) && (long.TryParse((string)propertyValue, out var offset))) { systemProperties.LastOffset = offset; } if ((source.DeliveryAnnotations.Map.TryGetValue(AmqpProperty.LastPartitionInformationRetrievalTimeUtc, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue))) { systemProperties.LastReceivedTime = propertyValue switch { DateTime dateValue => new DateTimeOffset(dateValue, TimeSpan.Zero), long longValue => new DateTimeOffset(longValue, TimeSpan.Zero), _ => (DateTimeOffset)propertyValue }; } } // Process the properties annotations if (source.Sections.HasFlag(SectionFlag.Properties)) { Properties properties = source.Properties; void conditionalAdd(string name, object value, bool condition) { if (condition) { systemProperties.ServiceAnnotations.Add(name, value); } } conditionalAdd(Properties.MessageIdName, properties.MessageId, properties.MessageId != null); conditionalAdd(Properties.UserIdName, properties.UserId, properties.UserId.Array != null); conditionalAdd(Properties.ToName, properties.To, properties.To != null); conditionalAdd(Properties.SubjectName, properties.Subject, properties.Subject != null); conditionalAdd(Properties.ReplyToName, properties.ReplyTo, properties.ReplyTo != null); conditionalAdd(Properties.CorrelationIdName, properties.CorrelationId, properties.CorrelationId != null); conditionalAdd(Properties.ContentTypeName, properties.ContentType, properties.ContentType.Value != null); conditionalAdd(Properties.ContentEncodingName, properties.ContentEncoding, properties.ContentEncoding.Value != null); conditionalAdd(Properties.AbsoluteExpiryTimeName, properties.AbsoluteExpiryTime, properties.AbsoluteExpiryTime != null); conditionalAdd(Properties.CreationTimeName, properties.CreationTime, properties.CreationTime != null); conditionalAdd(Properties.GroupIdName, properties.GroupId, properties.GroupId != null); conditionalAdd(Properties.GroupSequenceName, properties.GroupSequence, properties.GroupSequence != null); conditionalAdd(Properties.ReplyToGroupIdName, properties.ReplyToGroupId, properties.ReplyToGroupId != null); } return(systemProperties); }
/// <summary> /// Parses the annotations set by the Event Hubs service on the <see cref="AmqpMessage"/> /// associated with an event, extracting them into a consumable form. /// </summary> /// /// <param name="source">The message to use as the source of the event.</param> /// /// <returns>The <see cref="ParsedAnnotations" /> parsed from the source message.</returns> /// private static ParsedAnnotations ParseSystemAnnotations(AmqpMessage source) { var systemProperties = new ParsedAnnotations(); systemProperties.ServiceAnnotations = new Dictionary <string, object>(); object amqpValue; object propertyValue; // Process the message annotations. if (source.Sections.HasFlag(SectionFlag.MessageAnnotations)) { var annotations = source.MessageAnnotations.Map; var processed = new HashSet <string>(); if ((annotations.TryGetValue(AmqpProperty.EnqueuedTime, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue))) { systemProperties.EnqueuedTime = (DateTimeOffset)propertyValue; processed.Add(AmqpProperty.EnqueuedTime.ToString()); } if ((annotations.TryGetValue(AmqpProperty.SequenceNumber, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue))) { systemProperties.SequenceNumber = (long)propertyValue; processed.Add(AmqpProperty.SequenceNumber.ToString()); } if ((annotations.TryGetValue(AmqpProperty.Offset, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue)) && (Int64.TryParse((string)propertyValue, out var offset))) { systemProperties.Offset = offset; processed.Add(AmqpProperty.Offset.ToString()); } if ((annotations.TryGetValue(AmqpProperty.PartitionKey, out amqpValue)) && (TryCreateEventPropertyForAmqpProperty(amqpValue, out propertyValue))) { systemProperties.PartitionKey = (string)propertyValue; processed.Add(AmqpProperty.PartitionKey.ToString()); } string key; foreach (var pair in annotations) { key = pair.Key.ToString(); if ((!processed.Contains(key)) && (TryCreateEventPropertyForAmqpProperty(pair.Value, out propertyValue))) { systemProperties.ServiceAnnotations.Add(key, propertyValue); processed.Add(key); } } } // Process the properties annotations if (source.Sections.HasFlag(SectionFlag.Properties)) { var properties = source.Properties; void conditionalAdd(string name, object value, bool condition) { if (condition) { systemProperties.ServiceAnnotations.Add(name, value); } } conditionalAdd(Properties.MessageIdName, properties.MessageId, properties.MessageId != null); conditionalAdd(Properties.UserIdName, properties.UserId, properties.UserId.Array != null); conditionalAdd(Properties.ToName, properties.To, properties.To != null); conditionalAdd(Properties.SubjectName, properties.Subject, properties.Subject != null); conditionalAdd(Properties.ReplyToName, properties.ReplyTo, properties.ReplyTo != null); conditionalAdd(Properties.CorrelationIdName, properties.CorrelationId, properties.CorrelationId != null); conditionalAdd(Properties.ContentTypeName, properties.ContentType, properties.ContentType.Value != null); conditionalAdd(Properties.ContentEncodingName, properties.ContentEncoding, properties.ContentEncoding.Value != null); conditionalAdd(Properties.AbsoluteExpiryTimeName, properties.AbsoluteExpiryTime, properties.AbsoluteExpiryTime != null); conditionalAdd(Properties.CreationTimeName, properties.CreationTime, properties.CreationTime != null); conditionalAdd(Properties.GroupIdName, properties.GroupId, properties.GroupId != null); conditionalAdd(Properties.GroupSequenceName, properties.GroupSequence, properties.GroupSequence != null); conditionalAdd(Properties.ReplyToGroupIdName, properties.ReplyToGroupId, properties.ReplyToGroupId != null); } return(systemProperties); }