static async Task Main(string[] args) { Logger.LogInformation($"Starting Relayer with the following settings: \r\n{Settings.Current}"); ModuleClient moduleClient = null; try { moduleClient = await ModuleUtil.CreateModuleClientAsync( Settings.Current.TransportType, ModuleUtil.DefaultTimeoutErrorDetectionStrategy, ModuleUtil.DefaultTransientRetryStrategy, Logger); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); // Receive a message and call ProcessAndSendMessageAsync to send it on its way await moduleClient.SetInputMessageHandlerAsync(Settings.Current.InputName, ProcessAndSendMessageAsync, moduleClient); await cts.Token.WhenCanceled(); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("Relayer Main() finished."); } catch (Exception ex) { Logger.LogError(ex, "Error occurred during Relayer."); } finally { moduleClient?.CloseAsync(); moduleClient?.Dispose(); } }
static async Task Main() { // TODO: Add Coordinator logic (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); await cts.Token.WhenCanceled(); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Console.WriteLine("TestResultCoordinator Main() exited."); }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration).ConfigureAwait(false); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, new DependencyManager(configuration, certificates.ServerCertificate)); IContainer container = hosting.Container; ILogger logger = container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); logger.LogInformation("Starting Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(ShutdownWaitPeriod, logger); Metrics.BuildMetricsCollector(configuration); using (IProtocolHead protocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, container, hosting).ConfigureAwait(false)) using (var renewal = new CertificateRenewal(certificates, logger)) { await protocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled()); logger.LogInformation("Stopping the protocol heads..."); await Task.WhenAny(protocolHead.CloseAsync(CancellationToken.None), Task.Delay(TimeSpan.FromSeconds(10), CancellationToken.None)); logger.LogInformation("Protocol heads stopped."); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }
static async Task <int> MainAsync() { Logger.LogInformation("DirectMethodSender Main() started."); IConfiguration configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("config/appsettings.json", optional: true) .AddEnvironmentVariables() .Build(); TimeSpan dmDelay = configuration.GetValue("DirectMethodDelay", TimeSpan.FromSeconds(5)); // Get device id of this device, exposed as a system variable by the iot edge runtime string targetDeviceId = configuration.GetValue <string>("IOTEDGE_DEVICEID"); string targetModuleId = configuration.GetValue("TargetModuleId", "DirectMethodReceiver"); 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 CallDirectMethod(moduleClient, dmDelay, targetDeviceId, targetModuleId, cts); await moduleClient.CloseAsync(); await cts.Token.WhenCanceled(); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("DirectMethodSender 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)) { try { await protocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled()); } catch (Exception ex) { logger.LogError($"Error starting protocol heads: {ex.Message}"); } 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() { Logger.LogInformation("DirectMethodCloudSender Main() started."); IConfiguration configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("config/appsettings.json", optional: true) .AddEnvironmentVariables() .Build(); string serviceClientConnectionString = Preconditions.CheckNonWhiteSpace(configuration.GetValue <string>("ServiceClientConnectionString"), nameof(serviceClientConnectionString)); // Get device id of this device, exposed as a system variable by the iot edge runtime string targetDeviceId = configuration.GetValue <string>("IOTEDGE_DEVICEID"); string targetModuleId = configuration.GetValue("TargetModuleId", "DirectMethodReceiver"); TransportType transportType = configuration.GetValue("ClientTransportType", TransportType.Amqp_Tcp_Only); TimeSpan dmDelay = configuration.GetValue("DirectMethodDelay", TimeSpan.FromSeconds(5)); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); await CallDirectMethodFromCloud(serviceClientConnectionString, targetDeviceId, targetModuleId, transportType, dmDelay, cts); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("DirectMethodCloudSender 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"); try { EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration, logger); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); string sslProtocolsConfig = configuration.GetValue(Constants.ConfigKey.SslProtocols, string.Empty); SslProtocols sslProtocols = SslProtocolsHelper.Parse(sslProtocolsConfig, DefaultSslProtocols, logger); logger.LogInformation($"Enabling SSL protocols: {sslProtocols.Print()}"); IDependencyManager dependencyManager = new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle, certificates.ManifestTrustBundle, sslProtocols); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, dependencyManager, clientCertAuthEnabled, sslProtocols); IContainer container = hosting.Container; logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation($"OptimizeForPerformance={configuration.GetValue("OptimizeForPerformance", true)}"); logger.LogInformation($"MessageAckTimeoutSecs={configuration.GetValue("MessageAckTimeoutSecs", 30)}"); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); var metricsProvider = container.Resolve <IMetricsProvider>(); Metrics.InitWithAspNet(metricsProvider, logger); // Note this requires App.UseMetricServer() to be called in Startup.cs // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Register EdgeHub indentity in device scopes cache. // When we connect upstream, we verify that identity is in scope. // On a fresh start, we may not yet received the scopes from the upstream, so we need // to force add edgeHub in the cache so it is able to connect upstream. // Once we get the scopes from the upstream, this record is replaced. ServiceIdentity edgeHubIdentity = container.ResolveNamed <ServiceIdentity>("EdgeHubIdentity"); IServiceIdentityHierarchy identityScopes = container.Resolve <IServiceIdentityHierarchy>(); await identityScopes.AddOrUpdate(edgeHubIdentity); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); ExperimentalFeatures experimentalFeatures = CreateExperimentalFeatures(configuration); var configUpdaterStartupFailed = new TaskCompletionSource <bool>(); var configDownloadTask = configUpdater.Init(configSource); _ = configDownloadTask.ContinueWith( _ => configUpdaterStartupFailed.SetResult(false), TaskContinuationOptions.OnlyOnFaulted); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } TimeSpan shutdownWaitPeriod = TimeSpan.FromSeconds(configuration.GetValue("ShutdownWaitPeriod", DefaultShutdownWaitPeriod)); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(shutdownWaitPeriod, logger); double renewAfter = configuration.GetValue("ServerCertificateRenewAfterInMs", int.MaxValue); renewAfter = renewAfter > int.MaxValue ? int.MaxValue : renewAfter; TimeSpan maxRenewAfter = TimeSpan.FromMilliseconds(renewAfter); using (IProtocolHead mqttBrokerProtocolHead = await GetMqttBrokerProtocolHeadAsync(experimentalFeatures, container)) using (IProtocolHead edgeHubProtocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, experimentalFeatures, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger, maxRenewAfter)) { try { await Task.WhenAll(mqttBrokerProtocolHead.StartAsync(), configDownloadTask); await edgeHubProtocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled(), configUpdaterStartupFailed.Task); } catch (Exception ex) { logger.LogError($"Error starting protocol heads: {ex.Message}"); } logger.LogInformation("Stopping the protocol heads..."); await Task.WhenAll(mqttBrokerProtocolHead.CloseAsync(CancellationToken.None), edgeHubProtocolHead.CloseAsync(CancellationToken.None)); logger.LogInformation("Protocol heads stopped."); await CloseDbStoreProviderAsync(container); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); } catch (Exception ex) { logger.LogError(ex, "Stopping with exception"); throw; } return(0); }
static async Task <int> MainAsync() { Logger.LogInformation($"Starting module restarter with the following settings:\r\n{Settings.Current}"); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); await RestartModules(cts); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("ModuleRestarter Main() finished."); return(0); }
public static void Main() { (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), NullLogger.Instance); string countString = Environment.GetEnvironmentVariable("Count"); int parsedCount = int.Parse(countString); for (int i = 0; i < parsedCount; i++) { Console.WriteLine(i); } cts.Token.WhenCanceled().Wait(); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); }
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(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."); } }
static async Task Main() { ILogger logger = InitLogger().CreateLogger("loadgen"); Log.Information($"Starting load gen with the following settings:\r\n{Settings.Current}"); try { var client = await GetModuleClientWithRetryAsync(); using (var timers = new Timers()) { Guid batchId = Guid.NewGuid(); // setup the message timer timers.Add( Settings.Current.MessageFrequency, Settings.Current.JitterFactor, () => GenerateMessageAsync(client, batchId)); // setup the twin update timer timers.Add( Settings.Current.TwinUpdateFrequency, Settings.Current.JitterFactor, () => GenerateTwinUpdateAsync(client, batchId)); timers.Start(); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), logger); Log.Information("Load gen running."); await cts.Token.WhenCanceled(); Log.Information("Stopping timers."); timers.Stop(); Log.Information("Closing connection to Edge Hub."); await client.CloseAsync(); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Log.Information("Load gen complete. Exiting."); } } catch (Exception ex) { Log.Error($"Error occurred during load gen.\r\n{ex}"); } }
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() { Console.WriteLine($"{DateTime.Now.ToLocalTime()}>\t The PumpSimulator Main() has started."); SetupTelemetry(); try { RetrieveSettingsFromConfig(); var simulatorParameters = SimulatorParameters.Create(); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), null); Console.WriteLine( $"Initializing simulated 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)."); moduleClient = await ModuleUtil.CreateModuleClientAsync( protocol, ModuleUtil.DefaultTimeoutErrorDetectionStrategy, ModuleUtil.DefaultTransientRetryStrategy); ModuleClient userContext = moduleClient; reportedProperties = new TwinCollection(); await moduleClient.SetDesiredPropertyUpdateCallbackAsync(OnDesiredPropertiesUpdated, userContext); await moduleClient.SetMethodHandlerAsync("reset", ResetMethod, null); await moduleClient.SetMethodHandlerAsync("ping", PingMethod, null); await moduleClient.SetMethodHandlerAsync("check", CheckMethod, null); await moduleClient.SetInputMessageHandlerAsync("control", ControlMessageHandle, userContext); await RetrieveSettingsFromTwin(moduleClient); 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); } catch (System.Exception ex) { Console.WriteLine($"{DateTime.Now.ToLocalTime()}>\t PumpSimulator Main() error."); Console.WriteLine(ex.Message); var telemetry = new ExceptionTelemetry(ex); telemetryClient.TrackException(telemetry); return(-1); } }
static async Task <int> MainAsync() { Logger.LogInformation("TemperatureFilter 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), null); ModuleConfig moduleConfig = await GetConfigurationAsync(moduleClient); Logger.LogInformation($"Using TemperatureThreshold value of {moduleConfig.TemperatureThreshold}"); var userContext = Tuple.Create(moduleClient, moduleConfig); await moduleClient.SetInputMessageHandlerAsync("input1", PrintAndFilterMessages, userContext); await cts.Token.WhenCanceled(); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("TemperatureFilter Main() finished."); 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("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); bool checkImagePullBeforeModuleCreate = configuration.GetValue <bool>(Constants.CheckImagePullBeforeModuleCreate, true); 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, checkImagePullBeforeModuleCreate)); 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: 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); } // 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 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 = CreateHostBuilder(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."); }
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}"); try { var networkInterfaceName = DockerHelper.GetDockerInterfaceName(); if (networkInterfaceName.HasValue) { await networkInterfaceName.ForEachAsync(async name => { var offline = new OfflineController(name, Settings.Current.IotHubHostname, Settings.Current.NetworkRunProfile.ProfileSetting); var satellite = new SatelliteController(name, Settings.Current.IotHubHostname, Settings.Current.NetworkRunProfile.ProfileSetting); var cellular = new CellularController(name, Settings.Current.IotHubHostname, Settings.Current.NetworkRunProfile.ProfileSetting); var controllers = 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: 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(); completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); }
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}"); ITwinTestInitializer twinOperator = null; try { using (RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Settings.Current.ServiceClientConnectionString)) { twinOperator = await GetTwinOperatorAsync(registryManager); await twinOperator.StartAsync(cts.Token); await Task.Delay(Settings.Current.TestDuration, cts.Token); Logger.LogInformation($"Test run completed after {Settings.Current.TestDuration}"); twinOperator.Stop(); 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."); twinOperator?.Stop(); } }
static async Task <int> MainAsync() { (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); Logger.LogInformation($"Starting metrics collector with the following settings:\r\n{Settings.Current}"); MqttTransportSettings mqttSetting = new MqttTransportSettings(TransportType.Mqtt_Tcp_Only); ITransportSettings[] transportSettings = { mqttSetting }; ModuleClient moduleClient = null; try { moduleClient = await ModuleClient.CreateFromEnvironmentAsync(transportSettings); Dictionary <string, string> additionalTags = await GetAdditionalTagsFromTwin(moduleClient); MetricsScraper scraper = new MetricsScraper(Settings.Current.Endpoints); IMetricsPublisher publisher; if (Settings.Current.UploadTarget == UploadTarget.AzureLogAnalytics) { publisher = new LogAnalyticsUpload(Settings.Current.LogAnalyticsWorkspaceId, Settings.Current.LogAnalyticsWorkspaceKey, Settings.Current.LogAnalyticsLogType); } else { publisher = new IotHubMetricsUpload(moduleClient, Settings.Current.MessageIdentifier); } using (MetricsScrapeAndUpload metricsScrapeAndUpload = new MetricsScrapeAndUpload(scraper, publisher, additionalTags)) { TimeSpan scrapeAndUploadInterval = TimeSpan.FromSeconds(Settings.Current.ScrapeFrequencySecs); metricsScrapeAndUpload.Start(scrapeAndUploadInterval); await cts.Token.WhenCanceled(); } } catch (Exception e) { Logger.LogError(e, "Error occurred during metrics collection setup."); } finally { moduleClient?.Dispose(); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("MetricsCollector 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.TestStartDelay}."); await Task.Delay(Settings.Current.TestStartDelay); DateTime testStartAt = DateTime.UtcNow; long messageIdCounter = 1; while (!cts.IsCancellationRequested && (Settings.Current.TestDuration == TimeSpan.Zero || DateTime.UtcNow - testStartAt < Settings.Current.TestDuration)) { try { await SendEventAsync(moduleClient, batchId, Settings.Current.TrackingId, 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)); } catch (Exception ex) { Logger.LogError(ex, "Error occurred during load gen."); moduleClient?.Dispose(); } Logger.LogInformation("Load Gen complete. Exiting."); }
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; string edgeDeviceHostName; string dockerLoggingDriver; Dictionary <string, string> dockerLoggingOptions; IEnumerable <global::Docker.DotNet.Models.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 <global::Docker.DotNet.Models.AuthConfig> >() ?? new List <global::Docker.DotNet.Models.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)); 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 = ExperimentalFeatures.Create(configuration.GetSection("experimentalFeatures"), logger); string iothubHostname; string deviceId; 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)); builder.RegisterModule(new DockerModule(deviceConnectionString, edgeDeviceHostName, dockerUri, dockerAuthConfig, upstreamProtocol, proxy, productInfo, closeOnIdleTimeout, idleTimeout)); 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); 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, closeOnIdleTimeout, idleTimeout)); 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 networkId = configuration.GetValue <string>(Constants.NetworkIdKey); string proxyImage = configuration.GetValue <string>(K8sConstants.ProxyImageEnvKey); 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); string persistentVolumeName = configuration.GetValue <string>(K8sConstants.PersistentVolumeNameKey); string storageClassName = configuration.GetValue <string>(K8sConstants.StorageClassNameKey); uint persistentVolumeClaimDefaultSizeMb = configuration.GetValue <uint>(K8sConstants.PersistentVolumeClaimDefaultSizeInMbKey); string deviceNamespace = configuration.GetValue <string>(K8sConstants.K8sNamespaceKey); var kubernetesExperimentalFeatures = KubernetesExperimentalFeatures.Create(configuration.GetSection("experimentalFeatures"), logger); builder.RegisterModule(new AgentModule(maxRestartCount, intensiveCareTime, coolOffTimeUnitInSeconds, usePersistentStorage, storagePath, Option.Some(new Uri(workloadUri)), Option.Some(apiVersion), moduleId, Option.Some(moduleGenerationId))); builder.RegisterModule(new KubernetesModule( iothubHostname, deviceId, networkId, edgeDeviceHostName, proxyImage, proxyConfigPath, proxyConfigVolumeName, proxyConfigMapName, proxyTrustBundlePath, proxyTrustBundleVolumeName, proxyTrustBundleConfigMapName, apiVersion, deviceNamespace, new Uri(managementUri), new Uri(workloadUri), dockerAuthConfig, upstreamProtocol, Option.Some(productInfo), mappedServiceDefault, enableServiceCallTracing, persistentVolumeName, storageClassName, persistentVolumeClaimDefaultSizeMb, proxy, closeOnIdleTimeout, idleTimeout, kubernetesExperimentalFeatures)); 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, backupConfigFilePath, configuration, versionInfo, TimeSpan.FromSeconds(configRefreshFrequencySecs), enableStreams, TimeSpan.FromSeconds(requestTimeoutSecs), experimentalFeatures)); break; case "local": string localConfigFilePath = GetLocalConfigFilePath(configuration, logger); builder.RegisterModule(new FileConfigSourceModule(localConfigFilePath, 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); } // TODO move this code to Agent if (mode.ToLowerInvariant().Equals(Constants.KubernetesMode)) { // Start environment operator IKubernetesEnvironmentOperator environmentOperator = container.Resolve <IKubernetesEnvironmentOperator>(); environmentOperator.Start(); // Start the edge deployment operator IEdgeDeploymentOperator edgeDeploymentOperator = container.Resolve <IEdgeDeploymentOperator>(); edgeDeploymentOperator.Start(); } (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); completed.Set(); } handler.ForEach(h => GC.KeepAlive(h)); return(returnCode); }
static async Task <int> MainAsync() { Console.WriteLine("SampleModule Main() started."); var appSettings = ConfigurationManager.AppSettings; if (!TimeSpan.TryParse(appSettings["MessageDelay"], out messageDelay)) { messageDelay = TimeSpan.FromSeconds(5); } int messageCount; if (!int.TryParse(Environment.GetEnvironmentVariable(MessageCountConfigKey), out messageCount)) { if (!int.TryParse(appSettings[MessageCountConfigKey], out messageCount)) { messageCount = -1; } } var simulatorParameters = SimulatorParameters.Create(); ModuleClient moduleClient = await ModuleUtil.CreateModuleClientAsync( TransportType.Amqp_Tcp_Only, ModuleUtil.DefaultTimeoutErrorDetectionStrategy, ModuleUtil.DefaultTransientRetryStrategy); await moduleClient.OpenAsync(); await moduleClient.SetMethodHandlerAsync("reset", ResetMethod, null); await moduleClient.SetMethodHandlerAsync("ping", PingMethod, null); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), null); Twin currentTwinProperties = await moduleClient.GetTwinAsync(); Console.WriteLine("Initialized Twin State Received"); if (currentTwinProperties.Properties.Desired.Contains(SendIntervalConfigKey)) { Console.WriteLine("SendInterval: " + currentTwinProperties.Properties.Desired[SendIntervalConfigKey]); var desiredInterval = (int)currentTwinProperties.Properties.Desired[SendIntervalConfigKey]; messageDelay = TimeSpan.FromSeconds(desiredInterval); } if (currentTwinProperties.Properties.Desired.Contains(EventCountConfigKey)) { Console.WriteLine("EventCount: " + currentTwinProperties.Properties.Desired[EventCountConfigKey]); var desiredCount = (int)currentTwinProperties.Properties.Desired[EventCountConfigKey]; eventCount = desiredCount; } if (currentTwinProperties.Properties.Desired.Contains(SendDataConfigKey)) { Console.WriteLine("SendData: " + currentTwinProperties.Properties.Desired[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("SampleModule Main() finished."); return(0); }
static async Task Main() { Logger.LogInformation($"Starting load gen with the following settings:\r\n{Settings.Current}"); try { ModuleClient moduleClient = await ModuleUtil.CreateModuleClientAsync( Settings.Current.TransportType, ModuleUtil.DefaultTimeoutErrorDetectionStrategy, ModuleUtil.DefaultTransientRetryStrategy, Logger); using (var timers = new Timers()) { Guid batchId = Guid.NewGuid(); Logger.LogInformation($"Batch Id={batchId}"); // setup the message timer timers.Add( Settings.Current.MessageFrequency, Settings.Current.JitterFactor, () => GenerateMessageAsync(moduleClient, batchId)); // setup the twin update timer timers.Add( Settings.Current.TwinUpdateFrequency, Settings.Current.JitterFactor, () => GenerateTwinUpdateAsync(moduleClient, batchId)); timers.Start(); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); Logger.LogInformation("Load gen running."); await cts.Token.WhenCanceled(); Logger.LogInformation("Stopping timers."); timers.Stop(); 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}"); } }
public static async Task <int> MainAsync() { Logger.LogInformation($"Starting DirectMethodSender with the following settings:\r\n{Settings.Current}"); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); DirectMethodSenderBase directMethodClient = null; ReporterClientBase reportClient = null; try { Guid batchId = Guid.NewGuid(); Logger.LogInformation($"Batch Id={batchId}"); Logger.LogInformation($"Load gen delay start for {Settings.Current.TestStartDelay}."); await Task.Delay(Settings.Current.TestStartDelay, cts.Token); DateTime testStartAt = DateTime.UtcNow; directMethodClient = await CreateClientAsync(Settings.Current.InvocationSource); reportClient = ReporterClientBase.Create( Logger, Settings.Current.ReportingEndpointUrl, Settings.Current.TransportType); while (!cts.Token.IsCancellationRequested && IsTestTimeUp(testStartAt)) { (HttpStatusCode result, ulong dmCounter) = await directMethodClient.InvokeDirectMethodAsync(Settings.Current.DirectMethodName, cts); // Generate a testResult type depending on the reporting endpoint TestResultBase testResult = ConstructTestResult( Settings.Current.DirectMethodResultType, batchId, dmCounter, result); await reportClient.SendTestResultAsync(testResult); await Task.Delay(Settings.Current.DirectMethodDelay, cts.Token); } await cts.Token.WhenCanceled(); } catch (Exception e) { Logger.LogError(e, "Error occurred during direct method sender test setup"); } finally { // Implicit CloseAsync() directMethodClient?.Dispose(); reportClient?.Dispose(); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("DirectMethodSender Main() finished."); return(0); }
public static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.Core.Routing.LoggerFactory = Logger.Factory; } X509Certificate2 cert; IEnumerable <X509Certificate2> chain; string edgeHubConnectionString = configuration.GetValue <string>(Constants.IotHubConnectionStringVariableName); // When connection string is not set it is edged mode if (string.IsNullOrEmpty(edgeHubConnectionString)) { var workloadUri = new Uri(configuration.GetValue <string>(Constants.WorkloadUriVariableName)); string edgeHubHostname = configuration.GetValue <string>(Constants.EdgeDeviceHostnameVariableName); string moduleId = configuration.GetValue <string>(Constants.ModuleIdVariableName); string generationId = configuration.GetValue <string>(Constants.ModuleGenerationIdVariableName); DateTime expiration = DateTime.UtcNow.AddDays(Constants.CertificateValidityDays); (cert, chain) = await CertificateHelper.GetServerCertificatesFromEdgelet(workloadUri, Constants.WorkloadApiVersion, moduleId, generationId, edgeHubHostname, expiration); } else { string edgeHubCertPath = configuration.GetValue <string>(Constants.EdgeHubServerCertificateFileKey); cert = new X509Certificate2(edgeHubCertPath); string edgeHubCaChainCertPath = configuration.GetValue <string>(Constants.EdgeHubServerCAChainCertificateFileKey); chain = CertificateHelper.GetServerCACertificatesFromFile(edgeHubCaChainCertPath); } // TODO: set certificate for Startup without the cache ServerCertificateCache.X509Certificate = cert; int port = configuration.GetValue("httpSettings:port", 443); Hosting hosting = Hosting.Initialize(port); IContainer container = hosting.Container; ILogger logger = container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); logger.LogInformation("Starting Edge Hub"); VersionInfo versionInfo = VersionInfo.Get(Constants.VersionInfoFileName); if (versionInfo != VersionInfo.Empty) { logger.LogInformation($"Version - {versionInfo.ToString(true)}"); } LogLogo(logger); if (chain != null) { logger.LogInformation("Installing intermediate certificates."); CertificateHelper.InstallCerts( RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? StoreName.CertificateAuthority : StoreName.Root, StoreLocation.CurrentUser, chain); } else { logger.LogWarning("Unable to find intermediate certificates."); } // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // Resolve IDeviceScopeIdentitiesCache to start the pump await container.Resolve <Task <IDeviceScopeIdentitiesCache> >(); // 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 <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); using (ModuleClient moduleClient = await ModuleUtil.CreateModuleClientAsync( transportType, 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))); } return(new MethodResponse(Encoding.UTF8.GetBytes(testReporter.ReportResults()), (int)HttpStatusCode.OK)); }, null); 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); }
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; 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); string iothubHostname; string deviceId; 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)); 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); 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); 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": bool enableStreams = configuration.GetValue(Constants.EnableStreams, false); int requestTimeoutSecs = configuration.GetValue(Constants.RequestTimeoutSecs, 600); builder.RegisterModule( new TwinConfigSourceModule( iothubHostname, deviceId, backupConfigFilePath, configuration, versionInfo, TimeSpan.FromSeconds(configRefreshFrequencySecs), enableStreams, TimeSpan.FromSeconds(requestTimeoutSecs))); break; case "local": string localConfigFilePath = GetLocalConfigFilePath(configuration, logger); builder.RegisterModule(new FileConfigSourceModule(localConfigFilePath, 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).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); completed.Set(); } handler.ForEach(h => GC.KeepAlive(h)); return(returnCode); }
public static async Task <int> MainAsync() { Logger.LogInformation($"Starting DirectMethodSender with the following settings:\r\n{Settings.Current}"); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(TimeSpan.FromSeconds(5), Logger); DirectMethodSenderBase directMethodClient = null; ModuleClient reportClient = null; Option <Uri> analyzerUrl = Settings.Current.AnalyzerUrl; Option <Uri> testReportCoordinatorUrl = Settings.Current.TestResultCoordinatorUrl; try { Guid batchId = Guid.NewGuid(); Logger.LogInformation($"Batch Id={batchId}"); directMethodClient = await CreateClientAsync(Settings.Current.InvocationSource); reportClient = await ModuleUtil.CreateModuleClientAsync( Settings.Current.TransportType, ModuleUtil.DefaultTimeoutErrorDetectionStrategy, ModuleUtil.DefaultTransientRetryStrategy, Logger); Logger.LogInformation($"Load gen delay start for {Settings.Current.TestStartDelay}."); await Task.Delay(Settings.Current.TestStartDelay, cts.Token); DateTime testStartAt = DateTime.UtcNow; while (!cts.Token.IsCancellationRequested && IsTestTimeUp(testStartAt)) { (HttpStatusCode result, long dmCounter) = await directMethodClient.InvokeDirectMethodAsync(cts); // TODO: Create an abstract class to handle the reporting client generation if (testReportCoordinatorUrl.HasValue) { await testReportCoordinatorUrl.ForEachAsync( async (Uri uri) => { var testResult = new DirectMethodTestResult(Settings.Current.ModuleId + ".send", DateTime.UtcNow) { TrackingId = Settings.Current.TrackingId.Expect(() => new ArgumentException("TrackingId is empty")), BatchId = batchId.ToString(), SequenceNumber = dmCounter.ToString(), Result = result.ToString() }; var testResultReportingClient = new TestResultReportingClient { BaseUrl = uri.AbsoluteUri }; await ModuleUtil.ReportTestResultAsync(testResultReportingClient, Logger, testResult); }); } else { await analyzerUrl.ForEachAsync( async (Uri uri) => { var testResult = new LegacyDirectMethodTestResult(Settings.Current.TargetModuleId, DateTime.UtcNow) { Result = result.ToString() }; var testResultReportingClient = new TestResultReportingClient { BaseUrl = uri.AbsoluteUri }; await ModuleUtil.ReportTestResultAsync(testResultReportingClient, Logger, testResult); }, async() => { await reportClient.SendEventAsync("AnyOutput", new Message(Encoding.UTF8.GetBytes("Direct Method call succeeded."))); }); } await Task.Delay(Settings.Current.DirectMethodDelay, cts.Token); } await cts.Token.WhenCanceled(); } catch (Exception e) { Logger.LogError(e, "Error occurred during direct method sender test setup"); } finally { // Implicit CloseAsync() directMethodClient?.Dispose(); reportClient?.Dispose(); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); Logger.LogInformation("DirectMethodSender Main() finished."); return(0); }