public async Task InvokeMethodClientTimesOutTest()
        {
            // Arrange
            var request = new DirectMethodRequest("d1", "poke", null, TimeSpan.FromSeconds(10));

            var deviceProxy = new Mock <IDeviceProxy>();

            deviceProxy.Setup(d => d.InvokeMethodAsync(It.IsAny <DirectMethodRequest>()))
            .ReturnsAsync(() => new DirectMethodResponse(new EdgeHubTimeoutException("Edge hub timed out"), HttpStatusCode.GatewayTimeout));

            var deviceSubscriptions = new Dictionary <DeviceSubscription, bool>
            {
                [DeviceSubscription.Methods] = true
            };

            var connectionManager = new Mock <IConnectionManager>();

            connectionManager.Setup(c => c.GetDeviceConnection(It.IsAny <string>())).Returns(Option.Some(deviceProxy.Object));
            connectionManager.Setup(c => c.GetSubscriptions(It.IsAny <string>()))
            .Returns(Option.Some(new ReadOnlyDictionary <DeviceSubscription, bool>(deviceSubscriptions) as IReadOnlyDictionary <DeviceSubscription, bool>));

            IInvokeMethodHandler invokeMethodHandler = new InvokeMethodHandler(connectionManager.Object);

            // Act
            DirectMethodResponse response = await invokeMethodHandler.InvokeMethod(request);

            // Assert
            Assert.NotNull(response);
            Assert.Null(response.CorrelationId);
            Assert.Equal(response.HttpStatusCode, HttpStatusCode.GatewayTimeout);
            Assert.Null(response.Data);
            Assert.Equal(response.Status, 0);
            Assert.IsType <EdgeHubTimeoutException>(response.Exception.OrDefault());
        }
            public async Task <DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest request)
            {
                if (!this.clientConnectionHandler.registry.TryGetValue(LinkType.MethodSending, out ILinkHandler linkHandler))
                {
                    Events.LinkNotFound(LinkType.ModuleMessages, this.Identity, "method request");
                    return(default(DirectMethodResponse));
                }

                IMessage message = new EdgeMessage.Builder(request.Data)
                                   .SetProperties(
                    new Dictionary <string, string>
                {
                    [Constants.MessagePropertiesMethodNameKey] = request.Name
                })
                                   .SetSystemProperties(
                    new Dictionary <string, string>
                {
                    [SystemProperties.CorrelationId] = request.CorrelationId
                })
                                   .Build();

                await((ISendingLinkHandler)linkHandler).SendMessage(message);
                Events.SentMethodInvocation(this.Identity);
                return(default(DirectMethodResponse));
            }
        public async Task HandleMethodInvocationBadInputTest()
        {
            // Arrange
            var edgeHubIdentity = Mock.Of <IModuleIdentity>();
            var twinManager     = Mock.Of <ITwinManager>();
            var routeFactory    = new EdgeRouteFactory(Mock.Of <IEndpointFactory>());
            var twinCollectionMessageConverter = Mock.Of <Core.IMessageConverter <TwinCollection> >();
            var twinMessageConverter           = Mock.Of <Core.IMessageConverter <Twin> >();
            var versionInfo = new VersionInfo("1.0", "1", "123");
            var deviceScopeIdentitiesCache = new Mock <IDeviceScopeIdentitiesCache>();

            deviceScopeIdentitiesCache.Setup(d => d.RefreshServiceIdentities(It.IsAny <IEnumerable <string> >())).Returns(Task.CompletedTask);
            var edgeHubConnection = new EdgeHubConnection(edgeHubIdentity, twinManager, routeFactory, twinCollectionMessageConverter, twinMessageConverter, versionInfo, deviceScopeIdentitiesCache.Object);

            string correlationId  = Guid.NewGuid().ToString();
            var    requestPayload = new []
            {
                "d1",
                "d2"
            };

            byte[] requestBytes        = requestPayload.ToBytes();
            var    directMethodRequest = new DirectMethodRequest(correlationId, Constants.ServiceIdentityRefreshMethodName, requestBytes, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));

            // Act
            DirectMethodResponse directMethodResponse = await edgeHubConnection.HandleMethodInvocation(directMethodRequest);

            // Assert
            Assert.NotNull(directMethodResponse);
            Assert.Equal(HttpStatusCode.BadRequest, directMethodResponse.HttpStatusCode);
        }
Example #4
0
        public Task <DirectMethodResponse> InvokeMethodAsync(string id, DirectMethodRequest methodRequest)
        {
            Preconditions.CheckNonWhiteSpace(id, nameof(id));
            Preconditions.CheckNotNull(methodRequest, nameof(methodRequest));

            Events.MethodCallReceived(id, methodRequest.Id, methodRequest.CorrelationId);
            return(this.invokeMethodHandler.InvokeMethod(methodRequest));
        }
Example #5
0
        public Task <IActionResult> InvokeDeviceMethodAsync([FromRoute] string deviceId, [FromBody] MethodRequest methodRequest)
        {
            deviceId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(deviceId, nameof(deviceId)));
            this.validator.Validate(methodRequest);

            var directMethodRequest = new DirectMethodRequest(deviceId, methodRequest.MethodName, methodRequest.PayloadBytes, methodRequest.ResponseTimeout, methodRequest.ConnectTimeout);

            return(this.InvokeMethodAsync(directMethodRequest));
        }
Example #6
0
        public Task <DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest request)
        {
            string address = TwinAddressHelper.FormatDeviceMethodRequestAddress(request.CorrelationId, request.Name);
            IProtocolGatewayMessage pgMessage = new ProtocolGatewayMessage.Builder(this.byteBufferConverter.ToByteBuffer(request.Data), address)
                                                .WithCreatedTimeUtc(DateTime.UtcNow)
                                                .Build();

            this.channel.Handle(pgMessage);
            return(Task.FromResult(default(DirectMethodResponse)));
        }
Example #7
0
        public async Task InvokeModuleMethodAsync([FromRoute] string deviceId, [FromRoute] string moduleId, [FromBody] MethodRequest methodRequest)
        {
            deviceId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(deviceId, nameof(deviceId)));
            moduleId = WebUtility.UrlDecode(Preconditions.CheckNonWhiteSpace(moduleId, nameof(moduleId)));
            this.validator.Validate(methodRequest);

            var directMethodRequest = new DirectMethodRequest($"{deviceId}/{moduleId}", methodRequest.MethodName, methodRequest.PayloadBytes, methodRequest.ResponseTimeout, methodRequest.ConnectTimeout);
            var methodResult        = await this.InvokeMethodAsync(directMethodRequest);

            await this.SendResponse(methodResult);
        }
Example #8
0
            internal async Task <MethodResponse> MethodCallHandler(MethodRequest methodrequest, object usercontext)
            {
                Preconditions.CheckNotNull(methodrequest, nameof(methodrequest));

                Events.MethodCallReceived(this.cloudProxy.clientId);
                var direceMethodRequest = new DirectMethodRequest(this.cloudProxy.clientId, methodrequest.Name, methodrequest.Data, DeviceMethodMaxResponseTimeout);
                DirectMethodResponse directMethodResponse = await this.cloudListener.CallMethodAsync(direceMethodRequest);

                MethodResponse methodResponse = directMethodResponse.Data == null ? new MethodResponse(directMethodResponse.Status) : new MethodResponse(directMethodResponse.Data, directMethodResponse.Status);

                return(methodResponse);
            }
Example #9
0
        async Task <MethodResult> InvokeMethodAsync(DirectMethodRequest directMethodRequest)
        {
            Events.ReceivedMethodCall(directMethodRequest, this.identity);
            IEdgeHub             edgeHub = await this.edgeHubGetter;
            DirectMethodResponse directMethodResponse = await edgeHub.InvokeMethodAsync(this.identity.Id, directMethodRequest);

            Events.ReceivedMethodCallResponse(directMethodRequest, this.identity);

            MethodResult methodResult = GetMethodResult(directMethodResponse);

            return(methodResult);
        }
Example #10
0
        public async Task CallMethodAsync_InvokesDeviceProxy()
        {
            var    edgeHub       = Mock.Of <IEdgeHub>();
            var    identity      = Mock.Of <IIdentity>(i => i.Id == "device1");
            string testMethod    = "testMethod";
            var    testByteArray = new byte[] { 0x00, 0x01, 0x02 };
            string id            = "1";
            var    request       = new DirectMethodRequest(id, testMethod, testByteArray, TimeSpan.FromSeconds(30));

            var cloudListener = new CloudListener(edgeHub, identity.Id);
            await cloudListener.CallMethodAsync(request);

            Mock.Get(edgeHub).Verify(eh => eh.InvokeMethodAsync("upstream", request), Times.Once);
        }
        public async Task InvokeMethodTimeoutTest()
        {
            DeviceMessageHandler deviceMessageHandler = this.GetDeviceMessageHandler();
            var methodRequest = new DirectMethodRequest("device10", "shutdown", null, TimeSpan.FromSeconds(2), TimeSpan.FromMilliseconds(10));

            Task <DirectMethodResponse> responseTask = deviceMessageHandler.InvokeMethodAsync(methodRequest);

            Assert.False(responseTask.IsCompleted);

            await Task.Delay(TimeSpan.FromSeconds(5));

            Assert.True(responseTask.IsCompleted);
            Assert.NotNull(responseTask.Result);
            Assert.Null(responseTask.Result.Data);
        }
Example #12
0
        async Task <IActionResult> InvokeMethodAsync(DirectMethodRequest directMethodRequest)
        {
            Events.ReceivedMethodCall(directMethodRequest, this.identity);
            IEdgeHub             edgeHub = await this.edgeHubGetter;
            DirectMethodResponse directMethodResponse = await edgeHub.InvokeMethodAsync(this.identity.Id, directMethodRequest);

            Events.ReceivedMethodCallResponse(directMethodRequest, this.identity);

            var methodResult = new MethodResult
            {
                Status  = directMethodResponse.Status,
                Payload = GetRawJson(directMethodResponse.Data)
            };

            return(this.Json(methodResult));
        }
Example #13
0
        public Task <DirectMethodResponse> InvokeMethodAsync(string id, DirectMethodRequest methodRequest)
        {
            Preconditions.CheckNotNull(methodRequest, nameof(methodRequest));

            Events.MethodCallReceived(id, methodRequest.Id, methodRequest.CorrelationId);
            Option <IDeviceProxy> deviceProxy = this.connectionManager.GetDeviceConnection(methodRequest.Id);

            return(deviceProxy.Match(
                       dp =>
            {
                if (this.connectionManager.GetSubscriptions(methodRequest.Id)
                    .Filter(s => s.TryGetValue(DeviceSubscription.Methods, out bool isActive) && isActive)
                    .HasValue)
                {
                    Events.InvokingMethod(methodRequest);
                    return dp.InvokeMethodAsync(methodRequest);
                }
        public async Task InvokedMethodMismatchedResponseTest()
        {
            DeviceMessageHandler deviceMessageHandler = this.GetDeviceMessageHandler();
            var methodRequest = new DirectMethodRequest("device10", "shutdown", null, TimeSpan.FromSeconds(2), TimeSpan.FromMilliseconds(10));

            Task <DirectMethodResponse> responseTask = deviceMessageHandler.InvokeMethodAsync(methodRequest);

            Assert.False(responseTask.IsCompleted);

            IMessage message = new EdgeMessage.Builder(new byte[0]).Build();

            message.Properties[SystemProperties.CorrelationId] = methodRequest.CorrelationId + 1;
            message.Properties[SystemProperties.StatusCode]    = "200";
            await deviceMessageHandler.ProcessMethodResponseAsync(message);

            Assert.False(responseTask.IsCompleted);
        }
Example #15
0
        async Task <IActionResult> InvokeMethodAsync(DirectMethodRequest directMethodRequest)
        {
            Events.ReceivedMethodCall(directMethodRequest, this.identity);
            IEdgeHub             edgeHub = await this.edgeHubGetter;
            DirectMethodResponse directMethodResponse = await edgeHub.InvokeMethodAsync(this.identity.Id, directMethodRequest);

            Events.ReceivedMethodCallResponse(directMethodRequest, this.identity);

            MethodResult methodResult = GetMethodResult(directMethodResponse);
            HttpResponse response     = this.Request?.HttpContext?.Response;

            if (response != null)
            {
                response.ContentLength = GetContentLength(methodResult);
            }
            return(this.StatusCode((int)directMethodResponse.HttpStatusCode, methodResult));
        }
Example #16
0
        public async Task SendsMessageDataAsPayload()
        {
            var capture   = new SendCapture();
            var connector = GetConnector(capture);

            var(connectionRegistry, identityProvider) = GetHandlerDependencies();
            var identity = new DeviceIdentity("hub", "device_id");
            var method   = new DirectMethodRequest("12345", "method", new byte[] { 1, 2, 3 }, TimeSpan.FromSeconds(5));

            var sut = new DirectMethodHandler(connectionRegistry, identityProvider);

            sut.SetConnector(connector);

            await sut.CallDirectMethodAsync(method, identity, true);

            Assert.Equal(new byte[] { 1, 2, 3 }, capture.Content);
        }
Example #17
0
        public async Task EncodesDeviceNameInTopic()
        {
            var capture   = new SendCapture();
            var connector = GetConnector(capture);

            var(connectionRegistry, identityProvider) = GetHandlerDependencies();
            var identity = new DeviceIdentity("hub", "device_id");
            var method   = new DirectMethodRequest("12345", "method", new byte[] { 1, 2, 3 }, TimeSpan.FromSeconds(5));

            var sut = new DirectMethodHandler(connectionRegistry, identityProvider);

            sut.SetConnector(connector);

            await sut.CallDirectMethodAsync(method, identity, true);

            Assert.Equal("$edgehub/device_id/methods/post/method/?$rid=" + method.CorrelationId, capture.Topic);
        }
Example #18
0
        public async Task InvokeMethodDeviceNotConnectedTest()
        {
            // Arrange
            var request = new DirectMethodRequest("d1", "poke", null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(60));

            var deviceProxy = new Mock <IDeviceProxy>();

            deviceProxy.Setup(d => d.InvokeMethodAsync(It.IsAny <DirectMethodRequest>()))
            .ReturnsAsync(() => new DirectMethodResponse(request.CorrelationId, null, 200));

            var deviceSubscriptions = new Dictionary <DeviceSubscription, bool>
            {
                [DeviceSubscription.Methods] = true
            };

            var connectionManager = new Mock <IConnectionManager>();

            connectionManager.SetupSequence(c => c.GetDeviceConnection(It.IsAny <string>()))
            .Returns(Option.None <IDeviceProxy>())
            .Returns(Option.Some(deviceProxy.Object));
            connectionManager.Setup(c => c.GetSubscriptions(It.IsAny <string>()))
            .Returns(Option.Some(new ReadOnlyDictionary <DeviceSubscription, bool>(deviceSubscriptions) as IReadOnlyDictionary <DeviceSubscription, bool>));

            IInvokeMethodHandler invokeMethodHandler = new InvokeMethodHandler(connectionManager.Object);

            // Act
            Task <DirectMethodResponse> invokeMethodTask = invokeMethodHandler.InvokeMethod(request);
            await Task.Delay(TimeSpan.FromSeconds(2));

            // Assert
            Assert.False(invokeMethodTask.IsCompleted);

            // Act
            await invokeMethodHandler.ProcessInvokeMethodSubscription("d1");

            DirectMethodResponse response = await invokeMethodTask;

            // Assert
            Assert.NotNull(response);
            Assert.Equal(response.CorrelationId, request.CorrelationId);
            Assert.Equal(HttpStatusCode.OK, response.HttpStatusCode);
            Assert.Null(response.Data);
            Assert.Equal((int)HttpStatusCode.OK, response.Status);
            Assert.False(response.Exception.HasValue);
        }
Example #19
0
        async Task <MethodResult> InvokeMethodAsync(DirectMethodRequest directMethodRequest)
        {
            Events.ReceivedMethodCall(directMethodRequest);
            IEdgeHub edgeHub = await this.edgeHubGetter;

            MethodResult methodResult;
            string       currentEdgeDeviceId = edgeHub.GetEdgeDeviceId();

            if (this.TryGetActorId(out string actorDeviceId, out string actorModuleId))
            {
                string actorId = $"{actorDeviceId}/{actorModuleId}";

                if (actorDeviceId == currentEdgeDeviceId)
                {
                    IHttpRequestAuthenticator authenticator = await this.authenticatorGetter;
                    HttpAuthResult            authResult    = await authenticator.AuthenticateAsync(actorDeviceId, Option.Some(actorModuleId), this.HttpContext);

                    if (authResult.Authenticated)
                    {
                        using (Metrics.TimeDirectMethod(actorDeviceId, directMethodRequest.Id))
                        {
                            DirectMethodResponse directMethodResponse = await edgeHub.InvokeMethodAsync(actorId, directMethodRequest);

                            Events.ReceivedMethodCallResponse(directMethodRequest, actorId);

                            methodResult = GetMethodResult(directMethodResponse);
                        }
                    }
                    else
                    {
                        methodResult = new MethodErrorResult(HttpStatusCode.Unauthorized, authResult.ErrorMessage);
                    }
                }
                else
                {
                    methodResult = new MethodErrorResult(HttpStatusCode.Unauthorized, "Only modules on the same device can invoke DirectMethods");
                }
            }
            else
            {
                methodResult = new MethodErrorResult(HttpStatusCode.BadRequest, $"Invalid header value for {Constants.ServiceApiIdHeaderKey}");
            }

            return(methodResult);
        }
Example #20
0
        /// <summary>
        /// This method invokes the method on the device, and adds the TaskCompletionSource (that awaits the response) to the methodCallTaskCompletionSources list.
        /// When the response comes back, SendMethodResponse sets the TaskCompletionSource value, which results in the awaiting task to be completed.
        /// If no response comes back, then it times out.
        /// </summary>
        public async Task<DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest request)
        {
            var taskCompletion = new TaskCompletionSource<DirectMethodResponse>();

            this.methodCallTaskCompletionSources.TryAdd(request.CorrelationId.ToLowerInvariant(), taskCompletion);
            await this.underlyingProxy.InvokeMethodAsync(request);
            Events.MethodCallSentToClient(this.Identity, request.Id, request.CorrelationId);

            Task completedTask = await Task.WhenAny(taskCompletion.Task, Task.Delay(request.ResponseTimeout));
            if (completedTask != taskCompletion.Task)
            {
                Events.MethodResponseTimedout(this.Identity, request.Id, request.CorrelationId);
                taskCompletion.TrySetResult(new DirectMethodResponse(new EdgeHubTimeoutException($"Timed out waiting for device to respond to method request {request.CorrelationId}"), HttpStatusCode.GatewayTimeout));
                this.methodCallTaskCompletionSources.TryRemove(request.CorrelationId.ToLowerInvariant(), out taskCompletion);
            }

            return await taskCompletion.Task;
        }
Example #21
0
        public async Task RegisterMethodInvokerTest()
        {
            // Arrange
            IDeviceProxy deviceProxy       = null;
            var          identity          = Mock.Of <IIdentity>(i => i.Id == "d1/m1");
            var          clientCredentials = Mock.Of <IClientCredentials>(c => c.Identity == identity);
            var          deviceListener    = Mock.Of <IDeviceListener>();

            Mock.Get(deviceListener).Setup(d => d.BindDeviceProxy(It.IsAny <IDeviceProxy>()))
            .Callback <IDeviceProxy>(d => deviceProxy = d);

            var connectionProvider = Mock.Of <IConnectionProvider>(c => c.GetDeviceListenerAsync(clientCredentials) == Task.FromResult(deviceListener));

            var amqpAuthentication = new AmqpAuthentication(true, Option.Some(clientCredentials));
            var cbsNode            = Mock.Of <ICbsNode>(c => c.GetAmqpAuthentication() == Task.FromResult(amqpAuthentication));
            var amqpConnection     = Mock.Of <IAmqpConnection>(c => c.FindExtension <ICbsNode>() == cbsNode);
            var connectionHandler  = new ConnectionHandler(amqpConnection, connectionProvider);

            IMessage receivedMessage          = null;
            var      methodSendingLinkHandler = new Mock <ISendingLinkHandler>();

            methodSendingLinkHandler.Setup(c => c.SendMessage(It.IsAny <IMessage>()))
            .Callback <IMessage>(m => receivedMessage = m)
            .Returns(Task.CompletedTask);
            methodSendingLinkHandler.SetupGet(c => c.Type)
            .Returns(LinkType.MethodSending);

            var sentRequest = new DirectMethodRequest(identity.Id, "poke", new byte[] { 0, 1, 2 }, TimeSpan.FromSeconds(10));

            // Act
            await connectionHandler.GetDeviceListener();

            await connectionHandler.RegisterLinkHandler(methodSendingLinkHandler.Object);

            await deviceProxy.InvokeMethodAsync(sentRequest);

            // Assert
            Assert.NotNull(receivedMessage);
            Assert.Equal(sentRequest.Data, receivedMessage.Body);
            Assert.Equal(sentRequest.CorrelationId, receivedMessage.SystemProperties[SystemProperties.CorrelationId]);
            Assert.Equal(sentRequest.Name, receivedMessage.Properties[Amqp.Constants.MessagePropertiesMethodNameKey]);
        }
        /// <summary>
        /// This method invokes the method on the device, and adds the TaskCompletionSource (that awaits the response) to the methodCallTaskCompletionSources list.
        /// When the response comes back, SendMethodResponse sets the TaskCompletionSource value, which results in the awaiting task to be completed.
        /// If no response comes back, then it times out.
        /// </summary>
        public async Task <DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest request)
        {
            var taskCompletion = new TaskCompletionSource <DirectMethodResponse>();

            this.methodCallTaskCompletionSources.TryAdd(request.CorrelationId.ToLowerInvariant(), taskCompletion);
            await this.underlyingProxy.InvokeMethodAsync(request);

            Events.MethodCallSentToClient(this.Identity, request.Id, request.CorrelationId);

            Task completedTask = await Task.WhenAny(taskCompletion.Task, Task.Delay(request.ResponseTimeout));

            if (completedTask != taskCompletion.Task)
            {
                Events.MethodResponseTimedout(this.Identity, request.Id, request.CorrelationId);
                taskCompletion.TrySetResult(new DirectMethodResponse(null, null, GatewayTimeoutErrorCode));
                this.methodCallTaskCompletionSources.TryRemove(request.CorrelationId.ToLowerInvariant(), out taskCompletion);
            }

            return(await taskCompletion.Task);
        }
Example #23
0
        public async Task DirectMethodCallForwarded()
        {
            var twinHandler         = Mock.Of <ITwinHandler>();
            var m2mHandler          = Mock.Of <IModuleToModuleMessageHandler>();
            var c2dHandler          = Mock.Of <ICloud2DeviceMessageHandler>();
            var directMethodHandler = Mock.Of <IDirectMethodHandler>();
            var identity            = new DeviceIdentity("hub", "device_id");

            var request = new DirectMethodRequest("123", "name", new byte[] { 1, 2, 3 }, TimeSpan.FromSeconds(60));

            Mock.Get(directMethodHandler)
            .Setup(h => h.CallDirectMethodAsync(It.Is <DirectMethodRequest>(m => m == request), It.Is <IIdentity>(i => i == identity)))
            .Returns(Task.FromResult(new DirectMethodResponse("123", new byte[0], 200)));

            var sut = new DeviceProxy(identity, twinHandler, m2mHandler, c2dHandler, directMethodHandler);

            await sut.InvokeMethodAsync(request);

            Mock.Get(directMethodHandler).VerifyAll();
        }
Example #24
0
        public async Task<DirectMethodResponse> CallDirectMethodAsync(DirectMethodRequest request, IIdentity identity, bool isDirectClient)
        {
            try
            {
                var topicPrefix = isDirectClient ? MqttBrokerAdapterConstants.DirectTopicPrefix : MqttBrokerAdapterConstants.IndirectTopicPrefix;
                var result = await this.connector.SendAsync(
                                            GetMethodCallTopic(identity, request.Name, request.CorrelationId, topicPrefix),
                                            request.Data);
                if (!result)
                {
                    throw new Exception($"MQTT transport failed to forward message for Direct Method call with rid [{request.CorrelationId}]");
                }

                return null;
            }
            catch (Exception e)
            {
                Events.FailedToSendDirectMethodMessage(e);
                return null;
            }
        }
Example #25
0
        public async Task <DirectMethodResponse> CallDirectMethodAsync(DirectMethodRequest request, IIdentity identity)
        {
            try
            {
                var result = await this.connector.SendAsync(
                    GetMethodCallTopic(identity, request.Name, request.CorrelationId),
                    request.Data);

                if (!result)
                {
                    throw new Exception($"MQTT transport failed to forward message for Direct Method call with rid [{request.CorrelationId}]");
                }

                return(null);
            }
            catch (Exception e)
            {
                Events.FailedToSendDirectMethodMessage(e);
                return(null);
            }
        }
Example #26
0
        public async Task InvokeMethodLateSubscriptionTest()
        {
            // Create a mock endpoint capable of returning a mock processor
            var processor = Mock.Of <IProcessor>();
            var endpoint  = new Mock <Endpoint>("myId");

            endpoint.Setup(ep => ep.CreateProcessor()).Returns(processor);
            endpoint.SetupGet(ep => ep.Id).Returns("myId");

            // Create a mock endpoint executor factory to create the endpoint executor to verify invocation
            var endpointExecutor = Mock.Of <IEndpointExecutor>();

            Mock.Get(endpointExecutor).SetupGet(ee => ee.Endpoint).Returns(() => endpoint.Object);
            var endpointExecutorFactory = Mock.Of <IEndpointExecutorFactory>();

            Mock.Get(endpointExecutorFactory).Setup(eef => eef.CreateAsync(It.IsAny <Endpoint>())).ReturnsAsync(endpointExecutor);

            // Create a route to map to the message
            var endpoints = new HashSet <Endpoint> {
                endpoint.Object
            };
            var route = new Route("myRoute", "true", "myIotHub", TelemetryMessageSource.Instance, endpoints);

            // Create a router
            var    routerConfig = new RouterConfig(new[] { route });
            Router router       = await Router.CreateAsync("myRouter", "myIotHub", routerConfig, endpointExecutorFactory);

            // Create mock message converter to generate a message with source matching the route
            var messageConverter = Mock.Of <Core.IMessageConverter <Devices.Routing.Core.IMessage> >();
            var methodRequest    = new DirectMethodRequest("device1/module1", "shutdown", null, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(20));

            // Mock of twin manager
            var twinManager = Mock.Of <ITwinManager>();

            // DeviceListener
            var identity   = Mock.Of <IModuleIdentity>(m => m.DeviceId == "device1" && m.ModuleId == "module1" && m.Id == "device1/module1");
            var cloudProxy = new Mock <ICloudProxy>();

            // ICloudConnectionProvider
            var cloudConnection         = Mock.Of <ICloudConnection>(c => c.IsActive && c.CloudProxy == Option.Some(cloudProxy.Object));
            var cloudConnectionProvider = new Mock <ICloudConnectionProvider>();

            cloudConnectionProvider.Setup(c => c.Connect(It.IsAny <IIdentity>(), It.IsAny <Action <string, CloudConnectionStatus> >()))
            .ReturnsAsync(Try.Success(cloudConnection));

            var deviceConnectivitymanager = Mock.Of <IDeviceConnectivityManager>();
            var connectionManager         = new ConnectionManager(cloudConnectionProvider.Object, Mock.Of <ICredentialsCache>(), new IdentityProvider("myIotHub"), deviceConnectivitymanager);

            IInvokeMethodHandler invokeMethodHandler = new InvokeMethodHandler(connectionManager);
            var subscriptionProcessor = new SubscriptionProcessor(connectionManager, invokeMethodHandler, Mock.Of <IDeviceConnectivityManager>());

            // RoutingEdgeHub
            var routingEdgeHub = new RoutingEdgeHub(
                router,
                messageConverter,
                connectionManager,
                twinManager,
                "testEdgeDevice",
                invokeMethodHandler,
                subscriptionProcessor);

            var deviceMessageHandler  = new DeviceMessageHandler(identity, routingEdgeHub, connectionManager);
            var underlyingDeviceProxy = new Mock <IDeviceProxy>();

            // Arrange
            Message message = new EdgeMessage.Builder(new byte[0]).Build();

            message.Properties[SystemProperties.CorrelationId] = methodRequest.CorrelationId;
            message.Properties[SystemProperties.StatusCode]    = "200";

            underlyingDeviceProxy.Setup(d => d.InvokeMethodAsync(It.IsAny <DirectMethodRequest>()))
            .Callback(() => deviceMessageHandler.ProcessMethodResponseAsync(message))
            .ReturnsAsync(default(DirectMethodResponse));
            underlyingDeviceProxy.SetupGet(d => d.IsActive).Returns(true);

            // Act
            deviceMessageHandler.BindDeviceProxy(underlyingDeviceProxy.Object);
            Task <DirectMethodResponse> responseTask = routingEdgeHub.InvokeMethodAsync(identity.Id, methodRequest);

            // Assert
            Assert.False(responseTask.IsCompleted);

            // Act
            await routingEdgeHub.AddSubscription(identity.Id, DeviceSubscription.Methods);

            await Task.Delay(TimeSpan.FromSeconds(5));

            // Assert
            Assert.True(responseTask.IsCompleted);
            Assert.Equal(methodRequest.CorrelationId, responseTask.Result.CorrelationId);
            Assert.Equal(200, responseTask.Result.Status);
            Assert.False(responseTask.Result.Exception.HasValue);
            Assert.Equal(HttpStatusCode.OK, responseTask.Result.HttpStatusCode);
        }
Example #27
0
 public static void ReceivedMethodCallResponse(DirectMethodRequest methodRequest, IIdentity identity)
 {
     Log.LogDebug((int)EventIds.ReceivedMethodResponse, $"Received response from call to method {methodRequest.Name} from device or module {methodRequest.Id}. Method invoked by module {identity.Id}");
 }
Example #28
0
 public static void ReceivedMethodCall(DirectMethodRequest methodRequest, IIdentity identity)
 {
     Log.LogDebug((int)EventIds.ReceivedMethodCall, $"Received call to invoke method {methodRequest.Name} on device or module {methodRequest.Id} from module {identity.Id}");
 }
Example #29
0
 public Task <DirectMethodResponse> InvokeMethodAsync(string id, DirectMethodRequest methodRequest)
 {
     this.whenCalled();
     return(Task.FromResult(new DirectMethodResponse("boo", new byte[0], 200)));
 }
Example #30
0
 public Task <DirectMethodResponse> InvokeMethodAsync(DirectMethodRequest request)
 {
     Events.SendingDirectMethod(this.Identity);
     return(this.directMethodHandler.CallDirectMethodAsync(request, this.Identity));
 }