Esempio n. 1
0
        protected override async Task <IList <BrokeredMessage> > OnPeekAsync(long fromSequenceNumber, int messageCount = 1)
        {
            try
            {
                AmqpRequestMessage requestMessage =
                    AmqpRequestMessage.CreateRequest(
                        ManagementConstants.Operations.PeekMessageOperation,
                        this.OperationTimeout,
                        null);

                requestMessage.Map[ManagementConstants.Properties.FromSequenceNumber] = fromSequenceNumber;
                requestMessage.Map[ManagementConstants.Properties.MessageCount]       = messageCount;

                if (!string.IsNullOrWhiteSpace(this.sessionId))
                {
                    requestMessage.Map[ManagementConstants.Properties.SessionId] = this.sessionId;
                }

                List <BrokeredMessage> messages = new List <BrokeredMessage>();

                AmqpResponseMessage response = await this.ExecuteRequestResponseAsync(requestMessage);

                if (response.StatusCode == AmqpResponseStatusCode.OK)
                {
                    BrokeredMessage brokeredMessage = null;
                    var             messageList     = response.GetListValue <AmqpMap>(ManagementConstants.Properties.Messages);
                    foreach (AmqpMap entry in messageList)
                    {
                        var         payload     = (ArraySegment <byte>)entry[ManagementConstants.Properties.Message];
                        AmqpMessage amqpMessage =
                            AmqpMessage.CreateAmqpStreamMessage(new BufferListStream(new[] { payload }), true);
                        brokeredMessage = AmqpMessageConverter.ClientGetMessage(amqpMessage);
                        messages.Add(brokeredMessage);
                    }

                    if (brokeredMessage != null)
                    {
                        this.LastPeekedSequenceNumber = brokeredMessage.SequenceNumber;
                    }

                    return(messages);
                }
            }
            catch (AmqpException amqpException)
            {
                throw AmqpExceptionHelper.ToMessagingContract(amqpException.Error);
            }

            return(null);
        }
        protected override async Task <IList <Message> > OnReceiveAsync(int maxMessageCount, TimeSpan serverWaitTime)
        {
            ReceivingAmqpLink receiveLink = null;

            try
            {
                TimeoutHelper timeoutHelper = new TimeoutHelper(serverWaitTime, true);
                receiveLink = await this.ReceiveLinkManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                IEnumerable <AmqpMessage> amqpMessages = null;
                bool hasMessages = await Task.Factory.FromAsync(
                    (c, s) => receiveLink.BeginReceiveRemoteMessages(maxMessageCount, DefaultBatchFlushInterval, timeoutHelper.RemainingTime(), c, s),
                    a => receiveLink.EndReceiveMessages(a, out amqpMessages),
                    this).ConfigureAwait(false);

                if (receiveLink.TerminalException != null)
                {
                    throw receiveLink.TerminalException;
                }

                if (hasMessages && amqpMessages != null)
                {
                    IList <Message> brokeredMessages = null;
                    foreach (var amqpMessage in amqpMessages)
                    {
                        if (brokeredMessages == null)
                        {
                            brokeredMessages = new List <Message>();
                        }

                        if (this.ReceiveMode == ReceiveMode.ReceiveAndDelete)
                        {
                            receiveLink.DisposeDelivery(amqpMessage, true, AmqpConstants.AcceptedOutcome);
                        }

                        Message message = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage);
                        brokeredMessages.Add(message);
                    }

                    return(brokeredMessages);
                }

                return(null);
            }
            catch (Exception exception)
            {
                throw AmqpExceptionHelper.GetClientException(exception, receiveLink?.GetTrackingId());
            }
        }
Esempio n. 3
0
        protected override async Task <long> OnScheduleMessageAsync(BrokeredMessage brokeredMessage)
        {
            // TODO: Ensure System.Transactions.Transaction.Current is null. Transactions are not supported by 1.0.0 version of dotnet core.
            using (AmqpMessage amqpMessage = AmqpMessageConverter.ClientGetMessage(brokeredMessage))
            {
                var request = AmqpRequestMessage.CreateRequest(
                    ManagementConstants.Operations.ScheduleMessageOperation,
                    this.OperationTimeout,
                    null);

                ArraySegment <byte>[] payload = amqpMessage.GetPayload();
                BufferListStream      buffer  = new BufferListStream(payload);
                ArraySegment <byte>   value   = buffer.ReadBytes((int)buffer.Length);

                var entry = new AmqpMap();
                {
                    entry[ManagementConstants.Properties.Message]   = value;
                    entry[ManagementConstants.Properties.MessageId] = brokeredMessage.MessageId;

                    if (!string.IsNullOrWhiteSpace(brokeredMessage.SessionId))
                    {
                        entry[ManagementConstants.Properties.SessionId] = brokeredMessage.SessionId;
                    }

                    if (!string.IsNullOrWhiteSpace(brokeredMessage.PartitionKey))
                    {
                        entry[ManagementConstants.Properties.PartitionKey] = brokeredMessage.PartitionKey;
                    }
                }

                request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> {
                    entry
                };

                IEnumerable <long> sequenceNumbers = null;
                var response = await this.ExecuteRequestResponseAsync(request);

                if (response.StatusCode == AmqpResponseStatusCode.OK)
                {
                    sequenceNumbers = response.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers);
                }
                else
                {
                    response.ToMessagingContractException();
                }

                return(sequenceNumbers?.FirstOrDefault() ?? 0);
            }
        }
        public static AmqpMessage BrokeredMessagesToAmqpMessage(IEnumerable <BrokeredMessage> brokeredMessages, bool batchable)
        {
            AmqpMessage amqpMessage;

            if (brokeredMessages.Count() == 1)
            {
                BrokeredMessage singleBrokeredMessage = brokeredMessages.Single();
                amqpMessage = AmqpMessageConverter.ClientGetMessage(singleBrokeredMessage);
            }
            else
            {
                List <Data> dataList = new List <Data>();
                foreach (BrokeredMessage brokeredMessage in brokeredMessages)
                {
                    AmqpMessage           amqpMessageItem = AmqpMessageConverter.ClientGetMessage(brokeredMessage);
                    ArraySegment <byte>[] payload         = amqpMessageItem.GetPayload();
                    BufferListStream      buffer          = new BufferListStream(payload);
                    ArraySegment <byte>   value           = buffer.ReadBytes((int)buffer.Length);
                    dataList.Add(new Data()
                    {
                        Value = value
                    });
                }

                BrokeredMessage firstBrokeredMessage = brokeredMessages.First();

                amqpMessage = AmqpMessage.Create(dataList);
                amqpMessage.MessageFormat = AmqpConstants.AmqpBatchedMessageFormat;

                if (firstBrokeredMessage.MessageId != null)
                {
                    amqpMessage.Properties.MessageId = firstBrokeredMessage.MessageId;
                }

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

                if (firstBrokeredMessage.PartitionKey != null)
                {
                    amqpMessage.MessageAnnotations.Map[AmqpMessageConverter.PartitionKeyName] = firstBrokeredMessage.PartitionKey;
                }
            }

            amqpMessage.Batchable = batchable;
            return(amqpMessage);
        }
Esempio n. 5
0
        protected override async Task <IList <BrokeredMessage> > OnReceiveAsync(int maxMessageCount)
        {
            try
            {
                TimeoutHelper     timeoutHelper = new TimeoutHelper(this.OperationTimeout, true);
                ReceivingAmqpLink receiveLink   = await this.ReceiveLinkManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                IEnumerable <AmqpMessage> amqpMessages = null;
                bool hasMessages = await Task.Factory.FromAsync(
                    (c, s) => receiveLink.BeginReceiveRemoteMessages(maxMessageCount, AmqpMessageReceiver.DefaultBatchFlushInterval, timeoutHelper.RemainingTime(), c, s),
                    a => receiveLink.EndReceiveMessages(a, out amqpMessages),
                    this).ConfigureAwait(false);

                if (receiveLink.TerminalException != null)
                {
                    throw receiveLink.TerminalException;
                }

                if (hasMessages && amqpMessages != null)
                {
                    IList <BrokeredMessage> brokeredMessages = null;
                    foreach (var amqpMessage in amqpMessages)
                    {
                        if (brokeredMessages == null)
                        {
                            brokeredMessages = new List <BrokeredMessage>();
                        }

                        if (this.ReceiveMode == ReceiveMode.ReceiveAndDelete)
                        {
                            receiveLink.DisposeDelivery(amqpMessage, true, AmqpConstants.AcceptedOutcome);
                        }

                        BrokeredMessage brokeredMessage = AmqpMessageConverter.ClientGetMessage(amqpMessage);
                        brokeredMessage.Receiver = this; // Associate the Message with this Receiver.
                        brokeredMessages.Add(brokeredMessage);
                    }

                    return(brokeredMessages);
                }

                return(null);
            }
            catch (AmqpException amqpException)
            {
                throw AmqpExceptionHelper.ToMessagingContract(amqpException.Error);
            }
        }
Esempio n. 6
0
        protected override async Task <IList <BrokeredMessage> > OnReceiveBySequenceNumberAsync(IEnumerable <long> sequenceNumbers)
        {
            List <BrokeredMessage> messages = new List <BrokeredMessage>();

            try
            {
                AmqpRequestMessage requestMessage = AmqpRequestMessage.CreateRequest(ManagementConstants.Operations.ReceiveBySequenceNumberOperation, this.OperationTimeout, null);
                requestMessage.Map[ManagementConstants.Properties.SequenceNumbers]    = sequenceNumbers.ToArray();
                requestMessage.Map[ManagementConstants.Properties.ReceiverSettleMode] = (uint)(this.ReceiveMode == ReceiveMode.ReceiveAndDelete ? 0 : 1);

                AmqpResponseMessage response = await this.ExecuteRequestResponseAsync(requestMessage).ConfigureAwait(false);

                if (response.StatusCode == AmqpResponseStatusCode.OK)
                {
                    IEnumerable <AmqpMap> amqpMapList = response.GetListValue <AmqpMap>(ManagementConstants.Properties.Messages);
                    foreach (AmqpMap entry in amqpMapList)
                    {
                        ArraySegment <byte> payload         = (ArraySegment <byte>)entry[ManagementConstants.Properties.Message];
                        AmqpMessage         amqpMessage     = AmqpMessage.CreateAmqpStreamMessage(new BufferListStream(new[] { payload }), true);
                        BrokeredMessage     brokeredMessage = AmqpMessageConverter.ClientGetMessage(amqpMessage);
                        brokeredMessage.Receiver = this; // Associate the Message with this Receiver.
                        Guid lockToken;
                        if (entry.TryGetValue(ManagementConstants.Properties.LockToken, out lockToken))
                        {
                            brokeredMessage.LockToken = lockToken;
                            this.requestResponseLockedMessages.AddOrUpdate(lockToken, brokeredMessage.LockedUntilUtc);
                        }

                        messages.Add(brokeredMessage);
                    }
                }
                else
                {
                    throw response.ToMessagingContractException();
                }
            }
            catch (Exception exception)
            {
                throw AmqpExceptionHelper.GetClientException(exception);
            }

            return(messages);
        }
Esempio n. 7
0
        protected override async Task OnSendAsync(IEnumerable <BrokeredMessage> brokeredMessages)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(this.OperationTimeout, true);

            using (AmqpMessage amqpMessage = AmqpMessageConverter.BrokeredMessagesToAmqpMessage(brokeredMessages, true))
            {
                SendingAmqpLink amqpLink = null;
                try
                {
                    amqpLink = await this.SendLinkManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    if (amqpLink.Settings.MaxMessageSize.HasValue)
                    {
                        ulong size = (ulong)amqpMessage.SerializedMessageSize;
                        if (size > amqpLink.Settings.MaxMessageSize.Value)
                        {
                            // TODO: Add MessageSizeExceededException
                            throw new NotImplementedException("MessageSizeExceededException: " + Resources.AmqpMessageSizeExceeded.FormatForUser(amqpMessage.DeliveryId.Value, size, amqpLink.Settings.MaxMessageSize.Value));
                            ////throw Fx.Exception.AsError(new MessageSizeExceededException(
                            ////Resources.AmqpMessageSizeExceeded.FormatForUser(amqpMessage.DeliveryId.Value, size, amqpLink.Settings.MaxMessageSize.Value)));
                        }
                    }

                    Outcome outcome = await amqpLink.SendMessageAsync(amqpMessage, this.GetNextDeliveryTag(), AmqpConstants.NullBinary, timeoutHelper.RemainingTime()).ConfigureAwait(false);

                    if (outcome.DescriptorCode != Accepted.Code)
                    {
                        Rejected rejected = (Rejected)outcome;
                        throw Fx.Exception.AsError(AmqpExceptionHelper.ToMessagingContractException(rejected.Error));
                    }
                }
                catch (Exception exception)
                {
                    throw AmqpExceptionHelper.GetClientException(exception, amqpLink?.GetTrackingId());
                }
            }
        }
Esempio n. 8
0
        public static AmqpMessage BatchSBMessagesAsAmqpMessage(IEnumerable <SBMessage> sbMessages, bool batchable)
        {
            if (sbMessages == null)
            {
                throw Fx.Exception.ArgumentNull(nameof(sbMessages));
            }

            AmqpMessage amqpMessage;
            AmqpMessage firstAmqpMessage = null;
            SBMessage   firstMessage     = null;
            List <Data> dataList         = null;
            var         messageCount     = 0;

            foreach (var sbMessage in sbMessages)
            {
                messageCount++;

                amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(sbMessage);
                if (firstAmqpMessage == null)
                {
                    firstAmqpMessage = amqpMessage;
                    firstMessage     = sbMessage;
                    continue;
                }

                if (dataList == null)
                {
                    dataList = new List <Data> {
                        ToData(firstAmqpMessage)
                    };
                }

                dataList.Add(ToData(amqpMessage));
            }

            if (messageCount == 1 && firstAmqpMessage != null)
            {
                firstAmqpMessage.Batchable = batchable;
                return(firstAmqpMessage);
            }

            amqpMessage = AmqpMessage.Create(dataList);
            amqpMessage.MessageFormat = AmqpConstants.AmqpBatchedMessageFormat;

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

            if (firstMessage.PartitionKey != null)
            {
                amqpMessage.MessageAnnotations.Map[AmqpMessageConverter.PartitionKeyName] =
                    firstMessage.PartitionKey;
            }

            amqpMessage.Batchable = batchable;
            return(amqpMessage);
        }
        // return from AMQP lib to client API for a received message
        // TODO: expose other AMQP sections in BrokeredMessage
        public static BrokeredMessage ClientGetMessage(AmqpMessage amqpMessage)
        {
            BrokeredMessage brokeredMessage;

            if ((amqpMessage.BodyType & SectionFlag.Data) != 0 ||
                (amqpMessage.BodyType & SectionFlag.AmqpSequence) != 0)
            {
                Stream bodyStream = AmqpMessageConverter.GetMessageBodyStream(amqpMessage);
                brokeredMessage = new BrokeredMessage(bodyStream, true);
            }
            else if ((amqpMessage.BodyType & SectionFlag.AmqpValue) != 0)
            {
                object netObject;
                if (!TryGetNetObjectFromAmqpObject(amqpMessage.ValueBody.Value, MappingType.MessageBody, out netObject))
                {
                    netObject = amqpMessage.ValueBody.Value;
                }

                brokeredMessage = new BrokeredMessage(netObject, amqpMessage.BodyStream);
            }
            else
            {
                brokeredMessage = new BrokeredMessage();
            }

            SectionFlag sections = amqpMessage.Sections;

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

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

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

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

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

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

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

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

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

                if (amqpMessage.Properties.ReplyToGroupId != null)
                {
                    brokeredMessage.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))
                    {
                        brokeredMessage.Properties[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:
                        brokeredMessage.EnqueuedTimeUtc = (DateTime)pair.Value;
                        break;

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

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

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

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

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

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

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

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

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

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

            brokeredMessage.AttachDisposables(new[] { amqpMessage });

            return(brokeredMessage);
        }
        // return from Client API to AMQP lib for send
        public static AmqpMessage ClientGetMessage(BrokeredMessage brokeredMessage)
        {
            AmqpMessage amqpMessage = AmqpMessageConverter.CreateAmqpMessageFromSbmpMessage(brokeredMessage);

            amqpMessage.Properties.MessageId      = brokeredMessage.MessageId;
            amqpMessage.Properties.CorrelationId  = brokeredMessage.CorrelationId;
            amqpMessage.Properties.ContentType    = brokeredMessage.ContentType;
            amqpMessage.Properties.Subject        = brokeredMessage.Label;
            amqpMessage.Properties.To             = brokeredMessage.To;
            amqpMessage.Properties.ReplyTo        = brokeredMessage.ReplyTo;
            amqpMessage.Properties.GroupId        = brokeredMessage.SessionId;
            amqpMessage.Properties.ReplyToGroupId = brokeredMessage.ReplyToSessionId;

            if ((brokeredMessage.InitializedMembers & BrokeredMessage.MessageMembers.TimeToLive) != 0)
            {
                amqpMessage.Header.Ttl = (uint)brokeredMessage.TimeToLive.TotalMilliseconds;
                amqpMessage.Properties.CreationTime = DateTime.UtcNow;

                if (AmqpConstants.MaxAbsoluteExpiryTime - amqpMessage.Properties.CreationTime.Value > brokeredMessage.TimeToLive)
                {
                    amqpMessage.Properties.AbsoluteExpiryTime = amqpMessage.Properties.CreationTime.Value + brokeredMessage.TimeToLive;
                }
                else
                {
                    amqpMessage.Properties.AbsoluteExpiryTime = AmqpConstants.MaxAbsoluteExpiryTime;
                }
            }

            if ((brokeredMessage.InitializedMembers & BrokeredMessage.MessageMembers.ScheduledEnqueueTimeUtc) != 0 &&
                brokeredMessage.ScheduledEnqueueTimeUtc > DateTime.MinValue)
            {
                amqpMessage.MessageAnnotations.Map.Add(ScheduledEnqueueTimeUtcName, brokeredMessage.ScheduledEnqueueTimeUtc);
            }

            if ((brokeredMessage.InitializedMembers & BrokeredMessage.MessageMembers.Publisher) != 0 &&
                brokeredMessage.Publisher != null)
            {
                amqpMessage.MessageAnnotations.Map.Add(PublisherName, brokeredMessage.Publisher);
            }

            if ((brokeredMessage.InitializedMembers & BrokeredMessage.MessageMembers.DeadLetterSource) != 0 &&
                brokeredMessage.DeadLetterSource != null)
            {
                amqpMessage.MessageAnnotations.Map.Add(DeadLetterSourceName, brokeredMessage.DeadLetterSource);
            }

            if ((brokeredMessage.InitializedMembers & BrokeredMessage.MessageMembers.PartitionKey) != 0 &&
                brokeredMessage.PartitionKey != null)
            {
                amqpMessage.MessageAnnotations.Map.Add(PartitionKeyName, brokeredMessage.PartitionKey);
            }

            foreach (KeyValuePair <string, object> pair in brokeredMessage.Properties)
            {
                object amqpObject;
                if (TryGetAmqpObjectFromNetObject(pair.Value, MappingType.ApplicationProperty, out amqpObject))
                {
                    amqpMessage.ApplicationProperties.Map.Add(pair.Key, amqpObject);
                }
            }

            return(amqpMessage);
        }