public void CreateInitialDataIfNeeded()
        {
            try
            {
                bool initializationNeeded = false;

                // only create default data if the action mappings are missing

                // check if any devices are there
                Task <bool> .Run(async() => initializationNeeded = (await _virtualDeviceStorage.GetDeviceListAsync()).Count == 0).Wait();

                if (!initializationNeeded)
                {
                    Trace.TraceInformation("No initial data needed.");
                    return;
                }

                Trace.TraceInformation("Beginning initial data creation...");

                List <string> bootstrappedDevices = null;

                // create default devices
                Task.Run(async() => bootstrappedDevices = await BootstrapDefaultDevices()).Wait();

                Trace.TraceInformation("Initial data creation completed.");
            }
            catch (Exception ex)
            {
                Trace.TraceError("Failed to create initial default data: {0}", ex.ToString());
            }
        }
        /// <summary>
        /// Retrieves a set of device configs from the repository and creates devices with this information
        /// Once the devices are built, they are started
        /// </summary>
        /// <param name="token"></param>
        public async Task ProcessDevicesAsync(CancellationToken token)
        {
            var dm = new DeviceManager(_logger, token);

            try
            {
                _logger.LogInfo("********** Starting Simulator **********");
                while (!token.IsCancellationRequested)
                {
                    var devices = await _deviceStorage.GetDeviceListAsync();

                    var liveDevices = dm.GetLiveDevices();

                    var newDevices     = devices.Where(d => !liveDevices.Contains(d.DeviceId)).ToList();
                    var removedDevices = liveDevices.Where(d => !devices.Any(x => x.DeviceId == d)).ToList();

                    if (removedDevices.Any())
                    {
                        _logger.LogInfo("********** {0} DEVICES REMOVED ********** ", removedDevices.Count);

                        dm.StopDevices(removedDevices);
                    }

                    //begin processing any new devices that were retrieved
                    if (newDevices.Any())
                    {
                        _logger.LogInfo("********** {0} NEW DEVICES FOUND ********** ", newDevices.Count);

                        var devicesToProcess = new List <IDevice>();

                        foreach (var deviceConfig in newDevices)
                        {
                            _logger.LogInfo("********** SETTING UP NEW DEVICE : {0} ********** ", deviceConfig.DeviceId);
                            devicesToProcess.Add(_deviceFactory.CreateDevice(_logger, _transportFactory, _telemetryFactory, _configProvider, deviceConfig));
                        }

                        dm.StartDevices(devicesToProcess);
                    }

                    await Task.Delay(TimeSpan.FromSeconds(_devicePollIntervalSeconds), token);
                }
            }
            catch (TaskCanceledException)
            {
                //do nothing if task was cancelled
                _logger.LogInfo("********** Primary worker role cancellation token source has been cancelled. **********");
            }
            finally
            {
                //ensure that all devices have been stopped
                dm.StopAllDevices();
            }
        }
        public async void GetDeviceListAsync()
        {
            var deviceEntities = _fixture.Create <List <DeviceListEntity> >();

            _tableStorageClientMock.Setup(x => x.ExecuteQueryAsync(It.IsNotNull <TableQuery <DeviceListEntity> >()))
            .ReturnsAsync(deviceEntities);
            var ret = await _virtualDeviceStorage.GetDeviceListAsync();

            Assert.NotNull(ret);
            Assert.Equal(deviceEntities.Count, ret.Count);
            Assert.Equal(deviceEntities[0].DeviceId, ret[0].DeviceId);
            Assert.Equal(deviceEntities[0].HostName, ret[0].HostName);
            Assert.Equal(deviceEntities[0].Key, ret[0].Key);
        }
        /// <summary>
        /// Retrieves a set of device configs from the repository and creates devices with this information
        /// Once the devices are built, they are started
        /// </summary>
        /// <param name="token"></param>
        public async Task ProcessDevicesAsync(CancellationToken token)
        {
            var dm = new DeviceManager(_logger, token);

            try
            {
                _logger.LogInfo("********** Starting Simulator **********");
                while (!token.IsCancellationRequested)
                {
                    var newDevices     = new List <InitialDeviceConfig>();
                    var removedDevices = new List <string>();
                    var devices        = await _deviceStorage.GetDeviceListAsync();

                    if (devices != null && devices.Any())
                    {
                        newDevices     = devices.Where(d => !_deviceList.Any(x => x.DeviceId == d.DeviceId)).ToList();
                        removedDevices =
                            _deviceList.Where(d => !devices.Any(x => x.DeviceId == d.DeviceId))
                            .Select(x => x.DeviceId)
                            .ToList();
                    }
                    else if (_deviceList != null && _deviceList.Any())
                    {
                        removedDevices = _deviceList.Select(x => x.DeviceId).ToList();
                    }

                    if (newDevices.Count > 0)
                    {
                        _logger.LogInfo("********** {0} NEW DEVICES FOUND ********** ", newDevices.Count);
                    }
                    if (removedDevices.Count > 0)
                    {
                        _logger.LogInfo("********** {0} DEVICES REMOVED ********** ", removedDevices.Count);
                    }


                    //reset the base list of devices for comparison the next
                    //time we retrieve the device list
                    _deviceList = devices;

                    if (removedDevices.Any())
                    {
                        //stop processing any devices that have been removed
                        dm.StopDevices(removedDevices);
                    }

                    //begin processing any new devices that were retrieved
                    if (newDevices.Any())
                    {
                        var devicesToProcess = new List <IDevice>();

                        foreach (var deviceConfig in newDevices)
                        {
                            _logger.LogInfo("********** SETTING UP NEW DEVICE : {0} ********** ", deviceConfig.DeviceId);
                            devicesToProcess.Add(_deviceFactory.CreateDevice(_logger, _transportFactory, _telemetryFactory, _configProvider, deviceConfig));
                        }

#pragma warning disable 4014
                        //don't wait for this to finish
                        dm.StartDevicesAsync(devicesToProcess);
#pragma warning restore 4014
                    }
                    await Task.Delay(TimeSpan.FromSeconds(_devicePollIntervalSeconds), token);
                }
            }
            catch (TaskCanceledException)
            {
                //do nothing if task was cancelled
                _logger.LogInfo("********** Primary worker role cancellation token source has been cancelled. **********");
            }
            finally
            {
                //ensure that all devices have been stopped
                dm.StopAllDevices();
            }
        }