Exemple #1
0
        public void TestTryParseAddressWithTailingSlashOptional()
        {
            IList <string> input = new List <string> {
                "a/{b}/c/{d}", "a/{b}/c/{d}/"
            };
            var config = new MessageAddressConversionConfiguration(
                input,
                DontCareOutput);
            var converter = new MessageAddressConverter(config);

            string address = "a/bee/c/dee";
            ProtocolGatewayMessage message = new ProtocolGatewayMessage.Builder(Payload, address)
                                             .Build();
            bool status = converter.TryParseProtocolMessagePropsFromAddress(message);

            Assert.True(status);
            Assert.Equal(2, message.Properties.Count);
            Assert.Equal("bee", message.Properties["b"]);
            Assert.Equal("dee", message.Properties["d"]);

            string address2 = "a/bee/c/dee/";
            ProtocolGatewayMessage message2 = new ProtocolGatewayMessage.Builder(Payload, address2)
                                              .Build();
            bool status2 = converter.TryParseProtocolMessagePropsFromAddress(message2);

            Assert.True(status2);
            Assert.Equal(2, message2.Properties.Count);
            Assert.Equal("bee", message2.Properties["b"]);
            Assert.Equal("dee", message2.Properties["d"]);
        }
        public void TestTryParseAddressIntoMessagePropertiesMultipleInput()
        {
            IList <string> input = new List <string>()
            {
                "a/{b}/c/{d}/", "e/{f}/g/{h}/"
            };
            var config = new MessageAddressConversionConfiguration(
                input,
                DontCareOutput
                );
            var converter = new MessageAddressConverter(config);

            string address = "a/bee/c/dee/";
            ProtocolGatewayMessage message = new ProtocolGatewayMessage.Builder(Payload, address)
                                             .Build();
            bool status = converter.TryParseProtocolMessagePropsFromAddress(message);

            Assert.True(status);
            string value;

            Assert.True(message.Properties.TryGetValue("b", out value));
            Assert.Equal <string>("bee", value);
            Assert.True(message.Properties.TryGetValue("d", out value));
            Assert.Equal <string>("dee", value);
            Assert.Equal(2, message.Properties.Count);
        }
Exemple #3
0
        public void TestToMessage_NoTopicMatch()
        {
            var outputTemplates = new Dictionary <string, string>
            {
                ["Dummy"] = string.Empty
            };
            var inputTemplates = new List <string>
            {
                "devices/{deviceId}/messages/events/{params}/",
                "devices/{deviceId}/messages/events/"
            };
            var config = new MessageAddressConversionConfiguration(
                inputTemplates,
                outputTemplates);
            var converter              = new MessageAddressConverter(config);
            var properties             = new Dictionary <string, string>();
            var protocolGatewayMessage = Mock.Of <IProtocolGatewayMessage>(
                m =>
                m.Address == @"devices/Device_6/messages/eve/%24.cid=Corrid1&%24.mid=MessageId1&Foo=Bar&Prop2=Value2&Prop3=Value3/" &&
                m.Payload.Equals(Payload) &&
                m.Properties == properties);

            var protocolGatewayMessageConverter = new ProtocolGatewayMessageConverter(converter, ByteBufferConverter);

            Assert.Throws <InvalidOperationException>(() => protocolGatewayMessageConverter.ToMessage(protocolGatewayMessage));
        }
        public void TestTryParseAddressWithParamsIntoMessagePropertiesMultipleInput()
        {
            IList <string> input = new List <string>()
            {
                "a/{b}/c/{params}/", "a/{b}/{c}/d/{params}/"
            };
            var config = new MessageAddressConversionConfiguration(
                input,
                DontCareOutput
                );
            var converter = new MessageAddressConverter(config);

            string address = "a/bee/cee/d/p1=v1&p2=v2&$.mid=mv1/";
            ProtocolGatewayMessage message = new ProtocolGatewayMessage.Builder(Payload, address)
                                             .Build();
            bool status = converter.TryParseProtocolMessagePropsFromAddress(message);

            Assert.True(status);
            Assert.Equal(5, message.Properties.Count);
            Assert.Equal <string>("bee", message.Properties["b"]);
            Assert.Equal <string>("cee", message.Properties["c"]);
            Assert.Equal("v1", message.Properties["p1"]);
            Assert.Equal("v2", message.Properties["p2"]);
            Assert.Equal("mv1", message.Properties["$.mid"]);
        }
        public void TryDeriveAddressWorksWithMoreThanOneTemplate()
        {
            string address;
            var    testTemplate = new Dictionary <string, string>()
            {
                ["Test1"] = "a/{b}/c",
                ["Test2"] = "d/{e}/f",
                ["Test3"] = "x/{y}/z"
            };
            var config = new MessageAddressConversionConfiguration(
                DontCareInput,
                testTemplate
                );
            Mock <IMessage> message = CreateMessageWithSystemProps(new Dictionary <string, string>()
            {
                ["e"] = "123"
            });

            var  converter = new MessageAddressConverter(config);
            bool result    = converter.TryBuildProtocolAddressFromEdgeHubMessage("Test2", message.Object, EmptyProperties, out address);

            Assert.True(result);
            Assert.NotNull(address);
            Assert.NotEmpty(address);
            Assert.Equal <string>("d/123/f", address);
            message.VerifyAll();
        }
        public void TryDeriveAddressWorksWithMultipleVariableTemplate()
        {
            string address;
            var    testTemplate = new Dictionary <string, string>()
            {
                ["Test"] = "a/{b}/c/{d}/e/{f}/",
            };
            var config = new MessageAddressConversionConfiguration(
                DontCareInput,
                testTemplate
                );
            Mock <IMessage> message = CreateMessageWithSystemProps(new Dictionary <string, string>()
            {
                ["b"] = "123",
                ["d"] = "456",
                ["f"] = "789"
            });

            var  converter = new MessageAddressConverter(config);
            bool result    = converter.TryBuildProtocolAddressFromEdgeHubMessage("Test", message.Object, EmptyProperties, out address);

            Assert.True(result);
            Assert.NotNull(address);
            Assert.NotEmpty(address);
            Assert.Equal <string>("a/123/c/456/e/789/", address);
            message.VerifyAll();
        }
Exemple #7
0
        static ProtocolGatewayMessageConverter MakeProtocolGatewayMessageConverter()
        {
            var config    = new MessageAddressConversionConfiguration(Input, Output);
            var converter = new MessageAddressConverter(config);

            return(new ProtocolGatewayMessageConverter(converter, ByteBufferConverter));
        }
Exemple #8
0
        public void RpSenderTest()
        {
            // Setup
            const string DeviceId        = "Device1";
            const string ModuleId        = "Module1";
            const string Input           = "input1";
            var          outputTemplates = new Dictionary <string, string>
            {
                ["ModuleEndpoint"] = "devices/{deviceId}/modules/{moduleId}/inputs/{inputName}"
            };
            var inputTemplates = new List <string>
            {
                "devices/{deviceId}/messages/events/{params}/"
            };
            var config = new MessageAddressConversionConfiguration(
                inputTemplates,
                outputTemplates);
            var converter = new MessageAddressConverter(config);

            var properties = new Dictionary <string, string>();

            var systemProperties = new Dictionary <string, string>
            {
                [SystemProperties.OutboundUri]             = Constants.OutboundUriModuleEndpoint,
                [SystemProperties.LockToken]               = Guid.NewGuid().ToString(),
                [TemplateParameters.DeviceIdTemplateParam] = DeviceId,
                [Constants.ModuleIdTemplateParameter]      = ModuleId,
                [SystemProperties.InputName]               = Input,
                [SystemProperties.OutputName]              = "output",
                [SystemProperties.ContentEncoding]         = "utf-8",
                [SystemProperties.ContentType]             = "application/json",

                [SystemProperties.ConnectionDeviceId]           = "edgeDevice1",
                [SystemProperties.ConnectionModuleId]           = "$edgeHub",
                [SystemProperties.RpConnectionDeviceIdInternal] = "leafDevice1",
                [SystemProperties.RpConnectionModuleIdInternal] = "leafModule1",
            };

            var message = Mock.Of <IMessage>(
                m =>
                m.Body == new byte[] { 1, 2, 3 } &&
                m.Properties == properties &&
                m.SystemProperties == systemProperties);

            var protocolGatewayMessageConverter = new ProtocolGatewayMessageConverter(converter, ByteBufferConverter);

            // Act
            IProtocolGatewayMessage pgMessage = protocolGatewayMessageConverter.FromMessage(message);

            // Verify
            Assert.NotNull(pgMessage);
            Assert.Equal(@"devices/Device1/modules/Module1/inputs/input1/%24.ce=utf-8&%24.ct=application%2Fjson&%24.cdid=leafDevice1&%24.cmid=leafModule1", pgMessage.Address);
            Assert.Equal("leafDevice1", pgMessage.Properties["$.cdid"]);
            Assert.Equal("leafModule1", pgMessage.Properties["$.cmid"]);
        }
Exemple #9
0
 public MqttModule(
     IConfiguration mqttSettingsConfiguration,
     MessageAddressConversionConfiguration conversionConfiguration,
     X509Certificate2 tlsCertificate,
     bool isStoreAndForwardEnabled,
     bool clientCertAuthAllowed,
     bool optimizeForPerformance)
 {
     this.mqttSettingsConfiguration = Preconditions.CheckNotNull(mqttSettingsConfiguration, nameof(mqttSettingsConfiguration));
     this.conversionConfiguration   = Preconditions.CheckNotNull(conversionConfiguration, nameof(conversionConfiguration));
     this.tlsCertificate            = Preconditions.CheckNotNull(tlsCertificate, nameof(tlsCertificate));
     this.isStoreAndForwardEnabled  = isStoreAndForwardEnabled;
     this.clientCertAuthAllowed     = clientCertAuthAllowed;
     this.optimizeForPerformance    = optimizeForPerformance;
 }
Exemple #10
0
 public MqttModule(
     IConfiguration mqttSettingsConfiguration,
     MessageAddressConversionConfiguration conversionConfiguration,
     X509Certificate2 tlsCertificate,
     bool isStoreAndForwardEnabled,
     bool clientCertAuthAllowed,
     SslProtocols sslProtocols)
 {
     this.mqttSettingsConfiguration = Preconditions.CheckNotNull(mqttSettingsConfiguration, nameof(mqttSettingsConfiguration));
     this.conversionConfiguration   = Preconditions.CheckNotNull(conversionConfiguration, nameof(conversionConfiguration));
     this.tlsCertificate            = Preconditions.CheckNotNull(tlsCertificate, nameof(tlsCertificate));
     this.isStoreAndForwardEnabled  = isStoreAndForwardEnabled;
     this.clientCertAuthAllowed     = clientCertAuthAllowed;
     this.sslProtocols = sslProtocols;
 }
Exemple #11
0
        public void TestTryParseAddressWithParamsIntoMessagePropertiesFailsNoMatchMultiple()
        {
            IList <string> input = new List <string>()
            {
                "a/{b}/d/", "a/{b}/c/{params}"
            };
            var config = new MessageAddressConversionConfiguration(
                input,
                DontCareOutput);
            var converter = new MessageAddressConverter(config);

            string address = "a/bee/p1=v1&p2=v2";
            ProtocolGatewayMessage message = new ProtocolGatewayMessage.Builder(Payload, address)
                                             .Build();
            bool status = converter.TryParseProtocolMessagePropsFromAddress(message);

            Assert.False(status);
            Assert.Equal(0, message.Properties.Count);
        }
Exemple #12
0
        public void TestTryDeriveAddressFailsWithEmptyProperties()
        {
            string address;
            var    testTemplate = new Dictionary <string, string>()
            {
                ["Test"] = "a/{b}/c",
            };
            var config = new MessageAddressConversionConfiguration(
                DontCareInput,
                testTemplate);
            Mock <IMessage> message = CreateMessageWithSystemProps(new Dictionary <string, string>());

            var  converter = new MessageAddressConverter(config);
            bool result    = converter.TryBuildProtocolAddressFromEdgeHubMessage("Test", message.Object, EmptyProperties, out address);

            Assert.False(result);
            Assert.Null(address);
            message.VerifyAll();
        }
Exemple #13
0
        void RegisterMqttModule(
            ContainerBuilder builder,
            StoreAndForward storeAndForward,
            ExperimentalFeatures experimentalFeatures)
        {
            var topics = new MessageAddressConversionConfiguration(
                this.configuration.GetSection(Constants.TopicNameConversionSectionName + ":InboundTemplates").Get <List <string> >(),
                this.configuration.GetSection(Constants.TopicNameConversionSectionName + ":OutboundTemplates").Get <Dictionary <string, string> >());

            bool clientCertAuthEnabled = this.configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false);

            IConfiguration mqttSettingsConfiguration = this.configuration.GetSection("mqttSettings");

            // MQTT broker overrides the legacy MQTT protocol head
            if (mqttSettingsConfiguration.GetValue("enabled", true) && !experimentalFeatures.EnableMqttBroker)
            {
                builder.RegisterModule(new MqttModule(mqttSettingsConfiguration, topics, this.serverCertificate, storeAndForward.IsEnabled, clientCertAuthEnabled, this.sslProtocols));
            }
        }
        public void TestToMessage_Module()
        {
            var outputTemplates = new Dictionary <string, string>
            {
                ["Dummy"] = ""
            };
            var inputTemplates = new List <string>
            {
                "devices/{deviceId}/messages/events/{params}/",
                "devices/{deviceId}/messages/events/",
                "devices/{deviceId}/modules/{moduleId}/messages/events/{params}/",
                "devices/{deviceId}/modules/{moduleId}/messages/events/"
            };
            var config = new MessageAddressConversionConfiguration(
                inputTemplates,
                outputTemplates
                );
            var converter              = new MessageAddressConverter(config);
            var properties             = new Dictionary <string, string>();
            var protocolGatewayMessage = Mock.Of <IProtocolGatewayMessage>(
                m =>
                m.Address == @"devices/Device_6/modules/SensorModule/messages/events/%24.cid=Corrid1&%24.mid=MessageId1&Foo=Bar&Prop2=Value2&Prop3=Value3/" &&
                m.Payload.Equals(Payload) &&
                m.Properties == properties
                );

            var      protocolGatewayMessageConverter = new ProtocolGatewayMessageConverter(converter, ByteBufferConverter);
            IMessage message = protocolGatewayMessageConverter.ToMessage(protocolGatewayMessage);

            Assert.NotNull(message);

            Assert.Equal(4, message.SystemProperties.Count);
            Assert.Equal("Corrid1", message.SystemProperties[SystemProperties.MsgCorrelationId]);
            Assert.Equal("MessageId1", message.SystemProperties[SystemProperties.MessageId]);
            Assert.Equal("Device_6", message.SystemProperties[SystemProperties.ConnectionDeviceId]);
            Assert.Equal("SensorModule", message.SystemProperties[SystemProperties.ConnectionModuleId]);

            Assert.Equal(3, message.Properties.Count);
            Assert.Equal("Bar", message.Properties["Foo"]);
            Assert.Equal("Value2", message.Properties["Prop2"]);
            Assert.Equal("Value3", message.Properties["Prop3"]);
        }
        public void TryDeriveAddressWorksWithMultipleVariableTemplateWithParameters()
        {
            string address;
            var    testTemplate = new Dictionary <string, string>()
            {
                ["Test"] = "a/{b}/c/{d}/e/{f}/",
            };
            var config = new MessageAddressConversionConfiguration(
                DontCareInput,
                testTemplate
                );

            var systemProperties = new Dictionary <string, string>()
            {
                ["b"] = "123",
                ["d"] = "456",
                ["f"] = "789",
                [SystemProperties.OutgoingSystemPropertiesMap[SystemProperties.ConnectionDeviceId]] = "Device1",
                [SystemProperties.OutgoingSystemPropertiesMap[SystemProperties.ConnectionModuleId]] = "Module1"
            };

            var properties = new Dictionary <string, string>()
            {
                ["Prop1"] = "Val1",
                ["Prop2"] = "Val2",
                [SystemProperties.OutgoingSystemPropertiesMap[SystemProperties.ConnectionDeviceId]] = "Device1",
                [SystemProperties.OutgoingSystemPropertiesMap[SystemProperties.ConnectionModuleId]] = "Module1"
            };

            Mock <IMessage> message = CreateMessageWithSystemProps(systemProperties);

            var  converter = new MessageAddressConverter(config);
            bool result    = converter.TryBuildProtocolAddressFromEdgeHubMessage("Test", message.Object, properties, out address);

            Assert.True(result);
            Assert.NotNull(address);
            Assert.NotEmpty(address);
            Assert.Equal <string>("a/123/c/456/e/789/Prop1=Val1&Prop2=Val2&%24.cdid=Device1&%24.cmid=Module1", address);
            message.VerifyAll();
        }
        public void TryDeriveAddressWorksWithMoreThanOneTemplateWithParameters()
        {
            string address;
            var    testTemplate = new Dictionary <string, string>()
            {
                ["Test1"] = "a/{b}/c",
                ["Test2"] = "d/{e}/f",
                ["Test3"] = "x/{y}/z"
            };
            var config = new MessageAddressConversionConfiguration(
                DontCareInput,
                testTemplate
                );

            var systemProperties = new Dictionary <string, string>()
            {
                ["e"] = "123",
                [SystemProperties.OutgoingSystemPropertiesMap[SystemProperties.ConnectionDeviceId]] = "Device1"
            };

            var properties = new Dictionary <string, string>()
            {
                ["Prop1"] = "Val1",
                ["Prop2"] = "Val2",
                [SystemProperties.OutgoingSystemPropertiesMap[SystemProperties.ConnectionDeviceId]] = "Device1"
            };

            Mock <IMessage> message = CreateMessageWithSystemProps(systemProperties);

            var  converter = new MessageAddressConverter(config);
            bool result    = converter.TryBuildProtocolAddressFromEdgeHubMessage("Test2", message.Object, properties, out address);

            Assert.True(result);
            Assert.NotNull(address);
            Assert.NotEmpty(address);
            Assert.Equal <string>("d/123/f/Prop1=Val1&Prop2=Val2&%24.cdid=Device1", address);
            message.VerifyAll();
        }
Exemple #17
0
        public void Register(ContainerBuilder builder)
        {
            const int ConnectionPoolSize = 10;

            string edgeHubConnectionString = $"{this.configuration[Service.Constants.ConfigKey.IotHubConnectionString]};ModuleId=$edgeHub";

            Client.IotHubConnectionStringBuilder iotHubConnectionStringBuilder = Client.IotHubConnectionStringBuilder.Create(edgeHubConnectionString);
            var topics = new MessageAddressConversionConfiguration(this.inboundTemplates, this.outboundTemplates);

            builder.RegisterModule(new LoggingModule());

            var mqttSettingsConfiguration = new Mock <IConfiguration>();

            mqttSettingsConfiguration.Setup(c => c.GetSection(It.IsAny <string>())).Returns(Mock.Of <IConfigurationSection>(s => s.Value == null));

            builder.RegisterBuildCallback(
                c =>
            {
                // set up loggers for dotnetty
                var loggerFactory = c.Resolve <ILoggerFactory>();
                InternalLoggerFactory.DefaultFactory = loggerFactory;

                var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("ProtocolGateway"));
                eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational);
            });

            var versionInfo = new VersionInfo("v1", "b1", "c1");
            var storeAndForwardConfiguration = new StoreAndForwardConfiguration(-1);

            builder.RegisterModule(
                new CommonModule(
                    string.Empty,
                    iotHubConnectionStringBuilder.HostName,
                    iotHubConnectionStringBuilder.DeviceId,
                    iotHubConnectionStringBuilder.ModuleId,
                    string.Empty,
                    Option.None <string>(),
                    AuthenticationMode.CloudAndScope,
                    Option.Some(edgeHubConnectionString),
                    false,
                    false,
                    string.Empty,
                    Option.None <string>(),
                    TimeSpan.FromHours(1),
                    false,
                    this.trustBundle));

            builder.RegisterModule(
                new RoutingModule(
                    iotHubConnectionStringBuilder.HostName,
                    iotHubConnectionStringBuilder.DeviceId,
                    iotHubConnectionStringBuilder.ModuleId,
                    Option.Some(edgeHubConnectionString),
                    this.routes,
                    false,
                    storeAndForwardConfiguration,
                    ConnectionPoolSize,
                    false,
                    versionInfo,
                    Option.Some(UpstreamProtocol.Amqp),
                    TimeSpan.FromSeconds(5),
                    101,
                    TimeSpan.FromSeconds(3600),
                    true,
                    TimeSpan.FromSeconds(20)));

            builder.RegisterModule(new HttpModule());
            builder.RegisterModule(new MqttModule(mqttSettingsConfiguration.Object, topics, this.serverCertificate, false, false, false));
            builder.RegisterModule(new AmqpModule("amqps", 5671, this.serverCertificate, iotHubConnectionStringBuilder.HostName, true));
        }
Exemple #18
0
        public void Register(ContainerBuilder builder)
        {
            const int ConnectionPoolSize = 10;

            string edgeHubConnectionString = $"{this.configuration[EdgeHubConstants.ConfigKey.IotHubConnectionString]};ModuleId=$edgeHub";
            IotHubConnectionStringBuilder iotHubConnectionStringBuilder = IotHubConnectionStringBuilder.Create(edgeHubConnectionString);
            var topics = new MessageAddressConversionConfiguration(this.inboundTemplates, this.outboundTemplates);

            builder.RegisterModule(new LoggingModule());

            var mqttSettingsConfiguration = new Mock <IConfiguration>();

            mqttSettingsConfiguration.Setup(c => c.GetSection(It.IsAny <string>())).Returns(Mock.Of <IConfigurationSection>(s => s.Value == null));

            var experimentalFeatures = new ExperimentalFeatures(true, false, false, true);

            builder.RegisterBuildCallback(
                c =>
            {
                // set up loggers for dotnetty
                var loggerFactory = c.Resolve <ILoggerFactory>();
                InternalLoggerFactory.DefaultFactory = loggerFactory;

                var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("ProtocolGateway"));
                eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational);
            });

            var versionInfo   = new VersionInfo("v1", "b1", "c1");
            var metricsConfig = new MetricsConfig(true, new MetricsListenerConfig());
            var backupFolder  = Option.None <string>();

            string      storageFolder = string.Empty;
            StoreLimits storeLimits   = null;

            if (!int.TryParse(this.configuration["TimeToLiveSecs"], out int timeToLiveSecs))
            {
                timeToLiveSecs = -1;
            }

            if (long.TryParse(this.configuration["MaxStorageBytes"], out long maxStorageBytes))
            {
                storeLimits = new StoreLimits(maxStorageBytes);
            }

            var storeAndForwardConfiguration = new StoreAndForwardConfiguration(timeToLiveSecs, storeLimits);

            if (bool.TryParse(this.configuration["UsePersistentStorage"], out bool usePersistentStorage) && usePersistentStorage)
            {
                storageFolder = GetOrCreateDirectoryPath(this.configuration["StorageFolder"], EdgeHubConstants.EdgeHubStorageFolder);
            }

            if (bool.TryParse(this.configuration["EnableNonPersistentStorageBackup"], out bool enableNonPersistentStorageBackup))
            {
                backupFolder = Option.Some(this.configuration["BackupFolder"]);
            }

            var    testRoutes   = this.routes;
            string customRoutes = this.configuration["Routes"];

            if (!string.IsNullOrWhiteSpace(customRoutes))
            {
                testRoutes = JsonConvert.DeserializeObject <IDictionary <string, string> >(customRoutes);
            }

            builder.RegisterModule(
                new CommonModule(
                    string.Empty,
                    iotHubConnectionStringBuilder.HostName,
                    iotHubConnectionStringBuilder.DeviceId,
                    iotHubConnectionStringBuilder.ModuleId,
                    string.Empty,
                    Option.None <string>(),
                    AuthenticationMode.CloudAndScope,
                    Option.Some(edgeHubConnectionString),
                    false,
                    usePersistentStorage,
                    storageFolder,
                    Option.None <string>(),
                    Option.None <string>(),
                    TimeSpan.FromHours(1),
                    false,
                    this.trustBundle,
                    string.Empty,
                    metricsConfig,
                    enableNonPersistentStorageBackup,
                    backupFolder,
                    Option.None <ulong>(),
                    Option.None <StorageLogLevel>()));

            builder.RegisterModule(
                new RoutingModule(
                    iotHubConnectionStringBuilder.HostName,
                    iotHubConnectionStringBuilder.DeviceId,
                    iotHubConnectionStringBuilder.ModuleId,
                    Option.Some(edgeHubConnectionString),
                    testRoutes,
                    true,
                    storeAndForwardConfiguration,
                    ConnectionPoolSize,
                    false,
                    versionInfo,
                    Option.Some(UpstreamProtocol.Amqp),
                    TimeSpan.FromSeconds(5),
                    101,
                    TimeSpan.FromSeconds(30),
                    TimeSpan.FromSeconds(3600),
                    true,
                    TimeSpan.FromSeconds(20),
                    false,
                    Option.None <TimeSpan>(),
                    Option.None <TimeSpan>(),
                    false,
                    10,
                    10,
                    false,
                    TimeSpan.FromHours(1),
                    experimentalFeatures));

            builder.RegisterModule(new HttpModule());
            builder.RegisterModule(new MqttModule(mqttSettingsConfiguration.Object, topics, this.serverCertificate, false, false, false, this.sslProtocols));
            builder.RegisterModule(new AmqpModule("amqps", 5671, this.serverCertificate, iotHubConnectionStringBuilder.HostName, true, this.sslProtocols));
        }
            async Task StartProtocolHead()
            {
                const int ConnectionPoolSize = 10;
                string    certificateValue   = await SecretsHelper.GetSecret("IotHubMqttHeadCert");

                byte[] cert        = Convert.FromBase64String(certificateValue);
                var    certificate = new X509Certificate2(cert);

                string edgeDeviceConnectionString = await SecretsHelper.GetSecretFromConfigKey("edgeCapableDeviceConnStrKey");

                // TODO - After IoTHub supports MQTT, remove this and move to using MQTT for upstream connections
                await ConnectToIotHub(edgeDeviceConnectionString);

                string edgeHubConnectionString = $"{edgeDeviceConnectionString};ModuleId=$edgeHub";

                Client.IotHubConnectionStringBuilder iotHubConnectionStringBuilder = Client.IotHubConnectionStringBuilder.Create(edgeHubConnectionString);
                var topics = new MessageAddressConversionConfiguration(this.inboundTemplates, this.outboundTemplates);

                var builder = new ContainerBuilder();

                builder.RegisterModule(new LoggingModule());

                var mqttSettingsConfiguration = new Mock <IConfiguration>();

                mqttSettingsConfiguration.Setup(c => c.GetSection(It.IsAny <string>())).Returns(Mock.Of <IConfigurationSection>(s => s.Value == null));

                builder.RegisterBuildCallback(
                    c =>
                {
                    // set up loggers for dotnetty
                    var loggerFactory = c.Resolve <ILoggerFactory>();
                    InternalLoggerFactory.DefaultFactory = loggerFactory;

                    var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("ProtocolGateway"));
                    eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational);
                });

                var versionInfo = new VersionInfo("v1", "b1", "c1");
                var storeAndForwardConfiguration = new StoreAndForwardConfiguration(-1);

                builder.RegisterModule(new CommonModule(string.Empty, iotHubConnectionStringBuilder.HostName, iotHubConnectionStringBuilder.DeviceId));
                builder.RegisterModule(
                    new RoutingModule(
                        iotHubConnectionStringBuilder.HostName,
                        iotHubConnectionStringBuilder.DeviceId, iotHubConnectionStringBuilder.ModuleId,
                        Option.Some(edgeHubConnectionString),
                        this.routes, false, false, storeAndForwardConfiguration,
                        string.Empty, ConnectionPoolSize, false, versionInfo, Option.Some(UpstreamProtocol.Amqp),
                        true, TimeSpan.FromSeconds(5), 101, false, Option.None <string>(), Option.None <string>())
                    );
                builder.RegisterModule(new HttpModule());
                builder.RegisterModule(new MqttModule(mqttSettingsConfiguration.Object, topics, certificate, false, false, string.Empty, false));
                builder.RegisterModule(new AmqpModule("amqps", 5671, certificate, iotHubConnectionStringBuilder.HostName));
                this.container = builder.Build();

                IConfigSource configSource = await this.container.Resolve <Task <IConfigSource> >();

                ConfigUpdater configUpdater = await this.container.Resolve <Task <ConfigUpdater> >();

                await configUpdater.Init(configSource);

                ILogger          logger           = this.container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub");
                MqttProtocolHead mqttProtocolHead = await this.container.Resolve <Task <MqttProtocolHead> >();

                AmqpProtocolHead amqpProtocolHead = await this.container.Resolve <Task <AmqpProtocolHead> >();

                this.protocolHead = new EdgeHubProtocolHead(new List <IProtocolHead> {
                    mqttProtocolHead, amqpProtocolHead
                }, logger);
                await this.protocolHead.StartAsync();
            }
Exemple #20
0
        public void TestToMessage_AllSystemProperties()
        {
            var outputTemplates = new Dictionary <string, string>
            {
                ["Dummy"] = string.Empty
            };
            var inputTemplates = new List <string>
            {
                "devices/{deviceId}/messages/events/{params}/",
                "devices/{deviceId}/messages/events/"
            };
            var config = new MessageAddressConversionConfiguration(
                inputTemplates,
                outputTemplates);
            var converter  = new MessageAddressConverter(config);
            var properties = new Dictionary <string, string>();

            var address = new StringBuilder();

            // base address
            address.Append("devices/Device_6/messages/events/");

            // append all system properties
            // correlation id
            address.Append($"{HttpUtility.UrlEncode("$.cid")}=1234");
            // message id
            address.Append($"&{HttpUtility.UrlEncode("$.mid")}=mid1");
            // to
            address.Append($"&{HttpUtility.UrlEncode("$.to")}=d2");
            // userId
            address.Append($"&{HttpUtility.UrlEncode("$.uid")}=u1");
            // output name
            address.Append($"&{HttpUtility.UrlEncode("$.on")}=op1");
            // contentType
            address.Append($"&{HttpUtility.UrlEncode("$.ct")}={HttpUtility.UrlEncode("application/json")}");
            // content encoding
            address.Append($"&{HttpUtility.UrlEncode("$.ce")}={HttpUtility.UrlEncode("utf-8")}");
            // messageSchema
            address.Append($"&{HttpUtility.UrlEncode("$.schema")}=someschema");
            // creation time
            address.Append($"&{HttpUtility.UrlEncode("$.ctime")}={HttpUtility.UrlEncode("2018-01-31")}");
            // component name
            address.Append($"&{HttpUtility.UrlEncode("$.sub")}=testComponent");

            // add custom properties
            address.Append("&Foo=Bar&Prop2=Value2&Prop3=Value3/");

            var protocolGatewayMessage = Mock.Of <IProtocolGatewayMessage>(
                m =>
                m.Address == address.ToString() &&
                m.Payload.Equals(Payload) &&
                m.Properties == properties);

            var      protocolGatewayMessageConverter = new ProtocolGatewayMessageConverter(converter, ByteBufferConverter);
            IMessage message = protocolGatewayMessageConverter.ToMessage(protocolGatewayMessage);

            Assert.NotNull(message);

            Assert.Equal(11, message.SystemProperties.Count);
            Assert.Equal("1234", message.SystemProperties[SystemProperties.MsgCorrelationId]);
            Assert.Equal("mid1", message.SystemProperties[SystemProperties.MessageId]);
            Assert.Equal("d2", message.SystemProperties[SystemProperties.To]);
            Assert.Equal("u1", message.SystemProperties[SystemProperties.UserId]);
            Assert.Equal("op1", message.SystemProperties[SystemProperties.OutputName]);
            Assert.Equal("application/json", message.SystemProperties[SystemProperties.ContentType]);
            Assert.Equal("utf-8", message.SystemProperties[SystemProperties.ContentEncoding]);
            Assert.Equal("someschema", message.SystemProperties[SystemProperties.MessageSchema]);
            Assert.Equal("2018-01-31", message.SystemProperties[SystemProperties.CreationTime]);
            Assert.Equal("Device_6", message.SystemProperties[SystemProperties.ConnectionDeviceId]);
            Assert.Equal("testComponent", message.SystemProperties[SystemProperties.ComponentName]);

            Assert.Equal(3, message.Properties.Count);
            Assert.Equal("Bar", message.Properties["Foo"]);
            Assert.Equal("Value2", message.Properties["Prop2"]);
            Assert.Equal("Value3", message.Properties["Prop3"]);
        }
Exemple #21
0
        public void TestFromMessage_DuplicateSystemProperties()
        {
            const string DeviceId        = "Device1";
            const string ModuleId        = "Module1";
            const string Input           = "input1";
            var          outputTemplates = new Dictionary <string, string>
            {
                ["ModuleEndpoint"] = "devices/{deviceId}/modules/{moduleId}/inputs/{inputName}"
            };
            var inputTemplates = new List <string>
            {
                "devices/{deviceId}/messages/events/{params}/",
                "devices/{deviceId}/messages/events/"
            };
            var config = new MessageAddressConversionConfiguration(
                inputTemplates,
                outputTemplates);
            var converter = new MessageAddressConverter(config);

            var properties = new Dictionary <string, string>
            {
                ["Foo"]    = "Bar",
                ["Prop2"]  = "Value2",
                ["Prop3"]  = "Value3",
                ["$.cdid"] = "IncorrectDeviceId",
                ["$.cmid"] = "IncorrectModuleId"
            };

            var systemProperties = new Dictionary <string, string>
            {
                [SystemProperties.OutboundUri]             = Constants.OutboundUriModuleEndpoint,
                [SystemProperties.LockToken]               = Guid.NewGuid().ToString(),
                [TemplateParameters.DeviceIdTemplateParam] = DeviceId,
                [Constants.ModuleIdTemplateParameter]      = ModuleId,
                [SystemProperties.InputName]               = Input,
                [SystemProperties.OutputName]              = "output",
                [SystemProperties.ContentEncoding]         = "utf-8",
                [SystemProperties.ContentType]             = "application/json",
                [SystemProperties.MessageSchema]           = "schema1",
                [SystemProperties.To]                 = "foo",
                [SystemProperties.UserId]             = "user1",
                [SystemProperties.MsgCorrelationId]   = "1234",
                [SystemProperties.MessageId]          = "m1",
                [SystemProperties.ConnectionDeviceId] = "fromDevice1",
                [SystemProperties.ConnectionModuleId] = "fromModule1"
            };

            var message = Mock.Of <IMessage>(
                m =>
                m.Body == new byte[] { 1, 2, 3 } &&
                m.Properties == properties &&
                m.SystemProperties == systemProperties);

            var protocolGatewayMessageConverter = new ProtocolGatewayMessageConverter(converter, ByteBufferConverter);
            IProtocolGatewayMessage pgMessage   = protocolGatewayMessageConverter.FromMessage(message);

            Assert.NotNull(pgMessage);
            Assert.Equal(
                @"devices/Device1/modules/Module1/inputs/input1/Foo=Bar&Prop2=Value2&Prop3=Value3&%24.cdid=fromDevice1&%24.cmid=fromModule1&%24.ce=utf-8&%24.ct=application%2Fjson&%24.schema=schema1&%24.to=foo&%24.uid=user1&%24.cid=1234&%24.mid=m1",
                pgMessage.Address);
            Assert.Equal(12, pgMessage.Properties.Count);
            Assert.Equal("Bar", pgMessage.Properties["Foo"]);
            Assert.Equal("Value2", pgMessage.Properties["Prop2"]);
            Assert.Equal("Value3", pgMessage.Properties["Prop3"]);
            Assert.Equal("utf-8", pgMessage.Properties["$.ce"]);
            Assert.Equal("application/json", pgMessage.Properties["$.ct"]);
            Assert.Equal("schema1", pgMessage.Properties["$.schema"]);
            Assert.Equal("foo", pgMessage.Properties["$.to"]);
            Assert.Equal("user1", pgMessage.Properties["$.uid"]);
            Assert.Equal("1234", pgMessage.Properties["$.cid"]);
            Assert.Equal("m1", pgMessage.Properties["$.mid"]);
            Assert.Equal("fromDevice1", pgMessage.Properties["$.cdid"]);
            Assert.Equal("fromModule1", pgMessage.Properties["$.cmid"]);
            Assert.False(pgMessage.Properties.ContainsKey("$.on"));
        }
Exemple #22
0
        IContainer BuildContainer(IServiceCollection services)
        {
            int  connectionPoolSize     = this.Configuration.GetValue <int>("IotHubConnectionPoolSize");
            bool optimizeForPerformance = this.Configuration.GetValue("OptimizeForPerformance", true);
            var  topics = new MessageAddressConversionConfiguration(
                this.Configuration.GetSection(Constants.TopicNameConversionSectionName + ":InboundTemplates").Get <List <string> >(),
                this.Configuration.GetSection(Constants.TopicNameConversionSectionName + ":OutboundTemplates").Get <Dictionary <string, string> >());

            string configSource  = this.Configuration.GetValue <string>("configSource");
            bool   useTwinConfig = !string.IsNullOrWhiteSpace(configSource) && configSource.Equals("twin", StringComparison.OrdinalIgnoreCase);

            var routes = this.Configuration.GetSection("routes").Get <Dictionary <string, string> >();

            (bool isEnabled, bool usePersistentStorage, StoreAndForwardConfiguration config, string storagePath)storeAndForward = this.GetStoreAndForwardConfiguration();

            IConfiguration            mqttSettingsConfiguration = this.Configuration.GetSection("appSettings");
            Option <UpstreamProtocol> upstreamProtocolOption    = Enum.TryParse(this.Configuration.GetValue("UpstreamProtocol", string.Empty), false, out UpstreamProtocol upstreamProtocol)
                ? Option.Some(upstreamProtocol)
                : Option.None <UpstreamProtocol>();
            int      connectivityCheckFrequencySecs = this.Configuration.GetValue("ConnectivityCheckFrequencySecs", 300);
            TimeSpan connectivityCheckFrequency     = connectivityCheckFrequencySecs < 0 ? TimeSpan.MaxValue : TimeSpan.FromSeconds(connectivityCheckFrequencySecs);

            // TODO: We don't want to make enabling Cert Auth configurable right now. Turn off Cert auth.
            //bool clientCertAuthEnabled = this.Configuration.GetValue("ClientCertAuthEnabled", false);
            bool            clientCertAuthEnabled = false;
            bool            cacheTokens           = this.Configuration.GetValue("CacheTokens", false);
            Option <string> workloadUri           = this.GetConfigurationValueIfExists <string>(Constants.WorkloadUriVariableName);
            Option <string> moduleGenerationId    = this.GetConfigurationValueIfExists <string>(Constants.ModuleGenerationIdVariableName);

            string caChainPath = this.Configuration.GetValue("EdgeModuleHubServerCAChainCertificateFile", string.Empty);
            // n Clients + 1 Edgehub
            int maxConnectedClients = this.Configuration.GetValue("MaxConnectedClients", 100) + 1;

            IConfiguration amqpSettings = this.Configuration.GetSection("amqp");

            var builder = new ContainerBuilder();

            builder.Populate(services);

            builder.RegisterModule(new LoggingModule());
            builder.RegisterBuildCallback(
                c =>
            {
                // set up loggers for dotnetty
                var loggerFactory = c.Resolve <ILoggerFactory>();
                InternalLoggerFactory.DefaultFactory = loggerFactory;

                var eventListener = new LoggerEventListener(loggerFactory.CreateLogger("ProtocolGateway"));
                eventListener.EnableEvents(CommonEventSource.Log, EventLevel.Informational);
            });

            string productInfo = VersionInfo.Get(Constants.VersionInfoFileName).ToString();

            Metrics.BuildMetricsCollector(this.Configuration);

            // Register modules
            builder.RegisterModule(
                new CommonModule(
                    productInfo,
                    this.iotHubHostname,
                    this.edgeDeviceId));
            builder.RegisterModule(
                new RoutingModule(
                    this.iotHubHostname,
                    this.edgeDeviceId,
                    this.edgeModuleId,
                    this.connectionString,
                    routes,
                    storeAndForward.isEnabled,
                    storeAndForward.usePersistentStorage,
                    storeAndForward.config,
                    storeAndForward.storagePath,
                    connectionPoolSize,
                    useTwinConfig,
                    this.VersionInfo,
                    upstreamProtocolOption,
                    optimizeForPerformance,
                    connectivityCheckFrequency,
                    maxConnectedClients,
                    cacheTokens,
                    workloadUri,
                    moduleGenerationId));

            builder.RegisterModule(new MqttModule(mqttSettingsConfiguration, topics, ServerCertificateCache.X509Certificate, storeAndForward.isEnabled, clientCertAuthEnabled, caChainPath, optimizeForPerformance));
            builder.RegisterModule(new AmqpModule(amqpSettings["scheme"], amqpSettings.GetValue <ushort>("port"), ServerCertificateCache.X509Certificate, this.iotHubHostname));
            builder.RegisterModule(new HttpModule());
            builder.RegisterInstance <IStartup>(this);

            IContainer container = builder.Build();

            return(container);
        }
        public void TestMessageAddressConverterWithEmptyConversionConfig()
        {
            var emptyConversionConfig = new MessageAddressConversionConfiguration();

            Assert.Throws(typeof(ArgumentException), () => new MessageAddressConverter(emptyConversionConfig));
        }