public async Task <Device> GetAsync(string deviceId, bool loadTwin, CancellationToken cancellationToken)
        {
            Device result = null;

            try
            {
                Azure.Devices.Device device = null;
                Twin twin = null;

                if (loadTwin)
                {
                    var deviceTask = this.rateLimiting.LimitRegistryOperationsAsync(
                        () => this.registry.GetDeviceAsync(deviceId, cancellationToken));

                    var twinTask = this.rateLimiting.LimitTwinReadsAsync(
                        () => this.registry.GetTwinAsync(deviceId, cancellationToken));

                    await Task.WhenAll(deviceTask, twinTask);

                    device = deviceTask.Result;
                    twin   = twinTask.Result;
                }
                else
                {
                    device = await this.rateLimiting.LimitRegistryOperationsAsync(
                        () => this.registry.GetDeviceAsync(deviceId, cancellationToken));
                }

                if (device != null)
                {
                    result = new Device(device, twin, this.ioTHubHostName);
                }
            }
            catch (Exception e)
            {
                if (e.InnerException != null && e.InnerException.GetType() == typeof(TaskCanceledException))
                {
                    // We get here when the cancellation token is triggered, which is fine
                    this.log.Debug("Get device task canceled", () => new { deviceId, e.Message });
                    return(null);
                }

                this.log.Error("Unable to fetch the IoT device", () => new { deviceId, e });
                throw new ExternalDependencyException("Unable to fetch the IoT device.");
            }

            if (result == null)
            {
                throw new ResourceNotFoundException("The device doesn't exist.");
            }

            return(result);
        }
        /// <summary>
        /// Get a client for the device
        /// </summary>
        public IDeviceClient GetClient(Device device, IoTHubProtocol protocol, IScriptInterpreter scriptInterpreter)
        {
            this.SetupHub();

            var sdkClient = this.GetDeviceSdkClient(device, protocol);
            var methods   = new DeviceMethods(sdkClient, this.log, scriptInterpreter);

            return(new DeviceClient(
                       device.Id,
                       protocol,
                       sdkClient,
                       methods,
                       this.log));
        }
Beispiel #3
0
        // Get a client for the device
        public IDeviceClient GetClient(Device device, IoTHubProtocol protocol, IScriptInterpreter scriptInterpreter)
        {
            this.instance.InitRequired();

            var sdkClient = this.GetDeviceSdkClient(device, protocol);
            var methods   = new DeviceMethods(sdkClient, this.log, this.diagnosticsLogger, scriptInterpreter);

            return(new DeviceClient(
                       device.Id,
                       protocol,
                       sdkClient,
                       methods,
                       this.log));
        }
Beispiel #4
0
        // Get a client for the device
        public IDeviceClient GetClient(Device device, IoTHubProtocol protocol)
        {
            this.instance.InitRequired();

            IDeviceClientWrapper sdkClient = this.GetDeviceSdkClient(device, protocol);
            var methods = new DeviceMethods(this.config, this.log, this.diagnosticsLogger);

            return(new DeviceClient(
                       device.Id,
                       protocol,
                       sdkClient,
                       methods,
                       this.config,
                       this.log));
        }
Beispiel #5
0
        private IDeviceClientWrapper GetDeviceSdkClient(Device device, IoTHubProtocol protocol)
        {
            var connectionString = $"HostName={device.IoTHubHostName};DeviceId={device.Id};SharedAccessKey={device.AuthPrimaryKey}";
            var userAgent        = config.UserAgent;

            IDeviceClientWrapper sdkClient;

            switch (protocol)
            {
            case IoTHubProtocol.AMQP:
                this.log.Debug("Creating AMQP device client",
                               () => new { device.Id, device.IoTHubHostName });

                sdkClient = this.deviceClient.CreateFromConnectionString(connectionString, TransportType.Amqp_Tcp_Only, userAgent);
                break;

            case IoTHubProtocol.MQTT:
                this.log.Debug("Creating MQTT device client",
                               () => new { device.Id, device.IoTHubHostName });

                sdkClient = this.deviceClient.CreateFromConnectionString(connectionString, TransportType.Mqtt_Tcp_Only, userAgent);
                break;

            case IoTHubProtocol.HTTP:
                this.log.Debug("Creating HTTP device client",
                               () => new { device.Id, device.IoTHubHostName });

                sdkClient = this.deviceClient.CreateFromConnectionString(connectionString, TransportType.Http1, userAgent);
                break;

            default:
                this.log.Error("Unable to create a client for the given protocol",
                               () => new { protocol });

                throw new InvalidConfigurationException($"Unable to create a client for the given protocol ({protocol})");
            }

            sdkClient.DisableRetryPolicy();
            if (this.config.IoTHubSdkDeviceClientTimeout.HasValue)
            {
                sdkClient.OperationTimeoutInMilliseconds = this.config.IoTHubSdkDeviceClientTimeout.Value;
            }

            return(sdkClient);
        }
Beispiel #6
0
        private Azure.Devices.Client.DeviceClient GetDeviceSdkClient(Device device, IoTHubProtocol protocol)
        {
            var connectionString = $"HostName={device.IoTHubHostName};DeviceId={device.Id};SharedAccessKey={device.AuthPrimaryKey}";

            Azure.Devices.Client.DeviceClient sdkClient;
            switch (protocol)
            {
            case IoTHubProtocol.AMQP:
                this.log.Debug("Creating AMQP device client",
                               () => new { device.Id, device.IoTHubHostName });

                sdkClient = Azure.Devices.Client.DeviceClient.CreateFromConnectionString(connectionString, TransportType.Amqp_Tcp_Only);
                break;

            case IoTHubProtocol.MQTT:
                this.log.Debug("Creating MQTT device client",
                               () => new { device.Id, device.IoTHubHostName });

                sdkClient = Azure.Devices.Client.DeviceClient.CreateFromConnectionString(connectionString, TransportType.Mqtt_Tcp_Only);
                break;

            case IoTHubProtocol.HTTP:
                this.log.Debug("Creating HTTP device client",
                               () => new { device.Id, device.IoTHubHostName });

                sdkClient = Azure.Devices.Client.DeviceClient.CreateFromConnectionString(connectionString, TransportType.Http1);
                break;

            default:
                this.log.Error("Unable to create a client for the given protocol",
                               () => new { protocol });

                throw new InvalidConfigurationException($"Unable to create a client for the given protocol ({protocol})");
            }

            sdkClient.SetRetryPolicy(new Azure.Devices.Client.NoRetry());

            // When sending telemetry or other operations, wait only for preconfigured number of milliseconds.
            // This setting sets how throttling affects the application. The default SDK value is 4 minutes,
            // that causes high CPU usage. However extreme lower values such as 10000 milliseconds causes
            // memory leaks leading to simulator crashing and termination of telemetry.
            sdkClient.OperationTimeoutInMilliseconds = (uint)this.servicesConfig.IoTSdkConnectTimeout;

            return(sdkClient);
        }
Beispiel #7
0
        // Get the device from the registry
        public async Task <Device> GetAsync(string deviceId)
        {
            this.instance.InitRequired();

            this.log.Debug("Fetching device from registry", () => new { deviceId });

            var start = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            long GetTimeSpentMsecs() => DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - start;

            Device result = null;

            try
            {
                Azure.Devices.Device device = await this.registry.GetDeviceAsync(deviceId);

                if (device != null)
                {
                    result = new Device(device, this.ioTHubHostName);
                }
                else
                {
                    var timeSpentMsecs = GetTimeSpentMsecs();
                    this.log.Debug("Device not found", () => new { timeSpentMsecs, deviceId });
                }
            }
            catch (Exception e) when(e is TaskCanceledException || e.InnerException is TaskCanceledException)
            {
                var timeSpentMsecs = GetTimeSpentMsecs();

                this.log.Error("Get device task timed out", () => new { timeSpentMsecs, deviceId, e.Message });

                throw new ExternalDependencyException("Get device task timed out", e);
            }
            catch (Exception e)
            {
                var          timeSpentMsecs = GetTimeSpentMsecs();
                const string MSG            = "Unable to fetch the IoT device";
                this.log.Error(MSG, () => new { timeSpentMsecs, deviceId, e });
                this.diagnosticsLogger.LogServiceError(MSG, new { timeSpentMsecs, deviceId, e.Message });
                throw new ExternalDependencyException(MSG);
            }

            return(result);
        }
        private Azure.Devices.Client.DeviceClient GetDeviceSdkClient(Device device, IoTHubProtocol protocol)
        {
            var connectionString = $"HostName={device.IoTHubHostName};DeviceId={device.Id};SharedAccessKey={device.AuthPrimaryKey}";

            Azure.Devices.Client.DeviceClient sdkClient;
            switch (protocol)
            {
            case IoTHubProtocol.AMQP:
                this.log.Debug("Creating AMQP device client",
                               () => new { device.Id, device.IoTHubHostName });

                sdkClient = Azure.Devices.Client.DeviceClient.CreateFromConnectionString(connectionString, TransportType.Amqp_Tcp_Only);
                break;

            case IoTHubProtocol.MQTT:
                this.log.Debug("Creating MQTT device client",
                               () => new { device.Id, device.IoTHubHostName });

                sdkClient = Azure.Devices.Client.DeviceClient.CreateFromConnectionString(connectionString, TransportType.Mqtt_Tcp_Only);
                break;

            case IoTHubProtocol.HTTP:
                this.log.Debug("Creating HTTP device client",
                               () => new { device.Id, device.IoTHubHostName });

                sdkClient = Azure.Devices.Client.DeviceClient.CreateFromConnectionString(connectionString, TransportType.Http1);
                break;

            default:
                this.log.Error("Unable to create a client for the given protocol",
                               () => new { protocol });

                throw new InvalidConfigurationException($"Unable to create a client for the given protocol ({protocol})");
            }

            sdkClient.SetRetryPolicy(new NoRetry());
            sdkClient.OperationTimeoutInMilliseconds = SDK_CLIENT_TIMEOUT;

            return(sdkClient);
        }
        /// <summary>
        /// Get the device from the registry
        /// </summary>
        public async Task <Device> GetAsync(string deviceId)
        {
            this.SetupHub();

            this.log.Debug("Fetching device from registry", () => new { deviceId });

            Device result = null;
            var    now    = DateTimeOffset.UtcNow;

            try
            {
                var device = await this.GetRegistry().GetDeviceAsync(deviceId);

                if (device != null)
                {
                    result = new Device(device, this.ioTHubHostName);
                }
                else
                {
                    this.log.Debug("Device not found", () => new { deviceId });
                }
            }
            catch (Exception e)
            {
                if (e.InnerException != null && e.InnerException.GetType() == typeof(TaskCanceledException))
                {
                    var timeSpent = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - now.ToUnixTimeMilliseconds();
                    this.log.Error("Get device task timed out", () => new { timeSpent, deviceId, e.Message });
                    throw;
                }

                this.log.Error("Unable to fetch the IoT device", () => new { deviceId, e });
                throw new ExternalDependencyException("Unable to fetch the IoT device");
            }

            return(result);
        }