/// <summary> /// Autofac configuration. /// </summary> /// <param name="configuration"></param> /// <returns></returns> private IContainer ConfigureContainer(IConfigurationRoot configuration) { var config = new Config(configuration); var builder = new ContainerBuilder(); // Register configuration interfaces builder.RegisterInstance(config) .AsImplementedInterfaces().SingleInstance(); builder.RegisterInstance(this) .AsImplementedInterfaces().SingleInstance(); // register logger builder.RegisterLogger(LogEx.Console(configuration)); // Register module framework builder.RegisterModule <ModuleFramework>(); // Register test publisher builder.RegisterType <TestPublisher>() .AsImplementedInterfaces().InstancePerLifetimeScope(); // Register controllers builder.RegisterType <v2.Supervisor.DiagnosticMethodsController>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <v2.Supervisor.DiagnosticSettingsController>() .AsImplementedInterfaces().InstancePerLifetimeScope(); return(builder.Build()); }
/// <summary> /// Clear registry /// </summary> private static async Task CleanupAsync(IIoTHubConfig config, bool includeSupervisors) { var logger = LogEx.Console(LogEventLevel.Error); var registry = new IoTHubServiceHttpClient(new HttpClient(logger), config, logger); var result = await registry.QueryDeviceTwinsAsync( "SELECT * from devices where IS_DEFINED(tags.DeviceType)"); foreach (var item in result) { Console.WriteLine($"Deleting {item.Id} {item.ModuleId ?? ""}"); await registry.DeleteAsync(item.Id, item.ModuleId); } if (!includeSupervisors) { return; } var query = "SELECT * FROM devices.modules WHERE " + $"properties.reported.{TwinProperty.kType} = 'supervisor'"; var supers = await registry.QueryDeviceTwinsAsync(query); foreach (var item in supers) { Console.WriteLine($"Deleting {item.Id} {item.ModuleId ?? ""}"); await registry.DeleteAsync(item.Id, item.ModuleId); } }
/// <summary> /// Autofac configuration. /// </summary> public static ContainerBuilder ConfigureContainer( IConfigurationRoot configuration) { var serviceInfo = new ServiceInfo(); var config = new Config(configuration); var builder = new ContainerBuilder(); builder.RegisterInstance(serviceInfo) .AsImplementedInterfaces().SingleInstance(); builder.RegisterInstance(config) .AsImplementedInterfaces().SingleInstance(); // register logger builder.RegisterLogger(LogEx.Console()); // Router host, processor and client ... builder.RegisterType <IoTHubFileNotificationHost>() .AsImplementedInterfaces(); builder.RegisterType <BlobUploadNotificationRouter>() .AsImplementedInterfaces(); builder.RegisterType <EventHubNamespaceClient>() .AsImplementedInterfaces(); return(builder); }
/// <summary> /// Delete supervisor /// </summary> private static async Task DeleteAsync(IIoTHubConfig config, string deviceId, string moduleId) { var logger = LogEx.Console(LogEventLevel.Error); var registry = new IoTHubServiceHttpClient(new HttpClient(logger), config, logger); await registry.DeleteAsync(deviceId, moduleId); }
/// <summary> /// Reset supervisor /// </summary> private static async Task ResetAsync(IIoTHubConfig config, string deviceId, string moduleId) { var logger = LogEx.Console(LogEventLevel.Error); var registry = new IoTHubServiceHttpClient(new HttpClient(logger), config, logger); await ResetAsync(registry, await registry.GetAsync(deviceId, moduleId, CancellationToken.None)); }
/// <summary> /// Get module connection string /// </summary> private static async Task GetAsync( IIoTHubConfig config, string deviceId, string moduleId) { var logger = LogEx.Console(LogEventLevel.Error); var registry = new IoTHubServiceHttpClient(new HttpClient(logger), config, logger); var cs = await registry.GetConnectionStringAsync(deviceId, moduleId); Console.WriteLine(cs); }
/// <summary> /// Host the supervisor module giving it its connection string. /// </summary> private static async Task HostAsync(IIoTHubConfig config, string deviceId, string moduleId) { Console.WriteLine("Create or retrieve connection string..."); var logger = LogEx.Console(LogEventLevel.Error); var cs = await Retry.WithExponentialBackoff(logger, () => AddOrGetAsync(config, deviceId, moduleId)); Console.WriteLine("Starting twin module..."); Twin.Program.Main(new string[] { $"EdgeHubConnectionString={cs}" }); Console.WriteLine("Twin module exited."); }
/// <summary> /// Autofac configuration. /// </summary> public static ContainerBuilder ConfigureContainer( IConfigurationRoot configuration) { var config = new Config(ServiceInfo.ID, configuration); var builder = new ContainerBuilder(); // Register configuration interfaces builder.RegisterInstance(config) .AsImplementedInterfaces().SingleInstance(); // register logger builder.RegisterLogger(LogEx.Console()); // Now Monitor model upload notification using ... if (!config.UseFileNotificationHost) { // ... event processor for fan out (requires blob // notification router to be running) ... builder.RegisterType <EventProcessorHost>() .AsImplementedInterfaces(); builder.RegisterType <EventProcessorFactory>() .AsImplementedInterfaces().SingleInstance(); } else { // ... or listen for file notifications on hub // (for simplicity) ... builder.RegisterType <IoTHubFileNotificationHost>() .AsImplementedInterfaces(); } // ... then call the injected blob processor to load blob ... builder.RegisterType <BlobStreamProcessor>() .AsImplementedInterfaces(); // ... and pass to either importer which imports the data ... builder.RegisterType <SourceStreamImporter>() .AsImplementedInterfaces(); builder.RegisterType <TaskProcessor>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <JsonVariantEncoder>() .AsImplementedInterfaces().SingleInstance(); // ... into cosmos db collection with configured name. builder.RegisterType <ItemContainerFactory>() .AsImplementedInterfaces(); builder.RegisterType <CosmosDbServiceClient>() .AsImplementedInterfaces(); // ... or ... return(builder); }
/// <summary> /// Get database /// </summary> /// <param name="options"></param> /// <returns></returns> private static async Task <IDatabase> GetDatabaseAsync(CliOptions options) { var logger = LogEx.Console(); var config = new ConfigurationBuilder() .AddFromDotEnvFile() .AddEnvironmentVariables() .Build(); var configuration = new CosmosDbConfig(config); var server = new CosmosDbServiceClient(configuration, logger); return(await server.OpenAsync( options.GetValueOrDefault("-d", "--db", "default"))); }
/// <summary> /// Host the module giving it its connection string. /// </summary> private static async Task HostAsync(IIoTHubConfig config, string deviceId, string moduleId, string[] args) { Console.WriteLine("Create or retrieve connection string..."); var logger = LogEx.Console(LogEventLevel.Error); var cs = await Retry.WithExponentialBackoff(logger, () => AddOrGetAsync(config, deviceId, moduleId)); Console.WriteLine("Starting discovery module..."); var arguments = args.ToList(); arguments.Add($"EdgeHubConnectionString={cs}"); Discovery.Program.Main(arguments.ToArray()); Console.WriteLine("Discovery module exited."); }
/// <summary> /// List all twin module identities /// </summary> private static async Task ListAsync(IIoTHubConfig config) { var logger = LogEx.Console(LogEventLevel.Error); var registry = new IoTHubServiceHttpClient(new HttpClient(logger), config, logger); var query = "SELECT * FROM devices.modules WHERE " + $"properties.reported.{TwinProperty.kType} = 'supervisor'"; var supers = await registry.QueryDeviceTwinsAsync(query); foreach (var item in supers) { Console.WriteLine($"{item.Id} {item.ModuleId}"); } }
/// <summary> /// Autofac configuration. /// </summary> public static ContainerBuilder ConfigureContainer( IConfigurationRoot configuration) { var serviceInfo = new ServiceInfo(); var config = new Config(configuration); var builder = new ContainerBuilder(); builder.RegisterInstance(serviceInfo) .AsImplementedInterfaces().SingleInstance(); builder.RegisterInstance(config) .AsImplementedInterfaces().SingleInstance(); // register logger builder.RegisterLogger(LogEx.Console()); // Register http client module builder.RegisterModule <HttpClientModule>(); #if DEBUG builder.RegisterType <NoOpCertValidator>() .AsImplementedInterfaces(); #endif // Iot hub services builder.RegisterType <IoTHubMessagingHttpClient>() .AsImplementedInterfaces().SingleInstance(); // Register event bus builder.RegisterType <EventBusHost>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <ServiceBusClientFactory>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <ServiceBusEventBus>() .AsImplementedInterfaces().SingleInstance(); // ... and event subscriptions builder.RegisterType <ApplicationEventSubscriber>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <EndpointEventSubscriber>() .AsImplementedInterfaces().SingleInstance(); // ... // Register alerters builder.RegisterType <EndpointSecurityAlerter>() .AsImplementedInterfaces(); // ... return(builder); }
/// <summary> /// Add or get module identity /// </summary> private static async Task <ConnectionString> AddOrGetAsync(IIoTHubConfig config, string deviceId, string moduleId) { var logger = LogEx.Console(LogEventLevel.Error); var registry = CreateClient(config, logger); await registry.CreateAsync(new DeviceTwinModel { Id = deviceId, ModuleId = moduleId, Capabilities = new DeviceCapabilitiesModel { IotEdge = true } }, true, CancellationToken.None); var cs = await registry.GetConnectionStringAsync(deviceId, moduleId); return(cs); }
/// <summary> /// Autofac configuration. /// </summary> /// <param name="configuration"></param> /// <returns></returns> private IContainer ConfigureContainer(IConfigurationRoot configuration) { var config = new Config(configuration); var builder = new ContainerBuilder(); // Register configuration interfaces builder.RegisterInstance(config) .AsImplementedInterfaces().SingleInstance(); builder.RegisterInstance(this) .AsImplementedInterfaces().SingleInstance(); // register logger builder.RegisterLogger(LogEx.Console(configuration)); // Register module framework builder.RegisterModule <ModuleFramework>(); // Register opc ua services builder.RegisterType <ClientServices>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <StackLogger>() .AsImplementedInterfaces().SingleInstance().AutoActivate(); // Register discovery services builder.RegisterType <DiscoveryServices>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <ScannerServices>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <DiscoveryMessagePublisher>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <TaskProcessor>() .AsImplementedInterfaces(); // Register controllers builder.RegisterType <v2.Supervisor.DiscoveryMethodsController>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <v2.Supervisor.DiagnosticSettingsController>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <v2.Supervisor.DiscoverySettingsController>() .AsImplementedInterfaces().InstancePerLifetimeScope(); return(builder.Build()); }
/// <summary> /// Autofac configuration. /// </summary> /// <param name="configuration"></param> /// <returns></returns> private IContainer ConfigureContainer(IConfigurationRoot configuration) { var config = new Config(configuration); var builder = new ContainerBuilder(); // Register configuration interfaces builder.RegisterInstance(config) .AsImplementedInterfaces().SingleInstance(); builder.RegisterInstance(this) .AsImplementedInterfaces().SingleInstance(); // register logger builder.RegisterLogger(LogEx.Console(configuration)); // Register module framework builder.RegisterModule <ModuleFramework>(); // Register opc ua services builder.RegisterType <ClientServices>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <AddressSpaceServices>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <JsonVariantEncoder>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <PublisherDiscovery>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <PublisherServices>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <StackLogger>() .AsImplementedInterfaces().SingleInstance().AutoActivate(); // Register discovery services builder.RegisterType <DiscoveryServices>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <ScannerServices>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <DiscoveryMessagePublisher>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <TaskProcessor>() .AsImplementedInterfaces(); // Register controllers builder.RegisterType <v2.Supervisor.SupervisorMethodsController>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <v2.Supervisor.SupervisorSettingsController>() .AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterType <v2.Supervisor.DiscoverySettingsController>() .AsImplementedInterfaces().InstancePerLifetimeScope(); // Register supervisor services builder.RegisterType <SupervisorServices>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <TwinContainerFactory>() .AsImplementedInterfaces().SingleInstance(); if (_injector != null) { // Inject additional services builder.RegisterInstance(_injector) .AsImplementedInterfaces().SingleInstance() .ExternallyOwned(); _injector.Inject(builder); } return(builder.Build()); }
/// <summary> /// Entry point /// </summary> public static void Main(string[] args) { string deviceId = null, moduleId = null; var standalone = false; var echo = false; var publish = false; var logger = LogEx.Console(LogEventLevel.Information); Console.WriteLine("Edge Diagnostics command line interface."); var configuration = new ConfigurationBuilder() .AddFromDotEnvFile() .AddEnvironmentVariables() .Build(); var cs = configuration.GetValue <string>("PCS_IOTHUB_CONNSTRING", null); if (string.IsNullOrEmpty(cs)) { cs = configuration.GetValue <string>("_HUB_CS", null); } IIoTHubConfig config = null; try { for (var i = 0; i < args.Length; i++) { switch (args[i]) { case "-C": case "--connection-string": i++; if (i < args.Length) { cs = args[i]; break; } throw new ArgumentException( "Missing arguments for connection string"); case "-?": case "-h": case "--help": throw new ArgumentException("Help"); case "-s": case "--standalone": standalone = true; break; case "--verbose": logger = LogEx.Console(LogEventLevel.Debug); break; case "--silent": logger = Logger.None; break; case "--echo": case "-e": echo = true; break; case "--publish": case "-p": publish = true; break; case "-d": case "--deviceId": i++; if (i < args.Length) { deviceId = args[i]; break; } throw new ArgumentException( "Missing arguments for edge device id"); case "-m": case "--moduleId": i++; if (i < args.Length) { moduleId = args[i]; break; } throw new ArgumentException( "Missing arguments for diagnostic module id"); default: throw new ArgumentException($"Unknown {args[i]}"); } } if (string.IsNullOrEmpty(cs)) { throw new ArgumentException("Missing connection string."); } if (!ConnectionString.TryParse(cs, out var connectionString)) { throw new ArgumentException("Bad connection string."); } config = connectionString.ToIoTHubConfig(); if (string.IsNullOrEmpty(deviceId)) { standalone = true; deviceId = Dns.GetHostName(); } if (string.IsNullOrEmpty(moduleId)) { moduleId = "diagnostic"; } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine( @" Usage: Microsoft.Azure.IIoT.Modules.Diagnostic.Cli [Arguments] Arguments: --publish -P Publish test messages. --echo -e Send echo pings to diagnostic module. --standalone -s Run the diagnostic module standalone. --deviceId -d The edge device id that is hosting the diagnostic module. If the value is not set, the host name is used and the module is run standalone. --moduleId -m The id of the diagnostic module in the edge. Default: 'diagnostic'. --connection-string -C IoT Hub owner connection string to use to connect to IoT hub for operations on the registry. If not provided, read from environment. --verbose --silent Do debug or suppress trace logging - defaults to informational only. --help -? -h Prints out this help. " ); return; } Console.WriteLine("Press key to cancel..."); using (var cts = new CancellationTokenSource()) { var runner = Task.CompletedTask; var pinger = Task.CompletedTask; try { if (standalone) { // Start diagnostic module process standalone runner = Task.Run(() => HostAsync(config, logger, deviceId, moduleId, args), cts.Token); } if (echo) { // Call echo method until cancelled pinger = Task.Run(() => PingAsync(config, logger, deviceId, moduleId, cts.Token), cts.Token); } if (publish) { StartPublishAsync(config, logger, deviceId, moduleId, TimeSpan.Zero, cts.Token).Wait(); } // Wait until cancelled Console.ReadKey(); if (publish) { StopPublishAsync(config, logger, deviceId, moduleId, cts.Token).Wait(); } cts.Cancel(); } catch (OperationCanceledException) { } catch (Exception e) { logger.Information(e, "Error during execution"); } finally { Task.WaitAll(runner, pinger); } } }
/// <summary> /// Autofac configuration. /// </summary> public static ContainerBuilder ConfigureContainer( IConfigurationRoot configuration) { var serviceInfo = new ServiceInfo(); var config = new Config(configuration); var builder = new ContainerBuilder(); builder.RegisterInstance(serviceInfo) .AsImplementedInterfaces().SingleInstance(); builder.RegisterInstance(config) .AsImplementedInterfaces().SingleInstance(); // register logger builder.RegisterLogger(LogEx.Console()); // Register http client module builder.RegisterModule <HttpClientModule>(); #if DEBUG builder.RegisterType <NoOpCertValidator>() .AsImplementedInterfaces(); #endif // Iot hub services builder.RegisterType <IoTHubServiceHttpClient>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <IoTHubTwinMethodClient>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <ChunkMethodClient>() .AsImplementedInterfaces().SingleInstance(); // Register event bus builder.RegisterType <EventBusHost>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <ServiceBusClientFactory>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <ServiceBusEventBus>() .AsImplementedInterfaces().SingleInstance(); // Register task processor builder.RegisterType <TaskProcessor>() .AsImplementedInterfaces().SingleInstance(); // Handle discovery request and pass to all edges builder.RegisterType <SupervisorRegistry>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <DiscoveryRequestHandler>() .AsImplementedInterfaces().SingleInstance(); #if USE_JOBS builder.RegisterType <DiscoveryJobClient>() .AsImplementedInterfaces().SingleInstance(); #else builder.RegisterType <DiscoveryMultiplexer>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <DiscoveryClient>() .AsImplementedInterfaces().SingleInstance(); #endif // TODO: Add more jobs return(builder); }
/// <summary> /// Entry point /// </summary> public static void Main(string[] args) { var publish = false; var checkTrust = false; var listNodes = false; string deviceId = null, moduleId = null; Console.WriteLine("Publisher module command line interface."); var configuration = new ConfigurationBuilder() .AddFromDotEnvFile() .AddEnvironmentVariables() .Build(); var cs = configuration.GetValue <string>("PCS_IOTHUB_CONNSTRING", null); if (string.IsNullOrEmpty(cs)) { cs = configuration.GetValue <string>("_HUB_CS", null); } IIoTHubConfig config = null; var unknownArgs = new List <string>(); try { for (var i = 0; i < args.Length; i++) { switch (args[i]) { case "-C": case "--connection-string": i++; if (i < args.Length) { cs = args[i]; break; } throw new ArgumentException( "Missing arguments for connection string"); case "-?": case "-h": case "--help": throw new ArgumentException("Help"); case "-p": case "--publish": publish = true; break; case "-l": case "--list": listNodes = true; break; case "-t": case "--only-trusted": checkTrust = true; break; default: unknownArgs.Add(args[i]); break; } } if (string.IsNullOrEmpty(cs)) { throw new ArgumentException("Missing connection string."); } if (!ConnectionString.TryParse(cs, out var connectionString)) { throw new ArgumentException("Bad connection string."); } config = connectionString.ToIoTHubConfig(); if (deviceId == null) { deviceId = Dns.GetHostName(); Console.WriteLine($"Using <deviceId> '{deviceId}'"); } if (moduleId == null) { moduleId = "opcpublisher"; Console.WriteLine($"Using <moduleId> '{moduleId}'"); } args = unknownArgs.ToArray(); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine( @" Usage: Microsoft.Azure.IIoT.Modules.OpcUa.Publisher.Cli [options] Options: -C --connection-string IoT Hub owner connection string to use to connect to IoT hub for operations on the registry. If not provided, read from environment. -p --publish Connects to and publishes a set of nodes in the built-in sample server. -l --listNodes Continously lists published nodes - if combined with publish only lists the published nodes on the endpoint. --help -? -h Prints out this help. " ); return; } var logger = LogEx.Console(LogEventLevel.Error); AppDomain.CurrentDomain.UnhandledException += (s, e) => { logger.Fatal(e.ExceptionObject as Exception, "Exception"); Console.WriteLine(e); }; try { if (publish) { PublishAsync(config, logger, deviceId, moduleId, listNodes, args).Wait(); } else { HostAsync(config, logger, deviceId, moduleId, args, !checkTrust).Wait(); } } catch (Exception e) { Console.WriteLine(e); } }
/// <summary> /// Autofac configuration. /// </summary> public static ContainerBuilder ConfigureContainer( IConfigurationRoot configuration) { var config = new Config(ServiceInfo.ID, configuration); var builder = new ContainerBuilder(); // Register configuration interfaces builder.RegisterInstance(config) .AsImplementedInterfaces().SingleInstance(); // register logger builder.RegisterLogger(LogEx.Console()); // Register http client module builder.RegisterModule <HttpClientModule>(); #if DEBUG builder.RegisterType <NoOpCertValidator>() .AsImplementedInterfaces(); #endif // Iot hub services builder.RegisterType <IoTHubServiceHttpClient>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <IoTHubTwinMethodClient>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <ChunkMethodClient>() .AsImplementedInterfaces().SingleInstance(); // Event processor services builder.RegisterType <EventProcessorHost>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <EventProcessorFactory>() .AsImplementedInterfaces().SingleInstance(); // Handle device events builder.RegisterType <IoTHubDeviceEventHandler>() .AsImplementedInterfaces().SingleInstance(); // Including discovery events builder.RegisterType <DiscoveryEventHandler>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <DiscoveryRequestHandler>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <TaskProcessor>() .AsImplementedInterfaces().SingleInstance(); // And fleet discovery and activation builder.RegisterType <RegistryServices>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <ActivationClient>() .AsImplementedInterfaces().SingleInstance(); #if USE_JOBS builder.RegisterType <DiscoveryJobClient>() .AsImplementedInterfaces().SingleInstance(); #else builder.RegisterType <DiscoveryServices>() .AsImplementedInterfaces().SingleInstance(); builder.RegisterType <DiscoveryClient>() .AsImplementedInterfaces().SingleInstance(); #endif return(builder); }