public void DeviceScopeIdentitiesCacheOnDeviceConnectedEvent() { // Arrange var connectionManager = new Mock <IConnectionManager>(MockBehavior.Strict); var authenticator = new Mock <IAuthenticator>(MockBehavior.Strict); var credentialsStore = new Mock <ICredentialsCache>(MockBehavior.Strict); var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); TimeSpan reauthFrequency = TimeSpan.FromHours(1); var connectionReauthenticator = new ConnectionReauthenticator( connectionManager.Object, authenticator.Object, credentialsStore.Object, deviceScopeIdentitiesCache.Object, reauthFrequency, Mock.Of <IIdentity>(i => i.Id == "d1/$edgeHub"), deviceConnectivityManager); deviceScopeIdentitiesCache.Setup(d => d.InitiateCacheRefresh()); // Act Mock.Get(deviceConnectivityManager).Raise(d => d.DeviceConnected += null, new EventArgs()); // Assert deviceScopeIdentitiesCache.VerifyAll(); }
public void TestHandleEdgeHubServiceIdentityRemove() { // Arrange var connectionManager = new Mock <IConnectionManager>(MockBehavior.Strict); var authenticator = new Mock <IAuthenticator>(MockBehavior.Strict); var credentialsStore = new Mock <ICredentialsCache>(MockBehavior.Strict); var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); TimeSpan reauthFrequency = TimeSpan.FromSeconds(3); var edgeHubIdentity = Mock.Of <IIdentity>(i => i.Id == "d2/$edgeHub"); connectionManager.Setup(c => c.RemoveDeviceConnection("d2/$edgeHub")).Returns(Task.CompletedTask); // Act var connectionReauthenticator = new ConnectionReauthenticator( connectionManager.Object, authenticator.Object, credentialsStore.Object, deviceScopeIdentitiesCache.Object, reauthFrequency, edgeHubIdentity, deviceConnectivityManager); deviceScopeIdentitiesCache.Raise(d => d.ServiceIdentityRemoved += null, null, "d2/$edgeHub"); // Assert Assert.NotNull(connectionReauthenticator); connectionManager.Verify(c => c.RemoveDeviceConnection("d2/$edgeHub"), Times.Never); authenticator.VerifyAll(); credentialsStore.VerifyAll(); deviceScopeIdentitiesCache.VerifyAll(); }
public void TestHandleServiceIdentityUpdateSuccess() { // Arrange var connectionManager = new Mock <IConnectionManager>(MockBehavior.Strict); var authenticator = new Mock <IAuthenticator>(MockBehavior.Strict); var credentialsStore = new Mock <ICredentialsCache>(MockBehavior.Strict); var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>(MockBehavior.Strict); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); TimeSpan reauthFrequency = TimeSpan.FromSeconds(3); var deviceIdentity = new DeviceIdentity(IoTHubHostName, "d1"); var moduleIdentity = new ModuleIdentity(IoTHubHostName, "d1", "m1"); var deviceCredentials = Mock.Of <IClientCredentials>(c => c.Identity == deviceIdentity && c.AuthenticationType == AuthenticationType.SasKey); var moduleCredentials = Mock.Of <IClientCredentials>(c => c.Identity == moduleIdentity && c.AuthenticationType == AuthenticationType.SasKey); credentialsStore.Setup(c => c.Get(deviceIdentity)).ReturnsAsync(Option.Some(deviceCredentials)); credentialsStore.Setup(c => c.Get(moduleIdentity)).ReturnsAsync(Option.Some(moduleCredentials)); var deviceProxy = Mock.Of <IDeviceProxy>(d => d.IsActive && d.Identity == deviceIdentity); var moduleProxy = Mock.Of <IDeviceProxy>(d => d.IsActive && d.Identity == moduleIdentity); connectionManager.Setup(c => c.GetDeviceConnection("d1")).Returns(Option.Some(deviceProxy)); connectionManager.Setup(c => c.GetDeviceConnection("d1/m1")).Returns(Option.Some(moduleProxy)); connectionManager.Setup(c => c.RemoveDeviceConnection("d1")).Returns(Task.CompletedTask); connectionManager.Setup(c => c.RemoveDeviceConnection("d1/m1")).Returns(Task.CompletedTask); authenticator.Setup(a => a.ReauthenticateAsync(deviceCredentials)).ReturnsAsync(true); authenticator.Setup(a => a.ReauthenticateAsync(moduleCredentials)).ReturnsAsync(true); var serviceAuthentication = new ServiceAuthentication(ServiceAuthenticationType.None); var deviceServiceIdentity = new ServiceIdentity("d1", "1234", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); var moduleServiceIdentity = new ServiceIdentity("d1/m1", "1234", Enumerable.Empty <string>(), serviceAuthentication, ServiceIdentityStatus.Enabled); // Act var connectionReauthenticator = new ConnectionReauthenticator( connectionManager.Object, authenticator.Object, credentialsStore.Object, deviceScopeIdentitiesCache.Object, reauthFrequency, Mock.Of <IIdentity>(e => e.Id == "ed/$edgeHub"), deviceConnectivityManager); deviceScopeIdentitiesCache.Raise(d => d.ServiceIdentityUpdated += null, null, deviceServiceIdentity); deviceScopeIdentitiesCache.Raise(d => d.ServiceIdentityUpdated += null, null, moduleServiceIdentity); // Assert Assert.NotNull(connectionReauthenticator); connectionManager.Verify(c => c.RemoveDeviceConnection("d1"), Times.Never); connectionManager.Verify(c => c.RemoveDeviceConnection("d1/m1"), Times.Never); connectionManager.Verify(c => c.GetDeviceConnection("d1"), Times.Once); connectionManager.Verify(c => c.GetDeviceConnection("d1/m1"), Times.Once); authenticator.VerifyAll(); credentialsStore.VerifyAll(); deviceScopeIdentitiesCache.VerifyAll(); }
public async Task TestConnectionReauthentication_MultipleLoopsTest() { // Arrange var connectionManager = new Mock <IConnectionManager>(MockBehavior.Strict); var authenticator = new Mock <IAuthenticator>(MockBehavior.Strict); var credentialsStore = new Mock <ICredentialsCache>(MockBehavior.Strict); var deviceScopeIdentitiesCache = Mock.Of <IDeviceScopeIdentitiesCache>(); var deviceConnectivityManager = Mock.Of <IDeviceConnectivityManager>(); TimeSpan reauthFrequency = TimeSpan.FromSeconds(5); var deviceIdentity = new DeviceIdentity(IoTHubHostName, "d1"); var moduleIdentity = new ModuleIdentity(IoTHubHostName, "d1", "m1"); var clients = new List <IIdentity> { deviceIdentity, moduleIdentity }; connectionManager.Setup(c => c.GetConnectedClients()).Returns(clients); connectionManager.Setup(c => c.RemoveDeviceConnection("d1")).Returns(Task.CompletedTask); var deviceCredentials = Mock.Of <IClientCredentials>(c => c.Identity == deviceIdentity && c.AuthenticationType == AuthenticationType.SasKey); var moduleCredentials = Mock.Of <IClientCredentials>(c => c.Identity == moduleIdentity && c.AuthenticationType == AuthenticationType.SasKey); credentialsStore.Setup(c => c.Get(deviceIdentity)).ReturnsAsync(Option.Some(deviceCredentials)); credentialsStore.Setup(c => c.Get(moduleIdentity)).ReturnsAsync(Option.Some(moduleCredentials)); authenticator.SetupSequence(a => a.ReauthenticateAsync(deviceCredentials)) .ReturnsAsync(true) .ReturnsAsync(false); authenticator.SetupSequence(a => a.ReauthenticateAsync(moduleCredentials)) .ReturnsAsync(true) .ReturnsAsync(true); // Act var connectionReauthenticator = new ConnectionReauthenticator( connectionManager.Object, authenticator.Object, credentialsStore.Object, deviceScopeIdentitiesCache, reauthFrequency, Mock.Of <IIdentity>(e => e.Id == "ed/$edgeHub"), deviceConnectivityManager); connectionReauthenticator.Init(); // Assert connectionManager.Verify(c => c.GetConnectedClients(), Times.Never); await Task.Delay(reauthFrequency * 2 + TimeSpan.FromSeconds(1)); connectionManager.Verify(c => c.GetConnectedClients(), Times.Exactly(2)); connectionManager.VerifyAll(); authenticator.VerifyAll(); credentialsStore.VerifyAll(); Mock.Get(deviceScopeIdentitiesCache).VerifyAll(); }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } ILogger logger = Logger.Factory.CreateLogger("EdgeHub"); EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration, logger); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); string sslProtocolsConfig = configuration.GetValue(Constants.ConfigKey.SslProtocols, string.Empty); SslProtocols sslProtocols = SslProtocolsHelper.Parse(sslProtocolsConfig, DefaultSslProtocols, logger); logger.LogInformation($"Enabling SSL protocols: {sslProtocols.Print()}"); IDependencyManager dependencyManager = new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle, sslProtocols); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, dependencyManager, clientCertAuthEnabled, sslProtocols); IContainer container = hosting.Container; logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation($"OptimizeForPerformance={configuration.GetValue("OptimizeForPerformance", true)}"); logger.LogInformation($"MessageAckTimeoutSecs={configuration.GetValue("MessageAckTimeoutSecs", 30)}"); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); var metricsProvider = container.Resolve <IMetricsProvider>(); Metrics.InitWithAspNet(metricsProvider, logger); // Note this requires App.UseMetricServer() to be called in Startup.cs // Init V0 Metrics MetricsV0.BuildMetricsCollector(configuration); // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } TimeSpan shutdownWaitPeriod = TimeSpan.FromSeconds(configuration.GetValue("ShutdownWaitPeriod", DefaultShutdownWaitPeriod)); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(shutdownWaitPeriod, logger); using (IProtocolHead protocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { await protocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled()); logger.LogInformation("Stopping the protocol heads..."); await protocolHead.CloseAsync(CancellationToken.None); logger.LogInformation("Protocol heads stopped."); await CloseDbStoreProviderAsync(container); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }
protected override void Load(ContainerBuilder builder) { // ISignatureProvider builder.Register( c => { ISignatureProvider signatureProvider = this.edgeHubConnectionString.Map( cs => { IotHubConnectionStringBuilder csBuilder = IotHubConnectionStringBuilder.Create(cs); return(new SharedAccessKeySignatureProvider(csBuilder.SharedAccessKey) as ISignatureProvider); }) .GetOrElse( () => { string edgeHubGenerationId = this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Generation ID missing")); string workloadUri = this.workloadUri.Expect(() => new InvalidOperationException("workloadUri is missing")); return(new HttpHsmSignatureProvider(this.edgeHubModuleId, edgeHubGenerationId, workloadUri, Constants.WorkloadApiVersion) as ISignatureProvider); }); return(signatureProvider); }) .As <ISignatureProvider>() .SingleInstance(); // Detect system environment builder.Register(c => new SystemEnvironment()) .As <ISystemEnvironment>() .SingleInstance(); // DataBase options builder.Register(c => new RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), this.optimizeForPerformance)) .As <IRocksDbOptionsProvider>() .SingleInstance(); // IDbStoreProvider builder.Register( c => { var loggerFactory = c.Resolve <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger(typeof(RoutingModule)); if (this.usePersistentStorage) { // Create partitions for messages and twins var partitionsList = new List <string> { Core.Constants.MessageStorePartitionKey, Core.Constants.TwinStorePartitionKey, Core.Constants.CheckpointStorePartitionKey }; try { IDbStoreProvider dbStoreprovider = DbStoreProvider.Create( c.Resolve <IRocksDbOptionsProvider>(), this.storagePath, partitionsList); logger.LogInformation($"Created persistent store at {this.storagePath}"); return(dbStoreprovider); } catch (Exception ex) when(!ExceptionEx.IsFatal(ex)) { logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store."); return(new InMemoryDbStoreProvider()); } } else { logger.LogInformation($"Using in-memory store"); return(new InMemoryDbStoreProvider()); } }) .As <IDbStoreProvider>() .SingleInstance(); // Task<Option<IEncryptionProvider>> builder.Register( async c => { Option <IEncryptionProvider> encryptionProviderOption = await this.workloadUri .Map( async uri => { var encryptionProvider = await EncryptionProvider.CreateAsync( this.storagePath, new Uri(uri), Constants.WorkloadApiVersion, this.edgeHubModuleId, this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")), Constants.InitializationVectorFileName) as IEncryptionProvider; return(Option.Some(encryptionProvider)); }) .GetOrElse(() => Task.FromResult(Option.None <IEncryptionProvider>())); return(encryptionProviderOption); }) .As <Task <Option <IEncryptionProvider> > >() .SingleInstance(); // IStoreProvider builder.Register(c => new StoreProvider(c.Resolve <IDbStoreProvider>())) .As <IStoreProvider>() .SingleInstance(); // ITokenProvider builder.Register(c => new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, TimeSpan.FromHours(1))) .Named <ITokenProvider>("EdgeHubClientAuthTokenProvider") .SingleInstance(); // ITokenProvider builder.Register( c => { string deviceId = WebUtility.UrlEncode(this.edgeDeviceId); string moduleId = WebUtility.UrlEncode(this.edgeHubModuleId); return(new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1))); }) .Named <ITokenProvider>("EdgeHubServiceAuthTokenProvider") .SingleInstance(); // Task<IDeviceScopeIdentitiesCache> builder.Register( async c => { IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache; if (this.authenticationMode == AuthenticationMode.CloudAndScope || this.authenticationMode == AuthenticationMode.Scope) { var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider"); IDeviceScopeApiClient securityScopesApiClient = new DeviceScopeApiClient(this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, 10, edgeHubTokenProvider); IServiceProxy serviceProxy = new ServiceProxy(securityScopesApiClient); IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "DeviceScopeCache"); deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy, encryptedStore, this.scopeCacheRefreshRate); } else { deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache(); } return(deviceScopeIdentitiesCache); }) .As <Task <IDeviceScopeIdentitiesCache> >() .AutoActivate() .SingleInstance(); // Task<ICredentialsCache> builder.Register( async c => { ICredentialsCache underlyingCredentialsCache; if (this.persistTokens) { IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "CredentialsCache"); return(new PersistedTokenCredentialsCache(encryptedStore)); } else { underlyingCredentialsCache = new NullCredentialsCache(); } ICredentialsCache credentialsCache = new CredentialsCache(underlyingCredentialsCache); return(credentialsCache); }) .As <Task <ICredentialsCache> >() .SingleInstance(); // Task<IAuthenticator> builder.Register( async c => { IAuthenticator tokenAuthenticator; IAuthenticator certificateAuthenticator; IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache; var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); // by default regardless of how the authenticationMode, X.509 certificate validation will always be scoped deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); certificateAuthenticator = new DeviceScopeCertificateAuthenticator(deviceScopeIdentitiesCache, new NullAuthenticator(), this.trustBundle, true); switch (this.authenticationMode) { case AuthenticationMode.Cloud: tokenAuthenticator = await this.GetCloudTokenAuthenticator(c); break; case AuthenticationMode.Scope: tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), true, true); break; default: IAuthenticator cloudTokenAuthenticator = await this.GetCloudTokenAuthenticator(c); tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudTokenAuthenticator, true, true); break; } ICredentialsCache credentialsCache = await credentialsCacheTask; return(new Authenticator(tokenAuthenticator, certificateAuthenticator, credentialsCache) as IAuthenticator); }) .As <Task <IAuthenticator> >() .SingleInstance(); // IClientCredentialsFactory builder.Register(c => new ClientCredentialsFactory(c.Resolve <IIdentityProvider>(), this.productInfo)) .As <IClientCredentialsFactory>() .SingleInstance(); // ConnectionReauthenticator builder.Register( async c => { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); var authenticatorTask = c.Resolve <Task <IAuthenticator> >(); var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); var deviceScopeIdentitiesCacheTask = c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await connectionManagerTask; IAuthenticator authenticator = await authenticatorTask; ICredentialsCache credentialsCache = await credentialsCacheTask; IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask; var connectionReauthenticator = new ConnectionReauthenticator( connectionManager, authenticator, credentialsCache, deviceScopeIdentitiesCache, TimeSpan.FromMinutes(5), edgeHubCredentials.Identity, deviceConnectivityManager); return(connectionReauthenticator); }) .As <Task <ConnectionReauthenticator> >() .SingleInstance(); base.Load(builder); }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle), clientCertAuthEnabled); IContainer container = hosting.Container; ILogger logger = container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(ShutdownWaitPeriod, logger); Metrics.BuildMetricsCollector(configuration); using (IProtocolHead protocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { await protocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled()); logger.LogInformation("Stopping the protocol heads..."); await Task.WhenAny(protocolHead.CloseAsync(CancellationToken.None), Task.Delay(TimeSpan.FromSeconds(10), CancellationToken.None)); logger.LogInformation("Protocol heads stopped."); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } ILogger logger = Logger.Factory.CreateLogger("EdgeHub"); EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration, logger); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); string sslProtocolsConfig = configuration.GetValue(Constants.ConfigKey.SslProtocols, string.Empty); SslProtocols sslProtocols = SslProtocolsHelper.Parse(sslProtocolsConfig, DefaultSslProtocols, logger); logger.LogInformation($"Enabling SSL protocols: {sslProtocols.Print()}"); IDependencyManager dependencyManager = new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle, certificates.ManifestTrustBundle, sslProtocols); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, dependencyManager, clientCertAuthEnabled, sslProtocols); IContainer container = hosting.Container; logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation($"OptimizeForPerformance={configuration.GetValue("OptimizeForPerformance", true)}"); logger.LogInformation($"MessageAckTimeoutSecs={configuration.GetValue("MessageAckTimeoutSecs", 30)}"); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); var metricsProvider = container.Resolve <IMetricsProvider>(); Metrics.InitWithAspNet(metricsProvider, logger); // Note this requires App.UseMetricServer() to be called in Startup.cs // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Register EdgeHub indentity in device scopes cache. // When we connect upstream, we verify that identity is in scope. // On a fresh start, we may not yet received the scopes from the upstream, so we need // to force add edgeHub in the cache so it is able to connect upstream. // Once we get the scopes from the upstream, this record is replaced. ServiceIdentity edgeHubIdentity = container.ResolveNamed <ServiceIdentity>("EdgeHubIdentity"); IServiceIdentityHierarchy identityScopes = container.Resolve <IServiceIdentityHierarchy>(); await identityScopes.InsertOrUpdate(edgeHubIdentity); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); ExperimentalFeatures experimentalFeatures = CreateExperimentalFeatures(configuration); var configUpdaterStartupFailed = new TaskCompletionSource <bool>(); var configDownloadTask = configUpdater.Init(configSource); _ = configDownloadTask.ContinueWith( _ => configUpdaterStartupFailed.SetResult(false), TaskContinuationOptions.OnlyOnFaulted); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } TimeSpan shutdownWaitPeriod = TimeSpan.FromSeconds(configuration.GetValue("ShutdownWaitPeriod", DefaultShutdownWaitPeriod)); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(shutdownWaitPeriod, logger); using (IProtocolHead mqttBrokerProtocolHead = await GetMqttBrokerProtocolHeadAsync(experimentalFeatures, container)) using (IProtocolHead edgeHubProtocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, experimentalFeatures, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { try { await Task.WhenAll(mqttBrokerProtocolHead.StartAsync(), configDownloadTask); await edgeHubProtocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled(), configUpdaterStartupFailed.Task); } catch (Exception ex) { logger.LogError($"Error starting protocol heads: {ex.Message}"); } logger.LogInformation("Stopping the protocol heads..."); await Task.WhenAll(mqttBrokerProtocolHead.CloseAsync(CancellationToken.None), edgeHubProtocolHead.CloseAsync(CancellationToken.None)); logger.LogInformation("Protocol heads stopped."); await CloseDbStoreProviderAsync(container); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }
public static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.Core.Routing.LoggerFactory = Logger.Factory; } X509Certificate2 cert; IEnumerable <X509Certificate2> chain; string edgeHubConnectionString = configuration.GetValue <string>(Constants.IotHubConnectionStringVariableName); // When connection string is not set it is edged mode if (string.IsNullOrEmpty(edgeHubConnectionString)) { var workloadUri = new Uri(configuration.GetValue <string>(Constants.WorkloadUriVariableName)); string edgeHubHostname = configuration.GetValue <string>(Constants.EdgeDeviceHostnameVariableName); string moduleId = configuration.GetValue <string>(Constants.ModuleIdVariableName); string generationId = configuration.GetValue <string>(Constants.ModuleGenerationIdVariableName); DateTime expiration = DateTime.UtcNow.AddDays(Constants.CertificateValidityDays); (cert, chain) = await CertificateHelper.GetServerCertificatesFromEdgelet(workloadUri, Constants.WorkloadApiVersion, moduleId, generationId, edgeHubHostname, expiration); } else { string edgeHubCertPath = configuration.GetValue <string>(Constants.EdgeHubServerCertificateFileKey); cert = new X509Certificate2(edgeHubCertPath); string edgeHubCaChainCertPath = configuration.GetValue <string>(Constants.EdgeHubServerCAChainCertificateFileKey); chain = CertificateHelper.GetServerCACertificatesFromFile(edgeHubCaChainCertPath); } // TODO: set certificate for Startup without the cache ServerCertificateCache.X509Certificate = cert; int port = configuration.GetValue("httpSettings:port", 443); Hosting hosting = Hosting.Initialize(port); IContainer container = hosting.Container; ILogger logger = container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); logger.LogInformation("Starting Edge Hub"); VersionInfo versionInfo = VersionInfo.Get(Constants.VersionInfoFileName); if (versionInfo != VersionInfo.Empty) { logger.LogInformation($"Version - {versionInfo.ToString(true)}"); } LogLogo(logger); if (chain != null) { logger.LogInformation("Installing intermediate certificates."); CertificateHelper.InstallCerts( RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? StoreName.CertificateAuthority : StoreName.Root, StoreLocation.CurrentUser, chain); } else { logger.LogWarning("Unable to find intermediate certificates."); } // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(ShutdownWaitPeriod, logger); var protocolHeads = new List <IProtocolHead>(); if (configuration.GetValue("mqttSettings:enabled", true)) { protocolHeads.Add(await container.Resolve <Task <MqttProtocolHead> >()); } if (configuration.GetValue("amqpSettings:enabled", true)) { protocolHeads.Add(await container.Resolve <Task <AmqpProtocolHead> >()); } if (configuration.GetValue("httpSettings:enabled", true)) { protocolHeads.Add(new HttpProtocolHead(hosting.WebHost)); } using (IProtocolHead protocolHead = new EdgeHubProtocolHead(protocolHeads, logger)) { await protocolHead.StartAsync(); await cts.Token.WhenCanceled(); await Task.WhenAny(protocolHead.CloseAsync(CancellationToken.None), Task.Delay(TimeSpan.FromSeconds(10), CancellationToken.None)); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); return(0); }
protected override void Load(ContainerBuilder builder) { // IMetricsListener builder.Register( c => this.metricsConfig.Enabled ? new MetricsListener(this.metricsConfig.ListenerConfig, c.Resolve <IMetricsProvider>()) : new NullMetricsListener() as IMetricsListener) .As <IMetricsListener>() .SingleInstance(); // IMetricsProvider builder.Register( c => this.metricsConfig.Enabled ? new MetricsProvider(MetricsConstants.EdgeHubMetricPrefix, this.iothubHostName, this.edgeDeviceId, this.metricsConfig.HistogramMaxAge) : new NullMetricsProvider() as IMetricsProvider) .As <IMetricsProvider>() .SingleInstance(); // ISignatureProvider builder.Register( c => { ISignatureProvider signatureProvider = this.edgeHubConnectionString.Map( cs => { IotHubConnectionStringBuilder csBuilder = IotHubConnectionStringBuilder.Create(cs); return(new SharedAccessKeySignatureProvider(csBuilder.SharedAccessKey) as ISignatureProvider); }) .GetOrElse( () => { string edgeHubGenerationId = this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Generation ID missing")); string workloadUri = this.workloadUri.Expect(() => new InvalidOperationException("workloadUri is missing")); string workloadApiVersion = this.workloadApiVersion.Expect(() => new InvalidOperationException("workloadUri version is missing")); return(new HttpHsmSignatureProvider(this.edgeHubModuleId, edgeHubGenerationId, workloadUri, workloadApiVersion, Constants.WorkloadApiVersion) as ISignatureProvider); }); return(signatureProvider); }) .As <ISignatureProvider>() .SingleInstance(); // Detect system environment builder.Register(c => new SystemEnvironment()) .As <ISystemEnvironment>() .SingleInstance(); // DataBase options builder.Register(c => new RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), this.optimizeForPerformance, this.storageMaxTotalWalSize, this.storageMaxOpenFiles, this.storageLogLevel)) .As <IRocksDbOptionsProvider>() .SingleInstance(); if (!this.usePersistentStorage && this.useBackupAndRestore) { // Backup and restore serialization builder.Register(c => new ProtoBufDataBackupRestore()) .As <IDataBackupRestore>() .SingleInstance(); } // IStorageSpaceChecker builder.Register( c => { IStorageSpaceChecker spaceChecker = !this.usePersistentStorage ? new MemorySpaceChecker(() => 0L) as IStorageSpaceChecker : new NullStorageSpaceChecker(); return(spaceChecker); }) .As <IStorageSpaceChecker>() .SingleInstance(); // IDbStoreProvider builder.Register( async c => { var loggerFactory = c.Resolve <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger(typeof(RoutingModule)); if (this.usePersistentStorage) { // Create partitions for messages and twins var partitionsList = new List <string> { Core.Constants.MessageStorePartitionKey, Core.Constants.TwinStorePartitionKey, Core.Constants.CheckpointStorePartitionKey }; try { IDbStoreProvider dbStoreProvider = DbStoreProvider.Create( c.Resolve <IRocksDbOptionsProvider>(), this.storagePath, partitionsList); logger.LogInformation($"Created persistent store at {this.storagePath}"); return(dbStoreProvider); } catch (Exception ex) when(!ex.IsFatal()) { logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store."); IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c); return(dbStoreProvider); } } else { logger.LogInformation($"Using in-memory store"); IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c); return(dbStoreProvider); } }) .As <Task <IDbStoreProvider> >() .SingleInstance(); // Task<Option<IEncryptionProvider>> builder.Register( async c => { Option <IEncryptionProvider> encryptionProviderOption = await this.workloadUri .Map( async uri => { var encryptionProvider = await EncryptionProvider.CreateAsync( this.storagePath, new Uri(uri), this.workloadApiVersion.Expect(() => new InvalidOperationException("Missing workload API version")), Constants.WorkloadApiVersion, this.edgeHubModuleId, this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")), Constants.InitializationVectorFileName) as IEncryptionProvider; return(Option.Some(encryptionProvider)); }) .GetOrElse(() => Task.FromResult(Option.None <IEncryptionProvider>())); return(encryptionProviderOption); }) .As <Task <Option <IEncryptionProvider> > >() .SingleInstance(); // Task<IStoreProvider> builder.Register(async c => { var dbStoreProvider = await c.Resolve <Task <IDbStoreProvider> >(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); return(storeProvider); }) .As <Task <IStoreProvider> >() .SingleInstance(); // Task<IMetadataStore> builder.Register( async c => { var storeProvider = await c.Resolve <Task <IStoreProvider> >(); IKeyValueStore <string, string> entityStore = storeProvider.GetEntityStore <string, string>("ProductInfo", "MetadataStore"); IMetadataStore metadataStore = new MetadataStore(entityStore, this.productInfo); return(metadataStore); }) .As <Task <IMetadataStore> >() .SingleInstance(); // ITokenProvider builder.Register(c => new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, TimeSpan.FromHours(1))) .Named <ITokenProvider>("EdgeHubClientAuthTokenProvider") .SingleInstance(); // ITokenProvider builder.Register( c => { string deviceId = WebUtility.UrlEncode(this.edgeDeviceId); string moduleId = WebUtility.UrlEncode(this.edgeHubModuleId); return(new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1))); }) .Named <ITokenProvider>("EdgeHubServiceAuthTokenProvider") .SingleInstance(); builder.Register( c => { var loggerFactory = c.Resolve <ILoggerFactory>(); var logger = loggerFactory.CreateLogger <RoutingModule>(); return(Proxy.Parse(this.proxy, logger)); }) .As <Option <IWebProxy> >() .SingleInstance(); // IServiceIdentityHierarchy builder.Register <IServiceIdentityHierarchy>( c => { if (this.nestedEdgeEnabled) { return(new ServiceIdentityTree(this.edgeDeviceId)); } else { return(new ServiceIdentityDictionary(this.edgeDeviceId)); } }) .As <IServiceIdentityHierarchy>() .SingleInstance(); // Task<IDeviceScopeIdentitiesCache> builder.Register( async c => { IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache; if (this.authenticationMode == AuthenticationMode.CloudAndScope || this.authenticationMode == AuthenticationMode.Scope) { var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider"); var proxy = c.Resolve <Option <IWebProxy> >(); IServiceIdentityHierarchy serviceIdentityHierarchy = c.Resolve <IServiceIdentityHierarchy>(); string hostName = this.gatewayHostName.GetOrElse(this.iothubHostName); IDeviceScopeApiClientProvider securityScopesApiClientProvider = new DeviceScopeApiClientProvider(hostName, this.edgeDeviceId, this.edgeHubModuleId, 10, edgeHubTokenProvider, serviceIdentityHierarchy, proxy); IServiceProxy serviceProxy = new ServiceProxy(securityScopesApiClientProvider, this.nestedEdgeEnabled); IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "DeviceScopeCache"); deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceIdentityHierarchy, serviceProxy, encryptedStore, this.scopeCacheRefreshRate, this.scopeCacheRefreshDelay); } else { deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache(); } return(deviceScopeIdentitiesCache); }) .As <Task <IDeviceScopeIdentitiesCache> >() .AutoActivate() .SingleInstance(); // IRegistryApiClient builder.Register( c => { string upstreamHostname = this.gatewayHostName.GetOrElse(this.iothubHostName); var proxy = c.Resolve <Option <IWebProxy> >(); var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider"); return(new RegistryOnBehalfOfApiClient(upstreamHostname, proxy, edgeHubTokenProvider)); }) .As <IRegistryOnBehalfOfApiClient>() .SingleInstance(); // Task<ICredentialsCache> builder.Register( async c => { ICredentialsCache underlyingCredentialsCache; if (this.persistTokens) { IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "CredentialsCache"); return(new PersistedTokenCredentialsCache(encryptedStore)); } else { underlyingCredentialsCache = new NullCredentialsCache(); } ICredentialsCache credentialsCache; if (this.nestedEdgeEnabled) { credentialsCache = new NestedCredentialsCache(underlyingCredentialsCache); } else { credentialsCache = new CredentialsCache(underlyingCredentialsCache); } return(credentialsCache); }) .As <Task <ICredentialsCache> >() .SingleInstance(); // Task<IAuthenticator> builder.Register( async c => { IAuthenticator tokenAuthenticator; IAuthenticator certificateAuthenticator; IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache; var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); // by default regardless of how the authenticationMode, X.509 certificate validation will always be scoped deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); certificateAuthenticator = new DeviceScopeCertificateAuthenticator(deviceScopeIdentitiesCache, new NullAuthenticator(), this.trustBundle, true, this.nestedEdgeEnabled); switch (this.authenticationMode) { case AuthenticationMode.Cloud: tokenAuthenticator = await this.GetCloudTokenAuthenticator(c); break; case AuthenticationMode.Scope: tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), true, true, this.nestedEdgeEnabled); break; default: IAuthenticator cloudTokenAuthenticator = await this.GetCloudTokenAuthenticator(c); tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudTokenAuthenticator, true, true, this.nestedEdgeEnabled); break; } ICredentialsCache credentialsCache = await credentialsCacheTask; return(new Authenticator(tokenAuthenticator, certificateAuthenticator, credentialsCache) as IAuthenticator); }) .As <Task <IAuthenticator> >() .SingleInstance(); // IClientCredentialsFactory builder.Register(c => new ClientCredentialsFactory(c.Resolve <IIdentityProvider>(), this.productInfo)) .As <IClientCredentialsFactory>() .SingleInstance(); // IClientCredentials "EdgeHubCredentials" builder.Register( c => { var identityFactory = c.Resolve <IClientCredentialsFactory>(); IClientCredentials edgeHubCredentials = this.edgeHubConnectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse( () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeHubModuleId)); return(edgeHubCredentials); }) .Named <IClientCredentials>("EdgeHubCredentials") .SingleInstance(); // ServiceIdentity "EdgeHubIdentity" builder.Register( c => { return(new ServiceIdentity( this.edgeDeviceId, this.edgeHubModuleId, deviceScope: null, parentScopes: new List <string>(), this.edgeHubGenerationId.GetOrElse("0"), capabilities: new List <string>(), new ServiceAuthentication(ServiceAuthenticationType.None), ServiceIdentityStatus.Enabled)); }) .Named <ServiceIdentity>("EdgeHubIdentity") .SingleInstance(); // ConnectionReauthenticator builder.Register( async c => { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); var authenticatorTask = c.Resolve <Task <IAuthenticator> >(); var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); var deviceScopeIdentitiesCacheTask = c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await connectionManagerTask; IAuthenticator authenticator = await authenticatorTask; ICredentialsCache credentialsCache = await credentialsCacheTask; IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask; var connectionReauthenticator = new ConnectionReauthenticator( connectionManager, authenticator, credentialsCache, deviceScopeIdentitiesCache, TimeSpan.FromMinutes(5), edgeHubCredentials.Identity, deviceConnectivityManager); return(connectionReauthenticator); }) .As <Task <ConnectionReauthenticator> >() .SingleInstance(); base.Load(builder); }