/// <summary> /// Removes a device from the underlying repositories /// </summary> /// <param name="deviceId">ID of the device to remove</param> /// <returns></returns> public async Task RemoveDeviceAsync(string deviceId) { ExceptionDispatchInfo capturedException = null; Azure.Devices.Device iotHubDevice = await _iotHubRepository.GetIotHubDeviceAsync(deviceId); // if the device isn't already in the IotHub throw an exception and let the caller know if (iotHubDevice == null) { throw new DeviceNotRegisteredException(deviceId); } // Attempt to remove the device from the IotHub. If this fails an exception will be thrown // and the remainder of the code not run, which is by design await _iotHubRepository.RemoveDeviceAsync(deviceId); try { await _deviceRegistryCrudRepository.RemoveDeviceAsync(deviceId); } catch (Exception ex) { // if there is an exception while attempting to remove the device from the Device Registry // capture it so a rollback can be done on the Identity Registry capturedException = ExceptionDispatchInfo.Capture(ex); } if (capturedException == null) { try { await _virtualDeviceStorage.RemoveDeviceAsync(deviceId); } catch (Exception ex) { //if an exception occurs while attempting to remove the //simulated device from table storage do not roll back the changes. Trace.TraceError("Failed to remove simulated device : {0}", ex.Message); } await _deviceRulesLogic.RemoveAllRulesForDeviceAsync(deviceId); } else { // The "rollback" is an attempt to add the device back in to the Identity Registry // It is assumed that if an exception has occured in the Device Registry, the device // is still in that store and this works to ensure that both repositories have the same // devices registered // A more robust rollback may be needed in some scenarios. await _iotHubRepository.TryAddDeviceAsync(iotHubDevice); capturedException.Throw(); } }
public async void RemoveDeviceAsyncTest() { var entities = _fixture.Create <List <DeviceListEntity> >(); _tableStorageClientMock.Setup(x => x.ExecuteQueryAsync(It.IsNotNull <TableQuery <DeviceListEntity> >())) .ReturnsAsync(entities); _tableStorageClientMock.Setup(x => x.ExecuteAsync(It.IsNotNull <TableOperation>())) .ReturnsAsync(new TableResult() { Result = entities[0] }); Assert.True(await _virtualDeviceStorage.RemoveDeviceAsync(entities[0].DeviceId)); }