示例#1
0
        public void Register(ContainerBuilder builder)
        {
            builder.RegisterModule(new LoggingModule());
            builder.RegisterBuildCallback(
                c =>
            {
                // set up loggers for Dotnetty
                var loggerFactory = c.Resolve <ILoggerFactory>();
                InternalLoggerFactory.DefaultFactory = loggerFactory;

                var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("EdgeHub"));
                eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational);
            });

            bool optimizeForPerformance = this.configuration.GetValue("OptimizeForPerformance", true);

            (bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, bool useBackupAndRestore, Option <string> storageBackupPath, Option <ulong> storageMaxTotalWalSize, Option <StorageLogLevel> storageLogLevel)storeAndForward =
                this.GetStoreAndForwardConfiguration();

            IConfiguration       configuration        = this.configuration.GetSection("experimentalFeatures");
            ExperimentalFeatures experimentalFeatures = ExperimentalFeatures.Create(configuration, Logger.Factory.CreateLogger("EdgeHub"));

            MetricsListenerConfig listenerConfig = experimentalFeatures.EnableMetrics
                ? MetricsListenerConfig.Create(this.configuration.GetSection("metrics:listener"))
                : new MetricsListenerConfig();
            MetricsConfig metricsConfig = new MetricsConfig(experimentalFeatures.EnableMetrics, listenerConfig);

            this.RegisterCommonModule(builder, optimizeForPerformance, storeAndForward, metricsConfig);
            this.RegisterRoutingModule(builder, storeAndForward, experimentalFeatures);
            this.RegisterMqttModule(builder, storeAndForward, optimizeForPerformance);
            this.RegisterAmqpModule(builder);
            builder.RegisterModule(new HttpModule());
        }
示例#2
0
        public void Register(ContainerBuilder builder)
        {
            builder.RegisterModule(new LoggingModule());
            builder.RegisterBuildCallback(
                c =>
            {
                // set up loggers for Dotnetty
                var loggerFactory = c.Resolve <ILoggerFactory>();
                InternalLoggerFactory.DefaultFactory = loggerFactory;

                var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("EdgeHub"));
                eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational);
            });

            bool optimizeForPerformance = this.configuration.GetValue("OptimizeForPerformance", true);

            (bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath)storeAndForward = this.GetStoreAndForwardConfiguration();

            IConfiguration       configuration        = this.configuration.GetSection("experimentalFeatures");
            ExperimentalFeatures experimentalFeatures = ExperimentalFeatures.Create(configuration);

            this.RegisterCommonModule(builder, optimizeForPerformance, storeAndForward);
            this.RegisterRoutingModule(builder, storeAndForward, experimentalFeatures);
            this.RegisterMqttModule(builder, storeAndForward, optimizeForPerformance);
            this.RegisterAmqpModule(builder);
            builder.RegisterModule(new HttpModule());
        }
示例#3
0
        static ExperimentalFeatures CreateExperimentalFeatures(IConfigurationRoot configuration)
        {
            IConfiguration       experimentalFeaturesConfig = configuration.GetSection(Constants.ConfigKey.ExperimentalFeatures);
            ExperimentalFeatures experimentalFeatures       = ExperimentalFeatures.Create(experimentalFeaturesConfig, Logger.Factory.CreateLogger("EdgeHub"));

            return(experimentalFeatures);
        }
示例#4
0
        public void Register(ContainerBuilder builder)
        {
            builder.RegisterModule(new LoggingModule());
            builder.RegisterBuildCallback(
                c =>
            {
                // set up loggers for Dotnetty
                var loggerFactory = c.Resolve <ILoggerFactory>();
                InternalLoggerFactory.DefaultFactory = loggerFactory;

                var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("EdgeHub"));
                eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational);
            });

            bool optimizeForPerformance = this.configuration.GetValue("OptimizeForPerformance", true);

            (bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath, bool useBackupAndRestore, Option <string> storageBackupPath, Option <ulong> storageMaxTotalWalSize, Option <StorageLogLevel> storageLogLevel)storeAndForward =
                this.GetStoreAndForwardConfiguration();

            IConfiguration       configuration        = this.configuration.GetSection("experimentalFeatures");
            ExperimentalFeatures experimentalFeatures = ExperimentalFeatures.Create(configuration, Logger.Factory.CreateLogger("EdgeHub"));

            // Temporarly make metrics default to off for windows. This is only until the dotnet 3.1 work is completed
            // This temp fix is needed to fix all e2e tests since edgehub currently crashes
            MetricsConfig metricsConfig = new MetricsConfig(this.configuration.GetSection("metrics:listener"), !RuntimeInformation.IsOSPlatform(OSPlatform.Windows));

            this.RegisterCommonModule(builder, optimizeForPerformance, storeAndForward, metricsConfig);
            this.RegisterRoutingModule(builder, storeAndForward, experimentalFeatures);
            this.RegisterMqttModule(builder, storeAndForward, optimizeForPerformance);
            this.RegisterAmqpModule(builder);
            builder.RegisterModule(new HttpModule());
        }
示例#5
0
        public static bool IsViaBrokerUpstream(ExperimentalFeatures experimentalFeatures, bool nestedEdgeEnabled, bool hasGatewayHostname)
        {
            bool isLegacyUpstream = !experimentalFeatures.Enabled ||
                                    !experimentalFeatures.EnableMqttBroker ||
                                    !nestedEdgeEnabled ||
                                    !hasGatewayHostname;

            return(isLegacyUpstream);
        }
示例#6
0
        void RegisterCommonModule(
            ContainerBuilder builder,
            bool optimizeForPerformance,
            StoreAndForward storeAndForward,
            MetricsConfig metricsConfig,
            ExperimentalFeatures experimentalFeatures)
        {
            bool            cacheTokens        = this.configuration.GetValue("CacheTokens", false);
            Option <string> workloadUri        = this.GetConfigurationValueIfExists <string>(Constants.ConfigKey.WorkloadUri);
            Option <string> workloadApiVersion = this.GetConfigurationValueIfExists <string>(Constants.ConfigKey.WorkloadAPiVersion);
            Option <string> moduleGenerationId = this.GetConfigurationValueIfExists <string>(Constants.ConfigKey.ModuleGenerationId);
            bool            hasParentEdge      = this.GetConfigurationValueIfExists <string>(Constants.ConfigKey.GatewayHostname).HasValue;

            if (!Enum.TryParse(this.configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode))
            {
                authenticationMode = AuthenticationMode.Scope;
            }

            int      scopeCacheRefreshRateSecs = this.configuration.GetValue("DeviceScopeCacheRefreshRateSecs", 3600);
            TimeSpan scopeCacheRefreshRate     = TimeSpan.FromSeconds(scopeCacheRefreshRateSecs);

            int      scopeCacheRefreshDelaySecs = this.configuration.GetValue("DeviceScopeCacheRefreshDelaySecs", 120);
            TimeSpan scopeCacheRefreshDelay     = TimeSpan.FromSeconds(scopeCacheRefreshDelaySecs);

            string proxy       = this.configuration.GetValue("https_proxy", string.Empty);
            string productInfo = GetProductInfo();

            // Register modules
            builder.RegisterModule(
                new CommonModule(
                    productInfo,
                    this.iotHubHostname,
                    this.gatewayHostname,
                    this.edgeDeviceId,
                    this.edgeModuleId,
                    this.edgeDeviceHostName,
                    moduleGenerationId,
                    authenticationMode,
                    this.connectionString,
                    optimizeForPerformance,
                    storeAndForward.UsePersistentStorage,
                    storeAndForward.StoragePath,
                    workloadUri,
                    workloadApiVersion,
                    scopeCacheRefreshRate,
                    scopeCacheRefreshDelay,
                    cacheTokens,
                    this.trustBundle,
                    proxy,
                    metricsConfig,
                    storeAndForward.UseBackupAndRestore,
                    storeAndForward.StorageBackupPath,
                    storeAndForward.StorageMaxTotalWalSize,
                    storeAndForward.StorageMaxOpenFiles,
                    storeAndForward.StorageLogLevel,
                    experimentalFeatures.EnableNestedEdge));
        }
示例#7
0
        public static ExperimentalFeatures Create(IConfiguration experimentalFeaturesConfig, ILogger logger)
        {
            bool enabled = experimentalFeaturesConfig.GetValue("enabled", false);
            bool disableCloudSubscriptions = enabled && experimentalFeaturesConfig.GetValue("disableCloudSubscriptions", false);
            bool disableConnectivityCheck  = enabled && experimentalFeaturesConfig.GetValue("disableConnectivityCheck", false);
            var  experimentalFeatures      = new ExperimentalFeatures(enabled, disableCloudSubscriptions, disableConnectivityCheck);

            logger.LogInformation($"Experimental features configuration: {experimentalFeatures.ToJson()}");
            return(experimentalFeatures);
        }
示例#8
0
        static async Task <IProtocolHead> GetMqttBrokerProtocolHeadAsync(ExperimentalFeatures experimentalFeatures, IContainer container)
        {
            if (!experimentalFeatures.EnableMqttBroker)
            {
                return(EmptyProtocolHead.GetInstance());
            }

            var orderedProtocolHeads = new List <IProtocolHead>();

            orderedProtocolHeads.Add(container.Resolve <MqttBrokerProtocolHead>());
            orderedProtocolHeads.Add(await container.Resolve <Task <AuthAgentProtocolHead> >());
            return(new OrderedProtocolHead(orderedProtocolHeads));
        }
示例#9
0
        public void Register(ContainerBuilder builder)
        {
            builder.RegisterModule(new LoggingModule());
            builder.RegisterBuildCallback(
                c =>
            {
                // set up loggers for Dotnetty
                var loggerFactory = c.Resolve <ILoggerFactory>();
                InternalLoggerFactory.DefaultFactory = loggerFactory;

                var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("EdgeHub"));
                eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational);
            });

            bool            optimizeForPerformance = this.configuration.GetValue("OptimizeForPerformance", true);
            StoreAndForward storeAndForward        = this.GetStoreAndForwardConfiguration();

            IConfiguration       experimentalFeaturesConfig = this.configuration.GetSection(Constants.ConfigKey.ExperimentalFeatures);
            ExperimentalFeatures experimentalFeatures       = ExperimentalFeatures.Create(experimentalFeaturesConfig, Logger.Factory.CreateLogger("EdgeHub"));

            MetricsConfig metricsConfig = new MetricsConfig(this.configuration.GetSection("metrics:listener"));

            bool nestedEdgeEnabled = this.configuration.GetValue <bool>(Constants.ConfigKey.NestedEdgeEnabled, true);

            if (!Enum.TryParse(this.configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode))
            {
                authenticationMode = AuthenticationMode.Scope;
            }

            bool trackDeviceState = authenticationMode == AuthenticationMode.Scope &&
                                    this.configuration.GetValue("TrackDeviceState", true);

            string proxyModuleId = this.configuration.GetValue("ApiProxyModuleId", Core.Constants.DefaultApiProxyId);

            this.RegisterCommonModule(builder, optimizeForPerformance, storeAndForward, metricsConfig, nestedEdgeEnabled, authenticationMode);
            this.RegisterRoutingModule(builder, storeAndForward, experimentalFeatures, nestedEdgeEnabled, authenticationMode == AuthenticationMode.Scope, trackDeviceState);
            this.RegisterMqttModule(builder, storeAndForward, optimizeForPerformance, experimentalFeatures);
            this.RegisterAmqpModule(builder);
            builder.RegisterModule(new HttpModule(this.iotHubHostname, this.edgeDeviceId, proxyModuleId));

            if (experimentalFeatures.EnableMqttBroker)
            {
                var authConfig = this.configuration.GetSection("authAgentSettings");
                builder.RegisterModule(new AuthModule(authConfig));

                var mqttBrokerConfig = this.configuration.GetSection("mqttBrokerSettings");
                builder.RegisterModule(new MqttBrokerModule(mqttBrokerConfig));
            }
        }
示例#10
0
        static async Task <EdgeHubProtocolHead> GetEdgeHubProtocolHeadAsync(ILogger logger, IConfigurationRoot configuration, IContainer container, Hosting hosting)
        {
            IConfiguration       experimentalFeaturesConfig = configuration.GetSection(Constants.ConfigKey.ExperimentalFeatures);
            ExperimentalFeatures experimentalFeatures       = ExperimentalFeatures.Create(experimentalFeaturesConfig, Logger.Factory.CreateLogger("EdgeHub"));

            var protocolHeads = new List <IProtocolHead>();

            // MQTT broker overrides the legacy MQTT protocol head
            if (configuration.GetValue("mqttSettings:enabled", true) && !experimentalFeatures.EnableMqttBroker)
            {
                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));
            }

            var orderedProtocolHeads = new List <IProtocolHead>();

            if (experimentalFeatures.EnableMqttBroker)
            {
                orderedProtocolHeads.Add(container.Resolve <MqttBrokerProtocolHead>());
                orderedProtocolHeads.Add(await container.Resolve <Task <AuthAgentProtocolHead> >());
            }

            switch (orderedProtocolHeads.Count)
            {
            case 0:
                break;

            case 1:
                protocolHeads.Add(orderedProtocolHeads.First());
                break;

            default:
                protocolHeads.Add(new OrderedProtocolHead(orderedProtocolHeads));
                break;
            }

            return(new EdgeHubProtocolHead(protocolHeads, logger));
        }
示例#11
0
        void RegisterMqttModule(
            ContainerBuilder builder,
            StoreAndForward storeAndForward,
            ExperimentalFeatures experimentalFeatures)
        {
            var topics = new MessageAddressConversionConfiguration(
                this.configuration.GetSection(Constants.TopicNameConversionSectionName + ":InboundTemplates").Get <List <string> >(),
                this.configuration.GetSection(Constants.TopicNameConversionSectionName + ":OutboundTemplates").Get <Dictionary <string, string> >());

            bool clientCertAuthEnabled = this.configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false);

            IConfiguration mqttSettingsConfiguration = this.configuration.GetSection("mqttSettings");

            // MQTT broker overrides the legacy MQTT protocol head
            if (mqttSettingsConfiguration.GetValue("enabled", true) && !experimentalFeatures.EnableMqttBroker)
            {
                builder.RegisterModule(new MqttModule(mqttSettingsConfiguration, topics, this.serverCertificate, storeAndForward.IsEnabled, clientCertAuthEnabled, this.sslProtocols));
            }
        }
示例#12
0
        public void Register(ContainerBuilder builder)
        {
            builder.RegisterModule(new LoggingModule());
            builder.RegisterBuildCallback(
                c =>
            {
                // set up loggers for Dotnetty
                var loggerFactory = c.Resolve <ILoggerFactory>();
                InternalLoggerFactory.DefaultFactory = loggerFactory;

                var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("EdgeHub"));
                eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational);
            });

            bool            optimizeForPerformance = this.configuration.GetValue("OptimizeForPerformance", true);
            StoreAndForward storeAndForward        = this.GetStoreAndForwardConfiguration();

            IConfiguration       experimentalFeaturesConfig = this.configuration.GetSection(Constants.ConfigKey.ExperimentalFeatures);
            ExperimentalFeatures experimentalFeatures       = ExperimentalFeatures.Create(experimentalFeaturesConfig, Logger.Factory.CreateLogger("EdgeHub"));

            MetricsConfig metricsConfig = new MetricsConfig(this.configuration.GetSection("metrics:listener"));

            this.RegisterCommonModule(builder, optimizeForPerformance, storeAndForward, metricsConfig, experimentalFeatures);
            this.RegisterRoutingModule(builder, storeAndForward, experimentalFeatures);
            this.RegisterMqttModule(builder, storeAndForward, optimizeForPerformance, experimentalFeatures);
            this.RegisterAmqpModule(builder);
            builder.RegisterModule(new HttpModule(this.iotHubHostname));

            if (experimentalFeatures.EnableMqttBroker)
            {
                var authConfig = this.configuration.GetSection("authAgentSettings");
                builder.RegisterModule(new AuthModule(authConfig));

                var mqttBrokerConfig = this.configuration.GetSection("mqttBrokerSettings");
                builder.RegisterModule(new MqttBrokerModule(mqttBrokerConfig));
            }
        }
示例#13
0
        void RegisterRoutingModule(
            ContainerBuilder builder,
            StoreAndForward storeAndForward,
            ExperimentalFeatures experimentalFeatures,
            bool nestedEdgeEnabled,
            bool scopeAuthenticationOnly,
            bool trackDeviceState)
        {
            var    routes             = this.configuration.GetSection("routes").Get <Dictionary <string, string> >();
            int    connectionPoolSize = this.configuration.GetValue <int>("IotHubConnectionPoolSize");
            string configSource       = this.configuration.GetValue <string>("configSource");
            bool   useTwinConfig      = !string.IsNullOrWhiteSpace(configSource) && configSource.Equals("twin", StringComparison.OrdinalIgnoreCase);
            Option <UpstreamProtocol> upstreamProtocolOption = GetUpstreamProtocol(this.configuration);
            int      connectivityCheckFrequencySecs          = this.configuration.GetValue("ConnectivityCheckFrequencySecs", 300);
            TimeSpan connectivityCheckFrequency = connectivityCheckFrequencySecs < 0 ? TimeSpan.MaxValue : TimeSpan.FromSeconds(connectivityCheckFrequencySecs);
            // n Clients + 1 Edgehub
            int               maxConnectedClients               = this.configuration.GetValue("MaxConnectedClients", 100) + 1;
            int               messageAckTimeoutSecs             = this.configuration.GetValue("MessageAckTimeoutSecs", 30);
            TimeSpan          messageAckTimeout                 = TimeSpan.FromSeconds(messageAckTimeoutSecs);
            int               cloudConnectionIdleTimeoutSecs    = this.configuration.GetValue("CloudConnectionIdleTimeoutSecs", 3600);
            TimeSpan          cloudConnectionIdleTimeout        = TimeSpan.FromSeconds(cloudConnectionIdleTimeoutSecs);
            bool              closeCloudConnectionOnIdleTimeout = this.configuration.GetValue("CloseCloudConnectionOnIdleTimeout", true);
            int               cloudOperationTimeoutSecs         = this.configuration.GetValue("CloudOperationTimeoutSecs", 20);
            bool              useServerHeartbeat                = this.configuration.GetValue("UseServerHeartbeat", true);
            TimeSpan          cloudOperationTimeout             = TimeSpan.FromSeconds(cloudOperationTimeoutSecs);
            Option <TimeSpan> minTwinSyncPeriod                 = this.GetConfigurationValueIfExists("MinTwinSyncPeriodSecs")
                                                                  .Map(s => TimeSpan.FromSeconds(s));
            Option <TimeSpan> reportedPropertiesSyncFrequency = this.GetConfigurationValueIfExists("ReportedPropertiesSyncFrequencySecs")
                                                                .Map(s => TimeSpan.FromSeconds(s));
            bool useV1TwinManager = this.GetConfigurationValueIfExists <string>("TwinManagerVersion")
                                    .Map(v => v.Equals("v1", StringComparison.OrdinalIgnoreCase))
                                    .GetOrElse(false);
            int      maxUpstreamBatchSize                   = this.configuration.GetValue("MaxUpstreamBatchSize", 10);
            int      upstreamFanOutFactor                   = this.configuration.GetValue("UpstreamFanOutFactor", 10);
            bool     encryptTwinStore                       = this.configuration.GetValue("EncryptTwinStore", true);
            int      configUpdateFrequencySecs              = this.configuration.GetValue("ConfigRefreshFrequencySecs", 3600);
            TimeSpan configUpdateFrequency                  = TimeSpan.FromSeconds(configUpdateFrequencySecs);
            bool     checkEntireQueueOnCleanup              = this.configuration.GetValue("CheckEntireQueueOnCleanup", false);
            int      messageCleanupIntervalSecs             = this.configuration.GetValue("MessageCleanupIntervalSecs", 1800);
            bool     closeCloudConnectionOnDeviceDisconnect = this.configuration.GetValue("CloseCloudConnectionOnDeviceDisconnect", true);
            bool     isLegacyUpstream                       = ExperimentalFeatures.IsViaBrokerUpstream(
                experimentalFeatures,
                nestedEdgeEnabled,
                this.GetConfigurationValueIfExists <string>(Constants.ConfigKey.GatewayHostname).HasValue);

            builder.RegisterModule(
                new RoutingModule(
                    this.iotHubHostname,
                    this.gatewayHostname,
                    this.edgeDeviceId,
                    this.edgeModuleId,
                    this.connectionString,
                    routes,
                    storeAndForward.IsEnabled,
                    storeAndForward.Config,
                    connectionPoolSize,
                    useTwinConfig,
                    this.versionInfo,
                    upstreamProtocolOption,
                    connectivityCheckFrequency,
                    maxConnectedClients,
                    messageAckTimeout,
                    cloudConnectionIdleTimeout,
                    closeCloudConnectionOnIdleTimeout,
                    cloudOperationTimeout,
                    useServerHeartbeat,
                    minTwinSyncPeriod,
                    reportedPropertiesSyncFrequency,
                    useV1TwinManager,
                    maxUpstreamBatchSize,
                    upstreamFanOutFactor,
                    encryptTwinStore,
                    configUpdateFrequency,
                    checkEntireQueueOnCleanup,
                    messageCleanupIntervalSecs,
                    experimentalFeatures,
                    closeCloudConnectionOnDeviceDisconnect,
                    nestedEdgeEnabled,
                    isLegacyUpstream,
                    scopeAuthenticationOnly: scopeAuthenticationOnly,
                    trackDeviceState: trackDeviceState));
        }
示例#14
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, 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);

            // 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);
        }
示例#15
0
        static async Task <IProtocolHead> GetEdgeHubProtocolHeadAsync(ILogger logger, IConfigurationRoot configuration, ExperimentalFeatures experimentalFeatures, IContainer container, Hosting hosting)
        {
            var protocolHeads = new List <IProtocolHead>();

            // MQTT broker overrides the legacy MQTT protocol head
            if (configuration.GetValue("mqttSettings:enabled", true) && !experimentalFeatures.EnableMqttBroker)
            {
                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));
            }

            return(new EdgeHubProtocolHead(protocolHeads, logger));
        }