public async Task <IAmqpAuthenticationRefresher> CreateRefresherAsync(DeviceIdentity deviceIdentity, TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, timeout, $"{nameof(CreateRefresherAsync)}"); } AmqpIoTConnection amqpIoTConnection = await EnsureConnectionAsync(timeout).ConfigureAwait(false); IAmqpAuthenticationRefresher amqpAuthenticator = await amqpIoTConnection.CreateRefresherAsync(deviceIdentity, timeout).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, timeout, $"{nameof(CreateRefresherAsync)}"); } return(amqpAuthenticator); }
public AmqpUnit CreateAmqpUnit( DeviceIdentity deviceIdentity, Func <MethodRequestInternal, Task> methodHandler, Action <Twin, string, TwinCollection> twinMessageListener, Func <string, Message, Task> eventListener, Action onUnitDisconnected) { IAmqpUnitManager amqpConnectionPool = ResolveConnectionPool(deviceIdentity.IotHubConnectionString.HostName); return(amqpConnectionPool.CreateAmqpUnit( deviceIdentity, methodHandler, twinMessageListener, eventListener, onUnitDisconnected)); }
public AmqpUnit CreateAmqpUnit( DeviceIdentity deviceIdentity, Func <MethodRequestInternal, Task> methodHandler, Action <Twin, string, TwinCollection> twinMessageListener, Func <string, Message, Task> eventListener) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, $"{nameof(CreateAmqpUnit)}"); } if (deviceIdentity.AuthenticationModel != AuthenticationModel.X509 && (deviceIdentity.AmqpTransportSettings?.AmqpConnectionPoolSettings?.Pooling ?? false)) { IAmqpConnectionHolder amqpConnectionHolder; lock (Lock) { ISet <IAmqpConnectionHolder> amqpConnectionHolders = ResolveConnectionGroup(deviceIdentity, true); if (amqpConnectionHolders.Count < deviceIdentity.AmqpTransportSettings.AmqpConnectionPoolSettings.MaxPoolSize) { amqpConnectionHolder = new AmqpConnectionHolder(deviceIdentity); amqpConnectionHolder.OnConnectionDisconnected += (o, args) => RemoveConnection(amqpConnectionHolders, o as IAmqpConnectionHolder); amqpConnectionHolders.Add(amqpConnectionHolder); if (Logging.IsEnabled) { Logging.Associate(this, amqpConnectionHolder, "amqpConnectionHolders"); } } else { amqpConnectionHolder = GetLeastUsedConnection(amqpConnectionHolders); } } if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, $"{nameof(CreateAmqpUnit)}"); } return(amqpConnectionHolder.CreateAmqpUnit(deviceIdentity, methodHandler, twinMessageListener, eventListener)); } else { if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, $"{nameof(CreateAmqpUnit)}"); } return(new AmqpConnectionHolder(deviceIdentity) .CreateAmqpUnit(deviceIdentity, methodHandler, twinMessageListener, eventListener)); } }
internal AmqpAuthenticationRefresher(DeviceIdentity deviceIdentity, AmqpIoTCbsLink amqpCbsLink) { _amqpIoTCbsLink = amqpCbsLink; _connectionString = deviceIdentity.IotHubConnectionString; _operationTimeout = deviceIdentity.AmqpTransportSettings.OperationTimeout; _audience = deviceIdentity.Audience; _amqpIoTCbsTokenProvider = new AmqpIoTCbsTokenProvider(_connectionString); if (Logging.IsEnabled) { Logging.Associate(this, deviceIdentity, $"{nameof(DeviceIdentity)}"); } if (Logging.IsEnabled) { Logging.Associate(this, amqpCbsLink, $"{nameof(_amqpIoTCbsLink)}"); } }
public AmqpUnit CreateAmqpUnit( DeviceIdentity deviceIdentity, Func <MethodRequestInternal, Task> onMethodCallback, Action <Twin, string, TwinCollection, IotHubException> twinMessageListener, Func <string, Message, Task> onModuleMessageReceivedCallback, Func <Message, Task> onDeviceMessageReceivedCallback, Action onUnitDisconnected) { IAmqpUnitManager amqpConnectionPool = ResolveConnectionPool(deviceIdentity.IotHubConnectionString.HostName); return(amqpConnectionPool.CreateAmqpUnit( deviceIdentity, onMethodCallback, twinMessageListener, onModuleMessageReceivedCallback, onDeviceMessageReceivedCallback, onUnitDisconnected)); }
internal static async Task <ReceivingAmqpLink> OpenEventsReceiverLinkAsync( DeviceIdentity deviceIdentity, AmqpSession amqpSession, TimeSpan timeout ) { return(await OpenReceivingAmqpLinkAsync( deviceIdentity, amqpSession, null, (byte)ReceiverSettleMode.First, CommonConstants.DeviceEventPathTemplate, CommonConstants.ModuleEventPathTemplate, EventsReceiverLinkSuffix, null, timeout ).ConfigureAwait(false)); }
internal static async Task <SendingAmqpLink> OpenTelemetrySenderLinkAsync( DeviceIdentity deviceIdentity, AmqpSession amqpSession, TimeSpan timeout ) { return(await OpenSendingAmqpLinkAsync( deviceIdentity, amqpSession, null, null, CommonConstants.DeviceEventPathTemplate, CommonConstants.ModuleEventPathTemplate, TelemetrySenderLinkSuffix, null, timeout ).ConfigureAwait(false)); }
private ISet <IAmqpConnectionHolder> ResolveConnectionGroup(DeviceIdentity deviceIdentity, bool create) { if (deviceIdentity.AuthenticationModel == AuthenticationModel.SasIndividual) { return(AmqpSasIndividualPool); } else { string scope = deviceIdentity.IotHubConnectionString.SharedAccessKeyName; AmqpSasGroupedPool.TryGetValue(scope, out ISet <IAmqpConnectionHolder> amqpConnectionHolders); if (create && amqpConnectionHolders == null) { amqpConnectionHolders = new HashSet <IAmqpConnectionHolder>(); AmqpSasGroupedPool.Add(scope, amqpConnectionHolders); } return(amqpConnectionHolders); } }
private void RemoveDevice(DeviceIdentity deviceIdentity, bool gracefulDisconnect) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, $"{nameof(RemoveDevice)}"); } bool removed = AmqpUnits.Remove(deviceIdentity); if (removed && GetNumberOfUnits() == 0) { // TODO #887: handle gracefulDisconnect Shutdown(); } if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, $"{nameof(RemoveDevice)}"); } }
internal static async Task <SendingAmqpLink> OpenTwinSenderLinkAsync( DeviceIdentity deviceIdentity, AmqpSession amqpSession, string correlationIdSuffix, TimeSpan timeout ) { return(await OpenSendingAmqpLinkAsync( deviceIdentity, amqpSession, (byte)SenderSettleMode.Settled, (byte)ReceiverSettleMode.First, CommonConstants.DeviceTwinPathTemplate, CommonConstants.ModuleTwinPathTemplate, TwinSenderLinkSuffix, TwinCorrelationIdPrefix + correlationIdSuffix, timeout ).ConfigureAwait(false)); }
public async Task <AmqpIoTSession> OpenSessionAsync(DeviceIdentity deviceIdentity, TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, timeout, $"{nameof(OpenSessionAsync)}"); } AmqpIoTConnection amqpIoTConnection = await EnsureConnectionAsync(timeout).ConfigureAwait(false); AmqpIoTSession amqpIoTSession = await amqpIoTConnection.OpenSessionAsync(timeout).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Associate(amqpIoTConnection, amqpIoTSession, $"{nameof(OpenSessionAsync)}"); } if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, timeout, $"{nameof(OpenSessionAsync)}"); } return(amqpIoTSession); }
private async Task <AmqpSession> AmqpSessionCreator(DeviceIdentity deviceIdentity, ILinkFactory linkFactory, AmqpSessionSettings amqpSessionSettings, TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, timeout, $"{nameof(AmqpSessionCreator)}"); } AmqpConnection amqpConnection = await EnsureConnection(timeout).ConfigureAwait(false); AmqpSession amqpSession = new AmqpSession(amqpConnection, amqpSessionSettings, linkFactory); amqpConnection.AddSession(amqpSession, new ushort?()); if (Logging.IsEnabled) { Logging.Associate(amqpConnection, amqpSession, $"{nameof(AmqpSessionCreator)}"); } if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, timeout, $"{nameof(AmqpSessionCreator)}"); } return(amqpSession); }
public AmqpUnit( DeviceIdentity deviceIdentity, Func<DeviceIdentity, ILinkFactory, AmqpSessionSettings, TimeSpan, Task<AmqpSession>> amqpSessionCreator, Func<DeviceIdentity, TimeSpan, Task<IAmqpAuthenticationRefresher>> amqpAuthenticationRefresherCreator, Func<MethodRequestInternal, Task> methodHandler, Action<AmqpMessage> twinMessageListener, Func<string, Message, Task> eventListener) { _deviceIdentity = deviceIdentity; _methodHandler = methodHandler; _twinMessageListener = twinMessageListener; _eventListener = eventListener; _amqpSessionCreator = amqpSessionCreator; _amqpAuthenticationRefresherCreator = amqpAuthenticationRefresherCreator; _amqpSessionSettings = new AmqpSessionSettings() { Properties = new Fields() }; if (Logging.IsEnabled) Logging.Associate(this, _deviceIdentity, $"{nameof(_deviceIdentity)}"); }
private static string BuildLinkAddress(DeviceIdentity deviceIdentity, string deviceTemplate, string moduleTemplate) { string path; if (string.IsNullOrEmpty(deviceIdentity.IotHubConnectionString.ModuleId)) { path = string.Format( CultureInfo.InvariantCulture, deviceTemplate, WebUtility.UrlEncode(deviceIdentity.IotHubConnectionString.DeviceId) ); } else { path = string.Format( CultureInfo.InvariantCulture, moduleTemplate, WebUtility.UrlEncode(deviceIdentity.IotHubConnectionString.DeviceId), WebUtility.UrlEncode(deviceIdentity.IotHubConnectionString.ModuleId) ); } return(deviceIdentity.IotHubConnectionString.BuildLinkAddress(path).AbsoluteUri); }
public AmqpUnit CreateAmqpUnit( DeviceIdentity deviceIdentity, Func <MethodRequestInternal, Task> methodHandler, Action <Twin, string, TwinCollection> twinMessageListener, Func <string, Message, Task> eventListener, Action onUnitDisconnected) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, $"{nameof(CreateAmqpUnit)}"); } if (deviceIdentity.IsPooling()) { AmqpConnectionHolder amqpConnectionHolder; lock (_lock) { AmqpConnectionHolder[] amqpConnectionHolders = ResolveConnectionGroup(deviceIdentity); amqpConnectionHolder = ResolveConnectionByHashing(amqpConnectionHolders, deviceIdentity); } if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, $"{nameof(CreateAmqpUnit)}"); } return(amqpConnectionHolder.CreateAmqpUnit(deviceIdentity, methodHandler, twinMessageListener, eventListener, onUnitDisconnected)); } else { if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, $"{nameof(CreateAmqpUnit)}"); } return(new AmqpConnectionHolder(deviceIdentity).CreateAmqpUnit(deviceIdentity, methodHandler, twinMessageListener, eventListener, onUnitDisconnected)); } }
internal AmqpTransportHandler( IPipelineContext context, IotHubConnectionString connectionString, AmqpTransportSettings transportSettings, Func <MethodRequestInternal, Task> methodHandler = null, Action <TwinCollection> desiredPropertyListener = null, Func <string, Message, Task> eventListener = null) : base(context, transportSettings) { _operationTimeout = transportSettings.OperationTimeout; _desiredPropertyListener = desiredPropertyListener; DeviceIdentity deviceIdentity = new DeviceIdentity(connectionString, transportSettings, context.Get <ProductInfo>()); _amqpUnit = AmqpUnitManager.GetInstance().CreateAmqpUnit( deviceIdentity, methodHandler, TwinMessageListener, eventListener ); _amqpUnit.OnUnitDisconnected += (o, args) => { bool gracefulDisconnect = (bool)o; if (gracefulDisconnect) { OnTransportClosedGracefully(); } else { OnTransportDisconnected(); } }; if (Logging.IsEnabled) { Logging.Associate(this, _amqpUnit, $"{nameof(_amqpUnit)}"); } }
private AmqpConnectionHolder[] ResolveConnectionGroup(DeviceIdentity deviceIdentity) { if (deviceIdentity.AuthenticationModel == AuthenticationModel.SasIndividual) { if (_amqpSasIndividualPool == null) { _amqpSasIndividualPool = new AmqpConnectionHolder[deviceIdentity.AmqpTransportSettings.AmqpConnectionPoolSettings.MaxPoolSize]; } return(_amqpSasIndividualPool); } else { string scope = deviceIdentity.IotHubConnectionString.SharedAccessKeyName; _amqpSasGroupedPool.TryGetValue(scope, out AmqpConnectionHolder[] amqpConnectionHolders); if (amqpConnectionHolders == null) { amqpConnectionHolders = new AmqpConnectionHolder[deviceIdentity.AmqpTransportSettings.AmqpConnectionPoolSettings.MaxPoolSize]; _amqpSasGroupedPool.Add(scope, amqpConnectionHolders); } return(amqpConnectionHolders); } }
public void RemoveAmqpUnit(AmqpUnit amqpUnit) { if (Logging.IsEnabled) { Logging.Enter(this, amqpUnit, $"{nameof(RemoveAmqpUnit)}"); } DeviceIdentity deviceIdentity = amqpUnit.GetDeviceIdentity(); if (deviceIdentity.IsPooling()) { AmqpConnectionHolder amqpConnectionHolder; lock (_lock) { AmqpConnectionHolder[] amqpConnectionHolders = ResolveConnectionGroup(deviceIdentity); amqpConnectionHolder = ResolveConnectionByHashing(amqpConnectionHolders, deviceIdentity); } amqpConnectionHolder.RemoveAmqpUnit(amqpUnit); } if (Logging.IsEnabled) { Logging.Exit(this, amqpUnit, $"{nameof(RemoveAmqpUnit)}"); } }
internal AmqpTransportHandler( IPipelineContext context, IotHubConnectionString connectionString, AmqpTransportSettings transportSettings, Func <MethodRequestInternal, Task> onMethodCallback = null, Action <TwinCollection> onDesiredStatePatchReceivedCallback = null, Func <string, Message, Task> onModuleMessageReceivedCallback = null, Func <Message, Task> onDeviceMessageReceivedCallback = null) : base(context, transportSettings) { _operationTimeout = transportSettings.OperationTimeout; _onDesiredStatePatchListener = onDesiredStatePatchReceivedCallback; var deviceIdentity = new DeviceIdentity(connectionString, transportSettings, context.Get <ProductInfo>(), context.Get <ClientOptions>()); _amqpUnit = AmqpUnitManager.GetInstance().CreateAmqpUnit( deviceIdentity, onMethodCallback, TwinMessageListener, onModuleMessageReceivedCallback, onDeviceMessageReceivedCallback, OnDisconnected); Logging.Associate(this, _amqpUnit, nameof(_amqpUnit)); }
private AmqpConnectionHolder ResolveConnectionByHashing(AmqpConnectionHolder[] pool, DeviceIdentity deviceIdentity) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, $"{nameof(ResolveConnectionByHashing)}"); } int index = Math.Abs(deviceIdentity.GetHashCode()) % pool.Length; if (pool[index] == null) { pool[index] = new AmqpConnectionHolder(deviceIdentity); } if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, $"{nameof(ResolveConnectionByHashing)}"); } return(pool[index]); }
private async Task <IAmqpAuthenticationRefresher> AuthenticationRefresherCreator(DeviceIdentity deviceIdentity, TimeSpan timeout) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, timeout, $"{nameof(AuthenticationRefresherCreator)}"); } if (AmqpConnection == null) { throw new IotHubCommunicationException(); } AmqpCbsLink = AmqpCbsLink ?? new AmqpCbsLink(AmqpConnection); IAmqpAuthenticationRefresher amqpAuthenticator = new AmqpAuthenticationRefresher(deviceIdentity, AmqpCbsLink); await amqpAuthenticator.InitLoopAsync(timeout).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, timeout, $"{nameof(AuthenticationRefresherCreator)}"); } return(amqpAuthenticator); }
public AmqpUnit CreateAmqpUnit( DeviceIdentity deviceIdentity, Func <MethodRequestInternal, Task> onMethodCallback, Action <Twin, string, TwinCollection, IotHubException> twinMessageListener, Func <string, Message, Task> onModuleMessageReceivedCallback, Func <Message, Task> onDeviceMessageReceivedCallback, Action onUnitDisconnected) { if (Logging.IsEnabled) { Logging.Enter(this, deviceIdentity, nameof(CreateAmqpUnit)); } if (deviceIdentity.IsPooling()) { AmqpConnectionHolder amqpConnectionHolder; lock (_lock) { AmqpConnectionHolder[] amqpConnectionHolders = ResolveConnectionGroup(deviceIdentity); amqpConnectionHolder = ResolveConnectionByHashing(amqpConnectionHolders, deviceIdentity); // For group sas token authenticated devices over a multiplexed connection, the TokenRefresher // of the first client connecting will be used for generating the group sas tokens // and will be associated with the connection itself. // For this reason, if the device identity of the client is not the one associated with the // connection, the associated TokenRefresher can be safely disposed. // Note - This does not cause any identity related issues since the group sas tokens are generated // against the hub host as the intended audience (without the "device Id"). if (deviceIdentity.AuthenticationModel == AuthenticationModel.SasGrouped && !ReferenceEquals(amqpConnectionHolder.GetDeviceIdentityOfAuthenticationProvider(), deviceIdentity) && deviceIdentity.IotHubConnectionString?.TokenRefresher != null && deviceIdentity.IotHubConnectionString.TokenRefresher.DisposalWithClient) { deviceIdentity.IotHubConnectionString.TokenRefresher.Dispose(); } } if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, nameof(CreateAmqpUnit)); } return(amqpConnectionHolder.CreateAmqpUnit( deviceIdentity, onMethodCallback, twinMessageListener, onModuleMessageReceivedCallback, onDeviceMessageReceivedCallback, onUnitDisconnected)); } else { if (Logging.IsEnabled) { Logging.Exit(this, deviceIdentity, nameof(CreateAmqpUnit)); } return(new AmqpConnectionHolder(deviceIdentity) .CreateAmqpUnit( deviceIdentity, onMethodCallback, twinMessageListener, onModuleMessageReceivedCallback, onDeviceMessageReceivedCallback, onUnitDisconnected)); } }