/// <summary> /// Method to write the IoTHub owner connection string into the cert store. /// </summary> /// <param name="iotHubOwnerConnectionString"></param> public void ConnectionStringWrite(string iotHubOwnerConnectionString) { DeviceClient newClient = DeviceClient.CreateFromConnectionString(iotHubOwnerConnectionString, IotHubProtocol); newClient.RetryPolicy = RetryPolicyType.Exponential_Backoff_With_Jitter; newClient.OpenAsync().Wait(); SecureIoTHubToken.Write(OpcConfiguration.ApplicationName, iotHubOwnerConnectionString, IotDeviceCertStoreType, IotDeviceCertStorePath); _iotHubClient = newClient; }
/// <summary> /// Ctor for the singleton class. /// </summary> private IotHubCommunication(bool isIotEdge) { // check if we got an IoTHub owner connection string if (string.IsNullOrEmpty(IotHubOwnerConnectionString)) { Logger.Information("IoT Hub owner connection string not passed as argument."); // check if we have an environment variable to register ourselves with IoT Hub if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_HUB_CS"))) { IotHubOwnerConnectionString = Environment.GetEnvironmentVariable("_HUB_CS"); Logger.Information("IoT Hub owner connection string read from environment."); } } Logger.Information($"IoTHub device cert store type is: {IotDeviceCertStoreType}"); Logger.Information($"IoTHub device cert path is: {IotDeviceCertStorePath}"); // save the device connectionstring, if we have one if (!string.IsNullOrEmpty(IotCentralDeviceConnectionString)) { Logger.Information($"Adding IoT Central device connection string to secure store."); SecureIoTHubToken.WriteAsync(ApplicationName, IotCentralDeviceConnectionString, IotDeviceCertStoreType, IotDeviceCertStorePath).Wait(); } else { string errorMessage = "When running in IoT Hub extended mode you have to pass a connection string with icdc|iotcentraldeviceconnectionstring parameter"; Logger.Fatal(errorMessage); throw new ArgumentException(errorMessage); } // connect as device client if (isIotEdge) { Logger.Information($"Create IoT Central device client using '{SendHubProtocol}' for communication."); IotHubClient = HubClient.CreateDeviceClientFromConnectionString(IotCentralDeviceConnectionString, SendHubProtocol, Logger); } else { Logger.Error("Your module must run in IoTEdge mode to run in extended mode."); } if (!InitHubCommunicationAsync(IotHubClient, false, true).Result) { string errorMessage = $"Cannot create IoTHub client. Exiting..."; Logger.Fatal(errorMessage); throw new Exception(errorMessage); } }
/// <summary> /// Data node in the server which registers ourselves with IoT Hub when this node is written. /// </summary> public ServiceResult OnConnectionStringWrite(ISystemContext context, NodeState node, NumericRange indexRange, QualifiedName dataEncoding, ref object value, ref StatusCode statusCode, ref DateTime timestamp) { var connectionString = value as string; if (string.IsNullOrEmpty(connectionString)) { Trace("ConnectionStringWrite: Invalid Argument!"); return(ServiceResult.Create(StatusCodes.BadArgumentsMissing, "Please provide all arguments as strings!")); } statusCode = StatusCodes.Bad; timestamp = DateTime.Now; // read current connection string and compare to the one passed in string currentConnectionString = SecureIoTHubToken.Read(OpcConfiguration.ApplicationName, IotDeviceCertStoreType, IotDeviceCertStorePath); if (string.Equals(connectionString, currentConnectionString, StringComparison.OrdinalIgnoreCase)) { Trace("ConnectionStringWrite: Connection string up to date!"); return(ServiceResult.Create(StatusCodes.Bad, "Connection string already up-to-date!")); } Trace($"ConnectionStringWrite: Attempting to configure publisher with connection string: {connectionString}"); // configure publisher and write connection string try { IotHubCommunication.ConnectionStringWrite(connectionString); } catch (Exception e) { statusCode = StatusCodes.Bad; Trace(e, $"ConnectionStringWrite: Exception while trying to create IoTHub client and store device connection string in cert store"); return(ServiceResult.Create(StatusCodes.Bad, "Publisher registration failed: " + e.Message)); } statusCode = StatusCodes.Good; Trace("ConnectionStringWrite: Success!"); return(statusCode); }
/// <summary> /// Initializes the IoTHub communication. /// </summary> public async Task <bool> InitAsync() { try { // check if we got an IoTHub owner connection string if (string.IsNullOrEmpty(IotHubOwnerConnectionString)) { Logger.Information("IoT Hub owner connection string not passed as argument."); // check if we have an environment variable to register ourselves with IoT Hub if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_HUB_CS"))) { IotHubOwnerConnectionString = Environment.GetEnvironmentVariable("_HUB_CS"); Logger.Information("IoT Hub owner connection string read from environment."); } } Logger.Information($"IoTHub device cert store type is: {IotDeviceCertStoreType}"); Logger.Information($"IoTHub device cert path is: {IotDeviceCertStorePath}"); if (string.IsNullOrEmpty(IotHubOwnerConnectionString)) { Logger.Information("IoT Hub owner connection string not specified. Assume device connection string already in cert store or passed in via command line option."); } else { if (string.IsNullOrEmpty(DeviceConnectionString)) { Logger.Information($"Attempting to register ourselves with IoT Hub using owner connection string."); RegistryManager manager = RegistryManager.CreateFromConnectionString(IotHubOwnerConnectionString); // remove any existing device Device existingDevice = await manager.GetDeviceAsync(ApplicationName).ConfigureAwait(false); if (existingDevice != null) { Logger.Information($"Device '{ApplicationName}' found in IoTHub registry. Remove it."); await manager.RemoveDeviceAsync(ApplicationName).ConfigureAwait(false); } Logger.Information($"Adding device '{ApplicationName}' to IoTHub registry."); Device newDevice = await manager.AddDeviceAsync(new Device(ApplicationName)).ConfigureAwait(false); if (newDevice != null) { Logger.Information($"Generate device connection string."); string hostname = IotHubOwnerConnectionString.Substring(0, IotHubOwnerConnectionString.IndexOf(";", StringComparison.InvariantCulture)); DeviceConnectionString = hostname + ";DeviceId=" + ApplicationName + ";SharedAccessKey=" + newDevice.Authentication.SymmetricKey.PrimaryKey; } else { Logger.Fatal($"Can not register ourselves with IoT Hub. Exiting..."); return(false); } } else { Logger.Information($"There have been a device connectionstring specified on command line. Skipping device creation in IoTHub. Please ensure you created a device with name '{ApplicationName}' manually."); } } // save the device connectionstring, if we have one if (!string.IsNullOrEmpty(DeviceConnectionString)) { Logger.Information($"Adding device connectionstring to secure store."); await SecureIoTHubToken.WriteAsync(ApplicationName, DeviceConnectionString, IotDeviceCertStoreType, IotDeviceCertStorePath).ConfigureAwait(false); } // try to read connection string from secure store and open IoTHub client Logger.Information($"Attempting to read device connection string from cert store using subject name: {ApplicationName}"); DeviceConnectionString = await SecureIoTHubToken.ReadAsync(ApplicationName, IotDeviceCertStoreType, IotDeviceCertStorePath).ConfigureAwait(false); if (string.IsNullOrEmpty(DeviceConnectionString)) { Logger.Fatal("Device connection string not found in secure store. Please pass it in at least once via command line option. Can not connect to IoTHub. Exiting..."); return(false); } // connect to IoTHub Logger.Information($"Protocol used for IoTHub communication is'{HubProtocol}'"); DeviceClient hubClient = DeviceClient.CreateFromConnectionString(DeviceConnectionString, HubProtocol); if (await InitHubCommunicationAsync(hubClient, HubProtocol).ConfigureAwait(false)) { return(true); } return(false); } catch (Exception e) { Logger.Fatal(e, "Error in IoTHub initialization."); return(false); } }
/// <summary> /// Ctor for the singleton class. /// </summary> internal IotHubCommunication() { // check if we got an IoTHub owner connection string if (string.IsNullOrEmpty(IotHubOwnerConnectionString)) { Logger.Information("IoT Hub owner connection string not passed as argument."); // check if we have an environment variable to register ourselves with IoT Hub if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_HUB_CS"))) { IotHubOwnerConnectionString = Environment.GetEnvironmentVariable("_HUB_CS"); Logger.Information("IoT Hub owner connection string read from environment."); } } Logger.Information($"IoTHub device cert store type is: {IotDeviceCertStoreType}"); Logger.Information($"IoTHub device cert path is: {IotDeviceCertStorePath}"); if (string.IsNullOrEmpty(IotHubOwnerConnectionString)) { Logger.Information("IoT Hub owner connection string not specified. Assume device connection string already in cert store or passed in via command line option."); } else { if (string.IsNullOrEmpty(DeviceConnectionString)) { Logger.Information($"Attempting to register ourselves with IoT Hub using owner connection string."); RegistryManager manager = RegistryManager.CreateFromConnectionString(IotHubOwnerConnectionString); // remove any existing device Device existingDevice = manager.GetDeviceAsync(ApplicationName).Result; if (existingDevice != null) { Logger.Information($"Device '{ApplicationName}' found in IoTHub registry. Remove it."); manager.RemoveDeviceAsync(ApplicationName).Wait(); } Logger.Information($"Adding device '{ApplicationName}' to IoTHub registry."); Device newDevice = manager.AddDeviceAsync(new Device(ApplicationName)).Result; if (newDevice != null) { Logger.Information($"Generate device connection string."); string hostname = IotHubOwnerConnectionString.Substring(0, IotHubOwnerConnectionString.IndexOf(";", StringComparison.InvariantCulture)); DeviceConnectionString = hostname + ";DeviceId=" + ApplicationName + ";SharedAccessKey=" + newDevice.Authentication.SymmetricKey.PrimaryKey; } else { string errorMessage = $"Can not register ourselves with IoT Hub. Exiting..."; Logger.Fatal(errorMessage); throw new Exception(errorMessage); } } else { Logger.Information($"There have been a device connectionstring specified on command line. Skipping device creation in IoTHub. Please ensure you created a device with name '{ApplicationName}' manually."); } } // save the device connectionstring, if we have one if (!string.IsNullOrEmpty(DeviceConnectionString)) { Logger.Information($"Adding device connectionstring to secure store."); SecureIoTHubToken.WriteAsync(ApplicationName, DeviceConnectionString, IotDeviceCertStoreType, IotDeviceCertStorePath).Wait(); } // try to read connection string from secure store and open IoTHub client Logger.Information($"Attempting to read device connection string from cert store using subject name: {ApplicationName}"); DeviceConnectionString = SecureIoTHubToken.ReadAsync(ApplicationName, IotDeviceCertStoreType, IotDeviceCertStorePath).Result; if (string.IsNullOrEmpty(DeviceConnectionString)) { string errorMessage = $"Device connection string not found in secure store. Please pass it in at least once via command line option. Can not connect to IoTHub. Exiting..."; Logger.Fatal(errorMessage); throw new ArgumentException(errorMessage); } // connect as device client Logger.Information($"Create device client using '{HubProtocol}' for communication."); IotHubClient = HubClient.CreateDeviceClientFromConnectionString(DeviceConnectionString, HubProtocol, Logger); if (!InitHubCommunicationAsync(IotHubClient, true, true).GetAwaiter().GetResult()) { string errorMessage = $"Cannot create IoTHub client. Exiting..."; Logger.Fatal(errorMessage); throw new Exception(errorMessage); } }
/// <summary> /// Initializes the communication with secrets and details for (batched) send process. /// </summary> /// <returns></returns> public bool Init(string iotHubOwnerConnectionString, uint maxSizeOfIoTHubMessageBytes, int defaultSendIntervalSeconds) { _maxSizeOfIoTHubMessageBytes = maxSizeOfIoTHubMessageBytes; _defaultSendIntervalSeconds = defaultSendIntervalSeconds; try { // check if we also received an owner connection string if (string.IsNullOrEmpty(iotHubOwnerConnectionString)) { Trace("IoT Hub owner connection string not passed as argument."); // check if we have an environment variable to register ourselves with IoT Hub if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("_HUB_CS"))) { iotHubOwnerConnectionString = Environment.GetEnvironmentVariable("_HUB_CS"); Trace("IoT Hub owner connection string read from environment."); } } // register ourselves with IoT Hub string deviceConnectionString; Trace($"IoTHub device cert store type is: {IotDeviceCertStoreType}"); Trace($"IoTHub device cert path is: {IotDeviceCertStorePath}"); if (string.IsNullOrEmpty(iotHubOwnerConnectionString)) { Trace("IoT Hub owner connection string not specified. Assume device connection string already in cert store."); } else { Trace($"Attempting to register ourselves with IoT Hub using owner connection string: {iotHubOwnerConnectionString}"); RegistryManager manager = RegistryManager.CreateFromConnectionString(iotHubOwnerConnectionString); // remove any existing device Device existingDevice = manager.GetDeviceAsync(ApplicationName).Result; if (existingDevice != null) { Trace($"Device '{ApplicationName}' found in IoTHub registry. Remove it."); manager.RemoveDeviceAsync(ApplicationName).Wait(); } Trace($"Adding device '{ApplicationName}' to IoTHub registry."); Device newDevice = manager.AddDeviceAsync(new Device(ApplicationName)).Result; if (newDevice != null) { string hostname = iotHubOwnerConnectionString.Substring(0, iotHubOwnerConnectionString.IndexOf(";")); deviceConnectionString = hostname + ";DeviceId=" + ApplicationName + ";SharedAccessKey=" + newDevice.Authentication.SymmetricKey.PrimaryKey; Trace($"Device connection string is: {deviceConnectionString}"); Trace($"Adding it to device cert store."); SecureIoTHubToken.Write(ApplicationName, deviceConnectionString, IotDeviceCertStoreType, IotDeviceCertStorePath); } else { Trace($"Could not register ourselves with IoT Hub using owner connection string: {iotHubOwnerConnectionString}"); Trace("exiting..."); return(false); } } // try to read connection string from secure store and open IoTHub client Trace($"Attempting to read device connection string from cert store using subject name: {ApplicationName}"); deviceConnectionString = SecureIoTHubToken.Read(ApplicationName, IotDeviceCertStoreType, IotDeviceCertStorePath); if (!string.IsNullOrEmpty(deviceConnectionString)) { Trace($"Create Publisher IoTHub client with device connection string: '{deviceConnectionString}' using '{IotHubProtocol}' for communication."); _iotHubClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, IotHubProtocol); _iotHubClient.RetryPolicy = RetryPolicyType.Exponential_Backoff_With_Jitter; _iotHubClient.OpenAsync().Wait(); } else { Trace("Device connection string not found in secure store. Could not connect to IoTHub."); Trace("exiting..."); return(false); } // start up task to send telemetry to IoTHub. _dequeueAndSendTask = null; _tokenSource = new CancellationTokenSource(); Trace("Creating task to send OPC UA messages in batches to IoT Hub..."); _dequeueAndSendTask = Task.Run(() => DeQueueMessagesAsync(_tokenSource.Token), _tokenSource.Token); } catch (Exception e) { Trace(e, "Error during IoTHub messaging initialization."); return(false); } return(true); }