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; }
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)); }
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]); }
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; } } }
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()); }
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."); }
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(); }