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);
        }
예제 #2
0
        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>();
        }
예제 #9
0
        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();
            }
        }