Beispiel #1
0
        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();
            }
        }
Beispiel #2
0
        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.");
        }
Beispiel #3
0
        static async Task <int> MainAsync(IConfigurationRoot configuration)
        {
            string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info");

            Logger.SetLogLevel(logLevel);

            // Set the LoggerFactory used by the Routing code.
            if (configuration.GetValue("EnableRoutingLogging", false))
            {
                Routing.LoggerFactory = Logger.Factory;
            }

            EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration).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);
        }
Beispiel #4
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);
        }
Beispiel #5
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);
        }
Beispiel #6
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);
        }
Beispiel #7
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);
        }
Beispiel #8
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);
        }
Beispiel #9
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));
        }
Beispiel #10
0
        static async Task <int> MainAsync()
        {
            Console.WriteLine("SimulatedTemperatureSensor Main() started.");

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

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

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

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

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

            await moduleClient.OpenAsync();

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

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

            Twin currentTwinProperties = await moduleClient.GetTwinAsync();

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

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

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

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

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

            await cts.Token.WhenCanceled();

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            Console.WriteLine("SimulatedTemperatureSensor Main() finished.");
            return(0);
        }
Beispiel #11
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.");
            }
        }
Beispiel #12
0
        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}");
            }
        }
Beispiel #13
0
        static async Task <int> MainAsync()
        {
            Logger.LogInformation("DirectMethodReceiver Main() started.");

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

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

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

            await moduleClient.OpenAsync();

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

            await cts.Token.WhenCanceled();

            completed.Set();
            handler.ForEach(h => GC.KeepAlive(h));
            Logger.LogInformation("DirectMethodReceiver Main() finished.");
            return(0);
        }
Beispiel #14
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);
            }
        }
Beispiel #15
0
        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);
        }
Beispiel #16
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);
        }
Beispiel #17
0
        static async Task Main(string[] args)
        {
            Logger.LogInformation($"Starting TestResultCoordinator with the following settings:\r\n{Settings.Current}");

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

            Logger.LogInformation("Creating WebHostBuilder...");
            Task webHost = 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.");
        }
Beispiel #18
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}");

            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));
        }
Beispiel #19
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}");

            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();
            }
        }
Beispiel #20
0
        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);
        }
Beispiel #21
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.");
        }
Beispiel #22
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 <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);
        }
Beispiel #23
0
        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);
        }
Beispiel #24
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}");
            }
        }
Beispiel #25
0
        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);
        }
Beispiel #26
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);
        }
Beispiel #27
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);
        }
Beispiel #28
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);
        }
Beispiel #29
0
        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);
        }