Ejemplo n.º 1
0
 public Task SendMessageOnOutput(IMessage message, string outputNameArg)
 {
     message.SystemProperties[SystemProperties.ConnectionDeviceId] = this.moduleIdentity.DeviceId;
     message.SystemProperties[SystemProperties.ConnectionModuleId] = this.moduleIdentity.ModuleId;
     message.SystemProperties[SystemProperties.OutputName]         = outputNameArg;
     return(this.deviceListener.ProcessDeviceMessageAsync(message));
 }
Ejemplo n.º 2
0
            async Task <ISinkResult <IRoutingMessage> > ProcessAsync(IRoutingMessage routingMessage, string identity)
            {
                IMessage message = this.cloudEndpoint.messageConverter.ToMessage(routingMessage);

                Util.Option <ICloudProxy> cloudProxy = await this.cloudEndpoint.cloudProxyGetterFunc(identity);

                ISinkResult result = await cloudProxy.Match(
                    async cp =>
                {
                    try
                    {
                        using (Metrics.CloudLatency(identity))
                        {
                            await cp.SendMessageAsync(message);
                        }

                        var succeeded = new List <IRoutingMessage> {
                            routingMessage
                        };
                        Metrics.MessageCount(identity);

                        return(new SinkResult <IRoutingMessage>(succeeded));
                    }
                    catch (Exception ex)
                    {
                        return(this.HandleException(ex, routingMessage));
                    }
                },
                    () => this.ProcessNoConnection(identity, routingMessage));

                return(result);
            }
Ejemplo n.º 3
0
        public Task ProcessDeviceMessage(IIdentity identity, IMessage message)
        {
            Preconditions.CheckNotNull(message, nameof(message));
            Preconditions.CheckNotNull(identity, nameof(identity));
            Events.MessageReceived(identity);
            IRoutingMessage routingMessage = this.ProcessMessageInternal(message, true);

            return(this.router.RouteAsync(routingMessage));
        }
Ejemplo n.º 4
0
            public async Task <ISinkResult> ProcessAsync(ICollection <IRoutingMessage> routingMessages, CancellationToken token)
            {
                Preconditions.CheckNotNull(routingMessages, nameof(routingMessages));

                // TODO - figure out if we can use cancellation token to cancel send
                var succeeded = new List <IRoutingMessage>();
                var failed    = new List <IRoutingMessage>();
                var invalid   = new List <InvalidDetails <IRoutingMessage> >();
                SendFailureDetails sendFailureDetails = null;

                Events.ProcessingMessages(this.moduleEndpoint, routingMessages);
                Util.Option <IDeviceProxy> deviceProxy = this.GetDeviceProxy();
                if (!deviceProxy.HasValue)
                {
                    failed.AddRange(routingMessages);
                    sendFailureDetails = new SendFailureDetails(FailureKind.None, new EdgeHubConnectionException($"Target module {this.moduleEndpoint.moduleId} is not connected"));
                }
                else
                {
                    foreach (IRoutingMessage routingMessage in routingMessages)
                    {
                        IMessage message = this.moduleEndpoint.messageConverter.ToMessage(routingMessage);
                        await deviceProxy.ForEachAsync(
                            async dp =>
                        {
                            try
                            {
                                await dp.SendMessageAsync(message, this.moduleEndpoint.Input);
                                succeeded.Add(routingMessage);
                            }
                            catch (Exception ex)
                            {
                                if (IsRetryable(ex))
                                {
                                    failed.Add(routingMessage);
                                }
                                else
                                {
                                    Events.InvalidMessage(ex);
                                    invalid.Add(new InvalidDetails <IRoutingMessage>(routingMessage, FailureKind.None));
                                }

                                Events.ErrorSendingMessages(this.moduleEndpoint, ex);
                            }
                        });
                    }

                    if (failed.Count > 0)
                    {
                        Events.RetryingMessages(failed.Count, this.moduleEndpoint.Id);
                        sendFailureDetails = new SendFailureDetails(FailureKind.Transient, new EdgeHubIOException($"Error sending message to module {this.moduleEndpoint.moduleId}"));
                    }
                }

                return(new SinkResult <IRoutingMessage>(succeeded, failed, invalid, sendFailureDetails));
            }
Ejemplo n.º 5
0
 internal void AddEdgeSystemProperties(IMessage message)
 {
     message.SystemProperties[Core.SystemProperties.EdgeMessageId] = Guid.NewGuid().ToString();
     if (message.SystemProperties.TryGetValue(Core.SystemProperties.ConnectionDeviceId, out string deviceId))
     {
         string edgeHubOriginInterface = deviceId == this.edgeDeviceId
             ? Core.Constants.InternalOriginInterface
             : Core.Constants.DownstreamOriginInterface;
         message.SystemProperties[Core.SystemProperties.EdgeHubOriginInterface] = edgeHubOriginInterface;
     }
 }
Ejemplo n.º 6
0
            public async Task <ISinkResult> ProcessAsync(IRoutingMessage routingMessage, CancellationToken token)
            {
                Preconditions.CheckNotNull(routingMessage, nameof(routingMessage));
                var succeeded = new List <IRoutingMessage>();
                var failed    = new List <IRoutingMessage>();
                var invalid   = new List <InvalidDetails <IRoutingMessage> >();
                SendFailureDetails sendFailureDetails = null;

                IMessage message = this.cloudEndpoint.messageConverter.ToMessage(routingMessage);

                Util.Option <ICloudProxy> cloudProxy = await this.GetCloudProxy(routingMessage);

                if (!cloudProxy.HasValue)
                {
                    sendFailureDetails = new SendFailureDetails(FailureKind.None, new EdgeHubConnectionException("IoT Hub is not connected"));
                    failed.Add(routingMessage);
                }
                else
                {
                    await cloudProxy.ForEachAsync(async cp =>
                    {
                        try
                        {
                            string id = this.GetIdentity(routingMessage).Expect(() => new InvalidOperationException("Could not retrieve identity of message"));
                            using (Metrics.CloudLatency(id))
                            {
                                await cp.SendMessageAsync(message);
                            }
                            succeeded.Add(routingMessage);
                            Metrics.MessageCount(id);
                        }
                        catch (Exception ex)
                        {
                            if (IsRetryable(ex))
                            {
                                failed.Add(routingMessage);
                            }
                            else
                            {
                                Events.InvalidMessage(ex);
                                invalid.Add(new InvalidDetails <IRoutingMessage>(routingMessage, FailureKind.None));
                            }

                            if (failed.Count > 0)
                            {
                                Events.RetryingMessage(routingMessage, ex);
                                sendFailureDetails = new SendFailureDetails(FailureKind.Transient, new EdgeHubIOException($"Error sending messages to IotHub for device {this.cloudEndpoint.Id}"));
                            }
                        }
                    });
                }

                return(new SinkResult <IRoutingMessage>(succeeded, failed, invalid, sendFailureDetails));
            }
Ejemplo n.º 7
0
 internal static void MessageReceived(IIdentity identity, IMessage message)
 {
     if (message.SystemProperties.TryGetValue(Devices.Routing.Core.SystemProperties.MessageId, out string messageId))
     {
         Log.LogDebug((int)EventIds.MessageReceived, Invariant($"Received message from {identity.Id} with message Id {messageId}"));
     }
     else
     {
         Log.LogDebug((int)EventIds.MessageReceived, Invariant($"Received message from {identity.Id}"));
     }
 }
Ejemplo n.º 8
0
        public Task UpdateReportedPropertiesAsync(IIdentity identity, IMessage reportedPropertiesMessage)
        {
            Preconditions.CheckNotNull(identity, nameof(identity));
            Preconditions.CheckNotNull(reportedPropertiesMessage, nameof(reportedPropertiesMessage));
            Events.UpdateReportedPropertiesReceived(identity);
            Task cloudSendMessageTask = this.twinManager.UpdateReportedPropertiesAsync(identity.Id, reportedPropertiesMessage);

            IRoutingMessage routingMessage         = this.ProcessMessageInternal(reportedPropertiesMessage, false);
            Task            routingSendMessageTask = this.router.RouteAsync(routingMessage);

            return(Task.WhenAll(cloudSendMessageTask, routingSendMessageTask));
        }
Ejemplo n.º 9
0
        public IRoutingMessage FromMessage(IMessage edgeMessage)
        {
            Preconditions.CheckNotNull(edgeMessage, nameof(edgeMessage));
            Preconditions.CheckNotNull(edgeMessage.Body, nameof(edgeMessage.Body));
            Preconditions.CheckNotNull(edgeMessage.Properties, nameof(edgeMessage.Properties));
            Preconditions.CheckNotNull(edgeMessage.SystemProperties, nameof(edgeMessage.SystemProperties));

            IMessageSource messageSource  = this.GetMessageSource(edgeMessage.SystemProperties);
            var            routingMessage = new RoutingMessage(messageSource, edgeMessage.Body, edgeMessage.Properties, edgeMessage.SystemProperties);

            return(routingMessage);
        }
Ejemplo n.º 10
0
        IRoutingMessage ProcessMessageInternal(IMessage message, bool validateSize)
        {
            this.AddEdgeSystemProperties(message);
            IRoutingMessage routingMessage = this.messageConverter.FromMessage(Preconditions.CheckNotNull(message, nameof(message)));

            // Validate message size
            if (validateSize)
            {
                ValidateMessageSize(routingMessage);
            }

            return(routingMessage);
        }
Ejemplo n.º 11
0
 public Task ProcessDeviceMessage(IIdentity identity, IMessage message)
 {
     Preconditions.CheckNotNull(message, nameof(message));
     Preconditions.CheckNotNull(identity, nameof(identity));
     Events.MessageReceived(identity, message);
     MetricsV0.MessageCount(identity, 1);
     using (MetricsV0.MessageLatency(identity))
     {
         IRoutingMessage routingMessage = this.ProcessMessageInternal(message, true);
         Metrics.AddMessageSize(routingMessage.Size(), identity.Id);
         return(this.router.RouteAsync(routingMessage));
     }
 }
Ejemplo n.º 12
0
        public Task ProcessDeviceMessage(IIdentity identity, IMessage message)
        {
            Preconditions.CheckNotNull(message, nameof(message));
            Preconditions.CheckNotNull(identity, nameof(identity));
            Events.MessageReceived(identity, message);

            IRoutingMessage routingMessage = this.ProcessMessageInternal(message, true);

            Metrics.AddMessageSize(routingMessage.Size(), identity.Id);
            Metrics.AddReceivedMessage(identity.Id, message.GetOutput());

            return(this.router.RouteAsync(routingMessage));
        }
Ejemplo n.º 13
0
        public Task SendC2DMessageAsync(string id, IMessage message)
        {
            Preconditions.CheckNonWhiteSpace(id, nameof(id));
            Preconditions.CheckNotNull(message, nameof(message));

            Option <IDeviceProxy> deviceProxy = this.connectionManager.GetDeviceConnection(id);

            if (!deviceProxy.HasValue)
            {
                Events.UnableToSendC2DMessageNoDeviceConnection(id);
            }

            return(deviceProxy.ForEachAsync(d => d.SendC2DMessageAsync(message)));
        }
Ejemplo n.º 14
0
        public async Task GetTwinForwardsToTwinManager()
        {
            // 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>(), new List <uint>()
            {
                0
            })).ReturnsAsync(endpointExecutor);

            // Create a route to map to the message
            var route = new Route("myRoute", "true", "myIotHub", TelemetryMessageSource.Instance, endpoint.Object, 0, 3600);

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

            var messageConverter  = Mock.Of <Core.IMessageConverter <Devices.Routing.Core.IMessage> >();
            var connectionManager = Mock.Of <IConnectionManager>();
            var twinManager       = new Mock <ITwinManager>();
            var message           = Mock.Of <IMessage>();

            twinManager.Setup(t => t.GetTwinAsync(It.IsAny <string>())).Returns(Task.FromResult(message));
            var routingEdgeHub = new RoutingEdgeHub(
                router,
                messageConverter,
                connectionManager,
                twinManager.Object,
                "testEdgeDevice",
                "$edgeHub",
                Mock.Of <IInvokeMethodHandler>(),
                Mock.Of <ISubscriptionProcessor>(),
                Mock.Of <IDeviceScopeIdentitiesCache>());

            IMessage received = await routingEdgeHub.GetTwinAsync("*");

            twinManager.Verify(x => x.GetTwinAsync("*"), Times.Once);

            Assert.Equal(message, received);
        }
Ejemplo n.º 15
0
            async Task <ISinkResult> ProcessAsync(ICollection <IRoutingMessage> routingMessages, IDeviceProxy dp, CancellationToken token)
            {
                // TODO - figure out if we can use cancellation token to cancel send
                var succeeded = new List <IRoutingMessage>();
                var failed    = new List <IRoutingMessage>();
                var invalid   = new List <InvalidDetails <IRoutingMessage> >();
                SendFailureDetails sendFailureDetails = null;

                foreach (IRoutingMessage routingMessage in routingMessages)
                {
                    IMessage message = this.moduleEndpoint.messageConverter.ToMessage(routingMessage);
                    try
                    {
                        if (failed.Count == 0)
                        {
                            await dp.SendMessageAsync(message, this.moduleEndpoint.Input);

                            succeeded.Add(routingMessage);
                        }
                        else
                        {
                            // if one failed, fail the rest, so retry will keep message order
                            failed.Add(routingMessage);
                        }
                    }
                    catch (Exception ex)
                    {
                        if (IsRetryable(ex))
                        {
                            failed.Add(routingMessage);
                        }
                        else
                        {
                            Events.InvalidMessage(ex);
                            invalid.Add(new InvalidDetails <IRoutingMessage>(routingMessage, FailureKind.InvalidInput));
                        }

                        Events.ErrorSendingMessages(this.moduleEndpoint, ex);
                    }
                }

                if (failed.Count > 0)
                {
                    Events.RetryingMessages(failed.Count, this.moduleEndpoint.Id);
                    sendFailureDetails = new SendFailureDetails(FailureKind.Transient, new EdgeHubIOException($"Error sending message to module {this.moduleEndpoint.moduleId}"));
                }

                return(new SinkResult <IRoutingMessage>(succeeded, failed, invalid, sendFailureDetails));
            }
Ejemplo n.º 16
0
        public void TestToMessageCases(IRoutingMessage routingMessage)
        {
            Core.IMessageConverter <IRoutingMessage> messageConverter = new RoutingMessageConverter();
            IMessage message = messageConverter.ToMessage(routingMessage);

            Assert.Equal(routingMessage.Body, message.Body);
            Assert.Equal(routingMessage.Properties.Count, message.Properties.Count);
            foreach (KeyValuePair <string, string> property in routingMessage.Properties)
            {
                Assert.True(message.Properties.ContainsKey(property.Key));
                Assert.Equal(property.Value, message.Properties[property.Key]);
            }

            Assert.Equal(routingMessage.SystemProperties.Count, message.SystemProperties.Count);
            foreach (KeyValuePair <string, string> property in routingMessage.SystemProperties)
            {
                Assert.True(message.SystemProperties.ContainsKey(property.Key));
                Assert.Equal(property.Value, message.SystemProperties[property.Key]);
            }
        }
Ejemplo n.º 17
0
        public async Task ReportedPropertyUpdatesAsTelemetryTest()
        {
            var routes = new List <string>
            {
                @"FROM /* INTO $upstream",
            };

            string edgeDeviceId = "edge";
            var    iotHub       = new IoTHub();

            (IEdgeHub edgeHub, IConnectionManager connectionManager) = await SetupEdgeHub(routes, iotHub, edgeDeviceId);

            TestDevice device1 = await TestDevice.Create("device1", edgeHub, connectionManager);

            IMessage message = GetReportedPropertiesMessage();
            await device1.UpdateReportedProperties(message);

            await Task.Delay(GetSleepTime());

            Assert.True(iotHub.HasReceivedTwinChangeNotification(edgeDeviceId, edgeHubModuleId));
        }
Ejemplo n.º 18
0
        public async Task TestRoutingTwinChangeNotificationFromModule()
        {
            var routes = new List <string>
            {
                @"FROM /twinChangeNotifications INTO BrokeredEndpoint(""/modules/mod1/inputs/in1"")"
            };

            string edgeDeviceId = "edge";
            var    iotHub       = new IoTHub();

            (IEdgeHub edgeHub, IConnectionManager connectionManager) = await SetupEdgeHub(routes, iotHub, edgeDeviceId);

            TestModule module1 = await TestModule.Create(edgeDeviceId, "mod1", "op1", "in1", edgeHub, connectionManager);

            TestModule module2 = await TestModule.Create(edgeDeviceId, "mod2", "op2", "in2", edgeHub, connectionManager);

            IMessage message = GetReportedPropertiesMessage();
            await module2.UpdateReportedProperties(message);

            await Task.Delay(GetSleepTime());

            Assert.True(iotHub.HasReceivedTwinChangeNotification());
            Assert.True(module1.HasReceivedTwinChangeNotification());
        }
Ejemplo n.º 19
0
 public Task SendMessage(IMessage message)
 {
     message.SystemProperties[SystemProperties.ConnectionDeviceId] = this.deviceIdentity.DeviceId;
     return(this.deviceListener.ProcessDeviceMessageAsync(message));
 }
Ejemplo n.º 20
0
 public void TestFromMessageErrorCases(IMessage inputMessage, Type exceptionType)
 {
     Core.IMessageConverter <IRoutingMessage> messageConverter = new RoutingMessageConverter();
     Assert.Throws(exceptionType, () => messageConverter.FromMessage(inputMessage));
 }
Ejemplo n.º 21
0
 public Task SendMessageOnOutput(IMessage message) => this.SendMessageOnOutput(message, this.outputName);
Ejemplo n.º 22
0
 public Task UpdateDesiredPropertiesAsync(string id, IMessage twinCollection)
 {
     Events.UpdateDesiredPropertiesCallReceived(id);
     return(this.twinManager.UpdateDesiredPropertiesAsync(id, twinCollection));
 }
Ejemplo n.º 23
0
 public Task UpdateReportedProperties(IMessage reportedPropertiesMessage) =>
 this.deviceListener.UpdateReportedPropertiesAsync(reportedPropertiesMessage, Guid.NewGuid().ToString());
Ejemplo n.º 24
0
 public bool HasReceivedMessage(IMessage message) => this.ReceivedMessages.Any(m =>
                                                                               m.SystemProperties[SystemProperties.MessageId] == message.SystemProperties[SystemProperties.MessageId]);