private async Task SendMethodAndRespondAsync( Client.TransportType transport, Func <DeviceClient, string, MsTestLogger, Task <Task> > setDeviceReceiveMethod, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default) { using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); Task methodReceivedTask = await setDeviceReceiveMethod(deviceClient, MethodName, Logger).ConfigureAwait(false); Task serviceSendTask = ServiceSendMethodAndVerifyResponseAsync( testDevice.Id, MethodName, DeviceResponseJson, ServiceRequestJson, Logger, responseTimeout, serviceClientTransportSettings); await Task.WhenAll(serviceSendTask, methodReceivedTask).ConfigureAwait(false); await deviceClient.CloseAsync().ConfigureAwait(false); }
protected async Task VerifyDirectMethodAsync() { // User Service SDK to invoke Direct Method on the device. var settings = new ServiceClientTransportSettings(); this.proxy.ForEach(p => settings.HttpProxy = p); ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(this.context.IotHubConnectionString, this.serviceClientTransportType, settings); // Call a direct method using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(300))) { CloudToDeviceMethod cloudToDeviceMethod = new CloudToDeviceMethod("DirectMethod").SetPayloadJson("{\"TestKey\" : \"TestValue\"}"); CloudToDeviceMethodResult result = await serviceClient.InvokeDeviceMethodAsync( this.context.Device.Id, cloudToDeviceMethod, cts.Token); if (result.Status != 200) { throw new Exception($"Could not invoke Direct Method on Device with result status {result.Status}."); } if (!result.GetPayloadAsJson().Equals("{\"TestKey\":\"TestValue\"}", StringComparison.Ordinal)) { throw new Exception($"Payload doesn't match with Sent Payload. Received payload: {result.GetPayloadAsJson()}. Expected: {{\"TestKey\":\"TestValue\"}}"); } } }
public static async Task ServiceSendMethodAndVerifyResponseAsync( string deviceId, string moduleId, string methodName, string respJson, string reqJson, MsTestLogger logger, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default) { ServiceClient serviceClient = serviceClientTransportSettings == default ? ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString) : ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, TransportType.Amqp, serviceClientTransportSettings); TimeSpan methodTimeout = responseTimeout == default ? s_defaultMethodTimeoutMinutes : responseTimeout; logger.Trace($"{nameof(ServiceSendMethodAndVerifyResponseAsync)}: Invoke method {methodName}."); CloudToDeviceMethodResult response = await serviceClient.InvokeDeviceMethodAsync( deviceId, moduleId, new CloudToDeviceMethod(methodName, responseTimeout).SetPayloadJson(reqJson)).ConfigureAwait(false); logger.Trace($"{nameof(ServiceSendMethodAndVerifyResponseAsync)}: Method status: {response.Status}."); Assert.AreEqual(200, response.Status, $"The expected response status should be 200 but was {response.Status}"); string payload = response.GetPayloadAsJson(); Assert.AreEqual(respJson, payload, $"The expected response payload should be {respJson} but was {payload}"); await serviceClient.CloseAsync().ConfigureAwait(false); serviceClient.Dispose(); }
public static async Task ServiceSendMethodAndVerifyNotReceivedAsync( string deviceId, string methodName, MsTestLogger logger, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default) { ServiceClient serviceClient = serviceClientTransportSettings == default ? ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString) : ServiceClient.CreateFromConnectionString(TestConfiguration.IoTHub.ConnectionString, TransportType.Amqp, serviceClientTransportSettings); TimeSpan methodTimeout = responseTimeout == default ? s_defaultMethodTimeoutMinutes : responseTimeout; logger.Trace($"{nameof(ServiceSendMethodAndVerifyResponseAsync)}: Invoke method {methodName}."); try { CloudToDeviceMethodResult response = await serviceClient .InvokeDeviceMethodAsync( deviceId, new CloudToDeviceMethod(methodName, methodTimeout).SetPayloadJson(null)) .ConfigureAwait(false); } catch (DeviceNotFoundException) { } finally { await serviceClient.CloseAsync().ConfigureAwait(false); serviceClient.Dispose(); } }
public async Task ServiceClient_Message_SendSingleMessage_WithProxy() { ServiceClientTransportSettings transportSettings = new ServiceClientTransportSettings(); transportSettings.AmqpProxy = new WebProxy(s_proxyServerAddress); transportSettings.HttpProxy = new WebProxy(s_proxyServerAddress); await SendSingleMessageService(transportSettings).ConfigureAwait(false); }
public async Task Method_ServiceSendsMethodThroughProxyWithCustomTimeout() { ServiceClientTransportSettings serviceClientTransportSettings = new ServiceClientTransportSettings { HttpProxy = new WebProxy(Configuration.IoTHub.ProxyServerAddress) }; await SendMethodAndRespond(Client.TransportType.Mqtt_Tcp_Only, SetDeviceReceiveMethod, TimeSpan.FromMinutes(5), serviceClientTransportSettings).ConfigureAwait(false); }
protected async Task VerifyDirectMethodAsync() { // User Service SDK to invoke Direct Method on the device. var settings = new ServiceClientTransportSettings(); this.proxy.ForEach(p => settings.HttpProxy = p); ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(this.context.IotHubConnectionString, this.serviceClientTransportType, settings); // Call a direct method TimeSpan testDuration = TimeSpan.FromSeconds(300); DateTime endTime = DateTime.UtcNow + testDuration; using (var cts = new CancellationTokenSource(testDuration)) { CloudToDeviceMethod cloudToDeviceMethod = new CloudToDeviceMethod("DirectMethod").SetPayloadJson("{\"TestKey\" : \"TestValue\"}"); CloudToDeviceMethodResult result = null; bool isRetrying = true; while (isRetrying) { try { result = await serviceClient.InvokeDeviceMethodAsync( this.context.Device.Id, cloudToDeviceMethod, cts.Token); } catch (Exception ex) { if (DateTime.UtcNow >= endTime) { Console.WriteLine($"Failed to send direct method from device '{this.context.Device.Id}' with payload '{cloudToDeviceMethod}: {ex}'"); isRetrying = false; } else { Console.WriteLine($"Failed to send direct method from device '{this.context.Device.Id}' with payload '{cloudToDeviceMethod}: {ex.Message}'"); } } } if (result?.Status != 200) { throw new Exception($"Could not invoke Direct Method on Device with result status {result?.Status}."); } if (!result.GetPayloadAsJson().Equals("{\"TestKey\":\"TestValue\"}", StringComparison.Ordinal)) { throw new Exception($"Payload doesn't match with Sent Payload. Received payload: {result.GetPayloadAsJson()}. Expected: {{\"TestKey\":\"TestValue\"}}"); } } }
private async Task SendSingleMessageService(ServiceClientTransportSettings transportSettings) { TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false); DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString); ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(ConnectionString, TransportType.Amqp, transportSettings); string payload; string p1Value; Message testMessage = ComposeD2CTestMessage(out payload, out p1Value); await serviceClient.SendAsync(testDevice.Id, testMessage).ConfigureAwait(false); }
public async Task Method_ServiceSendsMethodThroughProxyWithDefaultTimeout() { var serviceClientTransportSettings = new ServiceClientTransportSettings { HttpProxy = new WebProxy(TestConfiguration.IoTHub.ProxyServerAddress) }; await SendMethodAndRespondAsync( Client.TransportType.Mqtt_Tcp_Only, SetDeviceReceiveMethodAsync, serviceClientTransportSettings : serviceClientTransportSettings) .ConfigureAwait(false); }
private async Task SendSingleMessageService(ServiceClientTransportSettings transportSettings) { TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString)) using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(s_connectionString, TransportType.Amqp, transportSettings)) { (Message testMessage, string messageId, string payload, string p1Value) = ComposeD2CTestMessage(); await serviceClient.SendAsync(testDevice.Id, testMessage).ConfigureAwait(false); await deviceClient.CloseAsync().ConfigureAwait(false); await serviceClient.CloseAsync().ConfigureAwait(false); } }
protected async Task VerifyEdgeAgentIsConnectedToIotHub() { Console.WriteLine("Verifying if edge is connected to IoThub"); using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(300))) { Exception savedException = null; try { var settings = new ServiceClientTransportSettings(); this.proxy.ForEach(p => settings.HttpProxy = p); ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(this.context.IotHubConnectionString, this.serviceClientTransportType, settings); while (true) { await Task.Delay(TimeSpan.FromSeconds(10), cts.Token); try { CloudToDeviceMethodResult result = await serviceClient.InvokeDeviceMethodAsync( this.context.DeviceId, "$edgeAgent", new CloudToDeviceMethod("ping"), cts.Token); if (result.Status == 200) { break; } } catch (Exception e) { savedException = e; } } } catch (OperationCanceledException e) { throw new Exception($"Failed to ping $edgeAgent from the cloud: {savedException?.Message ?? e.Message}"); } catch (Exception e) { throw new Exception($"Failed to ping $edgeAgent from the cloud: {e.Message}"); } } }
private async Task SendMethodAndUnsubscribeAsync( Client.TransportType transport, Func <DeviceClient, string, MsTestLogger, Task <Task> > subscribeAndUnsubscribeMethod, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default) { using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); await subscribeAndUnsubscribeMethod(deviceClient, MethodName, Logger).ConfigureAwait(false); await ServiceSendMethodAndVerifyNotReceivedAsync(testDevice.Id, MethodName, Logger, responseTimeout, serviceClientTransportSettings).ConfigureAwait(false); await deviceClient.CloseAsync().ConfigureAwait(false); }
public IotHub(string iotHubConnectionString, string eventHubEndpoint, Option <Uri> proxyUri) { this.eventHubEndpoint = eventHubEndpoint; this.iotHubConnectionString = iotHubConnectionString; Option <IWebProxy> proxy = proxyUri.Map(p => new WebProxy(p) as IWebProxy); this.registryManager = new Lazy <RegistryManager>( () => { var settings = new HttpTransportSettings(); proxy.ForEach(p => settings.Proxy = p); return(RegistryManager.CreateFromConnectionString( this.iotHubConnectionString, settings)); }); this.serviceClient = new Lazy <ServiceClient>( () => { var settings = new ServiceClientTransportSettings(); proxy.ForEach(p => settings.HttpProxy = p); return(ServiceClient.CreateFromConnectionString( this.iotHubConnectionString, DeviceTransportType.Amqp_WebSocket_Only, settings)); }); this.eventHubClient = new Lazy <EventHubClient>( () => { var builder = new EventHubsConnectionStringBuilder(this.eventHubEndpoint) { TransportType = EventHubTransportType.AmqpWebSockets }; var client = EventHubClient.CreateFromConnectionString(builder.ToString()); proxy.ForEach(p => client.WebProxy = p); return(client); }); }
public static async Task ServiceSendMethodAndVerifyResponse(string deviceName, string methodName, string respJson, string reqJson, TimeSpan responseTimeout, ServiceClientTransportSettings serviceClientTransportSettings) { using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, TransportType.Amqp, serviceClientTransportSettings)) { _log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponse)}: Invoke method {methodName}."); CloudToDeviceMethodResult response = await serviceClient.InvokeDeviceMethodAsync( deviceName, new CloudToDeviceMethod(methodName, responseTimeout).SetPayloadJson(reqJson)).ConfigureAwait(false); _log.WriteLine($"{nameof(ServiceSendMethodAndVerifyResponse)}: Method status: {response.Status}."); Assert.AreEqual(200, response.Status, $"The expected response status should be 200 but was {response.Status}"); string payload = response.GetPayloadAsJson(); Assert.AreEqual(respJson, payload, $"The expected response payload should be {respJson} but was {payload}"); await serviceClient.CloseAsync().ConfigureAwait(false); } }
private async Task SendMethodAndRespond(Client.TransportType transport, Func <DeviceClient, string, Task <Task> > setDeviceReceiveMethod, ServiceClientTransportSettings serviceClientTransportSettings) { await SendMethodAndRespond(transport, setDeviceReceiveMethod, DefaultMethodTimeoutMinutes, serviceClientTransportSettings).ConfigureAwait(false); }
private async Task SendMethodAndRespond(Client.TransportType transport, Func <DeviceClient, string, Task <Task> > setDeviceReceiveMethod, TimeSpan responseTimeout, ServiceClientTransportSettings serviceClientTransportSettings) { TestDevice testDevice = await TestDevice.GetTestDeviceAsync(DevicePrefix).ConfigureAwait(false); using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport)) { Task methodReceivedTask = await setDeviceReceiveMethod(deviceClient, MethodName).ConfigureAwait(false); await Task.WhenAll( ServiceSendMethodAndVerifyResponse(testDevice.Id, MethodName, DeviceResponseJson, ServiceRequestJson, responseTimeout, serviceClientTransportSettings), methodReceivedTask).ConfigureAwait(false); await deviceClient.CloseAsync().ConfigureAwait(false); } }
protected async Task VerifyDirectMethodAsync() { // User Service SDK to invoke Direct Method on the device. var settings = new ServiceClientTransportSettings(); this.proxy.ForEach(p => settings.HttpProxy = p); ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(this.context.IotHubConnectionString, this.serviceClientTransportType, settings); // Call a direct method TimeSpan testDuration = TimeSpan.FromSeconds(300); DateTime endTime = DateTime.UtcNow + testDuration; CloudToDeviceMethod cloudToDeviceMethod = new CloudToDeviceMethod("DirectMethod").SetPayloadJson("{\"TestKey\" : \"TestValue\"}"); CloudToDeviceMethodResult result = null; // To reduce log size and make troubleshooting easier, log last exception only. Exception lastException = null; bool isRetrying = true; Console.WriteLine("Starting Direct method test."); while (isRetrying && DateTime.UtcNow <= endTime) { try { using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))) { result = await serviceClient.InvokeDeviceMethodAsync( this.context.Device.Id, cloudToDeviceMethod, cts.Token); if (result?.Status == 200) { isRetrying = false; } // Don't retry too fast await Task.Delay(1000, cts.Token); } } catch (OperationCanceledException ex) { if (lastException == null) { lastException = ex; } } catch (Exception ex) { lastException = ex; } } if (result?.Status != 200) { if (lastException != null) { Console.WriteLine($"Failed to send direct method from device '{this.context.Device.Id}' with payload '{cloudToDeviceMethod}: {lastException}'"); } throw new Exception($"Could not invoke Direct Method on Device with result status {result?.Status}."); } if (!result.GetPayloadAsJson().Equals("{\"TestKey\":\"TestValue\"}", StringComparison.Ordinal)) { throw new Exception($"Payload doesn't match with Sent Payload. Received payload: {result.GetPayloadAsJson()}. Expected: {{\"TestKey\":\"TestValue\"}}"); } Console.WriteLine("Direct method test passed."); }