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