private void ServiceHelper_ServiceStopping(object sender, EventArgs eventArgs)
        {
            // Shutdown algorithm processing framework
            StopAlgorithmProcessing();

            // Dispose of run-time log
            if ((object)m_runTimeLog != null)
            {
                m_serviceHelper.ServiceComponents.Remove(m_runTimeLog);
                m_runTimeLog.ProcessException -= ProcessExceptionHandler;
                m_runTimeLog.Dispose();
                m_runTimeLog = null;
            }

            if (m_allowServiceMonitors && (object)m_serviceMonitors != null)
            {
                m_serviceMonitors.AdapterLoaded   -= ServiceMonitors_AdapterLoaded;
                m_serviceMonitors.AdapterUnloaded -= ServiceMonitors_AdapterUnloaded;
                m_serviceMonitors.Dispose();
            }

            // Deregister event handlers
            m_serviceHelper.ServiceStarting -= ServiceHelper_ServiceStarting;
            m_serviceHelper.ServiceStarted  -= ServiceHelper_ServiceStarted;
            m_serviceHelper.ServiceStopping -= ServiceHelper_ServiceStopping;

            // Detach from handler for unobserved task exceptions
            TaskScheduler.UnobservedTaskException -= TaskScheduler_UnobservedTaskException;

            ShutdownHandler.InitiateSafeShutdown();
        }
        public async Task ShouldHandle_Request_WithMissingParameters()
        {
            bool wasShutdown     = false;
            var  shutdownHandler = new ShutdownHandler();

            shutdownHandler.Shutdown.Subscribe(shutdownRequested =>
            {
                wasShutdown = true;
            });

            var collection = new HandlerCollection(SupportedCapabilitiesFixture.AlwaysTrue)
            {
                shutdownHandler
            };

            AutoSubstitute.Provide <IHandlerCollection>(collection);
            var mediator = AutoSubstitute.Resolve <LspRequestRouter>();

            JToken @params = null; // If the "params" property was missing entirely, this will be null.

            var id      = Guid.NewGuid().ToString();
            var request = new Request(id, GeneralNames.Shutdown, @params);

            await mediator.RouteRequest(mediator.GetDescriptor(request), request);

            Assert.True(shutdownHandler.ShutdownRequested, "WasShutDown");
        }
Example #3
0
        static async Task <int> MainAsync()
        {
            Console.WriteLine($"[{DateTime.UtcNow.ToString("MM/dd/yyyy hh:mm:ss.fff tt", CultureInfo.InvariantCulture)}] Main()");

            IConfiguration configuration = new ConfigurationBuilder()
                                           .SetBasePath(Directory.GetCurrentDirectory())
                                           .AddJsonFile("config/appsettings.json", optional: true)
                                           .AddEnvironmentVariables()
                                           .Build();

            TimeSpan dmDelay = configuration.GetValue("DMDelay", TimeSpan.FromSeconds(5));

            string targetModuleId = configuration.GetValue("TargetModuleId", "DirectMethodReceiver");

            // Get deviced id of this device, exposed as a system variable by the iot edge runtime
            string targetDeviceId = configuration.GetValue <string>("IOTEDGE_DEVICEID");

            TransportType transportType = configuration.GetValue("ClientTransportType", TransportType.Amqp_Tcp_Only);

            Console.WriteLine($"Using transport {transportType.ToString()}");

            ModuleClient moduleClient = await InitModuleClient(transportType);

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler)
                = ShutdownHandler.Init(TimeSpan.FromSeconds(5), null);
            Console.WriteLine($"Target device Id = [{targetDeviceId}], Target module Id = [{targetModuleId}]");
            await CallDirectMethod(moduleClient, dmDelay, targetDeviceId, targetModuleId, cts).ConfigureAwait(false);

            await moduleClient.CloseAsync();

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            return(0);
        }
Example #4
0
        public void TestMethod1()
        {
            ShutdownHandler.Initialize();

            Logger.Console.Verbose = VerboseLevel.Ultra;
            LogPublisher pub2;

            var pub1 = Logger.CreatePublisher(typeof(LoggerTest), MessageClass.Application);

            using (Logger.AppendStackMessages("Test2", "Adapter2"))
                pub2 = Logger.CreatePublisher(typeof(int), MessageClass.Application);

            Error1(pub2);
            using (Logger.SuppressFirstChanceExceptionLogMessages())
            {
                Error1(pub2);
            }
            using (Logger.SuppressLogMessages())
            {
                Error1(pub1);
            }

            using (Logger.SuppressLogMessages())
                using (Logger.AppendStackMessages("Test1", "Adapter1"))
                    using (Logger.OverrideSuppressLogMessages())
                    {
                        Error1(pub2);
                    }

            ShutdownHandler.InitiateSafeShutdown();
        }
        public async Task ShouldHandle_Request_WithMissingParameters()
        {
            bool wasShutDown = false;

            var shutdownHandler = new ShutdownHandler();

            shutdownHandler.Shutdown += shutdownRequested =>
            {
                wasShutDown = true;
            };

            var collection = new HandlerCollection {
                shutdownHandler
            };
            var handlerMatcherCollection = new HandlerMatcherCollection {
                new TextDocumentMatcher(_testLoggerFactory.CreateLogger <TextDocumentMatcher>(), collection.TextDocumentSyncHandlers)
            };
            var mediator = new LspRequestRouter(collection, _testLoggerFactory, handlerMatcherCollection, new Serializer());

            JToken @params = null; // If the "params" property was missing entirely, this will be null.

            var id      = Guid.NewGuid().ToString();
            var request = new Request(id, GeneralNames.Shutdown, @params);

            await mediator.RouteRequest(mediator.GetDescriptor(request), request);

            Assert.True(wasShutDown, "WasShutDown");
        }
        public void ConfigureShouldNotFailTest()
        {
            var cts = new CancellationTokenSource();

            ShutdownHandler.Configure(cts);

            cts.IsCancellationRequested.Should().Be(false);
        }
Example #7
0
        static async Task <int> MainAsync()
        {
            Console.WriteLine($"[{DateTime.UtcNow.ToString("MM/dd/yyyy hh:mm:ss.fff tt", CultureInfo.InvariantCulture)}] Main()");

            IConfiguration configuration = new ConfigurationBuilder()
                                           .SetBasePath(Directory.GetCurrentDirectory())
                                           .AddJsonFile("config/appsettings.json", optional: true)
                                           .AddEnvironmentVariables()
                                           .Build();

            TimeSpan messageDelay = configuration.GetValue("MessageDelay", TimeSpan.FromSeconds(5));
            int      messageCount = configuration.GetValue(MessageCountConfigKey, 500);
            bool     sendForever  = messageCount < 0;
            var      sim          = new SimulatorParameters
            {
                MachineTempMin     = configuration.GetValue <double>("machineTempMin", 21),
                MachineTempMax     = configuration.GetValue <double>("machineTempMax", 100),
                MachinePressureMin = configuration.GetValue <double>("machinePressureMin", 1),
                MachinePressureMax = configuration.GetValue <double>("machinePressureMax", 10),
                AmbientTemp        = configuration.GetValue <double>("ambientTemp", 21),
                HumidityPercent    = configuration.GetValue("ambientHumidity", 25)
            };

            string messagesToSendString = sendForever ? "unlimited" : messageCount.ToString();

            Console.WriteLine(
                $"Initializing simulated temperature sensor to send {messagesToSendString} messages, at an interval of {messageDelay.TotalSeconds} seconds.\n"
                + $"To change this, set the environment variable {MessageCountConfigKey} to the number of messages that should be sent (set it to -1 to send unlimited messages).");

            TransportType transportType = configuration.GetValue("ClientTransportType", TransportType.Amqp_Tcp_Only);

            Console.WriteLine($"Using transport {transportType.ToString()}");

            var retryPolicy = new RetryPolicy(TimeoutErrorDetectionStrategy, TransientRetryStrategy);

            retryPolicy.Retrying += (_, args) =>
            {
                Console.WriteLine($"Creating ModuleClient failed with exception {args.LastException}");
                if (args.CurrentRetryCount < RetryCount)
                {
                    Console.WriteLine("Retrying...");
                }
            };
            ModuleClient moduleClient = await retryPolicy.ExecuteAsync(() => InitModuleClient(transportType));

            ModuleClient userContext = moduleClient;
            await moduleClient.SetInputMessageHandlerAsync("control", ControlMessageHandle, userContext);

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler)
                = ShutdownHandler.Init(TimeSpan.FromSeconds(5), null);
            await SendEvents(moduleClient, messageDelay, sendForever, messageCount, sim, cts);

            await cts.Token.WhenCanceled();

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            return(0);
        }
Example #8
0
 /// <summary>
 /// Remove a shutdown handler.
 ///
 /// If the same shutdown handler is added several times, only the last
 /// one is removed.
 ///
 /// Don't remove shutdown handlers while running a shutdown handler.
 /// </summary>
 public static void RemoveShutdownHandler(ShutdownHandler handler)
 {
     for (int index = ShutdownHandlers.Count - 1; index >= 0; --index)
     {
         if (ShutdownHandlers[index] == handler)
         {
             ShutdownHandlers.RemoveAt(index);
             break;
         }
     }
 }
Example #9
0
        public void TestMethod1()
        {
            ShutdownHandler.Initialize();

            Logger.Console.Verbose = VerboseLevel.Ultra;
            System.Console.WriteLine(LoadingAdjustedTimestamp.CurrentTime);
            Thread.Sleep(1000);
            System.Console.WriteLine(LoadingAdjustedTimestamp.CurrentTime);
            ShutdownHandler.InitiateSafeShutdown();
            Thread.Sleep(1000);
        }
Example #10
0
 static void Main()
 {
     ShutdownHandler.Initialize();
     try
     {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Application.Run(new LogFileViewer());
     }
     finally
     {
         ShutdownHandler.InitiateSafeShutdown();
     }
 }
Example #11
0
        private void 立即进行一次同步ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Thread syncNowThread = new Thread(ServerHandler.syncNow);

            syncNowThread.IsBackground = true;
            syncNowThread.Start();
            syncNowThread.Join();
            if (步完成后关机ToolStripMenuItem.Checked)
            {
                ShutdownHandler.DoExitWin(ShutdownHandler.EWX_SHUTDOWN);
            }

            notifyIcon1.BalloonTipText = "同步完成";
            notifyIcon1.ShowBalloonTip(200);
        }
Example #12
0
        static async Task <int> MainAsync()
        {
            Console.WriteLine($"[{DateTime.UtcNow.ToString("MM/dd/yyyy hh:mm:ss.fff tt", CultureInfo.InvariantCulture)}] Main()");

            IConfiguration configuration = new ConfigurationBuilder()
                                           .SetBasePath(Directory.GetCurrentDirectory())
                                           .AddJsonFile("config/appsettings.json", optional: true)
                                           .AddEnvironmentVariables()
                                           .Build();

            TimeSpan messageDelay = configuration.GetValue("MessageDelay", TimeSpan.FromSeconds(5));
            var      sim          = new SimulatorParameters
            {
                MachineTempMin     = configuration.GetValue <double>("machineTempMin", 21),
                MachineTempMax     = configuration.GetValue <double>("machineTempMax", 100),
                MachinePressureMin = configuration.GetValue <double>("machinePressureMin", 1),
                MachinePressureMax = configuration.GetValue <double>("machinePressureMax", 10),
                AmbientTemp        = configuration.GetValue <double>("ambientTemp", 21),
                HumidityPercent    = configuration.GetValue("ambientHumidity", 25)
            };

            TransportType transportType = configuration.GetValue("ClientTransportType", TransportType.Amqp_Tcp_Only);

            Console.WriteLine($"Using transport {transportType.ToString()}");

            var retryPolicy = new RetryPolicy(TimeoutErrorDetectionStrategy, TransientRetryStrategy);

            retryPolicy.Retrying += (_, args) =>
            {
                Console.WriteLine($"Creating ModuleClient failed with exception {args.LastException}");
                if (args.CurrentRetryCount < RetryCount)
                {
                    Console.WriteLine("Retrying...");
                }
            };
            ModuleClient moduleClient = await retryPolicy.ExecuteAsync(() => InitModuleClient(transportType));

            ModuleClient userContext = moduleClient;
            await moduleClient.SetInputMessageHandlerAsync("control", ControlMessageHandle, userContext).ConfigureAwait(false);

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler)
                = ShutdownHandler.Init(TimeSpan.FromSeconds(5), null);
            await SendEvents(moduleClient, messageDelay, sim, cts).ConfigureAwait(false);

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            return(0);
        }
Example #13
0
        static Logger()
        {
            //Initializes the empty object of StackTraceDetails
            LogStackTrace.Initialize();
            LogStackMessages.Initialize();
            GrowStackDisposal(1);

            s_logger   = new LoggerInternal(out s_logger);
            Console    = new LogSubscriptionConsole();
            FileWriter = new LogSubscriptionFileWriter(1000);

            AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
            AppDomain.CurrentDomain.UnhandledException   += CurrentDomain_UnhandledException;

            Log = CreatePublisher(typeof(Logger), MessageClass.Component);
            Log.InitialStackTrace     = LogStackTrace.Empty;
            EventFirstChanceException = Log.RegisterEvent(MessageLevel.NA, MessageFlags.SystemHealth, "First Chance App Domain Exception", 30, MessageRate.PerSecond(30), 1000);
            EventAppDomainException   = Log.RegisterEvent(MessageLevel.Critical, MessageFlags.SystemHealth, "Unhandled App Domain Exception");
            EventSwallowedException   = Log.RegisterEvent(MessageLevel.Debug, MessageFlags.None, "Exception was Swallowed", 30, MessageRate.PerSecond(30), 1000);

            ShutdownHandler.Initialize();
        }
Example #14
0
        static async Task <int> MainAsync()
        {
            Console.WriteLine("SimulatedTemperatureSensor Main() started.");

            IConfiguration configuration = new ConfigurationBuilder()
                                           .SetBasePath(Directory.GetCurrentDirectory())
                                           .AddJsonFile("config/appsettings.json", optional: true)
                                           .AddEnvironmentVariables()
                                           .Build();

            messageDelay = configuration.GetValue("MessageDelay", TimeSpan.FromSeconds(5));
            int messageCount        = configuration.GetValue(MessageCountConfigKey, 500);
            var simulatorParameters = new SimulatorParameters
            {
                MachineTempMin     = configuration.GetValue <double>("machineTempMin", 21),
                MachineTempMax     = configuration.GetValue <double>("machineTempMax", 100),
                MachinePressureMin = configuration.GetValue <double>("machinePressureMin", 1),
                MachinePressureMax = configuration.GetValue <double>("machinePressureMax", 10),
                AmbientTemp        = configuration.GetValue <double>("ambientTemp", 21),
                HumidityPercent    = configuration.GetValue("ambientHumidity", 25)
            };

            Console.WriteLine(
                $"Initializing simulated temperature sensor to send {(SendUnlimitedMessages(messageCount) ? "unlimited" : messageCount.ToString())} "
                + $"messages, at an interval of {messageDelay.TotalSeconds} seconds.\n"
                + $"To change this, set the environment variable {MessageCountConfigKey} to the number of messages that should be sent (set it to -1 to send unlimited messages).");

            TransportType transportType = configuration.GetValue("ClientTransportType", TransportType.Amqp_Tcp_Only);

            ModuleClient moduleClient = await CreateModuleClientAsync(
                transportType,
                DefaultTimeoutErrorDetectionStrategy,
                DefaultTransientRetryStrategy);

            await moduleClient.OpenAsync();

            await moduleClient.SetMethodHandlerAsync("reset", ResetMethod, null);

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), null);

            Twin currentTwinProperties = await moduleClient.GetTwinAsync();

            if (currentTwinProperties.Properties.Desired.Contains(SendIntervalConfigKey))
            {
                messageDelay = TimeSpan.FromSeconds((int)currentTwinProperties.Properties.Desired[SendIntervalConfigKey]);
            }

            if (currentTwinProperties.Properties.Desired.Contains(SendDataConfigKey))
            {
                sendData = (bool)currentTwinProperties.Properties.Desired[SendDataConfigKey];
                if (!sendData)
                {
                    Console.WriteLine("Sending data disabled. Change twin configuration to start sending again.");
                }
            }

            ModuleClient userContext = moduleClient;
            await moduleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertiesUpdated, userContext);

            await moduleClient.SetInputMessageHandlerAsync("control", ControlMessageHandle, userContext);

            await SendEvents(moduleClient, messageCount, simulatorParameters, cts);

            await cts.Token.WhenCanceled();

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            Console.WriteLine("SimulatedTemperatureSensor Main() finished.");
            return(0);
        }
Example #15
0
        static async Task Main()
        {
            Logger.LogInformation($"Starting load gen with the following settings:\r\n{Settings.Current}");

            ModuleClient moduleClient = null;

            try
            {
                (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

                Guid batchId = Guid.NewGuid();
                Logger.LogInformation($"Batch Id={batchId}");

                moduleClient = await ModuleUtil.CreateModuleClientAsync(
                    Settings.Current.TransportType,
                    ModuleUtil.DefaultTimeoutErrorDetectionStrategy,
                    ModuleUtil.DefaultTransientRetryStrategy,
                    Logger);

                Logger.LogInformation($"Load gen delay start for {Settings.Current.StartDelay}.");
                await Task.Delay(Settings.Current.StartDelay);

                long messageIdCounter = 1;
                while (!cts.IsCancellationRequested)
                {
                    try
                    {
                        await SendEventAsync(moduleClient, batchId, messageIdCounter);

                        messageIdCounter++;
                        await Task.Delay(Settings.Current.MessageFrequency);

                        if (messageIdCounter % 1000 == 0)
                        {
                            Logger.LogInformation($"Sent {messageIdCounter} messages.");
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex, $"[SendEventAsync] Sequence number {messageIdCounter}, BatchId: {batchId.ToString()};");
                    }
                }

                Logger.LogInformation("Closing connection to Edge Hub.");
                await moduleClient.CloseAsync();

                completed.Set();
                handler.ForEach(h => GC.KeepAlive(h));
                Logger.LogInformation("Load Gen complete. Exiting.");
            }
            catch (Exception ex)
            {
                Logger.LogError($"Error occurred during load gen.\r\n{ex}");
            }
        }
Example #16
0
        static async Task Main(string[] args)
        {
            Logger.LogInformation($"Starting TestResultCoordinator with the following settings:\r\n{Settings.Current}");

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

            Logger.LogInformation("Creating WebHostBuilder...");
            Task webHost = CreateWebHostBuilder(args).Build().RunAsync(cts.Token);

            await Task.WhenAny(cts.Token.WhenCanceled(), webHost);

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            Logger.LogInformation("TestResultCoordinator Main() exited.");
        }
Example #17
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> >();

            var cloudConnectionProvider = container.Resolve <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>();
            ICloudProxy cloudProxy = await container.ResolveNamed <Task <ICloudProxy> >("EdgeHubCloudProxy");

            (deviceConnectivityManager as DeviceConnectivityManager)?.SetTestCloudProxy(cloudProxy);

            logger.LogInformation("Initializing configuration");
            IConfigSource configSource = await container.Resolve <Task <IConfigSource> >();

            ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >();

            await configUpdater.Init(configSource);

            (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);
        }
Example #18
0
        static async Task Main(string[] args)
        {
            Logger.LogInformation($"Starting Deployment Tester with the following settings: \r\n{Settings.Current}");

            try
            {
                (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

                var testResultReportingClient = new TestResultReportingClient {
                    BaseUrl = Settings.Current.TestResultCoordinatorUrl.AbsoluteUri
                };

                if (Settings.Current.TestMode == DeploymentTesterMode.Receiver)
                {
                    await ReportDeploymentEnvironmentVariablesAsync(testResultReportingClient);
                }
                else
                {
                    await Task.Delay(Settings.Current.TestStartDelay);
                    await UpdateDeploymentEnvironmentVariablesAsync(testResultReportingClient, cts);
                }

                await cts.Token.WhenCanceled();

                completed.Set();
                handler.ForEach(h => GC.KeepAlive(h));
                Logger.LogInformation("DeploymentTester Main() finished.");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Unexpected exception found.");
            }
        }
Example #19
0
        public static async Task <int> MainAsync(IConfiguration configuration)
        {
            // Bring up the logger before anything else so we can log errors ASAP
            ILogger logger = SetupLogger(configuration);

            logger.LogInformation("Initializing Edge Agent.");

            VersionInfo versionInfo = VersionInfo.Get(VersionInfoFileName);

            if (versionInfo != VersionInfo.Empty)
            {
                logger.LogInformation($"Version - {versionInfo.ToString(true)}");
            }

            LogLogo(logger);

            string mode;

            string                      configSourceConfig;
            string                      backupConfigFilePath;
            int                         maxRestartCount;
            TimeSpan                    intensiveCareTime;
            int                         coolOffTimeUnitInSeconds;
            bool                        usePersistentStorage;
            string                      storagePath;
            bool                        enableNonPersistentStorageBackup;
            Option <string>             storageBackupPath = Option.None <string>();
            string                      edgeDeviceHostName;
            string                      dockerLoggingDriver;
            Dictionary <string, string> dockerLoggingOptions;
            IEnumerable <global::Docker.DotNet.Models.AuthConfig> dockerAuthConfig;
            int configRefreshFrequencySecs;
            ExperimentalFeatures experimentalFeatures;
            MetricsConfig        metricsConfig;
            DiagnosticConfig     diagnosticConfig;
            bool useServerHeartbeat;

            try
            {
                mode = configuration.GetValue(Constants.ModeKey, "docker");
                configSourceConfig       = configuration.GetValue <string>("ConfigSource");
                backupConfigFilePath     = configuration.GetValue <string>("BackupConfigFilePath");
                maxRestartCount          = configuration.GetValue <int>("MaxRestartCount");
                intensiveCareTime        = TimeSpan.FromMinutes(configuration.GetValue <int>("IntensiveCareTimeInMinutes"));
                coolOffTimeUnitInSeconds = configuration.GetValue("CoolOffTimeUnitInSeconds", 10);
                usePersistentStorage     = configuration.GetValue("UsePersistentStorage", true);
                useServerHeartbeat       = configuration.GetValue("UseServerHeartbeat", true);

                // Note: Keep in sync with iotedge-check's edge-agent-storage-mounted-from-host check (edgelet/iotedge/src/check/checks/storage_mounted_from_host.rs)
                storagePath = GetOrCreateDirectoryPath(configuration.GetValue <string>("StorageFolder"), EdgeAgentStorageFolder);
                enableNonPersistentStorageBackup = configuration.GetValue("EnableNonPersistentStorageBackup", false);

                if (enableNonPersistentStorageBackup)
                {
                    storageBackupPath = Option.Some(GetOrCreateDirectoryPath(configuration.GetValue <string>("BackupFolder"), EdgeAgentStorageBackupFolder));
                }

                backupConfigFilePath = GetFullBackupFilePath(storagePath, backupConfigFilePath);

                edgeDeviceHostName   = configuration.GetValue <string>(Constants.EdgeDeviceHostNameKey);
                dockerLoggingDriver  = configuration.GetValue <string>("DockerLoggingDriver");
                dockerLoggingOptions = configuration.GetSection("DockerLoggingOptions").Get <Dictionary <string, string> >() ?? new Dictionary <string, string>();
                dockerAuthConfig     = configuration.GetSection("DockerRegistryAuth").Get <List <global::Docker.DotNet.Models.AuthConfig> >() ?? new List <global::Docker.DotNet.Models.AuthConfig>();

                NestedEdgeParentUriParser parser = new NestedEdgeParentUriParser();
                dockerAuthConfig = dockerAuthConfig.Select(c =>
                {
                    c.Password = parser.ParseURI(c.Password).GetOrElse(c.Password);
                    return(c);
                })
                                   .ToList();

                configRefreshFrequencySecs = configuration.GetValue("ConfigRefreshFrequencySecs", 3600);
            }
            catch (Exception ex)
            {
                logger.LogCritical(AgentEventIds.Agent, ex, "Fatal error reading the Agent's configuration.");
                return(1);
            }

            IContainer container;

            try
            {
                var builder = new ContainerBuilder();
                builder.RegisterModule(new LoggingModule(dockerLoggingDriver, dockerLoggingOptions));
                string productInfo =
                    versionInfo != VersionInfo.Empty ?
                    $"{Constants.IoTEdgeAgentProductInfoIdentifier}/{versionInfo}" :
                    Constants.IoTEdgeAgentProductInfoIdentifier;
                Option <UpstreamProtocol> upstreamProtocol = configuration.GetValue <string>(Constants.UpstreamProtocolKey).ToUpstreamProtocol();
                Option <IWebProxy>        proxy            = Proxy.Parse(configuration.GetValue <string>("https_proxy"), logger);
                bool     closeOnIdleTimeout = configuration.GetValue(Constants.CloseOnIdleTimeout, false);
                int      idleTimeoutSecs    = configuration.GetValue(Constants.IdleTimeoutSecs, 300);
                TimeSpan idleTimeout        = TimeSpan.FromSeconds(idleTimeoutSecs);
                experimentalFeatures = ExperimentalFeatures.Create(configuration.GetSection("experimentalFeatures"), logger);
                Option <ulong>           storageTotalMaxWalSize     = GetConfigIfExists <ulong>(Constants.StorageMaxTotalWalSize, configuration, logger);
                Option <ulong>           storageMaxManifestFileSize = GetConfigIfExists <ulong>(Constants.StorageMaxManifestFileSize, configuration, logger);
                Option <int>             storageMaxOpenFiles        = GetConfigIfExists <int>(Constants.StorageMaxOpenFiles, configuration, logger);
                Option <StorageLogLevel> storageLogLevel            = GetConfigIfExists <StorageLogLevel>(Constants.StorageLogLevel, configuration, logger);
                string iothubHostname;
                string deviceId;
                string apiVersion = "2018-06-28";
                Option <X509Certificate2> manifestTrustBundle = Option.None <X509Certificate2>();

                switch (mode.ToLowerInvariant())
                {
                case Constants.DockerMode:
                    var    dockerUri = new Uri(configuration.GetValue <string>("DockerUri"));
                    string deviceConnectionString = configuration.GetValue <string>("DeviceConnectionString");
                    IotHubConnectionStringBuilder connectionStringParser = IotHubConnectionStringBuilder.Create(deviceConnectionString);
                    deviceId       = connectionStringParser.DeviceId;
                    iothubHostname = connectionStringParser.HostName;
                    builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, enableNonPersistentStorageBackup, storageBackupPath, storageTotalMaxWalSize, storageMaxManifestFileSize, storageMaxOpenFiles, storageLogLevel));
                    builder.RegisterModule(new DockerModule(deviceConnectionString, edgeDeviceHostName, dockerUri, dockerAuthConfig, upstreamProtocol, proxy, productInfo, closeOnIdleTimeout, idleTimeout, useServerHeartbeat, backupConfigFilePath));
                    break;

                case Constants.IotedgedMode:
                    string managementUri = configuration.GetValue <string>(Constants.EdgeletManagementUriVariableName);
                    string workloadUri   = configuration.GetValue <string>(Constants.EdgeletWorkloadUriVariableName);
                    iothubHostname = configuration.GetValue <string>(Constants.IotHubHostnameVariableName);
                    deviceId       = configuration.GetValue <string>(Constants.DeviceIdVariableName);
                    string moduleId           = configuration.GetValue(Constants.ModuleIdVariableName, Constants.EdgeAgentModuleIdentityName);
                    string moduleGenerationId = configuration.GetValue <string>(Constants.EdgeletModuleGenerationIdVariableName);
                    apiVersion = configuration.GetValue <string>(Constants.EdgeletApiVersionVariableName);
                    TimeSpan performanceMetricsUpdateFrequency = configuration.GetTimeSpan("PerformanceMetricsUpdateFrequency", TimeSpan.FromMinutes(5));
                    builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, Option.Some(new Uri(workloadUri)), Option.Some(apiVersion), moduleId, Option.Some(moduleGenerationId), enableNonPersistentStorageBackup, storageBackupPath, storageTotalMaxWalSize, storageMaxManifestFileSize, storageMaxOpenFiles, storageLogLevel));
                    builder.RegisterModule(new EdgeletModule(iothubHostname, deviceId, new Uri(managementUri), new Uri(workloadUri), apiVersion, dockerAuthConfig, upstreamProtocol, proxy, productInfo, closeOnIdleTimeout, idleTimeout, performanceMetricsUpdateFrequency, useServerHeartbeat, backupConfigFilePath));
                    IEnumerable <X509Certificate2> trustBundle =
                        await CertificateHelper.GetTrustBundleFromEdgelet(new Uri(workloadUri), apiVersion, Constants.WorkloadApiVersion, moduleId, moduleGenerationId);

                    CertificateHelper.InstallCertificates(trustBundle, logger);
                    manifestTrustBundle = await CertificateHelper.GetManifestTrustBundleFromEdgelet(new Uri(workloadUri), apiVersion, Constants.WorkloadApiVersion, moduleId, moduleGenerationId);

                    break;

                case Constants.KubernetesMode:
                    managementUri      = configuration.GetValue <string>(Constants.EdgeletManagementUriVariableName);
                    workloadUri        = configuration.GetValue <string>(Constants.EdgeletWorkloadUriVariableName);
                    moduleId           = configuration.GetValue(Constants.ModuleIdVariableName, Constants.EdgeAgentModuleIdentityName);
                    moduleGenerationId = configuration.GetValue <string>(Constants.EdgeletModuleGenerationIdVariableName);
                    apiVersion         = configuration.GetValue <string>(Constants.EdgeletApiVersionVariableName);
                    iothubHostname     = configuration.GetValue <string>(Constants.IotHubHostnameVariableName);
                    deviceId           = configuration.GetValue <string>(Constants.DeviceIdVariableName);
                    string             proxyImage = configuration.GetValue <string>(K8sConstants.ProxyImageEnvKey);
                    Option <string>    proxyImagePullSecretName      = Option.Maybe(configuration.GetValue <string>(K8sConstants.ProxyImagePullSecretNameEnvKey));
                    string             proxyConfigPath               = configuration.GetValue <string>(K8sConstants.ProxyConfigPathEnvKey);
                    string             proxyConfigVolumeName         = configuration.GetValue <string>(K8sConstants.ProxyConfigVolumeEnvKey);
                    string             proxyConfigMapName            = configuration.GetValue <string>(K8sConstants.ProxyConfigMapNameEnvKey);
                    string             proxyTrustBundlePath          = configuration.GetValue <string>(K8sConstants.ProxyTrustBundlePathEnvKey);
                    string             proxyTrustBundleVolumeName    = configuration.GetValue <string>(K8sConstants.ProxyTrustBundleVolumeEnvKey);
                    string             proxyTrustBundleConfigMapName = configuration.GetValue <string>(K8sConstants.ProxyTrustBundleConfigMapEnvKey);
                    PortMapServiceType mappedServiceDefault          = GetDefaultServiceType(configuration);
                    bool          enableServiceCallTracing           = configuration.GetValue <bool>(K8sConstants.EnableK8sServiceCallTracingName);
                    bool          useMountSourceForVolumeName        = configuration.GetValue <bool>(K8sConstants.UseMountSourceForVolumeNameKey, false);
                    string        storageClassName = configuration.GetValue <string>(K8sConstants.StorageClassNameKey);
                    Option <uint> persistentVolumeClaimDefaultSizeMb = Option.Maybe(configuration.GetValue <uint?>(K8sConstants.PersistentVolumeClaimDefaultSizeInMbKey));
                    string        deviceNamespace = configuration.GetValue <string>(K8sConstants.K8sNamespaceKey);
                    var           kubernetesExperimentalFeatures = KubernetesExperimentalFeatures.Create(configuration.GetSection("experimentalFeatures"), logger);
                    var           moduleOwner = new KubernetesModuleOwner(
                        configuration.GetValue <string>(K8sConstants.EdgeK8sObjectOwnerApiVersionKey),
                        configuration.GetValue <string>(K8sConstants.EdgeK8sObjectOwnerKindKey),
                        configuration.GetValue <string>(K8sConstants.EdgeK8sObjectOwnerNameKey),
                        configuration.GetValue <string>(K8sConstants.EdgeK8sObjectOwnerUidKey));
                    bool runAsNonRoot = configuration.GetValue <bool>(K8sConstants.RunAsNonRootKey);

                    builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, Option.Some(new Uri(workloadUri)), Option.Some(apiVersion), moduleId, Option.Some(moduleGenerationId), enableNonPersistentStorageBackup, storageBackupPath, storageTotalMaxWalSize, storageMaxManifestFileSize, storageMaxOpenFiles, storageLogLevel));
                    builder.RegisterModule(
                        new KubernetesModule(
                            iothubHostname,
                            deviceId,
                            edgeDeviceHostName,
                            proxyImage,
                            proxyImagePullSecretName,
                            proxyConfigPath,
                            proxyConfigVolumeName,
                            proxyConfigMapName,
                            proxyTrustBundlePath,
                            proxyTrustBundleVolumeName,
                            proxyTrustBundleConfigMapName,
                            apiVersion,
                            deviceNamespace,
                            new Uri(managementUri),
                            new Uri(workloadUri),
                            dockerAuthConfig,
                            upstreamProtocol,
                            Option.Some(productInfo),
                            mappedServiceDefault,
                            enableServiceCallTracing,
                            useMountSourceForVolumeName,
                            storageClassName,
                            persistentVolumeClaimDefaultSizeMb,
                            proxy,
                            closeOnIdleTimeout,
                            idleTimeout,
                            useServerHeartbeat,
                            kubernetesExperimentalFeatures,
                            moduleOwner,
                            runAsNonRoot));

                    IEnumerable <X509Certificate2> k8sTrustBundle = await CertificateHelper.GetTrustBundleFromEdgelet(new Uri(workloadUri), apiVersion, Constants.WorkloadApiVersion, moduleId, moduleGenerationId);

                    CertificateHelper.InstallCertificates(k8sTrustBundle, logger);

                    break;

                default:
                    throw new InvalidOperationException($"Mode '{mode}' not supported.");
                }

                switch (configSourceConfig.ToLowerInvariant())
                {
                case "twin":
                    bool enableStreams      = configuration.GetValue(Constants.EnableStreams, false);
                    int  requestTimeoutSecs = configuration.GetValue(Constants.RequestTimeoutSecs, 600);
                    builder.RegisterModule(
                        new TwinConfigSourceModule(
                            iothubHostname,
                            deviceId,
                            configuration,
                            versionInfo,
                            TimeSpan.FromSeconds(configRefreshFrequencySecs),
                            enableStreams,
                            TimeSpan.FromSeconds(requestTimeoutSecs),
                            experimentalFeatures,
                            manifestTrustBundle));
                    break;

                case "local":
                    string localConfigFilePath = GetLocalConfigFilePath(configuration, logger);
                    builder.RegisterModule(new FileConfigSourceModule(localConfigFilePath, configuration, versionInfo));
                    break;

                default:
                    throw new InvalidOperationException($"ConfigSource '{configSourceConfig}' not supported.");
                }

                metricsConfig = new MetricsConfig(configuration);
                builder.RegisterModule(new MetricsModule(metricsConfig, iothubHostname, deviceId));

                bool diagnosticsEnabled = configuration.GetValue("SendRuntimeQualityTelemetry", true);
                diagnosticConfig = new DiagnosticConfig(diagnosticsEnabled, storagePath, configuration);
                builder.RegisterModule(new DiagnosticsModule(diagnosticConfig));

                container = builder.Build();
            }
            catch (Exception ex)
            {
                logger.LogCritical(AgentEventIds.Agent, ex, "Fatal error building application.");
                return(1);
            }

            // TODO move this code to Agent
            if (mode.ToLowerInvariant().Equals(Constants.KubernetesMode))
            {
                // Block agent startup routine until proxy sidecar container is ready
                string managementUri      = configuration.GetValue <string>(Constants.EdgeletManagementUriVariableName);
                string apiVersion         = configuration.GetValue <string>(Constants.EdgeletApiVersionVariableName);
                ProxyReadinessProbe probe = new ProxyReadinessProbe(new Uri(managementUri), apiVersion);

                CancellationTokenSource tokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));
                await probe.WaitUntilProxyIsReady(tokenSource.Token);

                // Start environment operator
                IKubernetesEnvironmentOperator environmentOperator = container.Resolve <IKubernetesEnvironmentOperator>();
                environmentOperator.Start();

                // Start the edge deployment operator
                IEdgeDeploymentOperator edgeDeploymentOperator = container.Resolve <IEdgeDeploymentOperator>();
                edgeDeploymentOperator.Start();
            }

            // Initialize metrics
            if (metricsConfig.Enabled)
            {
                container.Resolve <IMetricsListener>().Start(logger);
                container.Resolve <ISystemResourcesMetrics>().Start(logger);
                await container.Resolve <MetadataMetrics>().Start(logger, versionInfo.ToString(true), Newtonsoft.Json.JsonConvert.SerializeObject(experimentalFeatures));
            }

            // Initialize metric uploading
            if (diagnosticConfig.Enabled)
            {
                MetricsWorker worker = await container.Resolve <Task <MetricsWorker> >();

                worker.Start(diagnosticConfig.ScrapeInterval, diagnosticConfig.UploadInterval);
                Console.WriteLine($"Scraping frequency: {diagnosticConfig.ScrapeInterval}\nUpload Frequency: {diagnosticConfig.UploadInterval}");
            }

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler)
                = ShutdownHandler.Init(ShutdownWaitPeriod, logger);

            // Register request handlers
            await RegisterRequestHandlers(container);

            // Initialize stream request listener
            IStreamRequestListener streamRequestListener = await container.Resolve <Task <IStreamRequestListener> >();

            streamRequestListener.InitPump();

            int returnCode;

            using (IConfigSource unused = await container.Resolve <Task <IConfigSource> >())
            {
                Option <Agent> agentOption = Option.None <Agent>();

                try
                {
                    Agent agent = await container.Resolve <Task <Agent> >();

                    agentOption = Option.Some(agent);
                    while (!cts.Token.IsCancellationRequested)
                    {
                        try
                        {
                            await agent.ReconcileAsync(cts.Token).TimeoutAfter(ReconcileTimeout);
                        }
                        catch (Exception ex) when(!ex.IsFatal())
                        {
                            logger.LogWarning(AgentEventIds.Agent, ex, "Agent reconcile concluded with errors.");
                        }

                        await Task.Delay(TimeSpan.FromSeconds(5), cts.Token);
                    }

                    logger.LogInformation("Closing module management agent.");

                    returnCode = 0;
                }
                catch (OperationCanceledException)
                {
                    logger.LogInformation("Main thread terminated");
                    returnCode = 0;
                }
                catch (Exception ex)
                {
                    logger.LogCritical(AgentEventIds.Agent, ex, "Fatal error starting Agent.");
                    returnCode = 1;
                }

                // Attempt to report shutdown of Agent
                await Cleanup(agentOption, logger);
                await CloseDbStoreProviderAsync(container);

                if (metricsConfig.Enabled && returnCode == 0)
                {
                    container.Resolve <IDeploymentMetrics>().IndicateCleanShutdown();
                }

                completed.Set();
            }

            handler.ForEach(h => GC.KeepAlive(h));
            return(returnCode);
        }
Example #20
0
        static async Task <int> MainAsync()
        {
            DirectMethodReceiver directMethodReceiver = null;

            try
            {
                Logger.LogInformation("DirectMethodReceiver Main() started.");

                (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

                IConfiguration configuration = new ConfigurationBuilder()
                                               .SetBasePath(Directory.GetCurrentDirectory())
                                               .AddJsonFile("config/appsettings.json", optional: true)
                                               .AddEnvironmentVariables()
                                               .Build();

                directMethodReceiver = new DirectMethodReceiver(Logger, configuration);

                await directMethodReceiver.InitAsync();

                await cts.Token.WhenCanceled();

                completed.Set();
                handler.ForEach(h => GC.KeepAlive(h));
                Logger.LogInformation("DirectMethodReceiver Main() finished.");
            }
            catch (Exception e)
            {
                Logger.LogError(e.ToString());
            }
            finally
            {
                directMethodReceiver?.Dispose();
            }

            return(0);
        }
Example #21
0
        static async Task Main()
        {
            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

            Logger.LogInformation($"Starting twin tester with the following settings:\r\n{Settings.Current}");

            try
            {
                await Task.Delay(Settings.Current.TestStartDelay);

                RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Settings.Current.ServiceClientConnectionString);

                using (ITwinTestInitializer twinOperator = await GetTwinOperatorAsync(registryManager))
                {
                    await twinOperator.Start();

                    await Task.Delay(Settings.Current.TestDuration, cts.Token);
                }

                await cts.Token.WhenCanceled();

                completed.Set();
                handler.ForEach(h => GC.KeepAlive(h));
                Logger.LogInformation("TwinTester exiting.");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Error occurred during twin test setup.");
            }
        }
Example #22
0
        static async Task <int> MainAsync()
        {
            Guid batchId = Guid.NewGuid();

            Logger.LogInformation($"Starting EdgeHubRestartTester ({batchId}) with the following settings:\r\n{Settings.Current}");

            Logger.LogInformation($"EdgeHubRestartTester delay start for {Settings.Current.TestStartDelay}.");
            await Task.Delay(Settings.Current.TestStartDelay);

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

            ServiceClient       iotHubServiceClient = null;
            List <ModuleClient> moduleClients       = new List <ModuleClient>();

            try
            {
                iotHubServiceClient = ServiceClient.CreateFromConnectionString(Settings.Current.IoTHubConnectionString);

                List <IEdgeHubConnectorTest> edgeHubConnectorTests = new List <IEdgeHubConnectorTest>();

                foreach (EdgeHubConnectorsConfig eachConfig in await Settings.Current.GetConnectorConfigAsync())
                {
                    if (eachConfig.MessageOutputEndpoint != null)
                    {
                        ModuleClient msgModuleClient = await ModuleUtil.CreateModuleClientAsync(
                            eachConfig.TransportType,
                            new ClientOptions(),
                            ModuleUtil.DefaultTimeoutErrorDetectionStrategy,
                            ModuleUtil.DefaultTransientRetryStrategy,
                            Logger);

                        msgModuleClient.OperationTimeoutInMilliseconds = (uint)Settings.Current.SdkOperationTimeout.TotalMilliseconds;

                        moduleClients.Add(msgModuleClient);
                        edgeHubConnectorTests.Add(
                            new MessageEdgeHubConnectorTest(
                                batchId,
                                Logger,
                                msgModuleClient,
                                eachConfig.MessageOutputEndpoint));
                    }

                    if (eachConfig.DirectMethodTargetModuleId != null)
                    {
                        ModuleClient dmModuleClient = await ModuleUtil.CreateModuleClientAsync(
                            eachConfig.TransportType,
                            new ClientOptions(),
                            ModuleUtil.DefaultTimeoutErrorDetectionStrategy,
                            ModuleUtil.DefaultTransientRetryStrategy,
                            Logger);

                        moduleClients.Add(dmModuleClient);
                        edgeHubConnectorTests.Add(
                            new DirectMethodEdgeHubConnectorTest(
                                batchId,
                                Logger,
                                dmModuleClient,
                                eachConfig.DirectMethodTargetModuleId));
                    }
                }

                DateTime testStart          = DateTime.UtcNow;
                DateTime testCompletionTime = testStart + Settings.Current.TestDuration;

                while ((!cts.IsCancellationRequested) && (DateTime.UtcNow < testCompletionTime))
                {
                    DateTime restartTime = await RestartEdgeHubAsync(
                        iotHubServiceClient,
                        cts.Token);

                    DateTime eachTestExpirationTime = restartTime.Add(Settings.Current.RestartPeriod);

                    List <Task> taskList = new List <Task>();
                    foreach (IEdgeHubConnectorTest eachConnectorTest in edgeHubConnectorTests)
                    {
                        taskList.Add(
                            eachConnectorTest.StartAsync(
                                eachTestExpirationTime,
                                restartTime,
                                cts.Token));
                    }

                    // Wait for the two task to be done before do a restart
                    await Task.WhenAll(taskList);

                    // Wait until the specified restart period to do another restart
                    TimeSpan waitTime = eachTestExpirationTime - DateTime.UtcNow;
                    if (waitTime.TotalMilliseconds > 0)
                    {
                        await Task.Delay(waitTime, cts.Token);
                    }
                }
            }
            catch (Exception e)
            {
                Logger.LogError($"Exception caught: {e}");
                throw;
            }
            finally
            {
                iotHubServiceClient?.Dispose();

                foreach (ModuleClient client in moduleClients)
                {
                    client.Dispose();
                }
            }

            await cts.Token.WhenCanceled();

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            Logger.LogInformation("EdgeHubRestartTester Main() finished.");
            return(0);
        }
Example #23
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

            // 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);
        }
Example #24
0
        static async Task <int> MainAsync()
        {
            try
            {
                Logger.LogInformation("Validate Metrics Main() started.");

                (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

                IConfiguration configuration = new ConfigurationBuilder()
                                               .SetBasePath(Directory.GetCurrentDirectory())
                                               .AddJsonFile("config/appsettings.json", optional: true)
                                               .AddEnvironmentVariables()
                                               .Build();

                using (ModuleClient moduleClient = await ModuleClient.CreateFromEnvironmentAsync())
                    using (MetricsScraper scraper = new MetricsScraper(new List <string> {
                        "http://edgeHub:9600/metrics", "http://edgeAgent:9600/metrics"
                    }))
                    {
                        await moduleClient.OpenAsync();

                        await moduleClient.SetMethodHandlerAsync(
                            "ValidateMetrics",
                            async (MethodRequest methodRequest, object _) =>
                        {
                            Console.WriteLine("Validating metrics");

                            TestReporter testReporter = new TestReporter("Metrics Validation");
                            List <TestBase> tests     = new List <TestBase>
                            {
                                new ValidateNumberOfMessagesSent(testReporter, scraper, moduleClient),
                                // new ValidateDocumentedMetrics(testReporter, scraper, moduleClient),
                            };

                            await Task.WhenAll(tests.Select(test => test.Start(cts.Token)));
                            return(new MethodResponse(Encoding.UTF8.GetBytes(testReporter.ReportResults()), (int)HttpStatusCode.OK));
                        },
                            null);

                        Console.WriteLine("Ready to validate metrics");
                        await cts.Token.WhenCanceled();
                    }

                completed.Set();
                handler.ForEach(h => GC.KeepAlive(h));
                Logger.LogInformation("Validate Metrics Main() finished.");
            }
            catch (Exception e)
            {
                Logger.LogError(e.ToString());
            }

            return(0);
        }
Example #25
0
        public static async Task <int> MainAsync(IConfiguration configuration)
        {
            // Bring up the logger before anything else so we can log errors ASAP
            ILogger logger = SetupLogger(configuration);

            logger.LogInformation("Starting module management agent.");

            VersionInfo versionInfo = VersionInfo.Get(VersionInfoFileName);

            if (versionInfo != VersionInfo.Empty)
            {
                logger.LogInformation($"Version - {versionInfo.ToString(true)}");
            }

            LogLogo(logger);

            string mode;

            string   configSourceConfig;
            string   backupConfigFilePath;
            int      maxRestartCount;
            TimeSpan intensiveCareTime;
            int      coolOffTimeUnitInSeconds;
            bool     usePersistentStorage;
            string   storagePath;
            string   edgeDeviceHostName;
            string   dockerLoggingDriver;
            Dictionary <string, string> dockerLoggingOptions;
            IEnumerable <AuthConfig>    dockerAuthConfig;
            int configRefreshFrequencySecs;

            try
            {
                mode = configuration.GetValue(Constants.ModeKey, "docker");
                configSourceConfig       = configuration.GetValue <string>("ConfigSource");
                backupConfigFilePath     = configuration.GetValue <string>("BackupConfigFilePath");
                maxRestartCount          = configuration.GetValue <int>("MaxRestartCount");
                intensiveCareTime        = TimeSpan.FromMinutes(configuration.GetValue <int>("IntensiveCareTimeInMinutes"));
                coolOffTimeUnitInSeconds = configuration.GetValue("CoolOffTimeUnitInSeconds", 10);
                usePersistentStorage     = configuration.GetValue("UsePersistentStorage", true);
                storagePath                = GetStoragePath(configuration);
                edgeDeviceHostName         = configuration.GetValue <string>(Constants.EdgeDeviceHostNameKey);
                dockerLoggingDriver        = configuration.GetValue <string>("DockerLoggingDriver");
                dockerLoggingOptions       = configuration.GetSection("DockerLoggingOptions").Get <Dictionary <string, string> >() ?? new Dictionary <string, string>();
                dockerAuthConfig           = configuration.GetSection("DockerRegistryAuth").Get <List <AuthConfig> >() ?? new List <AuthConfig>();
                configRefreshFrequencySecs = configuration.GetValue("ConfigRefreshFrequencySecs", 3600);
            }
            catch (Exception ex)
            {
                logger.LogCritical(AgentEventIds.Agent, ex, "Fatal error reading the Agent's configuration.");
                return(1);
            }

            IContainer container;

            try
            {
                var builder = new ContainerBuilder();
                builder.RegisterModule(new LoggingModule(dockerLoggingDriver, dockerLoggingOptions));
                Option <string>           productInfo      = versionInfo != VersionInfo.Empty ? Option.Some(versionInfo.ToString()) : Option.None <string>();
                Option <UpstreamProtocol> upstreamProtocol = configuration.GetValue <string>(Constants.UpstreamProtocolKey).ToUpstreamProtocol();
                Option <IWebProxy>        proxy            = Proxy.Parse(configuration.GetValue <string>("https_proxy"), logger);
                switch (mode.ToLowerInvariant())
                {
                case Constants.DockerMode:
                    var    dockerUri = new Uri(configuration.GetValue <string>("DockerUri"));
                    string deviceConnectionString = configuration.GetValue <string>("DeviceConnectionString");
                    builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath));
                    builder.RegisterModule(new DockerModule(deviceConnectionString, edgeDeviceHostName, dockerUri, dockerAuthConfig, upstreamProtocol, proxy, productInfo));
                    break;

                case Constants.IotedgedMode:
                    string managementUri      = configuration.GetValue <string>(Constants.EdgeletManagementUriVariableName);
                    string workloadUri        = configuration.GetValue <string>(Constants.EdgeletWorkloadUriVariableName);
                    string iothubHostname     = configuration.GetValue <string>(Constants.IotHubHostnameVariableName);
                    string deviceId           = configuration.GetValue <string>(Constants.DeviceIdVariableName);
                    string moduleId           = configuration.GetValue(Constants.ModuleIdVariableName, Constants.EdgeAgentModuleIdentityName);
                    string moduleGenerationId = configuration.GetValue <string>(Constants.EdgeletModuleGenerationIdVariableName);
                    string apiVersion         = configuration.GetValue <string>(Constants.EdgeletApiVersionVariableName);
                    builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, Option.Some(new Uri(workloadUri)), Option.Some(apiVersion), moduleId, Option.Some(moduleGenerationId)));
                    builder.RegisterModule(new EdgeletModule(iothubHostname, edgeDeviceHostName, deviceId, new Uri(managementUri), new Uri(workloadUri), apiVersion, dockerAuthConfig, upstreamProtocol, proxy, productInfo));
                    break;

                default:
                    throw new InvalidOperationException($"Mode '{mode}' not supported.");
                }

                switch (configSourceConfig.ToLowerInvariant())
                {
                case "twin":
                    builder.RegisterModule(new TwinConfigSourceModule(backupConfigFilePath, configuration, versionInfo, TimeSpan.FromSeconds(configRefreshFrequencySecs)));
                    break;

                case "local":
                    builder.RegisterModule(new FileConfigSourceModule("config.json", configuration));
                    break;

                default:
                    throw new InvalidOperationException($"ConfigSource '{configSourceConfig}' not supported.");
                }

                container = builder.Build();
            }
            catch (Exception ex)
            {
                logger.LogCritical(AgentEventIds.Agent, ex, "Fatal error building application.");
                return(1);
            }

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler)
                = ShutdownHandler.Init(ShutdownWaitPeriod, logger);

            int returnCode;

            using (IConfigSource unused = await container.Resolve <Task <IConfigSource> >())
            {
                Option <Agent> agentOption = Option.None <Agent>();

                try
                {
                    Agent agent = await container.Resolve <Task <Agent> >();

                    agentOption = Option.Some(agent);
                    while (!cts.Token.IsCancellationRequested)
                    {
                        try
                        {
                            await agent.ReconcileAsync(cts.Token);
                        }
                        catch (Exception ex) when(!ex.IsFatal())
                        {
                            logger.LogWarning(AgentEventIds.Agent, ex, "Agent reconcile concluded with errors.");
                        }

                        await Task.Delay(TimeSpan.FromSeconds(5), cts.Token);
                    }

                    logger.LogInformation("Closing module management agent.");

                    returnCode = 0;
                }
                catch (OperationCanceledException)
                {
                    logger.LogInformation("Main thread terminated");
                    returnCode = 0;
                }
                catch (Exception ex)
                {
                    logger.LogCritical(AgentEventIds.Agent, ex, "Fatal error starting Agent.");
                    returnCode = 1;
                }

                // Attempt to report shutdown of Agent
                await Cleanup(agentOption, logger);

                completed.Set();
            }

            handler.ForEach(h => GC.KeepAlive(h));
            return(returnCode);
        }
Example #26
0
        static async Task <int> MainAsync()
        {
            Guid batchId = Guid.NewGuid();

            Logger.LogInformation($"Starting EdgeHubRestartTester ({batchId}) with the following settings:\r\n{Settings.Current}");

            Logger.LogInformation($"EdgeHubRestartTester delay start for {Settings.Current.TestStartDelay}.");
            await Task.Delay(Settings.Current.TestStartDelay);

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

            ServiceClient         iotHubServiceClient          = null;
            IEdgeHubConnectorTest edgeHubMessageConnector      = null;
            IEdgeHubConnectorTest edgeHubDirectMethodConnector = null;

            try
            {
                iotHubServiceClient = ServiceClient.CreateFromConnectionString(Settings.Current.IoTHubConnectionString);

                if (Settings.Current.MessageEnabled)
                {
                    edgeHubMessageConnector = new MessageEdgeHubConnectorTest(
                        batchId,
                        Logger);
                }

                if (Settings.Current.DirectMethodEnabled)
                {
                    edgeHubDirectMethodConnector = new DirectMethodEdgeHubConnectorTest(
                        batchId,
                        Logger);
                }

                DateTime testStart          = DateTime.UtcNow;
                DateTime testExpirationTime = testStart + Settings.Current.TestDuration;

                while ((!cts.IsCancellationRequested) && (DateTime.UtcNow < testExpirationTime))
                {
                    DateTime restartTime = await RestartEdgeHubAsync(
                        iotHubServiceClient,
                        cts.Token);

                    DateTime eachTestExpirationTime = restartTime.Add(Settings.Current.RestartPeriod);

                    // Setup Message Task
                    Task sendMessageTask = Task.CompletedTask;
                    sendMessageTask = edgeHubMessageConnector?.StartAsync(
                        eachTestExpirationTime,
                        restartTime,
                        cts.Token);

                    // Setup Direct Method Task
                    Task directMethodTask = Task.CompletedTask;
                    directMethodTask = edgeHubDirectMethodConnector?.StartAsync(
                        eachTestExpirationTime,
                        restartTime,
                        cts.Token);

                    // Wait for the two task to be done before do a restart
                    await Task.WhenAll(new[] { sendMessageTask, directMethodTask });

                    // Wait until the specified restart period to do another restart
                    await Task.Delay((int)(eachTestExpirationTime - DateTime.UtcNow).TotalMilliseconds, cts.Token);
                }
            }
            catch (Exception e)
            {
                Logger.LogError($"Exception caught: {e}");
                throw;
            }
            finally
            {
                iotHubServiceClient?.Dispose();
                edgeHubDirectMethodConnector?.Dispose();
                edgeHubMessageConnector?.Dispose();
            }

            await cts.Token.WhenCanceled();

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            Logger.LogInformation("EdgeHubRestartTester Main() finished.");
            return(0);
        }
Example #27
0
        static async Task Main()
        {
            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Log);

            Log.LogInformation($"Starting with {Settings.Current.NetworkControllerMode}");

            var networkInterfaceName = DockerHelper.GetDockerInterfaceName();

            if (networkInterfaceName.HasValue)
            {
                await networkInterfaceName.ForEachAsync(
                    async name =>
                {
                    var firewall    = new FirewallOfflineController(name, Settings.Current.IotHubHostname);
                    var satellite   = new SatelliteController(name);
                    var controllers = new List <INetworkController>()
                    {
                        firewall, satellite
                    };
                    await RemoveAllControllingRules(controllers, cts.Token);

                    switch (Settings.Current.NetworkControllerMode)
                    {
                    case NetworkControllerMode.OfflineTrafficController:
                        await StartAsync(firewall, cts.Token);
                        break;

                    case NetworkControllerMode.SatelliteTrafficController:
                        await StartAsync(satellite, cts.Token);
                        break;
                    }
                });

                await cts.Token.WhenCanceled();

                completed.Set();
                handler.ForEach(h => GC.KeepAlive(h));
            }
            else
            {
                Log.LogError($"No network interface found for docker network {Settings.Current.NetworkId}");
            }
        }
Example #28
0
        static async Task <int> MainAsync()
        {
            Logger.LogInformation("DirectMethodReceiver Main() started.");

            IConfiguration configuration = new ConfigurationBuilder()
                                           .SetBasePath(Directory.GetCurrentDirectory())
                                           .AddJsonFile("config/appsettings.json", optional: true)
                                           .AddEnvironmentVariables()
                                           .Build();

            TransportType transportType = configuration.GetValue("ClientTransportType", TransportType.Amqp_Tcp_Only);
            ModuleClient  moduleClient  = await ModuleUtil.CreateModuleClientAsync(
                transportType,
                ModuleUtil.DefaultTimeoutErrorDetectionStrategy,
                ModuleUtil.DefaultTransientRetryStrategy,
                Logger);

            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

            await moduleClient.OpenAsync();

            await moduleClient.SetMethodHandlerAsync("HelloWorldMethod", HelloWorldMethodAsync, null);

            await cts.Token.WhenCanceled();

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            Logger.LogInformation("DirectMethodReceiver Main() finished.");
            return(0);
        }
Example #29
0
        static async Task <int> MainAsync()
        {
            try
            {
                Logger.LogInformation("Validate Metrics Main() started.");

                (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger);

                IConfiguration configuration = new ConfigurationBuilder()
                                               .SetBasePath(Directory.GetCurrentDirectory())
                                               .AddJsonFile("config/appsettings.json", optional: true)
                                               .AddEnvironmentVariables()
                                               .Build();

                var transportType = configuration.GetValue("ClientTransportType", Microsoft.Azure.Devices.Client.TransportType.Mqtt);

                Logger.LogInformation("Make Client");
                using (ModuleClient moduleClient = await ModuleUtil.CreateModuleClientAsync(
                           transportType,
                           new ClientOptions(),
                           ModuleUtil.DefaultTimeoutErrorDetectionStrategy,
                           ModuleUtil.DefaultTransientRetryStrategy,
                           Logger))
                    using (MetricsScraper scraper = new MetricsScraper(new List <string> {
                        "http://edgeHub:9600/metrics", "http://edgeAgent:9600/metrics"
                    }))
                    {
                        Logger.LogInformation("Open Async");
                        await moduleClient.OpenAsync();

                        Logger.LogInformation("Set method handler");
                        await moduleClient.SetMethodHandlerAsync(
                            "ValidateMetrics",
                            async (MethodRequest methodRequest, object _) =>
                        {
                            Logger.LogInformation("Validating metrics");

                            TestReporter testReporter = new TestReporter("Metrics Validation");
                            List <TestBase> tests     = new List <TestBase>
                            {
                                new ValidateMessages(testReporter, scraper, moduleClient, transportType),
                                new ValidateDocumentedMetrics(testReporter, scraper, moduleClient),
                                // new ValidateHostRanges(testReporter, scraper, moduleClient),
                            };

                            using (testReporter.MeasureDuration())
                            {
                                await Task.WhenAll(tests.Select(test => test.Start(cts.Token)));
                            }

                            var result = new MethodResponse(Encoding.UTF8.GetBytes(testReporter.ReportResults()), (int)HttpStatusCode.OK);

                            Logger.LogInformation($"Finished validating metrics. Result size: {result.Result.Length}");
                            return(result);
                        },
                            null);

                        moduleClient.SetConnectionStatusChangesHandler((status, reason)
                                                                       => Logger.LogWarning($"Module to Edge Hub connection changed Status: {status} Reason: {reason}"));

                        Logger.LogInformation("Ready to validate metrics");
                        await cts.Token.WhenCanceled();
                    }

                completed.Set();
                handler.ForEach(h => GC.KeepAlive(h));
                Logger.LogInformation("Validate Metrics Main() finished.");
            }
            catch (Exception e)
            {
                Logger.LogError(e.ToString());
            }

            return(0);
        }
Example #30
0
        static async Task Main()
        {
            (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Log);

            Log.LogInformation($"Starting with {Settings.Current.NetworkRunProfile.ProfileType} Settings: {Settings.Current.NetworkRunProfile.ProfileSetting}");

            var controllers = new List <INetworkController>();

            try
            {
                var networkInterfaceName = DockerHelper.GetDockerInterfaceName();

                if (networkInterfaceName.HasValue)
                {
                    await networkInterfaceName.ForEachAsync(async name =>
                    {
                        string hubHostname = !string.IsNullOrEmpty(Settings.Current.ParentHostname) ? Settings.Current.ParentHostname : Settings.Current.IotHubHostname;
                        var offline        = new OfflineController(name, hubHostname, Settings.Current.NetworkRunProfile.ProfileSetting);
                        var satellite      = new SatelliteController(name, hubHostname, Settings.Current.NetworkRunProfile.ProfileSetting);
                        var cellular       = new CellularController(name, hubHostname, Settings.Current.NetworkRunProfile.ProfileSetting);
                        controllers.AddRange(new List <INetworkController> {
                            offline, satellite, cellular
                        });

                        // Reset network status before start delay to ensure network status is in designed state before test starts.
                        var sw = new Stopwatch();
                        sw.Start();
                        await RemoveAllControllingRules(controllers, cts.Token);
                        sw.Stop();
                        TimeSpan durationBeforeTestStart = Settings.Current.StartAfter <= sw.Elapsed ? TimeSpan.Zero : Settings.Current.StartAfter - sw.Elapsed;

                        Log.LogInformation($"Delay {durationBeforeTestStart} before starting network controller.");
                        await Task.Delay(durationBeforeTestStart, cts.Token);

                        switch (Settings.Current.NetworkRunProfile.ProfileType)
                        {
                        case NetworkControllerType.Offline:
                            await StartAsync(offline, cts.Token);
                            break;

                        case NetworkControllerType.Satellite:
                            await StartAsync(satellite, cts.Token);
                            break;

                        case NetworkControllerType.Cellular:
                            await StartAsync(cellular, cts.Token);
                            break;

                        case NetworkControllerType.Online:
                            await SetToggleConnectivityMethod(name, cts.Token);
                            Log.LogInformation($"No restrictions to be set, running as online");
                            break;

                        default:
                            throw new NotSupportedException($"Network type {Settings.Current.NetworkRunProfile.ProfileType} is not supported.");
                        }
                    });
                }
                else
                {
                    Log.LogError($"No network interface found for docker network {Settings.Current.NetworkId}");
                }
            }
            catch (Exception ex)
            {
                Log.LogError(ex, $"Unexpected exception thrown from {nameof(Main)} method");
            }

            await cts.Token.WhenCanceled();

            await CleanupControllingRulesOnShutdown(controllers, CancellationToken.None);

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
        }