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()); } }
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); }
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); } }
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); }
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()); } } }
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); }