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"); }
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); }
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); }
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); }
/// <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; } } }
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); }
static void Main() { ShutdownHandler.Initialize(); try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new LogFileViewer()); } finally { ShutdownHandler.InitiateSafeShutdown(); } }
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); }
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); }
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(); }
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); }
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}"); } }
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."); }
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); }
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."); } }
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); }
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); }
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."); } }
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); }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } ILogger logger = Logger.Factory.CreateLogger("EdgeHub"); EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration, logger); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); string sslProtocolsConfig = configuration.GetValue(Constants.ConfigKey.SslProtocols, string.Empty); SslProtocols sslProtocols = SslProtocolsHelper.Parse(sslProtocolsConfig, DefaultSslProtocols, logger); logger.LogInformation($"Enabling SSL protocols: {sslProtocols.Print()}"); IDependencyManager dependencyManager = new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle, sslProtocols); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, dependencyManager, clientCertAuthEnabled, sslProtocols); IContainer container = hosting.Container; logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation($"OptimizeForPerformance={configuration.GetValue("OptimizeForPerformance", true)}"); logger.LogInformation($"MessageAckTimeoutSecs={configuration.GetValue("MessageAckTimeoutSecs", 30)}"); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); var metricsProvider = container.Resolve <IMetricsProvider>(); Metrics.InitWithAspNet(metricsProvider, logger); // Note this requires App.UseMetricServer() to be called in Startup.cs // Init V0 Metrics MetricsV0.BuildMetricsCollector(configuration); // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } TimeSpan shutdownWaitPeriod = TimeSpan.FromSeconds(configuration.GetValue("ShutdownWaitPeriod", DefaultShutdownWaitPeriod)); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(shutdownWaitPeriod, logger); using (IProtocolHead protocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { await protocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled()); logger.LogInformation("Stopping the protocol heads..."); await protocolHead.CloseAsync(CancellationToken.None); logger.LogInformation("Protocol heads stopped."); await CloseDbStoreProviderAsync(container); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }
static async Task <int> MainAsync() { 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); }
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); }
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); }
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}"); } }
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); }
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); }
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)); }