public virtual IotHubConnectionStringBuilder Populate(IotHubConnectionStringBuilder iotHubConnectionStringBuilder)
 {
     // intentionally set SharedAccessKeyName to null;
     iotHubConnectionStringBuilder.SharedAccessKeyName = null;
     iotHubConnectionStringBuilder.SharedAccessKey = "CQN2K33r45/0WeIjpqmErV5EIvX8JZrozt3NEHCEkG8=";
     return iotHubConnectionStringBuilder;
 }
 protected DeviceRunner(IEventLoopGroup eventLoopGroup, string deviceKey, string iotHubConnectionString, IPEndPoint endpoint, string tlsHostName)
 {
     this.deviceKey = deviceKey;
     this.endpoint = endpoint;
     this.tlsHostName = tlsHostName;
     this.connectionStringBuilder = IotHubConnectionStringBuilder.Create(iotHubConnectionString.Contains("DeviceId=") ? iotHubConnectionString : iotHubConnectionString + ";DeviceId=abc");
     this.bootstrap = new Bootstrap()
         .Group(eventLoopGroup)
         .Channel<TcpSocketChannel>()
         .Option(ChannelOption.TcpNodelay, false);
 }
        public static IotHubConnectionStringBuilder Create(string hostname, IAuthenticationMethod authenticationMethod)
        {
            var iotHubConnectionStringBuilder = new IotHubConnectionStringBuilder
            {
                HostName = hostname,
                AuthenticationMethod = authenticationMethod
            };

            iotHubConnectionStringBuilder.Validate();

            return iotHubConnectionStringBuilder;
        }
        public static IotHubConnectionStringBuilder Create(string iotHubConnectionString)
        {
            if (string.IsNullOrWhiteSpace(iotHubConnectionString))
            {
                throw new ArgumentNullException("iotHubConnectionString");
            }

            var iotHubConnectionStringBuilder = new IotHubConnectionStringBuilder();        
            iotHubConnectionStringBuilder.Parse(iotHubConnectionString);
            iotHubConnectionStringBuilder.AuthenticationMethod = AuthenticationMethodFactory.GetAuthenticationMethod(iotHubConnectionStringBuilder);

            return iotHubConnectionStringBuilder;
        }
        static internal IAuthenticationMethod GetAuthenticationMethod(IotHubConnectionStringBuilder iotHubConnectionStringBuilder)
        {
            if (string.IsNullOrWhiteSpace(iotHubConnectionStringBuilder.SharedAccessKey))
            {
                return new ServiceAuthenticationWithSharedAccessPolicyToken(iotHubConnectionStringBuilder.SharedAccessKeyName, iotHubConnectionStringBuilder.SharedAccessSignature);
            }
            else if (string.IsNullOrWhiteSpace(iotHubConnectionStringBuilder.SharedAccessSignature))
            {
                return new ServiceAuthenticationWithSharedAccessPolicyKey(iotHubConnectionStringBuilder.SharedAccessKeyName, iotHubConnectionStringBuilder.SharedAccessKey);
            }

            throw new InvalidOperationException("Unsupported Authentication Method {0}".FormatInvariant(iotHubConnectionStringBuilder));
        }
        public IotHubConnectionStringBuilder Populate(IotHubConnectionStringBuilder iotHubConnectionStringBuilder)
        {
            if (iotHubConnectionStringBuilder == null)
            {
                throw new ArgumentNullException("iotHubConnectionStringBuilder");
            }

            iotHubConnectionStringBuilder.SharedAccessKeyName = this.PolicyName;
            iotHubConnectionStringBuilder.SharedAccessSignature = this.Token;
            iotHubConnectionStringBuilder.SharedAccessKey = null;

            return iotHubConnectionStringBuilder;
        }
        public IotHubConnectionString(IotHubConnectionStringBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }

            this.HostName = builder.HostName;
            this.SharedAccessKeyName = builder.SharedAccessKeyName;
            this.SharedAccessKey = builder.SharedAccessKey;
            this.SharedAccessSignature = builder.SharedAccessSignature;
            this.IotHubName = builder.IotHubName;
            this.HttpsEndpoint = new UriBuilder(Uri.UriSchemeHttps, builder.HostName).Uri;
            this.AmqpEndpoint = new UriBuilder(CommonConstants.AmqpsScheme, builder.HostName, AmqpConstants.DefaultSecurePort).Uri;
        }
        public IotHubConnectionString(IotHubConnectionStringBuilder builder)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            this.Audience              = builder.HostName;
            this.HostName              = string.IsNullOrEmpty(builder.GatewayHostName) ? builder.HostName : builder.GatewayHostName;
            this.SharedAccessKeyName   = builder.SharedAccessKeyName;
            this.SharedAccessKey       = builder.SharedAccessKey;
            this.SharedAccessSignature = builder.SharedAccessSignature;
            this.IotHubName            = builder.IotHubName;
            this.HttpsEndpoint         = new UriBuilder("https", this.HostName).Uri;
            this.AmqpEndpoint          = new UriBuilder(CommonConstants.AmqpsScheme, builder.HostName, AmqpConstants.DefaultSecurePort).Uri;
            this.DeviceId              = builder.DeviceId;
            this.ModuleId              = builder.ModuleId;
            this.GatewayHostName       = builder.GatewayHostName;
        }
Ejemplo n.º 9
0
        protected async Task GetOrCreateDeviceIdentityAsync()
        {
            IotHubConnectionStringBuilder builder = IotHubConnectionStringBuilder.Create(this.iothubConnectionString);
            RegistryManager rm = RegistryManager.CreateFromConnectionString(builder.ToString());

            Device device = await rm.GetDeviceAsync(this.deviceId);

            if (device != null)
            {
                Console.WriteLine($"Device '{device.Id}' already registered on IoT hub '{builder.HostName}'");

                if (this.authType == AuthenticationType.SelfSigned)
                {
                    var thumbprints = this.thumbprints.Expect(() => new InvalidOperationException("Missing thumprints list"));
                    if (!thumbprints.Contains(device.Authentication.X509Thumbprint.PrimaryThumbprint) ||
                        !thumbprints.Contains(device.Authentication.X509Thumbprint.SecondaryThumbprint))
                    {
                        // update the thumbprints before attempting to run any tests to ensure consistency
                        device.Authentication.X509Thumbprint = new X509Thumbprint {
                            PrimaryThumbprint = thumbprints[0], SecondaryThumbprint = thumbprints[1]
                        };
                        await rm.UpdateDeviceAsync(device);
                    }
                }

                this.context = new DeviceContext
                {
                    Device = device,
                    IotHubConnectionString = this.iothubConnectionString,
                    RegistryManager        = rm,
                    RemoveDevice           = false,
                    MessageGuid            = Guid.NewGuid().ToString()
                };
            }
            else
            {
                await this.CreateDeviceIdentityAsync(rm);
            }
        }
        static internal IAuthenticationMethod GetAuthenticationMethod(IotHubConnectionStringBuilder iotHubConnectionStringBuilder)
        {
            if (!string.IsNullOrWhiteSpace(iotHubConnectionStringBuilder.DeviceId))
            {
                if (!string.IsNullOrWhiteSpace(iotHubConnectionStringBuilder.SharedAccessKey))
                {
                    return(new ServiceAuthenticationWithDeviceSharedAccessPolicyKey(iotHubConnectionStringBuilder.DeviceId, iotHubConnectionStringBuilder.SharedAccessKey));
                }
                if (!string.IsNullOrWhiteSpace(iotHubConnectionStringBuilder.SharedAccessSignature))
                {
                    return(new ServiceAuthenticationWithDeviceSharedAccessPolicyToken(iotHubConnectionStringBuilder.DeviceId, iotHubConnectionStringBuilder.SharedAccessSignature));
                }
            }
            if (string.IsNullOrWhiteSpace(iotHubConnectionStringBuilder.SharedAccessKey))
            {
                return(new ServiceAuthenticationWithSharedAccessPolicyToken(iotHubConnectionStringBuilder.SharedAccessKeyName, iotHubConnectionStringBuilder.SharedAccessSignature));
            }
            if (string.IsNullOrWhiteSpace(iotHubConnectionStringBuilder.SharedAccessSignature))
            {
                return(new ServiceAuthenticationWithSharedAccessPolicyKey(iotHubConnectionStringBuilder.SharedAccessKeyName, iotHubConnectionStringBuilder.SharedAccessKey));
            }

            throw new InvalidOperationException("Unsupported Authentication Method {0}".FormatInvariant(iotHubConnectionStringBuilder));
        }
Ejemplo n.º 11
0
        private async Task <DeviceClient> GetDeviceClient(string deviceId, CancellationToken cancellationToken)
        {
            if (!DeviceClients.ContainsKey(deviceId))
            {
                // Check if device exists
                _logger.LogInformation($"Initializing device {deviceId}");
                var device = await IoTHubManager.GetDeviceAsync(deviceId, cancellationToken);

                if (device == null)
                {
                    await IoTHubManager.AddDeviceAsync(new Device(deviceId), cancellationToken);

                    device = await IoTHubManager.GetDeviceAsync(deviceId, cancellationToken);

                    _logger.LogInformation("Device " + deviceId + " created");
                }

                var deviceConnectionString =
                    $"HostName={IotHubConnectionStringBuilder.Create(_iotHubSettings.IoTHubOwnerConnectionString).HostName};DeviceId={deviceId};SharedAccessKey={device.Authentication.SymmetricKey.PrimaryKey}";
                DeviceClients.Add(deviceId, DeviceClient.CreateFromConnectionString(deviceConnectionString));
            }

            return(DeviceClients[deviceId]);
        }
Ejemplo n.º 12
0
        protected async Task ConnectToEdgeAndSendDataAsync()
        {
            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(600))) // Long timeout is needed because registry manager takes a while for the device identity to be usable
            {
                Exception savedException = null;

                try
                {
                    var          builder = IotHubConnectionStringBuilder.Create(this.iothubConnectionString);
                    DeviceClient deviceClient;
                    if (this.authType == AuthenticationType.Sas)
                    {
                        string leafDeviceConnectionString = $"HostName={builder.HostName};DeviceId={this.deviceId};SharedAccessKey={this.context.Device.Authentication.SymmetricKey.PrimaryKey};GatewayHostName={this.edgeHostName}";
                        deviceClient = DeviceClient.CreateFromConnectionString(leafDeviceConnectionString, this.deviceTransportSettings);
                    }
                    else
                    {
                        var auth = new DeviceAuthenticationWithX509Certificate(this.deviceId, this.clientCertificate.Expect(() => new InvalidOperationException("Missing client certificate")));
                        deviceClient = DeviceClient.Create(builder.HostName, this.edgeHostName, auth, this.deviceTransportSettings);
                    }

                    this.context.DeviceClientInstance = Option.Some(deviceClient);
                    Console.WriteLine("Leaf Device client created.");

                    var message = new Message(Encoding.ASCII.GetBytes($"Message from Leaf Device. Msg GUID: {this.context.MessageGuid}"));
                    Console.WriteLine($"Trying to send the message to '{this.edgeHostName}'");

                    while (!cts.IsCancellationRequested) // Retries are needed as the DeviceClient timeouts are not long enough
                    {
                        try
                        {
                            await deviceClient.SendEventAsync(message);

                            if (string.IsNullOrWhiteSpace(this.context.Device.Scope))
                            {
                                throw new InvalidOperationException("Expected to throw exception");
                            }

                            Console.WriteLine("Message Sent.");
                            await deviceClient.SetMethodHandlerAsync("DirectMethod", DirectMethod, null);

                            Console.WriteLine("Direct method callback is set.");
                            break;
                        }
                        catch (InvalidOperationException) when(string.IsNullOrWhiteSpace(this.context.Device.Scope))
                        {
                            Console.WriteLine("Expected exception was not thrown");
                            throw;
                        }
                        catch (UnauthorizedAccessException ex) when(!string.IsNullOrWhiteSpace(this.context.Device.Scope))
                        {
                            Console.WriteLine("Expected exception {0}", ex);
                            break;
                        }
                        catch (Exception e)
                        {
                            savedException = e;
                        }
                    }
                }
                catch (OperationCanceledException e)
                {
                    throw new InvalidOperationException("Failed to connect to edge and send data", savedException ?? e);
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException("Failed to connect to edge and send data", e);
                }
            }
        }
        public static async Task RunAsync(
            [IoTHubTrigger("messages/events", Connection = "IoTHubEventHubConnectionString", ConsumerGroup = "eventtotwinfunction")] EventData message,
            Microsoft.Azure.WebJobs.ExecutionContext context,
            CancellationToken token,
            ILogger log)
        {
            var config = new ConfigurationBuilder()
                         .SetBasePath(context.FunctionAppDirectory)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();

            if (!message.Properties.ContainsKey("UpdateTwin"))
            {
                return;
            }
            var connectionString = config["IoTHubConnectionString"];

            var deviceId = (string)message.SystemProperties["iothub-connection-device-id"]; // standard system property

            if (_manager == null)
            {
                _manager = RegistryManager.CreateFromConnectionString(connectionString);
            }

            var twin = await _manager.GetTwinAsync(deviceId, token);

            // merge properties
            twin.Properties.Reported.ClearMetadata();
            var reported = JObject.Parse(twin.Properties.Reported.ToJson());

            var eventData = JObject.Parse(Encoding.UTF8.GetString(message.Body.ToArray()));

            eventData.Remove("timeStamp"); // this one always changes and we do not need it in the properties

            // remove arrays, since they are not supported in reported properties
            var arrays = eventData.Values().OfType <JArray>().Select(item => item.Path).ToList();

            foreach (var arrayPath in arrays)
            {
                eventData.Remove(arrayPath);
            }

            JObject updatedProps = (JObject)reported.DeepClone();

            updatedProps.Merge(eventData);

            if (!JToken.DeepEquals(updatedProps, reported))
            {
                // need to update
                try
                {
                    var device = await _manager.GetDeviceAsync(deviceId, token);

                    var builder = IotHubConnectionStringBuilder.Create(connectionString);

                    var deviceClient = DeviceClient.Create(builder.HostName,
                                                           new DeviceAuthenticationWithRegistrySymmetricKey(deviceId,
                                                                                                            device.Authentication.SymmetricKey.PrimaryKey));

                    await deviceClient.UpdateReportedPropertiesAsync(new TwinCollection(updatedProps.ToString()), token);

                    // call below can only be used for desired properties! So we cannot use it even though it is tempting to do so!
                    //await _manager.UpdateTwinAsync(deviceId, twin, twin.ETag, token);
                    log.LogInformation($"Digital twin for {deviceId} updated from {reported} to {updatedProps}");
                }
                catch (Exception e)
                {
                    log.LogError($"Error updating reported properties of digital twin of {deviceId} to {updatedProps}: {e}");
                    throw;
                }
            }
        }
Ejemplo n.º 14
0
        static async Task CallDirectMethodFromCloud(
            string serviceClientConnectionString,
            string deviceId,
            string moduleId,
            TransportType transportType,
            TimeSpan delay,
            CancellationTokenSource cts)
        {
            Logger.LogInformation("CallDirectMethodFromCloud started.");
            ModuleClient  moduleClient  = null;
            ServiceClient serviceClient = null;

            try
            {
                Guid batchId = Guid.NewGuid();
                int  count   = 1;

                IotHubConnectionStringBuilder iotHubConnectionStringBuilder = IotHubConnectionStringBuilder.Create(serviceClientConnectionString);
                Logger.LogInformation($"Prepare to call Direct Method from cloud ({iotHubConnectionStringBuilder.IotHubName}) on device [{deviceId}] module [{moduleId}]");

                serviceClient = ServiceClient.CreateFromConnectionString(serviceClientConnectionString, Microsoft.Azure.Devices.TransportType.Amqp);
                var cloudToDeviceMethod = new CloudToDeviceMethod("HelloWorldMethod").SetPayloadJson("{ \"Message\": \"Hello\" }");

                moduleClient = await ModuleUtil.CreateModuleClientAsync(
                    transportType,
                    ModuleUtil.DefaultTimeoutErrorDetectionStrategy,
                    ModuleUtil.DefaultTransientRetryStrategy,
                    Logger);

                while (!cts.Token.IsCancellationRequested)
                {
                    Logger.LogInformation($"Calling Direct Method from cloud ({iotHubConnectionStringBuilder.IotHubName}) on device [{deviceId}] module [{moduleId}] of count {count}.");

                    try
                    {
                        CloudToDeviceMethodResult result = await serviceClient.InvokeDeviceMethodAsync(deviceId, moduleId, cloudToDeviceMethod, CancellationToken.None);

                        if (result.Status == (int)HttpStatusCode.OK)
                        {
                            var eventMessage = new Message(Encoding.UTF8.GetBytes($"Direct Method [{transportType}] Call succeeded."));
                            eventMessage.Properties.Add("sequenceNumber", count.ToString());
                            eventMessage.Properties.Add("batchId", batchId.ToString());
                            Logger.LogInformation($"Calling Direct Method from cloud with count {count} succeeded.");
                            await moduleClient.SendEventAsync(RouteOutputName, eventMessage);
                        }
                        else
                        {
                            Logger.LogError($"Calling Direct Method from cloud with count {count} failed with status code {result.Status}.");
                        }

                        count++;
                    }
                    catch (Exception e)
                    {
                        Logger.LogError($"Exception caught with count {count}: {e}");
                    }

                    await Task.Delay(delay, cts.Token);
                }
            }
            catch (Exception e)
            {
                Logger.LogError($"Exception caught: {e}");
                throw;
            }
            finally
            {
                Logger.LogInformation("Close connection for service client and module client");
                if (serviceClient != null)
                {
                    await serviceClient.CloseAsync();
                }

                if (moduleClient != null)
                {
                    await moduleClient.CloseAsync();
                }
            }

            Logger.LogInformation("CallDirectMethodFromCloud finished.");
        }
        public static IotHubConnectionString Parse(string connectionString)
        {
            var builder = IotHubConnectionStringBuilder.Create(connectionString);

            return(builder.ToIotHubConnectionString());
        }
Ejemplo n.º 16
0
        static async Task CallDirectMethodFromCloud(
            string serviceClientConnectionString,
            string deviceId,
            string moduleId,
            TimeSpan delay,
            AnalyzerClient analyzerClient,
            CancellationTokenSource cts)
        {
            Logger.LogInformation("CallDirectMethodFromCloud started.");
            ServiceClient serviceClient = null;

            try
            {
                int count = 1;

                IotHubConnectionStringBuilder iotHubConnectionStringBuilder = IotHubConnectionStringBuilder.Create(serviceClientConnectionString);
                Logger.LogInformation($"Prepare to call Direct Method from cloud ({iotHubConnectionStringBuilder.IotHubName}) on device [{deviceId}] module [{moduleId}]");

                serviceClient = ServiceClient.CreateFromConnectionString(serviceClientConnectionString, Microsoft.Azure.Devices.TransportType.Amqp);
                var cloudToDeviceMethod = new CloudToDeviceMethod("HelloWorldMethod").SetPayloadJson("{ \"Message\": \"Hello\" }");

                while (!cts.Token.IsCancellationRequested)
                {
                    Logger.LogInformation($"Calling Direct Method from cloud ({iotHubConnectionStringBuilder.IotHubName}) on device [{deviceId}] module [{moduleId}] of count {count}.");

                    try
                    {
                        CloudToDeviceMethodResult result = await serviceClient.InvokeDeviceMethodAsync(deviceId, moduleId, cloudToDeviceMethod, CancellationToken.None);

                        if (result.Status == (int)HttpStatusCode.OK)
                        {
                            Logger.LogDebug($"Calling Direct Method from cloud with count {count} returned with status code {result.Status}.");
                        }
                        else
                        {
                            Logger.LogError($"Calling Direct Method from cloud with count {count} failed with status code {result.Status}.");
                        }

                        await CallAnalyzerToReportStatusAsync(moduleId, result, analyzerClient);

                        count++;
                    }
                    catch (Exception e)
                    {
                        Logger.LogError($"Exception caught with count {count}: {e}");
                    }

                    await Task.Delay(delay, cts.Token);
                }
            }
            catch (Exception e)
            {
                Logger.LogError($"Exception caught: {e}");
                throw;
            }
            finally
            {
                Logger.LogInformation("Close connection for service client and module client");
                if (serviceClient != null)
                {
                    await serviceClient.CloseAsync();
                }
            }

            Logger.LogInformation("CallDirectMethodFromCloud finished.");
        }
Ejemplo n.º 17
0
        static async Task Main(string[] args)
        {
            var interval         = 1;
            var connectionString = "";
            var registryManager  = RegistryManager.CreateFromConnectionString(connectionString);
            var numberOfDevices  = Enumerable.Range(1, 50);

            var devices = new ConcurrentBag <DeviceItem>();

            await ForEachAsync(numberOfDevices, 10, async (deviceNumber) =>
            {
                var deviceName = $"SimulatedFridge-{deviceNumber:0000}";

                Console.WriteLine($"Registering device ({deviceName})");
                var device = await registryManager.GetDeviceAsync(deviceName);
                if (device == null)
                {
                    device = await registryManager.AddDeviceAsync(new Device(deviceName));
                }

                devices.Add(new DeviceItem()
                {
                    Id = deviceName,
                });

                var twin = new Twin()
                {
                    Tags = { ["IsSimulated"] = "Y" }
                };

                await registryManager.UpdateTwinAsync(device.Id, twin, "*");
            });

            await ForEachAsync(numberOfDevices, 10, async (deviceNumber) =>
            {
                var deviceName = $"SimulatedLightBulbs-{deviceNumber:0000}";

                Console.WriteLine($"Registering device ({deviceName})");
                var device = await registryManager.GetDeviceAsync(deviceName);
                if (device == null)
                {
                    device = await registryManager.AddDeviceAsync(new Device(deviceName));
                }

                devices.Add(new DeviceItem()
                {
                    Id = deviceName,
                });

                var twin = new Twin()
                {
                    Tags = { ["IsSimulated"] = "Y" }
                };

                await registryManager.UpdateTwinAsync(device.Id, twin, "*");
            });

            await ForEachAsync(devices, 100, async (deviceItem) =>
            {
                var device = await registryManager.GetDeviceAsync(deviceItem.Id);
                var iotHubConnectionString        = IotHubConnectionStringBuilder.Create(connectionString);
                var deviceKeyInfo                 = new DeviceAuthenticationWithRegistrySymmetricKey(deviceItem.Id, device.Authentication.SymmetricKey.PrimaryKey);
                var deviceConnectionStringBuilder = ClientIotHubConnectionStringBuilder.Create(iotHubConnectionString.HostName, deviceKeyInfo);
                var deviceConnectionString        = deviceConnectionStringBuilder.ToString();

                var deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString);
                await deviceClient.OpenAsync();

                var message = FetchClientMessage(deviceItem);
                while (true)
                {
                    await deviceClient.SendEventAsync(message);
                    Console.WriteLine($"Sent data for ({deviceItem.Id})");

                    await Task.Delay(interval * 1000);
                    message = FetchClientMessage(deviceItem);
                }
            });

            await Task.Delay(1000);

            Console.ReadKey();
        }