/// <summary> /// /// </summary> /// <param name="fromSequenceNumber"></param> /// <param name="maxMessages"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async IAsyncEnumerable <ServiceBusMessage> PeekRangeBySequenceInternal( long?fromSequenceNumber, int maxMessages = 1, [EnumeratorCancellation] CancellationToken cancellationToken = default) { RetriableContext context = CreateRetriableContext(cancellationToken); ReceivingAmqpLink openedLink = await context.RunOperation( async() => await Consumer.ReceiveLink.GetOrCreateAsync(context.TimeSpan) .ConfigureAwait(false)) .ConfigureAwait(false); var source = (Source)openedLink.Settings.Source; if (source.FilterSet.TryGetValue <string>(AmqpClientConstants.SessionFilterName, out var tempSessionId)) { // If one of the constructors not accepting a SessionId was used, the broker will determine which session to send messages from. SessionId = tempSessionId; } IAsyncEnumerable <ServiceBusMessage> ret = PeekRangeBySequenceInternal( fromSequenceNumber: fromSequenceNumber, maxMessages: maxMessages, sessionId: SessionId, cancellationToken: cancellationToken); await foreach (ServiceBusMessage msg in ret.ConfigureAwait(false)) { yield return(msg); } }
private static void StartReceiver() { Task.Run(async() => { var tfactory = new AmqpConnectionFactory(); var connection = await tfactory.OpenConnectionAsync("amqp://localhost:5672", TimeSpan.FromSeconds(10)); var session = connection.CreateSession(new AmqpSessionSettings()); var receicerSettings = new AmqpLinkSettings { LinkName = $"receiver-{DateTime.UtcNow.Ticks}", Role = true, TotalLinkCredit = 300, Source = new Source { Address = QueueName, }, Target = new Target() }; var receiver = new ReceivingAmqpLink(session, receicerSettings); while (true) { AmqpMessage message = await receiver.ReceiveMessageAsync(TimeSpan.FromSeconds(20)); if (message != null) { receiver.DisposeDelivery(message, true, AmqpConstants.AcceptedOutcome); DisplayMessage(new StreamReader(message.BodyStream).ReadToEnd()); } } }); }
public static void Start() { try { var connection = AmqpConnection.Factory.OpenConnectionAsync("amqp://localhost:5672/").Result; var sessionSettings = new AmqpSessionSettings { }; //AmqpSessionSettings.Create(new Begin()) var session = connection.CreateSession(sessionSettings); var linkSettings = new AmqpLinkSettings { LinkName = "theExchange", Handle = 1234, Role = false, Source = new Source { Address = "theQueue", Durable = 1 } }; var receiver = new ReceivingAmqpLink(session, linkSettings); receiver.RegisterMessageListener(message => { var stop = "here"; }); } catch (System.Exception ex) { var s = ex.Message; } }
async Task <ReceivingAmqpLink> CreateTwinReceivingLinkAsync(TimeSpan timeout, CancellationToken cancellationToken) { string path = string.Format(CultureInfo.InvariantCulture, CommonConstants.DeviceTwinPathTemplate, System.Net.WebUtility.UrlEncode(this.deviceId)); ReceivingAmqpLink twinReceivingLink = await this.IotHubConnection.CreateReceivingLinkAsync(path, this.iotHubConnectionString, this.twinConnectionCorrelationId, IotHubConnection.ReceivingLinkType.Twin, this.prefetchCount, timeout, cancellationToken); MyStringCopy(twinReceivingLink.Name, out twinReceivingLinkName); this.SafeAddClosedTwinReceivingLinkHandler = this.linkClosedListener; twinReceivingLink.SafeAddClosed(async(o, ea) => await Task.Run(async() => { await this.SafeAddClosedTwinReceivingLinkHandler( o, new ConnectionEventArgs { ConnectionType = ConnectionType.AmqpTwinReceiving, ConnectionStatus = ConnectionStatus.Disconnected_Retrying, ConnectionStatusChangeReason = ConnectionStatusChangeReason.No_Network }); } )); twinReceivingLink.RegisterMessageListener(message => this.HandleTwinMessage(message, twinReceivingLink)); return(twinReceivingLink); }
public async Task EnableEventReceiveAsync(TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, timeout, $"{nameof(EnableEventReceiveAsync)}"); } try { Debug.Assert(_eventReceivingLink == null); _eventReceivingLink = await AmqpLinkHelper.OpenEventsReceiverLinkAsync( _deviceIdentity, _amqpSession, timeout ).ConfigureAwait(false); _eventReceivingLink.RegisterMessageListener(OnEventsReceived); _eventReceivingLink.Closed += OnLinkDisconnected; if (Logging.IsEnabled) { Logging.Associate(this, this, _eventReceivingLink, $"{nameof(EnableEventReceiveAsync)}"); } } finally { if (Logging.IsEnabled) { Logging.Exit(this, timeout, $"{nameof(EnableEventReceiveAsync)}"); } } }
private async Task EnsureReceivingLinkIsOpenedAsync(TimeSpan timeout) { if (Volatile.Read(ref _messageReceivingLink) != null) return; if (Logging.IsEnabled) Logging.Enter(this, timeout, $"{nameof(EnsureReceivingLinkIsOpenedAsync)}"); try { await _messageReceivingLinkLock.WaitAsync().ConfigureAwait(false); if (_messageReceivingLink != null) return; _messageReceivingLink = await AmqpLinkHelper.OpenTelemetryReceiverLinkAsync( _deviceIdentity, _amqpSession, timeout ).ConfigureAwait(false); _messageReceivingLink.Closed += OnLinkDisconnected; if (Logging.IsEnabled) Logging.Associate(this, this, _messageReceivingLink, $"{nameof(EnsureReceivingLinkIsOpenedAsync)}"); } finally { _messageReceivingLinkLock.Release(); if (Logging.IsEnabled) Logging.Exit(this, timeout, $"{nameof(EnsureReceivingLinkIsOpenedAsync)}"); } }
/// <summary> /// Closes the AMQP link used by the consumer, capturing the passive terminal exception that triggered /// closing if it should be surfaced during the next requested operation. /// </summary> /// protected void CloseConsumerLink(ReceivingAmqpLink link) { // If there is no link, then no action needs to be // taken. if (link == null) { return; } // If the consumer is being closed, the sentinel variable will already be set, and // the terminal exception need not be considered. if (!_closed) { var linkException = GetTerminalException(link); // If the terminal exception indicates that the partition was stolen from the consumer, // capture it so that it can be surfaced when the next operation is requested. if (linkException.IsConsumerPartitionStolenException()) { EventHubsEventSource.Log.AmqpConsumerLinkFaultCapture(EventHubName, ConsumerGroup, PartitionId, linkException.Message); _activePartitionStolenException = linkException; } } // Close the link and it's associated session. link.Session?.SafeClose(); link.SafeClose(); EventHubsEventSource.Log.FaultTolerantAmqpObjectClose(nameof(ReceivingAmqpLink), "", EventHubName, ConsumerGroup, PartitionId, link.TerminalException?.Message); }
async Task <ReceivingAmqpLink> CreateLinkAsync(TimeSpan timeout) { FilterSet filterMap = null; MessagingEventSource.Log.AmqpReceiveLinkCreateStart(this.ClientId, false, this.EntityType, this.Path); if (this.isSessionReceiver) { filterMap = new FilterSet { { AmqpClientConstants.SessionFilterName, this.sessionId } }; } AmqpLinkSettings linkSettings = new AmqpLinkSettings { Role = true, TotalLinkCredit = (uint)this.PrefetchCount, AutoSendFlow = this.PrefetchCount > 0, Source = new Source { Address = this.Path, FilterSet = filterMap }, SettleType = (this.ReceiveMode == ReceiveMode.PeekLock) ? SettleMode.SettleOnDispose : SettleMode.SettleOnSend }; linkSettings.AddProperty(AmqpClientConstants.EntityTypeName, (int)this.EntityType); linkSettings.AddProperty(AmqpClientConstants.TimeoutName, (uint)timeout.TotalMilliseconds); AmqpSendReceiveLinkCreator sendReceiveLinkCreator = new AmqpSendReceiveLinkCreator(this.Path, this.ServiceBusConnection, new[] { ClaimConstants.Listen }, this.CbsTokenProvider, linkSettings); ReceivingAmqpLink receivingAmqpLink = (ReceivingAmqpLink)await sendReceiveLinkCreator.CreateAndOpenAmqpLinkAsync().ConfigureAwait(false); MessagingEventSource.Log.AmqpReceiveLinkCreateStop(this.ClientId); return(receivingAmqpLink); }
public override async Task <Message> ReceiveAsync(TimeSpan timeout, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); Message message = null; AmqpMessage amqpMessage; try { ReceivingAmqpLink deviceBoundReceivingLink = await this.GetDeviceBoundReceivingLinkAsync(cancellationToken).ConfigureAwait(false); amqpMessage = await deviceBoundReceivingLink.ReceiveMessageAsync(timeout).ConfigureAwait(false); } catch (Exception exception) when(!exception.IsFatal() && !(exception is OperationCanceledException)) { throw AmqpClientHelper.ToIotHubClientContract(exception); } if (amqpMessage != null) { message = new Message(amqpMessage) { LockToken = new Guid(amqpMessage.DeliveryTag.Array).ToString() }; } else { message = null; } return(message); }
public async Task DisableMethodsAsync(TimeSpan timeout) { if (Logging.IsEnabled) Logging.Enter(this, timeout, $"{nameof(DisableMethodsAsync)}"); Debug.Assert(_methodSendingLink != null); Debug.Assert(_methodReceivingLink != null); try { ICollection<Task> tasks = new List<Task>(); if (_methodReceivingLink != null) { tasks.Add(_methodReceivingLink.CloseAsync(timeout)); } if (_methodSendingLink != null) { tasks.Add(_methodSendingLink.CloseAsync(timeout)); } if (tasks.Count > 0) { await Task.WhenAll(tasks).ConfigureAwait(false); _methodReceivingLink = null; _methodSendingLink = null; } } finally { if (Logging.IsEnabled) Logging.Exit(this, timeout, $"{nameof(DisableMethodsAsync)}"); } }
private async Task EnableReceivingLinkAsync(CancellationToken cancellationToken) { ReceivingAmqpLink methodReceivingLink = await this.GetMethodReceivingLinkAsync(cancellationToken); this.SafeAddClosedReceivingLinkHandler = this.linkClosedListener; methodReceivingLink.SafeAddClosed((o, ea) => this.SafeAddClosedReceivingLinkHandler(o, ea)); }
public DuplexAmqpLink(AmqpSession session, AmqpLinkSettings settings) : base("duplex") { AmqpTrace.Provider.AmqpLogOperationInformational(this, TraceOperation.Create, "Create"); var senderSettings = new AmqpLinkSettings { Role = false, LinkName = settings.LinkName + ":out", SettleType = settings.SettleType, Source = new Source(), TotalLinkCredit = settings.TotalLinkCredit, AutoSendFlow = settings.AutoSendFlow, Target = settings.Target, Properties = settings.Properties }; this.sender = new SendingAmqpLink(session, senderSettings); var receiverSettings = new AmqpLinkSettings { Role = true, LinkName = settings.LinkName + ":in", SettleType = settings.SettleType, Source = settings.Source, TotalLinkCredit = settings.TotalLinkCredit, AutoSendFlow = settings.AutoSendFlow, Target = new Target(), Properties = settings.Properties }; this.receiver = new ReceivingAmqpLink(session, receiverSettings); this.receiver.SetTotalLinkCredit(receiverSettings.TotalLinkCredit, true); // WHY set both here AND on settings? Follow up with Xin. this.sender.SafeAddClosed(this.OnLinkClosed); this.receiver.SafeAddClosed(this.OnLinkClosed); }
internal static async Task DisposeMessageAsync(FaultTolerantAmqpObject <ReceivingAmqpLink> faultTolerantReceivingLink, string lockToken, Outcome outcome, bool batchable) { var deliveryTag = IotHubConnection.ConvertToDeliveryTag(lockToken); Outcome disposeOutcome; try { ReceivingAmqpLink deviceBoundReceivingLink = await faultTolerantReceivingLink.GetReceivingLinkAsync().ConfigureAwait(false); disposeOutcome = await deviceBoundReceivingLink.DisposeMessageAsync(deliveryTag, outcome, batchable, IotHubConnection.DefaultOperationTimeout).ConfigureAwait(false); } catch (Exception exception) { if (exception.IsFatal()) { throw; } throw AmqpClientHelper.ToIotHubClientContract(exception); } if (disposeOutcome.DescriptorCode != Accepted.Code) { throw AmqpErrorMapper.GetExceptionFromOutcome(disposeOutcome); } }
public AmqpLink CreateLink(AmqpSession session, AmqpLinkSettings settings) { bool isReceiver = settings.Role.Value; AmqpLink link; if (isReceiver) { if (settings.Target is Target && ((Target)settings.Target).Dynamic()) { string name = string.Format("$dynamic.{0}", Interlocked.Increment(ref this.dynamicId)); this.queues.Add(name, new TestQueue(this)); ((Target)settings.Target).Address = name; } link = new ReceivingAmqpLink(session, settings); } else { if (((Source)settings.Source).Dynamic()) { string name = string.Format("$dynamic.{0}", Interlocked.Increment(ref this.dynamicId)); this.queues.Add(name, new TestQueue(this)); ((Source)settings.Source).Address = name; } link = new SendingAmqpLink(session, settings); } return(link); }
async Task DisposeMessageAsync(string lockToken, Outcome outcome) { var deliveryTag = IotHubConnection.ConvertToDeliveryTag(lockToken); Outcome disposeOutcome; try { ReceivingAmqpLink deviceBoundReceivingLink = await this.GetReceivingLinkAsync(); disposeOutcome = await deviceBoundReceivingLink.DisposeMessageAsync(deliveryTag, outcome, batchable : true, timeout : this.OperationTimeout); } catch (Exception exception) { if (exception.IsFatal()) { throw; } throw AmqpClientHelper.ToIotHubClientContract(exception); } if (disposeOutcome.DescriptorCode != Accepted.Code) { throw AmqpErrorMapper.GetExceptionFromOutcome(disposeOutcome); } }
public override async Task <FileNotification> ReceiveAsync(TimeSpan timeout) { try { ReceivingAmqpLink receivingLink = await this.faultTolerantReceivingLink.GetReceivingLinkAsync(); AmqpMessage amqpMessage = await receivingLink.ReceiveMessageAsync(timeout); if (amqpMessage != null) { using (amqpMessage) { AmqpClientHelper.ValidateContentType(amqpMessage, CommonConstants.FileNotificationContentType); var fileNotification = await AmqpClientHelper.GetObjectFromAmqpMessageAsync <FileNotification>(amqpMessage); fileNotification.LockToken = new Guid(amqpMessage.DeliveryTag.Array).ToString(); return(fileNotification); } } return(null); } catch (Exception exception) { if (exception.IsFatal()) { throw; } throw AmqpClientHelper.ToIotHubClientContract(exception); } }
async Task <ReceivingAmqpLink> CreateMethodReceivingLinkAsync(TimeSpan timeout, CancellationToken cancellationToken) { string path = string.Format(CultureInfo.InvariantCulture, CommonConstants.DeviceMethodPathTemplate, System.Net.WebUtility.UrlEncode(this.deviceId)); ReceivingAmqpLink methodReceivingLink = await this.IotHubConnection.CreateReceivingLinkAsync(path, this.iotHubConnectionString, this.methodConnectionCorrelationId, IotHubConnection.ReceivingLinkType.Methods, this.prefetchCount, timeout, cancellationToken); methodReceivingLink.RegisterMessageListener(amqpMessage => { MethodRequestInternal methodRequestInternal = MethodConverter.ConstructMethodRequestFromAmqpMessage(amqpMessage); methodReceivingLink.DisposeDelivery(amqpMessage, true, AmqpConstants.AcceptedOutcome); this.messageListener(methodRequestInternal); }); MyStringCopy(methodReceivingLink.Name, out methodReceivingLinkName); this.SafeAddClosedMethodReceivingLinkHandler = this.linkClosedListener; methodReceivingLink.SafeAddClosed(async(o, ea) => await Task.Run(async() => { await this.SafeAddClosedMethodReceivingLinkHandler( o, new ConnectionEventArgs { ConnectionType = ConnectionType.AmqpMethodReceiving, ConnectionStatus = ConnectionStatus.Disconnected_Retrying, ConnectionStatusChangeReason = ConnectionStatusChangeReason.No_Network }); } )); return(methodReceivingLink); }
private void HandleTwinMessage(AmqpMessage message, ReceivingAmqpLink link) { link.DisposeDelivery(message, true, AmqpConstants.AcceptedOutcome); string correlationId = message.Properties?.CorrelationId?.ToString(); if (correlationId != null) { // If we have a correlation id, it must be a response, complete the task. TaskCompletionSource <AmqpMessage> task; if (this.twinResponseCompletions.TryRemove(correlationId, out task)) { task.SetResult(message); } } else { // No correlation id? Must be a patch. if (this.onDesiredStatePatchListener != null) { using (StreamReader reader = new StreamReader(message.BodyStream, System.Text.Encoding.UTF8)) { string patch = reader.ReadToEnd(); var props = JsonConvert.DeserializeObject <TwinCollection>(patch); this.onDesiredStatePatchListener(props); } } } }
public AmqpLink CreateLink(AmqpSession session, AmqpLinkSettings settings) { AmqpLink link; if (settings.Role.Value) { var receiver = new ReceivingAmqpLink(session, settings); receiver.RegisterMessageListener(m => { this.messages.Enqueue(m.Clone()); receiver.AcceptMessage(m, true, true); m.Dispose(); }); link = receiver; } else { var sender = new SendingAmqpLink(session, settings); sender.RegisterCreditListener((credit, drain, tx) => { AmqpMessage message = this.messages.Dequeue(); message.DeliveryAnnotations.Map["x-opt-sequence-number"] = 1; sender.SendMessageNoWait(message, EmptyBinary, NullBinary); }); sender.RegisterDispositionListener(d => { sender.DisposeDelivery(d, true, d.State); }); link = sender; } return(link); }
public Publisher(TestQueue queue, ReceivingAmqpLink link, int id) { this.queue = queue; this.link = link; this.id = id; this.link.RegisterMessageListener(this.OnMessage); this.link.Closed += new EventHandler(link_Closed); }
public async Task EnsureTwinLinksAreOpenedAsync(TimeSpan timeout) { if (Volatile.Read(ref _twinLinksOpened) == true) return; if (Logging.IsEnabled) Logging.Enter(this, timeout, $"{nameof(EnsureTwinLinksAreOpenedAsync)}"); try { await _twinLinksLock.WaitAsync().ConfigureAwait(false); if (_twinLinksOpened) return; Debug.Assert(_twinSendingLink == null); Debug.Assert(_twinReceivingLink == null); string correlationIdSuffix = Guid.NewGuid().ToString(); Task<ReceivingAmqpLink> receiveLinkCreator = AmqpLinkHelper.OpenTwinReceiverLinkAsync( _deviceIdentity, _amqpSession, correlationIdSuffix, timeout); Task<SendingAmqpLink> sendingLinkCreator = AmqpLinkHelper.OpenTwinSenderLinkAsync( _deviceIdentity, _amqpSession, correlationIdSuffix, timeout); await Task.WhenAll(receiveLinkCreator, sendingLinkCreator).ConfigureAwait(false); _twinSendingLink = sendingLinkCreator.Result; _twinSendingLink.Closed += OnLinkDisconnected; _twinReceivingLink = receiveLinkCreator.Result; _twinReceivingLink.RegisterMessageListener(OnDesiredPropertyReceived); _twinReceivingLink.Closed += OnLinkDisconnected; _twinLinksOpened = true; if (Logging.IsEnabled) Logging.Associate(this, this, _twinReceivingLink, $"{nameof(EnsureTwinLinksAreOpenedAsync)}"); if (Logging.IsEnabled) Logging.Associate(this, this, _twinSendingLink, $"{nameof(EnsureTwinLinksAreOpenedAsync)}"); } catch (Exception ex) when (!ex.IsFatal()) { _twinReceivingLink?.Abort(); _twinSendingLink?.Abort(); _twinReceivingLink = null; _twinSendingLink = null; throw; } finally { _twinLinksLock.Release(); if (Logging.IsEnabled) Logging.Exit(this, timeout, $"{nameof(EnsureTwinLinksAreOpenedAsync)}"); } }
private async Task EnableTwinReceivingLinkAsync(CancellationToken cancellationToken) { ReceivingAmqpLink twinReceivingLink = await this.GetTwinReceivingLinkAsync(cancellationToken); this.SafeAddClosedTwinReceivingLinkHandler = this.linkClosedListener; twinReceivingLink.SafeAddClosed((o, ea) => this.SafeAddClosedTwinReceivingLinkHandler(o, new ConnectionEventArgs { ConnectionKey = ConnectionKeys.AmqpTwinReceiving, ConnectionStatus = ConnectionStatus.Disconnected_Retrying, ConnectionStatusChangeReason = ConnectionStatusChangeReason.No_Network })); }
AmqpLink ILinkFactory.CreateLink(AmqpSession session, AmqpLinkSettings settings) { try { this.ValidateLinkSettings(settings); // Override AmqpLinkSetting MaxMessageSize to restrict it to Constants.AmqpMaxMessageSize if (settings.MaxMessageSize == null || settings.MaxMessageSize == 0 || settings.MaxMessageSize > Constants.AmqpMaxMessageSize) { settings.MaxMessageSize = Constants.AmqpMaxMessageSize; } AmqpLink amqpLink; IAmqpLink wrappingAmqpLink; string linkAddress; if (settings.IsReceiver()) { amqpLink = new ReceivingAmqpLink(session, settings); wrappingAmqpLink = new EdgeReceivingAmqpLink((ReceivingAmqpLink)amqpLink); linkAddress = ((Target)settings.Target).Address.ToString(); } else { amqpLink = new SendingAmqpLink(session, settings); wrappingAmqpLink = new EdgeSendingAmqpLink((SendingAmqpLink)amqpLink); linkAddress = ((Source)settings.Source).Address.ToString(); } // TODO: implement the rules below // Link address may be of the forms: // // amqp[s]://my.servicebus.windows.net/a/b <-- FQ address where host name should match connection remote host name // amqp[s]:a/b <-- path relative to hostname specified in OPEN // a/b <-- pre-global addressing style path relative to hostname specified in OPEN // /a/b <-- same as above Uri linkUri; if (!linkAddress.StartsWith(Constants.AmqpsScheme, StringComparison.OrdinalIgnoreCase)) { string host = session.Connection.Settings.RemoteHostName; linkUri = new Uri("amqps://" + host + linkAddress.EnsureStartsWith('/')); } else { linkUri = new Uri(linkAddress, UriKind.RelativeOrAbsolute); } ILinkHandler linkHandler = this.linkHandlerProvider.Create(wrappingAmqpLink, linkUri); amqpLink.Settings.AddProperty(LinkHandlerPropertyKey, linkHandler); return(amqpLink); } catch (Exception e) when(!ExceptionEx.IsFatal(e)) { // Don't throw here because we cannot provide error info. Instead delay and throw from Link.Open. return(new FaultedLink(e, session, settings)); } }
public void AddCoordinator(ReceivingAmqpLink link) { link.RegisterMessageListener(this.OnMessage); link.Closed += this.link_Closed; lock (this.coordinators) { this.coordinators.Add(link.Identifier, link); } }
private async Task EnableMethodReceivingLinkAsync(CancellationToken cancellationToken) { ReceivingAmqpLink methodReceivingLink = await this.GetMethodReceivingLinkAsync(cancellationToken); this.SafeAddClosedMethodReceivingLinkHandler = this.linkClosedListener; methodReceivingLink.SafeAddClosed((o, ea) => this.SafeAddClosedMethodReceivingLinkHandler(o, new ConnectionEventArgs { ConnectionKey = ConnectionKeys.AmqpMethodReceiving, ConnectionStatus = ConnectionStatus.Disconnected_Retrying })); }
internal static async Task <ReceivingAmqpLink> OpenReceivingAmqpLinkAsync( DeviceIdentity deviceIdentity, AmqpSession amqpSession, byte?senderSettleMode, byte?receiverSettleMode, string deviceTemplate, string moduleTemplate, string linkSuffix, string CorrelationId, TimeSpan timeout ) { if (Logging.IsEnabled) { Logging.Enter(typeof(AmqpLinkHelper), deviceIdentity, $"{nameof(OpenReceivingAmqpLinkAsync)}"); } uint prefetchCount = deviceIdentity.AmqpTransportSettings.PrefetchCount; AmqpLinkSettings amqpLinkSettings = new AmqpLinkSettings { LinkName = CommonResources.GetNewStringGuid(linkSuffix), Role = true, TotalLinkCredit = prefetchCount, AutoSendFlow = prefetchCount > 0, Source = new Source() { Address = BuildLinkAddress(deviceIdentity, deviceTemplate, moduleTemplate) }, Target = new Target() { Address = deviceIdentity.IotHubConnectionString.DeviceId } }; amqpLinkSettings.SndSettleMode = senderSettleMode; amqpLinkSettings.RcvSettleMode = receiverSettleMode; amqpLinkSettings.AddProperty(IotHubAmqpProperty.TimeoutName, timeout.TotalMilliseconds); amqpLinkSettings.AddProperty(IotHubAmqpProperty.ClientVersion, deviceIdentity.ProductInfo.ToString()); amqpLinkSettings.AddProperty(IotHubAmqpProperty.ApiVersion, ClientApiVersionHelper.ApiVersionString); if (CorrelationId != null) { amqpLinkSettings.AddProperty(IotHubAmqpProperty.ChannelCorrelationId, CorrelationId); } ReceivingAmqpLink receivingLink = new ReceivingAmqpLink(amqpLinkSettings); receivingLink.AttachTo(amqpSession); await receivingLink.OpenAsync(timeout).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Exit(typeof(AmqpLinkHelper), deviceIdentity, $"{nameof(OpenReceivingAmqpLinkAsync)}"); } return(receivingLink); }
public static async Task <AmqpMessage> ReceiveMessageAsync(this ReceivingAmqpLink link, TimeSpan timeout) { AmqpMessage message = null; await Task.Factory.FromAsync( (c, s) => link.BeginReceiveMessage(timeout, c, s), (r) => link.EndReceiveMessage(r, out message), link); return(message); }
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(); } }
async Task <ReceivingAmqpLink> CreateTwinReceivingLinkAsync(TimeSpan timeout, CancellationToken cancellationToken) { string path = this.BuildPath(CommonConstants.DeviceTwinPathTemplate, CommonConstants.ModuleTwinPathTemplate); ReceivingAmqpLink twinReceivingLink = await this.IotHubConnection.CreateReceivingLinkAsync(path, this.iotHubConnectionString, this.twinConnectionCorrelationId, IotHubConnection.ReceivingLinkType.Twin, this.prefetchCount, timeout, this.productInfo, cancellationToken).ConfigureAwait(false); MyStringCopy(twinReceivingLink.Name, out twinReceivingLinkName); twinReceivingLink.SafeAddClosed(OnAmqpConnectionClose); twinReceivingLink.RegisterMessageListener(message => this.HandleTwinMessage(message, twinReceivingLink)); return(twinReceivingLink); }
internal static async Task DisposeMessageAsync( FaultTolerantAmqpObject <ReceivingAmqpLink> faultTolerantReceivingLink, string lockToken, Outcome outcome, bool batchable, CancellationToken cancellationToken) { Logging.Enter(faultTolerantReceivingLink, lockToken, outcome.DescriptorCode, batchable, nameof(DisposeMessageAsync)); try { cancellationToken.ThrowIfCancellationRequested(); ArraySegment <byte> deliveryTag = IotHubConnection.ConvertToDeliveryTag(lockToken); Outcome disposeOutcome; try { ReceivingAmqpLink deviceBoundReceivingLink = await faultTolerantReceivingLink.GetReceivingLinkAsync().ConfigureAwait(false); disposeOutcome = await deviceBoundReceivingLink .DisposeMessageAsync( deliveryTag, outcome, batchable, cancellationToken) .ConfigureAwait(false); } catch (Exception exception) { Logging.Error(faultTolerantReceivingLink, exception, nameof(DisposeMessageAsync)); if (exception.IsFatal()) { throw; } throw ToIotHubClientContract(exception); } Logging.Info(faultTolerantReceivingLink, disposeOutcome.DescriptorCode, nameof(DisposeMessageAsync)); if (disposeOutcome.DescriptorCode != Accepted.Code) { throw AmqpErrorMapper.GetExceptionFromOutcome(disposeOutcome); } } finally { Logging.Exit(faultTolerantReceivingLink, lockToken, outcome.DescriptorCode, batchable, nameof(DisposeMessageAsync)); } }
private async Task <ReceivingAmqpLink> CreateEventReceivingLinkAsync(TimeSpan timeout, CancellationToken cancellationToken) { string path = this.BuildPath(CommonConstants.DeviceEventPathTemplate, CommonConstants.ModuleEventPathTemplate); ReceivingAmqpLink messageReceivingLink = await this.IotHubConnection.CreateReceivingLinkAsync(path, this.iotHubConnectionString, this.deviceId, IotHubConnection.ReceivingLinkType.Events, this.prefetchCount, timeout, this.productInfo, cancellationToken).ConfigureAwait(false); messageReceivingLink.RegisterMessageListener(amqpMessage => this.ProcessReceivedEventMessage(amqpMessage)); MyStringCopy(messageReceivingLink.Name, out eventReceivingLinkName); messageReceivingLink.SafeAddClosed(OnAmqpConnectionClose); return(messageReceivingLink); }
public DuplexAmqpLink(SendingAmqpLink sender, ReceivingAmqpLink receiver) : base("duplex") { AmqpTrace.Provider.AmqpLogOperationInformational(this, TraceOperation.Create, "Create"); this.sender = sender; this.receiver = receiver; this.sender.SafeAddClosed(this.OnLinkClosed); this.receiver.SafeAddClosed(this.OnLinkClosed); // TODO: ////if (this.sender.State != AmqpObjectState.Opened) ////{ //// this.SafeClose(); //// throw Fx.Exception.AsWarning(new ArgumentException("Sender wasn't open", "sender")); ////} ////if (this.receiver.State != AmqpObjectState.Opened) ////{ //// this.SafeClose(); //// throw Fx.Exception.AsWarning(new ArgumentException("Reciever wasn't open", "receiver")); ////} }
public void AddCoordinator(ReceivingAmqpLink link) { link.RegisterMessageListener(this.OnMessage); link.Closed += this.link_Closed; lock (this.coordinators) { this.coordinators.Add(link.Identifier, link); } }
public Publisher(TestQueue queue, ReceivingAmqpLink link, int id) { this.queue = queue; this.link = link; this.id = id; this.link.RegisterMessageListener(this.OnMessage); this.link.Closed += new EventHandler(link_Closed); }
public AmqpLink CreateLink(AmqpSession session, AmqpLinkSettings settings) { bool isReceiver = settings.Role.Value; AmqpLink link; if (isReceiver) { if (settings.Target is Target && ((Target)settings.Target).Dynamic()) { string name = string.Format("$dynamic.{0}", Interlocked.Increment(ref this.dynamicId)); this.queues.Add(name, new TestQueue(this)); ((Target)settings.Target).Address = name; } link = new ReceivingAmqpLink(session, settings); } else { if (((Source)settings.Source).Dynamic()) { string name = string.Format("$dynamic.{0}", Interlocked.Increment(ref this.dynamicId)); this.queues.Add(name, new TestQueue(this)); ((Source)settings.Source).Address = name; } link = new SendingAmqpLink(session, settings); } return link; }
public async Task<ReceivingAmqpLink> CreateReceivingLink(string path, TimeSpan timeout, uint prefetchCount) { var timeoutHelper = new TimeoutHelper(timeout); AmqpSession session; if (!this.faultTolerantSession.TryGetOpenedObject(out session)) { session = await this.faultTolerantSession.GetOrCreateAsync(timeoutHelper.RemainingTime()); } var linkAddress = this.connectionString.BuildLinkAddress(path); var linkSettings = new AmqpLinkSettings() { Role = true, TotalLinkCredit = prefetchCount, AutoSendFlow = prefetchCount > 0, Source = new Source() { Address = linkAddress.AbsoluteUri }, SndSettleMode = null, // SenderSettleMode.Unsettled (null as it is the default and to avoid bytes on the wire) RcvSettleMode = (byte)ReceiverSettleMode.Second, LinkName = Guid.NewGuid().ToString("N") // Use a human readable link name to help with debuggin }; SetLinkSettingsCommonProperties(linkSettings, timeoutHelper.RemainingTime()); var link = new ReceivingAmqpLink(linkSettings); link.AttachTo(session); await OpenLinkAsync(link, timeoutHelper.RemainingTime()); return link; }