/// <summary>
        ///   Attempts to add a message to the batch, ensuring that the size
        ///   of the batch does not exceed its maximum.
        /// </summary>
        ///
        /// <param name="message">The message to attempt to add to the batch.</param>
        ///
        /// <returns><c>true</c> if the message was added; otherwise, <c>false</c>.</returns>
        ///
        public override bool TryAdd(ServiceBusMessage message)
        {
            Argument.AssertNotNull(message, nameof(message));
            Argument.AssertNotDisposed(_disposed, nameof(ServiceBusMessageBatch));

            AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message);

            try
            {
                // Calculate the size for the message, based on the AMQP message size and accounting for a
                // bit of reserved overhead size.

                var size = _sizeBytes
                           + amqpMessage.SerializedMessageSize
                           + (amqpMessage.SerializedMessageSize <= MaximumBytesSmallMessage
                        ? OverheadBytesSmallMessage
                        : OverheadBytesLargeMessage);

                if (size > MaxSizeInBytes)
                {
                    return(false);
                }

                _sizeBytes = size;
                BatchMessages.Add(message);

                return(true);
            }
            finally
            {
                amqpMessage?.Dispose();
            }
        }
Пример #2
0
        /// <summary>
        ///   Attempts to add an event to the batch, ensuring that the size
        ///   of the batch does not exceed its maximum.
        /// </summary>
        ///
        /// <param name="eventData">The event to attempt to add to the batch.</param>
        ///
        /// <returns><c>true</c> if the event was added; otherwise, <c>false</c>.</returns>
        ///
        public override bool TryAdd(EventData eventData)
        {
            Argument.AssertNotNull(eventData, nameof(eventData));
            Argument.AssertNotDisposed(_disposed, nameof(EventDataBatch));

            AmqpMessage eventMessage = MessageConverter.CreateMessageFromEvent(eventData, Options.PartitionKey);

            try
            {
                // Calculate the size for the event, based on the AMQP message size and accounting for a
                // bit of reserved overhead size.

                var size = _sizeBytes
                           + eventMessage.SerializedMessageSize
                           + (eventMessage.SerializedMessageSize <= MaximumBytesSmallMessage
                        ? OverheadBytesSmallMessage
                        : OverheadBytesLargeMessage);

                if (size > MaximumSizeInBytes)
                {
                    return(false);
                }

                _sizeBytes = size;
                BatchEvents.Add(eventData);

                return(true);
            }
            finally
            {
                eventMessage?.Dispose();
            }
        }
Пример #3
0
                void OnMessage(AmqpMessage message)
                {
                    string errorCondition = null;

                    if (message.ApplicationProperties != null &&
                        message.ApplicationProperties.Map.TryGetValue <string>("errorcondition", out errorCondition))
                    {
                        this.link.DisposeMessage(message, new Rejected()
                        {
                            Error = new Error()
                            {
                                Condition = errorCondition, Description = "message was rejected"
                            }
                        }, true, false);
                    }
                    else
                    {
                        if (message.TxnId.Array != null)
                        {
                            Transaction txn = this.queue.broker.txnManager.GetTransaction(message.TxnId);
                            txn.AddOperation(message, this.OnTxnDischarge);
                            this.link.DisposeMessage(message, new TransactionalState()
                            {
                                Outcome = AmqpConstants.AcceptedOutcome
                            }, true, message.Batchable);
                        }
                        else
                        {
                            this.queue.Enqueue(new BrokerMessage(message));
                            this.link.AcceptMessage(message, message.Batchable);
                            message.Dispose();
                        }
                    }
                }
Пример #4
0
        public void AmqpWebSocketTransportTest()
        {
            string address = "ws://localhost:28088";
            var    broker  = new TestAmqpBroker(new string[] { address }, null, null, null);

            try
            {
                broker.Start();

                string queue = "AmqpWebSocketTransportTest";
                broker.AddQueue(queue);

                AmqpConnection connection = AmqpConnection.Factory.OpenConnectionAsync(address).GetAwaiter().GetResult();

                AmqpSession session = connection.CreateSession(new AmqpSessionSettings());
                session.Open();

                SendingAmqpLink sLink = new SendingAmqpLink(session, AmqpUtils.GetLinkSettings(true, queue, SettleMode.SettleOnSend));
                sLink.Open();

                int messageCount = 100;
                for (int i = 0; i < messageCount; i++)
                {
                    AmqpMessage message = AmqpMessage.Create(new AmqpValue()
                    {
                        Value = "message" + i
                    });
                    sLink.SendMessageAsync(message, AmqpConstants.EmptyBinary, AmqpConstants.NullBinary, TimeSpan.FromSeconds(10)).Wait();
                }

                sLink.Close();

                ReceivingAmqpLink rLink = new ReceivingAmqpLink(session, AmqpUtils.GetLinkSettings(false, queue, SettleMode.SettleOnReceive, 100));
                rLink.Open();

                for (int i = 0; i < messageCount; i++)
                {
                    AmqpMessage message2 = rLink.ReceiveMessageAsync(TimeSpan.FromSeconds(60)).GetAwaiter().GetResult();
                    Assert.NotNull(message2);

                    rLink.AcceptMessage(message2, false);
                    message2.Dispose();
                }

                rLink.Close();

                connection.Close();
            }
            finally
            {
                broker.Stop();
            }
        }
Пример #5
0
        private void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    AmqpMessage?.Dispose();
                }

                disposed = true;
            }
        }
        private async Task <RegistrationOperationStatus> RegisterDeviceAsync(
            AmqpClientConnection client,
            string correlationId,
            DeviceRegistration deviceRegistration)
        {
            AmqpMessage amqpMessage = null;

            try
            {
                if (deviceRegistration == null)
                {
                    amqpMessage = AmqpMessage.Create(new MemoryStream(), true);
                }
                else
                {
                    var customContentStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(deviceRegistration)));
                    amqpMessage = AmqpMessage.Create(customContentStream, true);
                }

                amqpMessage.Properties.CorrelationId = correlationId;
                amqpMessage.ApplicationProperties.Map[MessageApplicationPropertyNames.OperationType]     = DeviceOperations.Register;
                amqpMessage.ApplicationProperties.Map[MessageApplicationPropertyNames.ForceRegistration] = false;

                Outcome outcome = await client.AmqpSession.SendingLink
                                  .SendMessageAsync(
                    amqpMessage,
                    new ArraySegment <byte>(Guid.NewGuid().ToByteArray()),
                    s_timeoutConstant)
                                  .ConfigureAwait(false);

                ValidateOutcome(outcome);

                AmqpMessage amqpResponse = await client.AmqpSession.ReceivingLink.ReceiveMessageAsync(s_timeoutConstant).ConfigureAwait(false);

                client.AmqpSession.ReceivingLink.AcceptMessage(amqpResponse);

                using (var streamReader = new StreamReader(amqpResponse.BodyStream))
                {
                    string jsonResponse = await streamReader
                                          .ReadToEndAsync()
                                          .ConfigureAwait(false);

                    RegistrationOperationStatus status = JsonConvert.DeserializeObject <RegistrationOperationStatus>(jsonResponse);
                    status.RetryAfter = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultOperationPoolingInterval);
                    return(status);
                }
            }
            finally
            {
                amqpMessage?.Dispose();
            }
        }
Пример #7
0
        public void AmqpWebSocketTransportTest()
        {
            string queue = "AmqpWebSocketTransportTest";

            broker.AddQueue(queue);

            AmqpConnection connection = AmqpConnection.Factory.OpenConnectionAsync(
                TestAmqpBrokerFixture.WsAddress.OriginalString).GetAwaiter().GetResult();

            AmqpSession session = connection.CreateSession(new AmqpSessionSettings());

            session.Open();

            SendingAmqpLink sLink = new SendingAmqpLink(session, AmqpUtils.GetLinkSettings(true, queue, SettleMode.SettleOnSend));

            sLink.Open();

            int messageCount = 1800;

            for (int i = 0; i < messageCount; i++)
            {
                AmqpMessage message = AmqpMessage.Create(new AmqpValue()
                {
                    Value = "message" + i
                });
                sLink.SendMessageAsync(message, EmptyBinary, NullBinary, TimeSpan.FromSeconds(10)).Wait();
            }

            sLink.Close();

            ReceivingAmqpLink rLink = new ReceivingAmqpLink(session, AmqpUtils.GetLinkSettings(false, queue, SettleMode.SettleOnReceive, 100));

            rLink.Open();

            for (int i = 0; i < messageCount; i++)
            {
                AmqpMessage message2 = rLink.ReceiveMessageAsync(TimeSpan.FromSeconds(60)).GetAwaiter().GetResult();
                Assert.NotNull(message2);

                rLink.AcceptMessage(message2);
                message2.Dispose();
            }

            rLink.Close();

            connection.Close();
        }
Пример #8
0
        /// <summary>
        ///   Attempts to add a message to the batch, ensuring that the size
        ///   of the batch does not exceed its maximum.
        /// </summary>
        ///
        /// <param name="message">The message to attempt to add to the batch.</param>
        ///
        /// <returns><c>true</c> if the message was added; otherwise, <c>false</c>.</returns>
        ///
        public override bool TryAddMessage(ServiceBusMessage message)
        {
            Argument.AssertNotNull(message, nameof(message));
            Argument.AssertNotDisposed(_disposed, nameof(ServiceBusMessageBatch));

            AmqpMessage amqpMessage = null;

            try
            {
                if (BatchMessages.Count == 0)
                {
                    // Initialize the size by reserving space for the batch envelope taking into account the properties from the first
                    // message which will be used to populate properties on the batch envelope.
                    amqpMessage = AmqpMessageConverter.BatchSBMessagesAsAmqpMessage(message, forceBatch: true);
                }
                else
                {
                    amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message);
                }

                // Calculate the size for the message, based on the AMQP message size and accounting for a
                // bit of reserved overhead size.

                var size = _sizeBytes
                           + amqpMessage.SerializedMessageSize
                           + (amqpMessage.SerializedMessageSize <= MaximumBytesSmallMessage
                        ? OverheadBytesSmallMessage
                        : OverheadBytesLargeMessage);

                if (size > MaxSizeInBytes)
                {
                    return(false);
                }

                _sizeBytes = size;
                BatchMessages.Add(message);

                return(true);
            }
            finally
            {
                amqpMessage?.Dispose();
            }
        }
Пример #9
0
        internal async Task ProcessMessageAsync(AmqpMessage amqpMessage)
        {
            if (this.Link.State != AmqpObjectState.Opened)
            {
                Events.InvalidLinkState(this);
                return;
            }

            try
            {
                await this.OnMessageReceived(amqpMessage);

                ((IReceivingAmqpLink)this.Link).DisposeMessage(amqpMessage, AmqpConstants.AcceptedOutcome, true, true);
                amqpMessage.Dispose();
            }
            catch (Exception e) when(!e.IsFatal())
            {
                Events.ErrorProcessingMessage(e, this);
            }
        }
Пример #10
0
        void HandleException(Exception ex, AmqpMessage incoming, IList <AmqpMessage> outgoing)
        {
            // Get AmqpException
            AmqpException amqpException = AmqpExceptionsHelper.GetAmqpException(ex);
            var           rejected      = new Rejected {
                Error = amqpException.Error
            };

            ((IReceivingAmqpLink)this.Link).DisposeMessage(incoming, rejected, true, true);

            incoming?.Dispose();
            if (outgoing != null)
            {
                foreach (AmqpMessage message in outgoing)
                {
                    message.Dispose();
                }
            }

            Events.ErrorSending(ex, this);
        }
        public static ServiceBusReceivedMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage, bool isPeeked = false)
        {
            Argument.AssertNotNull(amqpMessage, nameof(amqpMessage));
            AmqpAnnotatedMessage annotatedMessage;

            if ((amqpMessage.BodyType & SectionFlag.Data) != 0 && amqpMessage.DataBody != null)
            {
                annotatedMessage = new AmqpAnnotatedMessage(amqpMessage.GetDataViaDataBody());
            }
            else
            {
                annotatedMessage = new AmqpAnnotatedMessage(new ReadOnlyMemory <byte>[] { Array.Empty <byte>() });
            }
            ServiceBusReceivedMessage sbMessage = new ServiceBusReceivedMessage(annotatedMessage);

            SectionFlag sections = amqpMessage.Sections;

            if ((sections & SectionFlag.Header) != 0)
            {
                if (amqpMessage.Header.Ttl != null)
                {
                    annotatedMessage.Header.TimeToLive = TimeSpan.FromMilliseconds(amqpMessage.Header.Ttl.Value);
                }

                if (amqpMessage.Header.DeliveryCount != null)
                {
                    annotatedMessage.Header.DeliveryCount = isPeeked ? (amqpMessage.Header.DeliveryCount.Value) : (amqpMessage.Header.DeliveryCount.Value + 1);
                }
            }

            if ((sections & SectionFlag.Properties) != 0)
            {
                if (amqpMessage.Properties.MessageId != null)
                {
                    annotatedMessage.Properties.MessageId = new AmqpMessageId(amqpMessage.Properties.MessageId.ToString());
                }

                if (amqpMessage.Properties.CorrelationId != null)
                {
                    annotatedMessage.Properties.CorrelationId = new AmqpMessageId(amqpMessage.Properties.CorrelationId.ToString());
                }

                if (amqpMessage.Properties.ContentType.Value != null)
                {
                    annotatedMessage.Properties.ContentType = amqpMessage.Properties.ContentType.Value;
                }

                if (amqpMessage.Properties.Subject != null)
                {
                    annotatedMessage.Properties.Subject = amqpMessage.Properties.Subject;
                }

                if (amqpMessage.Properties.To != null)
                {
                    annotatedMessage.Properties.To = new AmqpAddress(amqpMessage.Properties.To.ToString());
                }

                if (amqpMessage.Properties.ReplyTo != null)
                {
                    annotatedMessage.Properties.ReplyTo = new AmqpAddress(amqpMessage.Properties.ReplyTo.ToString());
                }

                if (amqpMessage.Properties.GroupId != null)
                {
                    annotatedMessage.Properties.GroupId = amqpMessage.Properties.GroupId;
                }

                if (amqpMessage.Properties.ReplyToGroupId != null)
                {
                    annotatedMessage.Properties.ReplyToGroupId = amqpMessage.Properties.ReplyToGroupId;
                }
            }

            // Do application properties before message annotations, because the application properties
            // can be updated by entries from message annotation.
            if ((sections & SectionFlag.ApplicationProperties) != 0)
            {
                foreach (var pair in amqpMessage.ApplicationProperties.Map)
                {
                    if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject))
                    {
                        annotatedMessage.ApplicationProperties[pair.Key.ToString()] = netObject;
                    }
                }
            }

            if ((sections & SectionFlag.MessageAnnotations) != 0)
            {
                foreach (var pair in amqpMessage.MessageAnnotations.Map)
                {
                    var key = pair.Key.ToString();
                    switch (key)
                    {
                    case AmqpMessageConstants.EnqueuedTimeUtcName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.EnqueuedTimeUtcName] = (DateTime)pair.Value;
                        break;

                    case AmqpMessageConstants.ScheduledEnqueueTimeUtcName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.ScheduledEnqueueTimeUtcName] = (DateTime)pair.Value;
                        break;

                    case AmqpMessageConstants.SequenceNumberName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.SequenceNumberName] = (long)pair.Value;
                        break;

                    case AmqpMessageConstants.EnqueueSequenceNumberName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.EnqueueSequenceNumberName] = (long)pair.Value;
                        break;

                    case AmqpMessageConstants.LockedUntilName:
                        DateTimeOffset lockedUntil = (DateTime)pair.Value >= DateTimeOffset.MaxValue.UtcDateTime ?
                                                     DateTimeOffset.MaxValue : (DateTime)pair.Value;
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.LockedUntilName] = lockedUntil.UtcDateTime;
                        break;

                    case AmqpMessageConstants.PartitionKeyName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.PartitionKeyName] = (string)pair.Value;
                        break;

                    case AmqpMessageConstants.PartitionIdName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.PartitionIdName] = (short)pair.Value;
                        break;

                    case AmqpMessageConstants.ViaPartitionKeyName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.ViaPartitionKeyName] = (string)pair.Value;
                        break;

                    case AmqpMessageConstants.DeadLetterSourceName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.DeadLetterSourceName] = (string)pair.Value;
                        break;

                    default:
                        if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject))
                        {
                            annotatedMessage.MessageAnnotations[key] = netObject;
                        }
                        break;
                    }
                }
            }

            if (amqpMessage.DeliveryTag.Count == GuidSizeInBytes)
            {
                var guidBuffer = new byte[GuidSizeInBytes];
                Buffer.BlockCopy(amqpMessage.DeliveryTag.Array, amqpMessage.DeliveryTag.Offset, guidBuffer, 0, GuidSizeInBytes);
                sbMessage.LockTokenGuid = new Guid(guidBuffer);
            }

            amqpMessage.Dispose();

            return(sbMessage);
        }
Пример #12
0
        public static ServiceBusReceivedMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage, bool isPeeked = false)
        {
            Argument.AssertNotNull(amqpMessage, nameof(amqpMessage));
            AmqpAnnotatedMessage annotatedMessage;

            if ((amqpMessage.BodyType & SectionFlag.Data) != 0 && amqpMessage.DataBody != null)
            {
                annotatedMessage = new AmqpAnnotatedMessage(AmqpMessageBody.FromData(BodyMemory.FromAmqpData(amqpMessage.DataBody)));
            }
            else if ((amqpMessage.BodyType & SectionFlag.AmqpValue) != 0 && amqpMessage.ValueBody?.Value != null)
            {
                if (TryGetNetObjectFromAmqpObject(amqpMessage.ValueBody.Value, MappingType.MessageBody, out object netObject))
                {
                    annotatedMessage = new AmqpAnnotatedMessage(AmqpMessageBody.FromValue(netObject));
                }
                else
                {
                    throw new NotSupportedException(Resources.InvalidAmqpMessageValueBody.FormatForUser(amqpMessage.ValueBody.Value.GetType()));
                }
            }
            else if ((amqpMessage.BodyType & SectionFlag.AmqpSequence) != 0)
            {
                annotatedMessage = new AmqpAnnotatedMessage(
                    AmqpMessageBody.FromSequence(amqpMessage.SequenceBody.Select(s => (IList <object>)s.List).ToList()));
            }
            // default to using an empty Data section if no data
            else
            {
                annotatedMessage = new AmqpAnnotatedMessage(new AmqpMessageBody(Enumerable.Empty <ReadOnlyMemory <byte> >()));
            }
            ServiceBusReceivedMessage sbMessage = new ServiceBusReceivedMessage(annotatedMessage);

            SectionFlag sections = amqpMessage.Sections;

            if ((sections & SectionFlag.Header) != 0)
            {
                if (amqpMessage.Header.Ttl != null)
                {
                    annotatedMessage.Header.TimeToLive = TimeSpan.FromMilliseconds(amqpMessage.Header.Ttl.Value);
                }

                if (amqpMessage.Header.DeliveryCount != null)
                {
                    annotatedMessage.Header.DeliveryCount = isPeeked ? (amqpMessage.Header.DeliveryCount.Value) : (amqpMessage.Header.DeliveryCount.Value + 1);
                }
            }

            if ((sections & SectionFlag.Properties) != 0)
            {
                if (amqpMessage.Properties.MessageId != null)
                {
                    annotatedMessage.Properties.MessageId = new AmqpMessageId(amqpMessage.Properties.MessageId.ToString());
                }

                if (amqpMessage.Properties.CorrelationId != null)
                {
                    annotatedMessage.Properties.CorrelationId = new AmqpMessageId(amqpMessage.Properties.CorrelationId.ToString());
                }

                if (amqpMessage.Properties.ContentType.Value != null)
                {
                    annotatedMessage.Properties.ContentType = amqpMessage.Properties.ContentType.Value;
                }

                if (amqpMessage.Properties.Subject != null)
                {
                    annotatedMessage.Properties.Subject = amqpMessage.Properties.Subject;
                }

                if (amqpMessage.Properties.To != null)
                {
                    annotatedMessage.Properties.To = new AmqpAddress(amqpMessage.Properties.To.ToString());
                }

                if (amqpMessage.Properties.ReplyTo != null)
                {
                    annotatedMessage.Properties.ReplyTo = new AmqpAddress(amqpMessage.Properties.ReplyTo.ToString());
                }

                if (amqpMessage.Properties.GroupId != null)
                {
                    annotatedMessage.Properties.GroupId = amqpMessage.Properties.GroupId;
                }

                if (amqpMessage.Properties.ReplyToGroupId != null)
                {
                    annotatedMessage.Properties.ReplyToGroupId = amqpMessage.Properties.ReplyToGroupId;
                }
            }

            // Do application properties before message annotations, because the application properties
            // can be updated by entries from message annotation.
            if ((sections & SectionFlag.ApplicationProperties) != 0)
            {
                foreach (var pair in amqpMessage.ApplicationProperties.Map)
                {
                    if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject))
                    {
                        annotatedMessage.ApplicationProperties[pair.Key.ToString()] = netObject;
                    }
                }
            }

            if ((sections & SectionFlag.MessageAnnotations) != 0)
            {
                foreach (var pair in amqpMessage.MessageAnnotations.Map)
                {
                    var key = pair.Key.ToString();
                    switch (key)
                    {
                    case AmqpMessageConstants.EnqueuedTimeUtcName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.EnqueuedTimeUtcName] = pair.Value;
                        break;

                    case AmqpMessageConstants.ScheduledEnqueueTimeUtcName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.ScheduledEnqueueTimeUtcName] = pair.Value;
                        break;

                    case AmqpMessageConstants.SequenceNumberName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.SequenceNumberName] = pair.Value;
                        break;

                    case AmqpMessageConstants.EnqueueSequenceNumberName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.EnqueueSequenceNumberName] = pair.Value;
                        break;

                    case AmqpMessageConstants.LockedUntilName:
                        DateTimeOffset lockedUntil = (DateTime)pair.Value >= DateTimeOffset.MaxValue.UtcDateTime ?
                                                     DateTimeOffset.MaxValue : (DateTime)pair.Value;
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.LockedUntilName] = lockedUntil.UtcDateTime;
                        break;

                    case AmqpMessageConstants.PartitionKeyName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.PartitionKeyName] = pair.Value;
                        break;

                    case AmqpMessageConstants.PartitionIdName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.PartitionIdName] = pair.Value;
                        break;

                    case AmqpMessageConstants.ViaPartitionKeyName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.ViaPartitionKeyName] = pair.Value;
                        break;

                    case AmqpMessageConstants.DeadLetterSourceName:
                        annotatedMessage.MessageAnnotations[AmqpMessageConstants.DeadLetterSourceName] = pair.Value;
                        break;

                    default:
                        if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject))
                        {
                            annotatedMessage.MessageAnnotations[key] = netObject;
                        }
                        break;
                    }
                }
            }

            if (amqpMessage.DeliveryTag.Count == GuidSizeInBytes)
            {
                Span <byte> guidBytes = stackalloc byte[GuidSizeInBytes];
                amqpMessage.DeliveryTag.AsSpan().CopyTo(guidBytes);
                if (!MemoryMarshal.TryRead <Guid>(guidBytes, out var lockTokenGuid))
                {
                    lockTokenGuid = new Guid(guidBytes.ToArray());
                }
                sbMessage.LockTokenGuid = lockTokenGuid;
            }

            amqpMessage.Dispose();

            return(sbMessage);
        }
        public static ServiceBusReceivedMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage, bool isPeeked = false)
        {
            Argument.AssertNotNull(amqpMessage, nameof(amqpMessage));

            ServiceBusReceivedMessage sbMessage = amqpMessage.ToServiceBusReceivedMessage();
            var sections = amqpMessage.Sections;

            if ((sections & SectionFlag.Header) != 0)
            {
                if (amqpMessage.Header.Ttl != null)
                {
                    sbMessage.SentMessage.TimeToLive = TimeSpan.FromMilliseconds(amqpMessage.Header.Ttl.Value);
                }

                if (amqpMessage.Header.DeliveryCount != null)
                {
                    sbMessage.DeliveryCount = isPeeked ? (int)(amqpMessage.Header.DeliveryCount.Value) : (int)(amqpMessage.Header.DeliveryCount.Value + 1);
                }
            }

            if ((sections & SectionFlag.Properties) != 0)
            {
                if (amqpMessage.Properties.MessageId != null)
                {
                    sbMessage.SentMessage.MessageId = amqpMessage.Properties.MessageId.ToString();
                }

                if (amqpMessage.Properties.CorrelationId != null)
                {
                    sbMessage.SentMessage.CorrelationId = amqpMessage.Properties.CorrelationId.ToString();
                }

                if (amqpMessage.Properties.ContentType.Value != null)
                {
                    sbMessage.SentMessage.ContentType = amqpMessage.Properties.ContentType.Value;
                }

                if (amqpMessage.Properties.Subject != null)
                {
                    sbMessage.SentMessage.Label = amqpMessage.Properties.Subject;
                }

                if (amqpMessage.Properties.To != null)
                {
                    sbMessage.SentMessage.To = amqpMessage.Properties.To.ToString();
                }

                if (amqpMessage.Properties.ReplyTo != null)
                {
                    sbMessage.SentMessage.ReplyTo = amqpMessage.Properties.ReplyTo.ToString();
                }

                if (amqpMessage.Properties.GroupId != null)
                {
                    sbMessage.SentMessage.SessionId = amqpMessage.Properties.GroupId;
                }

                if (amqpMessage.Properties.ReplyToGroupId != null)
                {
                    sbMessage.SentMessage.ReplyToSessionId = amqpMessage.Properties.ReplyToGroupId;
                }
            }

            // Do application properties before message annotations, because the application properties
            // can be updated by entries from message annotation.
            if ((sections & SectionFlag.ApplicationProperties) != 0)
            {
                foreach (var pair in amqpMessage.ApplicationProperties.Map)
                {
                    if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject))
                    {
                        sbMessage.SentMessage.Properties[pair.Key.ToString()] = netObject;
                    }
                }
            }

            if ((sections & SectionFlag.MessageAnnotations) != 0)
            {
                foreach (var pair in amqpMessage.MessageAnnotations.Map)
                {
                    var key = pair.Key.ToString();
                    switch (key)
                    {
                    case EnqueuedTimeUtcName:
                        sbMessage.EnqueuedTime = (DateTime)pair.Value;
                        break;

                    case ScheduledEnqueueTimeUtcName:
                        sbMessage.SentMessage.ScheduledEnqueueTime = (DateTime)pair.Value;
                        break;

                    case SequenceNumberName:
                        sbMessage.SequenceNumber = (long)pair.Value;
                        break;

                    case EnqueueSequenceNumberName:
                        sbMessage.EnqueuedSequenceNumber = (long)pair.Value;
                        break;

                    case LockedUntilName:
                        sbMessage.LockedUntil = (DateTime)pair.Value >= DateTimeOffset.MaxValue.UtcDateTime ?
                                                DateTimeOffset.MaxValue : (DateTime)pair.Value;
                        break;

                    case PartitionKeyName:
                        sbMessage.SentMessage.PartitionKey = (string)pair.Value;
                        break;

                    case PartitionIdName:
                        sbMessage.PartitionId = (short)pair.Value;
                        break;

                    case ViaPartitionKeyName:
                        sbMessage.SentMessage.ViaPartitionKey = (string)pair.Value;
                        break;

                    case DeadLetterSourceName:
                        sbMessage.DeadLetterSource = (string)pair.Value;
                        break;

                    default:
                        if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject))
                        {
                            sbMessage.SentMessage.Properties[key] = netObject;
                        }
                        break;
                    }
                }
            }

            if (amqpMessage.DeliveryTag.Count == GuidSize)
            {
                var guidBuffer = new byte[GuidSize];
                Buffer.BlockCopy(amqpMessage.DeliveryTag.Array, amqpMessage.DeliveryTag.Offset, guidBuffer, 0, GuidSize);
                sbMessage.LockTokenGuid = new Guid(guidBuffer);
            }

            amqpMessage.Dispose();

            return(sbMessage);
        }
Пример #14
0
 void OnMessage(AmqpMessage message)
 {
     string errorCondition = null;
     if (message.ApplicationProperties != null &&
         message.ApplicationProperties.Map.TryGetValue<string>("errorcondition", out errorCondition))
     {
         this.link.DisposeMessage(message, new Rejected() { Error = new Error() { Condition = errorCondition, Description = "message was rejected" } }, true, false);
     }
     else
     {
         if (message.TxnId.Array != null)
         {
             Transaction txn = this.queue.broker.txnManager.GetTransaction(message.TxnId);
             txn.AddOperation(message, this.OnTxnDischarge);
             this.link.DisposeMessage(message, new TransactionalState() { Outcome = AmqpConstants.AcceptedOutcome }, true, message.Batchable);
         }
         else
         {
             this.queue.Enqueue(new BrokerMessage(message));
             this.link.AcceptMessage(message, message.Batchable);
             message.Dispose();
         }
     }
 }
Пример #15
0
        private AmqpMessage WcfToQpid(Message wcfMessage)
        {
            object         obj;
            AmqpProperties applicationProperties = null;
            bool           success     = false;
            AmqpMessage    amqpMessage = null;

            if (wcfMessage.Properties.TryGetValue("AmqpProperties", out obj))
            {
                applicationProperties = obj as AmqpProperties;
            }

            try
            {
                AmqpProperties outgoingProperties = new AmqpProperties();

                // Start with AMQP properties from the binding and the URI
                if (this.factoryChannelProperties.DefaultMessageProperties != null)
                {
                    outgoingProperties.MergeFrom(this.factoryChannelProperties.DefaultMessageProperties);
                }

                if (this.subject != null)
                {
                    outgoingProperties.RoutingKey = this.subject;
                }

                if (this.qpidSubject != null)
                {
                    outgoingProperties.PropertyMap["qpid.subject"] = new AmqpString(this.qpidSubject);
                }

                // Add the Properties set by the application on this particular message.
                // Application properties trump channel properties
                if (applicationProperties != null)
                {
                    outgoingProperties.MergeFrom(applicationProperties);
                }

                amqpMessage            = this.outputLink.CreateMessage();
                amqpMessage.Properties = outgoingProperties;

                // copy the WCF message body to the AMQP message body
                if (this.streamed)
                {
                    this.encoder.WriteMessage(wcfMessage, amqpMessage.BodyStream);
                }
                else
                {
                    ArraySegment <byte> encodedBody = this.encoder.WriteMessage(wcfMessage, int.MaxValue, this.bufferManager);
                    try
                    {
                        amqpMessage.BodyStream.Write(encodedBody.Array, encodedBody.Offset, encodedBody.Count);
                    }
                    finally
                    {
                        this.bufferManager.ReturnBuffer(encodedBody.Array);
                    }
                }

                success = true;
            }
            finally
            {
                if (!success && (amqpMessage != null))
                {
                    amqpMessage.Dispose();
                }
            }
            return(amqpMessage);
        }
 public void Cleanup()
 {
     amqpMessage.Dispose();
 }
Пример #17
0
        public static SBMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage)
        {
            if (amqpMessage == null)
            {
                throw Fx.Exception.ArgumentNull(nameof(amqpMessage));
            }

            SBMessage sbMessage;

            if ((amqpMessage.BodyType & SectionFlag.AmqpValue) != 0 &&
                amqpMessage.ValueBody.Value != null)
            {
                sbMessage = new SBMessage();

                if (TryGetNetObjectFromAmqpObject(amqpMessage.ValueBody.Value, MappingType.MessageBody, out var dotNetObject))
                {
                    sbMessage.SystemProperties.BodyObject = dotNetObject;
                }
                else
                {
                    sbMessage.SystemProperties.BodyObject = amqpMessage.ValueBody.Value;
                }
            }
            else if ((amqpMessage.BodyType & SectionFlag.Data) != 0 &&
                     amqpMessage.DataBody != null)
            {
                var dataSegments = new List <byte>();
                foreach (var data in amqpMessage.DataBody)
                {
                    if (data.Value is byte[] byteArrayValue)
                    {
                        dataSegments.AddRange(byteArrayValue);
                    }
                    else if (data.Value is ArraySegment <byte> arraySegmentValue)
                    {
                        byte[] byteArray;
                        if (arraySegmentValue.Count == arraySegmentValue.Array.Length)
                        {
                            byteArray = arraySegmentValue.Array;
                        }
                        else
                        {
                            byteArray = new byte[arraySegmentValue.Count];
                            Array.ConstrainedCopy(arraySegmentValue.Array, arraySegmentValue.Offset, byteArray, 0, arraySegmentValue.Count);
                        }
                        dataSegments.AddRange(byteArray);
                    }
                }
                sbMessage = new SBMessage(dataSegments.ToArray());
            }
            else
            {
                sbMessage = new SBMessage();
            }

            var sections = amqpMessage.Sections;

            if ((sections & SectionFlag.Header) != 0)
            {
                if (amqpMessage.Header.Ttl != null)
                {
                    sbMessage.TimeToLive = TimeSpan.FromMilliseconds(amqpMessage.Header.Ttl.Value);
                }

                if (amqpMessage.Header.DeliveryCount != null)
                {
                    sbMessage.SystemProperties.DeliveryCount = (int)(amqpMessage.Header.DeliveryCount.Value + 1);
                }
            }

            if ((sections & SectionFlag.Properties) != 0)
            {
                if (amqpMessage.Properties.MessageId != null)
                {
                    sbMessage.MessageId = amqpMessage.Properties.MessageId.ToString();
                }

                if (amqpMessage.Properties.CorrelationId != null)
                {
                    sbMessage.CorrelationId = amqpMessage.Properties.CorrelationId.ToString();
                }

                if (amqpMessage.Properties.ContentType.Value != null)
                {
                    sbMessage.ContentType = amqpMessage.Properties.ContentType.Value;
                }

                if (amqpMessage.Properties.Subject != null)
                {
                    sbMessage.Label = amqpMessage.Properties.Subject;
                }

                if (amqpMessage.Properties.To != null)
                {
                    sbMessage.To = amqpMessage.Properties.To.ToString();
                }

                if (amqpMessage.Properties.ReplyTo != null)
                {
                    sbMessage.ReplyTo = amqpMessage.Properties.ReplyTo.ToString();
                }

                if (amqpMessage.Properties.GroupId != null)
                {
                    sbMessage.SessionId = amqpMessage.Properties.GroupId;
                }

                if (amqpMessage.Properties.ReplyToGroupId != null)
                {
                    sbMessage.ReplyToSessionId = amqpMessage.Properties.ReplyToGroupId;
                }
            }

            // Do application properties before message annotations, because the application properties
            // can be updated by entries from message annotation.
            if ((sections & SectionFlag.ApplicationProperties) != 0)
            {
                foreach (var pair in amqpMessage.ApplicationProperties.Map)
                {
                    if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject))
                    {
                        sbMessage.UserProperties[pair.Key.ToString()] = netObject;
                    }
                }
            }

            if ((sections & SectionFlag.MessageAnnotations) != 0)
            {
                foreach (var pair in amqpMessage.MessageAnnotations.Map)
                {
                    var key = pair.Key.ToString();
                    switch (key)
                    {
                    case EnqueuedTimeUtcName:
                        sbMessage.SystemProperties.EnqueuedTimeUtc = (DateTime)pair.Value;
                        break;

                    case ScheduledEnqueueTimeUtcName:
                        sbMessage.ScheduledEnqueueTimeUtc = (DateTime)pair.Value;
                        break;

                    case SequenceNumberName:
                        sbMessage.SystemProperties.SequenceNumber = (long)pair.Value;
                        break;

                    case OffsetName:
                        sbMessage.SystemProperties.EnqueuedSequenceNumber = long.Parse((string)pair.Value);
                        break;

                    case LockedUntilName:
                        sbMessage.SystemProperties.LockedUntilUtc = (DateTime)pair.Value;
                        break;

                    case PartitionKeyName:
                        sbMessage.PartitionKey = (string)pair.Value;
                        break;

                    case PartitionIdName:
                        sbMessage.SystemProperties.PartitionId = (short)pair.Value;
                        break;

                    case DeadLetterSourceName:
                        sbMessage.SystemProperties.DeadLetterSource = (string)pair.Value;
                        break;

                    default:
                        if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject))
                        {
                            sbMessage.UserProperties[key] = netObject;
                        }
                        break;
                    }
                }
            }

            if (amqpMessage.DeliveryTag.Count == GuidSize)
            {
                var guidBuffer = new byte[GuidSize];
                Buffer.BlockCopy(amqpMessage.DeliveryTag.Array, amqpMessage.DeliveryTag.Offset, guidBuffer, 0, GuidSize);
                sbMessage.SystemProperties.LockTokenGuid = new Guid(guidBuffer);
            }

            amqpMessage.Dispose();

            return(sbMessage);
        }
        public static SBMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage)
        {
            if (amqpMessage == null)
            {
                throw Fx.Exception.ArgumentNull(nameof(amqpMessage));
            }

            SBMessage sbMessage;

            if (amqpMessage.BodyType == SectionFlag.AmqpValue && amqpMessage.ValueBody.Value != null)
            {
                var byteArrayValue = (byte[])amqpMessage.ValueBody.Value;
                sbMessage = new SBMessage(byteArrayValue);
            }
            else if (amqpMessage.BodyType == SectionFlag.Data && amqpMessage.DataBody != null)
            {
                var data = amqpMessage.DataBody.FirstOrDefault();
                if (data != null)
                {
                    // Chek cast ???
                    var seg = (ArraySegment <byte>)data.Value;
                    sbMessage = new SBMessage(seg.ToArray());
                }
                else
                {
                    // ??
                    sbMessage = null;
                }
            }
            else
            {
                sbMessage = new SBMessage();
            }

            SectionFlag sections = amqpMessage.Sections;

            if ((sections & SectionFlag.Header) != 0)
            {
                if (amqpMessage.Header.Ttl != null)
                {
                    sbMessage.TimeToLive = TimeSpan.FromMilliseconds(amqpMessage.Header.Ttl.Value);
                }

                if (amqpMessage.Header.DeliveryCount != null)
                {
                    sbMessage.SystemProperties.DeliveryCount = (int)(amqpMessage.Header.DeliveryCount.Value + 1);
                }
            }

            if ((sections & SectionFlag.Properties) != 0)
            {
                if (amqpMessage.Properties.MessageId != null)
                {
                    sbMessage.MessageId = amqpMessage.Properties.MessageId.ToString();
                }

                if (amqpMessage.Properties.CorrelationId != null)
                {
                    sbMessage.CorrelationId = amqpMessage.Properties.CorrelationId.ToString();
                }

                if (amqpMessage.Properties.ContentType.Value != null)
                {
                    sbMessage.ContentType = amqpMessage.Properties.ContentType.Value;
                }

                if (amqpMessage.Properties.Subject != null)
                {
                    sbMessage.Label = amqpMessage.Properties.Subject;
                }

                if (amqpMessage.Properties.To != null)
                {
                    sbMessage.To = amqpMessage.Properties.To.ToString();
                }

                if (amqpMessage.Properties.ReplyTo != null)
                {
                    sbMessage.ReplyTo = amqpMessage.Properties.ReplyTo.ToString();
                }

                if (amqpMessage.Properties.GroupId != null)
                {
                    sbMessage.SessionId = amqpMessage.Properties.GroupId;
                }

                if (amqpMessage.Properties.ReplyToGroupId != null)
                {
                    sbMessage.ReplyToSessionId = amqpMessage.Properties.ReplyToGroupId;
                }
            }

            // Do applicaiton properties before message annotations, because the application properties
            // can be updated by entries from message annotation.
            if ((sections & SectionFlag.ApplicationProperties) != 0)
            {
                foreach (var pair in amqpMessage.ApplicationProperties.Map)
                {
                    object netObject;
                    if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out netObject))
                    {
                        sbMessage.UserProperties[pair.Key.ToString()] = netObject;
                    }
                }
            }

            if ((sections & SectionFlag.MessageAnnotations) != 0)
            {
                foreach (var pair in amqpMessage.MessageAnnotations.Map)
                {
                    string key = pair.Key.ToString();
                    switch (key)
                    {
                    case EnqueuedTimeUtcName:
                        sbMessage.SystemProperties.EnqueuedTimeUtc = (DateTime)pair.Value;
                        break;

                    case ScheduledEnqueueTimeUtcName:
                        sbMessage.ScheduledEnqueueTimeUtc = (DateTime)pair.Value;
                        break;

                    case SequenceNumberName:
                        sbMessage.SystemProperties.SequenceNumber = (long)pair.Value;
                        break;

                    case OffsetName:
                        sbMessage.SystemProperties.EnqueuedSequenceNumber = long.Parse((string)pair.Value);
                        break;

                    case LockedUntilName:
                        sbMessage.SystemProperties.LockedUntilUtc = (DateTime)pair.Value;
                        break;

                    case PublisherName:
                        sbMessage.Publisher = (string)pair.Value;
                        break;

                    case PartitionKeyName:
                        sbMessage.PartitionKey = (string)pair.Value;
                        break;

                    case PartitionIdName:
                        sbMessage.SystemProperties.PartitionId = (short)pair.Value;
                        break;

                    case DeadLetterSourceName:
                        sbMessage.DeadLetterSource = (string)pair.Value;
                        break;

                    default:
                        object netObject;
                        if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out netObject))
                        {
                            sbMessage.UserProperties[key] = netObject;
                        }
                        break;
                    }
                }
            }

            if (amqpMessage.DeliveryTag.Count == GuidSize)
            {
                byte[] guidBuffer = new byte[GuidSize];
                Buffer.BlockCopy(amqpMessage.DeliveryTag.Array, amqpMessage.DeliveryTag.Offset, guidBuffer, 0, GuidSize);
                sbMessage.SystemProperties.LockTokenGuid = new Guid(guidBuffer);
            }

            amqpMessage.Dispose();

            return(sbMessage);
        }