static DPSSettings ParseCommandParameters(string[] args) { DPSSettings result = null; if (args != null && args.Length > 0) { var parsingResult = Parser.Default.ParseArguments <DPSSymmetricKeyCommandParameters, DPSCAX509CommandParameters>(args); if (parsingResult != null && parsingResult.Tag == ParserResultType.Parsed) { result = parsingResult .MapResult <DPSSymmetricKeyCommandParameters, DPSCAX509CommandParameters, DPSSettings>( (DPSSymmetricKeyCommandParameters options) => ProcessSymmetricKeyOptions(options), (DPSCAX509CommandParameters options) => ProcessCAX509Options(options), errors => ProcessErrors(errors) ); } else { Environment.Exit(1); } } return(result); }
public static async Task WriteDpsSettings(DPSSettings content, string environment) { string fileName = $"{DPS_SETTINGS_FILE_NAME}.json"; if (!string.IsNullOrEmpty(environment)) { fileName = $"{DPS_SETTINGS_FILE_NAME}.{environment}.json"; } await WriteSettings(JsonConvert.SerializeObject(content, Formatting.Indented), fileName); }
/// <summary> /// Parses and types command parameters. /// </summary> /// <returns></returns> static DPSSettings LoadDPSOptionsFromCommandParameters() { DPSSettings settings = null; string[] args = Environment.GetCommandLineArgs(); if (args != null && args.Length > 1) { if (args.First().Contains(".dll")) { settings = ParseCommandParameters(args.Skip(1).ToArray()); } } return(settings); }
/// <summary> /// Checks and loads the DPS settings, as .NET IOptions. /// </summary> /// <param name="services"></param> /// <param name="configuration"></param> /// <param name="args"></param> /// <param name="_environmentName"></param> private static DPSSettings LoadDPSandProvisioningSettings(IServiceCollection services, IConfiguration configuration, string environmentName) { DPSSettings dpsEnvironmentSettings = LoadDPSOptionsFromEnvironmentVariables(); DPSSettings dpsCommandSettings = LoadDPSOptionsFromCommandParameters(); //Overwriting process in among environment, command and file settings DPSSettings dpsSettings = dpsEnvironmentSettings; if (dpsCommandSettings != null) { dpsSettings = dpsCommandSettings; } if (dpsSettings == null) { //WARNING: it seems that IOptions do not work properly with default deserializers string dpsSettingsJson = File.ReadAllText($"dpssettings.json"); if (File.Exists($"dpssettings.{environmentName}.json")) { dpsSettingsJson = File.ReadAllText($"dpssettings.{ environmentName}.json"); } if (!string.IsNullOrEmpty(dpsSettingsJson)) { JObject jData = JObject.Parse(dpsSettingsJson); if (jData != null && jData.ContainsKey(DPSSettings.DPSSettingsSection)) { dpsSettings = jData[DPSSettings.DPSSettingsSection].ToObject <DPSSettings>(); } } } //IF any DPS setting is found, it is bound as .NET IOptions. if (dpsSettings != null) { var dpsSettingsOptions = Options.Create(dpsSettings); services.AddSingleton(dpsSettingsOptions); configuration.Bind(DPSSettings.DPSSettingsSection, dpsSettingsOptions); } else { throw new Exception("No DPS settings have been provided (Environment variables, command parameters or settings files)."); } return(dpsSettings); }
static DPSSettings ProcessSymmetricKeyOptions(DPSSymmetricKeyCommandParameters parameters) { DPSSettings settings = new DPSSettings(); settings.EnrollmentType = EnrollmentType.Group; settings.GroupEnrollment = new GroupEnrollmentSettings(); settings.GroupEnrollment.SecurityType = SecurityType.SymmetricKey; settings.GroupEnrollment.SymmetricKeySettings = new DPSSymmetricKeySettings(); settings.GroupEnrollment.SymmetricKeySettings.TransportType = parameters.TransportType; settings.GroupEnrollment.SymmetricKeySettings.EnrollmentType = settings.EnrollmentType; settings.GroupEnrollment.SymmetricKeySettings.IdScope = parameters.IdScope; settings.GroupEnrollment.SymmetricKeySettings.PrimaryKey = parameters.PrimaryKey; return(settings); }
static DPSSettings ProcessCAX509Options(DPSCAX509CommandParameters parameters) { DPSSettings settings = new DPSSettings(); settings.EnrollmentType = EnrollmentType.Group; settings.GroupEnrollment = new GroupEnrollmentSettings(); settings.GroupEnrollment.SecurityType = SecurityType.X509CA; settings.GroupEnrollment.CAX509Settings = new DPSCAX509Settings(); settings.GroupEnrollment.CAX509Settings.TransportType = parameters.TransportType; settings.GroupEnrollment.CAX509Settings.EnrollmentType = settings.EnrollmentType; settings.GroupEnrollment.CAX509Settings.IdScope = parameters.IdScope; settings.GroupEnrollment.CAX509Settings.DeviceX509Path = parameters.DeviceCertificatePath; settings.GroupEnrollment.CAX509Settings.Password = parameters.DeviceCertificatePassword; return(settings); }
public DPSProvisioningServiceSymmetricKey( IOptions <AppSettings> appSettings, IOptions <DPSSettings> dpsSettings, IOptionsMonitor <DeviceSettings> deviceSettingsDelegate, ILoggerFactory loggerFactory) { if (appSettings == null) { throw new ArgumentNullException(nameof(appSettings)); } if (deviceSettingsDelegate == null) { throw new ArgumentNullException(nameof(deviceSettingsDelegate)); } if (dpsSettings == null) { throw new ArgumentNullException(nameof(dpsSettings)); } if (dpsSettings.Value == null) { throw new ArgumentNullException("dpsSettings.Value", "No device configuration has been loaded."); } if (loggerFactory == null) { throw new ArgumentNullException(nameof(loggerFactory), "No logger factory has been provided."); } _appSettings = appSettings.Value; _dpsSettings = dpsSettings.Value; _deviceSettingsDelegate = deviceSettingsDelegate; _logger = loggerFactory.CreateLogger <DPSProvisioningServiceSymmetricKey>(); string logPrefix = "system.dps.provisioning".BuildLogPrefix(); _logger.LogDebug($"{logPrefix}::{_deviceSettingsDelegate.CurrentValue.ArtifactId}::Logger created."); _logger.LogDebug($"{logPrefix}::{_deviceSettingsDelegate.CurrentValue.ArtifactId}::DPS Provisioning service created."); }
static void RegisterDeviceSimulators(IServiceCollection services, DPSSettings dpsSettings) { if (services == null) { throw new ArgumentNullException(nameof(services)); } if (dpsSettings == null) { throw new ArgumentNullException(nameof(dpsSettings)); } if (dpsSettings.GroupEnrollment != null) { if (dpsSettings.GroupEnrollment.SecurityType == SecurityType.X509CA) { if (dpsSettings.GroupEnrollment.CAX509Settings != null) { services.AddSingleton <IProvisioningService, DPSProvisioningServiceX509CA>(); } else { throw new Exception("RegisterDeviceSimulators::Missing CA X509 Settings"); } } else if (dpsSettings.GroupEnrollment.SecurityType == SecurityType.SymmetricKey) { if (dpsSettings.GroupEnrollment.SymmetricKeySettings != null) { services.AddSingleton <IProvisioningService, DPSProvisioningServiceSymmetricKey>(); } else { throw new Exception("RegisterDeviceSimulators::Missing Symmetric Key Settings"); } } } services.AddSingleton <ISimulationService, DeviceSimulationService>(); }
public DeviceSimulationService( IOptionsMonitor <DeviceSettings> deviceSettingsDelegate, IOptions <DPSSettings> dpsSettings, ITelemetryMessageService telemetryMessagingService, IErrorMessageService errorMessagingService, ICommissioningMessageService commissioningMessagingService, IProvisioningService provisioningService, ILoggerFactory loggerFactory) { if (deviceSettingsDelegate == null) { throw new ArgumentNullException(nameof(deviceSettingsDelegate)); } if (deviceSettingsDelegate.CurrentValue == null) { throw new ArgumentNullException("deviceSettingsDelegate.CurrentValue"); } if (deviceSettingsDelegate.CurrentValue.SimulationSettings == null) { throw new ArgumentNullException("deviceSettingsDelegate.CurrentValue.SimulationSettings"); } if (dpsSettings == null) { throw new ArgumentNullException(nameof(dpsSettings)); } if (dpsSettings.Value == null) { throw new ArgumentNullException("dpsSettings.Value"); } if (telemetryMessagingService == null) { throw new ArgumentNullException(nameof(telemetryMessagingService)); } if (errorMessagingService == null) { throw new ArgumentNullException(nameof(errorMessagingService)); } if (commissioningMessagingService == null) { throw new ArgumentNullException(nameof(commissioningMessagingService)); } if (provisioningService == null) { throw new ArgumentNullException(nameof(provisioningService)); } if (loggerFactory == null) { throw new ArgumentNullException(nameof(loggerFactory), "No logger factory has been provided."); } _deviceSettingsDelegate = deviceSettingsDelegate; _simulationSettings = _deviceSettingsDelegate.CurrentValue.SimulationSettings; _dpsSettings = dpsSettings.Value; //_deviceId = _deviceSettingsDelegate.CurrentValue.DeviceId; _iotHub = _deviceSettingsDelegate.CurrentValue.HostName; _telemetryInterval = _simulationSettings.TelemetryFrecuency; _logger = loggerFactory.CreateLogger <DeviceSimulationService>(); _telemetryMessagingService = telemetryMessagingService; _errorMessagingService = errorMessagingService; _commissioningMessagingService = commissioningMessagingService; _provisioningService = provisioningService; _environmentName = Environment.GetEnvironmentVariable("ENVIRONMENT"); string logPrefix = "system".BuildLogPrefix(); _logger.LogDebug($"{logPrefix}::{_deviceSettingsDelegate.CurrentValue.ArtifactId}::Logger created."); _logger.LogDebug($"{logPrefix}::{_deviceSettingsDelegate.CurrentValue.ArtifactId}::Device simulator created."); _logger.LogDebug($"{logPrefix}::{_deviceSettingsDelegate.CurrentValue.ArtifactId}::Enrollment type:{_dpsSettings.EnrollmentType.ToString()}."); _logger.LogDebug($"{logPrefix}::{_deviceSettingsDelegate.CurrentValue.ArtifactId}::Security type:{_dpsSettings.GroupEnrollment?.SecurityType.ToString()}."); }
//TODO: take into account the CA X509 settings static void RegisterModuleSimulators(DeviceSettings deviceSettings, IServiceCollection services, DPSSettings dpsSettings) { if (deviceSettings == null) { throw new ArgumentNullException(nameof(deviceSettings)); } if (deviceSettings.SimulationSettings == null) { throw new ArgumentNullException("No device simulation configuration has been configured."); } if (services == null) { throw new ArgumentNullException(nameof(services)); } if (dpsSettings == null) { throw new ArgumentNullException(nameof(dpsSettings)); } if (deviceSettings.SimulationSettings.EnableModules) { var modules = Configuration.Get <ModulesSettings>(); if (modules != null && modules.Modules != null && modules.Modules.Any()) { IServiceProvider serviceProvider = services.BuildServiceProvider(); if (serviceProvider == null) { throw new ApplicationException("IServiceProvider has not been resolved."); } ILoggerFactory loggerFactory = serviceProvider.GetService <ILoggerFactory>(); if (loggerFactory == null) { throw new ApplicationException("ILoggerFactory has not been resolved."); } foreach (var item in modules.Modules) { var simulator = new ModuleSimulationService( item, serviceProvider.GetService <ITelemetryMessageService>(), serviceProvider.GetService <IErrorMessageService>(), serviceProvider.GetService <ICommissioningMessageService>(), serviceProvider.GetService <IProvisioningService>(), loggerFactory); services.AddSingleton <IModuleSimulationService, ModuleSimulationService>(iServiceProvider => simulator); } } } }
/// <summary> /// Gets DPS parameters from environment variables. /// </summary> static DPSSettings LoadDPSOptionsFromEnvironmentVariables() { DPSSettings settings = null; var localVariables = Environment.GetEnvironmentVariables(); if (localVariables != null && localVariables.Count >= 2) { //Transport type string transportType = Environment.GetEnvironmentVariable("TRANSPORT_TYPE"); if (!string.IsNullOrEmpty(transportType)) { if (transportType.Trim().ToLower() != "mqtt") { throw new NotImplementedException("Only MQTT has been fully tested."); } string securityType = Environment.GetEnvironmentVariable("DPS_SECURITY_TYPE"); string idScope = Environment.GetEnvironmentVariable("DPS_IDSCOPE"); settings = new DPSSettings(); settings.EnrollmentType = EnrollmentType.Group; settings.GroupEnrollment = new GroupEnrollmentSettings(); TransportType typedTransportType = Enum.Parse <TransportType>(transportType); switch (Enum.Parse <SecurityType>(securityType)) { case SecurityType.SymmetricKey: string primarySymmetricKey = Environment.GetEnvironmentVariable("PRIMARY_SYMMETRIC_KEY"); if (!string.IsNullOrEmpty(primarySymmetricKey)) { settings.GroupEnrollment.SecurityType = SecurityType.SymmetricKey; settings.GroupEnrollment.SymmetricKeySettings = new DPSSymmetricKeySettings(); settings.GroupEnrollment.SymmetricKeySettings.TransportType = typedTransportType; settings.GroupEnrollment.SymmetricKeySettings.EnrollmentType = EnrollmentType.Group; settings.GroupEnrollment.SymmetricKeySettings.IdScope = idScope; settings.GroupEnrollment.SymmetricKeySettings.PrimaryKey = primarySymmetricKey; } break; case SecurityType.X509CA: string certificatePath = Environment.GetEnvironmentVariable("DEVICE_CERTIFICATE_PATH"); if (!string.IsNullOrEmpty(certificatePath)) { settings.GroupEnrollment.SecurityType = SecurityType.X509CA; settings.GroupEnrollment.CAX509Settings = new DPSCAX509Settings(); settings.GroupEnrollment.CAX509Settings.TransportType = typedTransportType; settings.GroupEnrollment.CAX509Settings.EnrollmentType = EnrollmentType.Group; settings.GroupEnrollment.CAX509Settings.IdScope = idScope; settings.GroupEnrollment.CAX509Settings.DeviceX509Path = certificatePath; settings.GroupEnrollment.CAX509Settings.Password = Environment.GetEnvironmentVariable("DEVICE_CERTIFICATE_PASSWORD"); } break; default: break; } } } return(settings); }
private static async Task Main(string[] args) { Console.WriteLine("======================================================================="); Console.WriteLine(AssemblyInformationHelper.HeaderMessage); Console.WriteLine("======================================================================="); Console.WriteLine(">> Loading configurations...."); try { //Loading environment related settings _environmentName = Environment.GetEnvironmentVariable("ENVIRONMENT"); // Environment device Id check await CheckEnvironmentDeviceId(_environmentName); //Configuration var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile("devicesettings.json", optional: false, reloadOnChange: true) .AddJsonFile("modulessettings.json", optional: true, reloadOnChange: true) .AddJsonFile("dpssettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables(); if (string.IsNullOrWhiteSpace(_environmentName)) { Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("No environment platform has been found. Default setting: Development."); _environmentName = "Development"; Console.ResetColor(); } try { ConfigurationHelpers.CheckEnvironmentConfigurationFiles(_environmentName); builder.AddJsonFile($"appsettings.{_environmentName}.json", optional: true, reloadOnChange: true); builder.AddJsonFile($"devicesettings.{_environmentName}.json", optional: true, reloadOnChange: true); builder.AddJsonFile($"modulessettings.{_environmentName}.json", optional: true, reloadOnChange: true); builder.AddJsonFile($"dpssettings.{_environmentName}.json", optional: true, reloadOnChange: true); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine($"Environment related files loaded for: '{_environmentName}'."); Console.ResetColor(); } catch (MissingEnvironmentConfigurationFileException ex) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(ex.Message); Console.ResetColor(); Console.WriteLine("Execution will continue with default settings in appsettings.json, devicesettings.json and modulessettings.json."); } Configuration = builder.Build(); //Service provider and DI IServiceCollection services = new ServiceCollection(); ConfigureServices(services); //DPS and provisioning DPSSettings dpsSettings = LoadDPSandProvisioningSettings(services, Configuration, _environmentName); //Device related settings var deviceSettings = Configuration.Get <DeviceSettings>(); if (deviceSettings == null) { throw new ArgumentException("No device settings have been configured."); } if (string.IsNullOrEmpty(deviceSettings.DeviceId)) { throw new ArgumentException("No device id has been found."); } if (deviceSettings.SimulationSettings == null) { throw new ArgumentException("No device simulation settings have been configured."); } if (deviceSettings.SimulationSettings.EnableDevice || deviceSettings.SimulationSettings.EnableModules) { //If any of the simulators is enabled, messaging services will be required to build the messages. RegisterMessagingServices(services); } if (deviceSettings.SimulationSettings.EnableDevice) { RegisterDeviceSimulators(services, dpsSettings); } if (deviceSettings.SimulationSettings.EnableModules) { RegisterModuleSimulators(deviceSettings, services, dpsSettings); } IServiceProvider serviceProvider = services.BuildServiceProvider(); //Logger var logger = serviceProvider.GetService <ILoggerFactory>().CreateLogger <Program>(); logger.LogDebug("PROGRAM::Settings, DI and logger configured and ready to use."); //Simulators if (!deviceSettings.SimulationSettings.EnableDevice && !deviceSettings.SimulationSettings.EnableModules) { logger.LogDebug("PROGRAM::No simulator has been configured."); } else { if (deviceSettings.SimulationSettings.EnableDevice) { await StartDevicesSimulatorsAsync(serviceProvider, logger); } if (deviceSettings.SimulationSettings.EnableModules) { StartModulesSimulators(serviceProvider, logger); } } } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(ex.Message); Console.ResetColor(); } finally { Console.ReadLine(); } }