Exemple #1
0
 public RoutingModule(string iotHubName,
                      string edgeDeviceId,
                      string edgeModuleId,
                      Option <string> connectionString,
                      IDictionary <string, string> routes,
                      bool isStoreAndForwardEnabled,
                      StoreAndForwardConfiguration storeAndForwardConfiguration,
                      int connectionPoolSize,
                      bool useTwinConfig,
                      VersionInfo versionInfo,
                      Option <UpstreamProtocol> upstreamProtocol,
                      TimeSpan connectivityCheckFrequency,
                      int maxConnectedClients,
                      bool cacheTokens)
 {
     this.iotHubName                   = Preconditions.CheckNonWhiteSpace(iotHubName, nameof(iotHubName));
     this.edgeDeviceId                 = Preconditions.CheckNonWhiteSpace(edgeDeviceId, nameof(edgeDeviceId));
     this.connectionString             = Preconditions.CheckNotNull(connectionString, nameof(connectionString));
     this.routes                       = Preconditions.CheckNotNull(routes, nameof(routes));
     this.storeAndForwardConfiguration = Preconditions.CheckNotNull(storeAndForwardConfiguration, nameof(storeAndForwardConfiguration));
     this.edgeModuleId                 = edgeModuleId;
     this.isStoreAndForwardEnabled     = isStoreAndForwardEnabled;
     this.connectionPoolSize           = connectionPoolSize;
     this.useTwinConfig                = useTwinConfig;
     this.versionInfo                  = versionInfo ?? VersionInfo.Empty;
     this.upstreamProtocol             = upstreamProtocol;
     this.connectivityCheckFrequency   = connectivityCheckFrequency;
     this.maxConnectedClients          = Preconditions.CheckRange(maxConnectedClients, 1);
     this.cacheTokens                  = cacheTokens;
 }
Exemple #2
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="filePath"></param>
        public JsonConfigurationService(string filePath)
        {
            // Load the configuration using the path
            string configuration = File.ReadAllText(filePath);

            Log.Information("Store and forward configuration {configuration}", configuration);
            _storeAndForwardConfiguration = JsonConvert.DeserializeObject <StoreAndForwardConfiguration>(configuration);

            // Load the certificate from the local store using the thumbprint (Local / My) for use with the MHR upload
            using (X509Store x509Store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
            {
                x509Store.Open(OpenFlags.ReadOnly);

                X509Certificate2Collection certificates = x509Store.Certificates.Find(X509FindType.FindByThumbprint,
                                                                                      _storeAndForwardConfiguration.certificate_thumbprint, true);

                Certificate = certificates[0];

                Log.Information("Loaded certificate with subject '{subject}'", Certificate.Subject);
            }

            // Upload metadata
            HealthcareFacility = (HealthcareFacilityTypeCodes)Enum.Parse(typeof(HealthcareFacilityTypeCodes), _storeAndForwardConfiguration.healthcare_facility);
            PracticeSetting    = (PracticeSettingTypes)Enum.Parse(typeof(PracticeSettingTypes), _storeAndForwardConfiguration.practice_setting);
            ClientSystemType   = (CommonPcehrHeaderClientSystemType)Enum.Parse(typeof(CommonPcehrHeaderClientSystemType), _storeAndForwardConfiguration.client_system_type);

            ProductInfo = new ProductInfo
            {
                Vendor   = _storeAndForwardConfiguration.product_info.vendor,
                Version  = _storeAndForwardConfiguration.product_info.version,
                Platform = _storeAndForwardConfiguration.product_info.platform,
                Name     = _storeAndForwardConfiguration.product_info.name,
            };
        }
Exemple #3
0
        StoreAndForward GetStoreAndForwardConfiguration()
        {
            int  defaultTtl           = -1;
            bool usePersistentStorage = this.configuration.GetValue <bool>("usePersistentStorage");
            int  timeToLiveSecs       = defaultTtl;

            // Note: Keep in sync with iotedge-check's edge-hub-storage-mounted-from-host check (edgelet/iotedge/src/check/checks/storage_mounted_from_host.rs)
            string                   storagePath            = GetOrCreateDirectoryPath(this.configuration.GetValue <string>("StorageFolder"), Constants.EdgeHubStorageFolder);
            bool                     storeAndForwardEnabled = this.configuration.GetValue <bool>("storeAndForwardEnabled");
            Option <ulong>           storageMaxTotalWalSize = this.GetConfigIfExists <ulong>(Constants.ConfigKey.StorageMaxTotalWalSize, this.configuration);
            Option <int>             storageMaxOpenFiles    = this.GetConfigIfExists <int>(Constants.ConfigKey.StorageMaxOpenFiles, this.configuration);
            Option <StorageLogLevel> storageLogLevel        = this.GetConfigIfExists <StorageLogLevel>(Constants.ConfigKey.StorageLogLevel, this.configuration);

            if (storeAndForwardEnabled)
            {
                IConfiguration storeAndForwardConfigurationSection = this.configuration.GetSection("storeAndForward");
                timeToLiveSecs = storeAndForwardConfigurationSection.GetValue("timeToLiveSecs", defaultTtl);
            }

            Option <string> storageBackupPath   = Option.None <string>();
            bool            useBackupAndRestore = !usePersistentStorage && this.configuration.GetValue <bool>("EnableNonPersistentStorageBackup");

            if (useBackupAndRestore)
            {
                storageBackupPath = Option.Some(GetOrCreateDirectoryPath(this.configuration.GetValue <string>("BackupFolder"), Constants.EdgeHubStorageBackupFolder));
            }

            var storeAndForwardConfiguration = new StoreAndForwardConfiguration(timeToLiveSecs);

            return(new StoreAndForward(storeAndForwardEnabled, usePersistentStorage, storeAndForwardConfiguration, storagePath, useBackupAndRestore, storageBackupPath, storageMaxTotalWalSize, storageMaxOpenFiles, storageLogLevel));
        }
Exemple #4
0
        public static IEnumerable <object[]> GetEdgeHubConfigData()
        {
            var r1 = new Route("id", string.Empty, "iotHub", Mock.Of <IMessageSource>(), new HashSet <Endpoint>());
            var r2 = new Route("id", string.Empty, "iotHub", Mock.Of <IMessageSource>(), new HashSet <Endpoint>());

            var routeConfig1 = new RouteConfig("r1", "FROM /* INTO $upstream", r1);
            var routeConfig2 = new RouteConfig("r2", "FROM /messages/* INTO $upstream", r2);

            var routes1 = new Dictionary <string, RouteConfig>
            {
                [routeConfig1.Name] = routeConfig1,
                [routeConfig2.Name] = routeConfig2
            };

            var routes2 = new Dictionary <string, RouteConfig>
            {
                [routeConfig1.Name] = routeConfig1
            };

            var routes3 = new Dictionary <string, RouteConfig>
            {
                [routeConfig2.Name] = routeConfig2
            };

            var storeAndForwardConfig1 = new StoreAndForwardConfiguration(-1);
            var storeAndForwardConfig2 = new StoreAndForwardConfiguration(7200);
            var storeAndForwardConfig3 = new StoreAndForwardConfiguration(3600);

            string version = "1.0";

            var edgeHubConfig1  = new EdgeHubConfig(version, routes1, storeAndForwardConfig1);
            var edgeHubConfig2  = new EdgeHubConfig(version, routes2, storeAndForwardConfig1);
            var edgeHubConfig3  = new EdgeHubConfig(version, routes3, storeAndForwardConfig1);
            var edgeHubConfig4  = new EdgeHubConfig(version, routes1, storeAndForwardConfig1);
            var edgeHubConfig5  = new EdgeHubConfig(version, routes1, storeAndForwardConfig2);
            var edgeHubConfig6  = new EdgeHubConfig(version, routes1, storeAndForwardConfig3);
            var edgeHubConfig7  = new EdgeHubConfig(version, routes2, storeAndForwardConfig2);
            var edgeHubConfig8  = new EdgeHubConfig(version, routes2, storeAndForwardConfig3);
            var edgeHubConfig9  = new EdgeHubConfig(version, routes3, storeAndForwardConfig3);
            var edgeHubConfig10 = new EdgeHubConfig(version, routes3, storeAndForwardConfig3);

            yield return(new object[] { edgeHubConfig1, edgeHubConfig2, false });

            yield return(new object[] { edgeHubConfig2, edgeHubConfig3, false });

            yield return(new object[] { edgeHubConfig3, edgeHubConfig4, false });

            yield return(new object[] { edgeHubConfig4, edgeHubConfig5, false });

            yield return(new object[] { edgeHubConfig5, edgeHubConfig6, false });

            yield return(new object[] { edgeHubConfig6, edgeHubConfig7, false });

            yield return(new object[] { edgeHubConfig7, edgeHubConfig8, false });

            yield return(new object[] { edgeHubConfig8, edgeHubConfig9, false });

            yield return(new object[] { edgeHubConfig9, edgeHubConfig10, true });
        }
Exemple #5
0
        public async Task TestInitialConfigUpdate_WaitForInit()
        {
            // Arrange
            string id           = "id";
            string iotHub       = "foo.azure-devices.net";
            var    routerConfig = new RouterConfig(Enumerable.Empty <Route>());

            var messageStore = new Mock <IMessageStore>();

            messageStore.Setup(m => m.SetTimeToLive(It.IsAny <TimeSpan>()));

            var storageSpaceChecker = new Mock <IStorageSpaceChecker>();

            storageSpaceChecker.Setup(m => m.SetMaxSizeBytes(It.IsAny <Option <long> >()));

            TimeSpan updateFrequency = TimeSpan.FromSeconds(10);

            Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of <IConnectionManager>(), Mock.Of <Core.IMessageConverter <IMessage> >());

            var endpointFactory = new Mock <IEndpointFactory>();

            endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint);
            var routeFactory = new EdgeRouteFactory(endpointFactory.Object);

            var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>();

            endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()))
            .Returns <Endpoint, IList <uint>, ICheckpointerFactory>((endpoint, priorities, checkpointerFactory) => Task.FromResult(Mock.Of <IEndpointExecutor>(e => e.Endpoint == endpoint)));
            Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object);

            var routes1 = Routes.Take(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>());

            var configProvider = new Mock <IConfigSource>();

            configProvider.SetupSequence(c => c.GetConfig())
            .Returns(async() =>
            {
                await Task.Delay(5000);
                return(Option.Some(edgeHubConfig1));
            });

            configProvider.Setup(c => c.GetCachedConfig())
            .Returns(() => Task.FromResult(Option.None <EdgeHubConfig>()));

            // Act
            var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency, storageSpaceChecker.Object);
            await configUpdater.Init(configProvider.Object);

            // Assert
            Assert.Equal(2, router.Routes.Count);

            // After 6 seconds no updates
            await Task.Delay(TimeSpan.FromSeconds(6));

            Assert.Equal(2, router.Routes.Count);
        }
Exemple #6
0
 public RoutingModule(
     string iotHubName,
     string edgeDeviceId,
     string edgeModuleId,
     Option <string> connectionString,
     IDictionary <string, string> routes,
     bool isStoreAndForwardEnabled,
     StoreAndForwardConfiguration storeAndForwardConfiguration,
     int connectionPoolSize,
     bool useTwinConfig,
     VersionInfo versionInfo,
     Option <UpstreamProtocol> upstreamProtocol,
     TimeSpan connectivityCheckFrequency,
     int maxConnectedClients,
     TimeSpan messageAckTimeout,
     TimeSpan cloudConnectionIdleTimeout,
     bool closeCloudConnectionOnIdleTimeout,
     TimeSpan operationTimeout,
     bool useServerHeartbeat,
     Option <TimeSpan> minTwinSyncPeriod,
     Option <TimeSpan> reportedPropertiesSyncFrequency,
     bool useV1TwinManager,
     int maxUpstreamBatchSize,
     int upstreamFanOutFactor,
     bool encryptTwinStore,
     TimeSpan configUpdateFrequency,
     bool checkEntireQueueOnCleanup,
     ExperimentalFeatures experimentalFeatures,
     bool closeCloudConnectionOnDeviceDisconnect)
 {
     this.iotHubName                             = Preconditions.CheckNonWhiteSpace(iotHubName, nameof(iotHubName));
     this.edgeDeviceId                           = Preconditions.CheckNonWhiteSpace(edgeDeviceId, nameof(edgeDeviceId));
     this.connectionString                       = Preconditions.CheckNotNull(connectionString, nameof(connectionString));
     this.routes                                 = Preconditions.CheckNotNull(routes, nameof(routes));
     this.storeAndForwardConfiguration           = Preconditions.CheckNotNull(storeAndForwardConfiguration, nameof(storeAndForwardConfiguration));
     this.edgeModuleId                           = edgeModuleId;
     this.isStoreAndForwardEnabled               = isStoreAndForwardEnabled;
     this.connectionPoolSize                     = connectionPoolSize;
     this.useTwinConfig                          = useTwinConfig;
     this.versionInfo                            = versionInfo ?? VersionInfo.Empty;
     this.upstreamProtocol                       = upstreamProtocol;
     this.connectivityCheckFrequency             = connectivityCheckFrequency;
     this.maxConnectedClients                    = Preconditions.CheckRange(maxConnectedClients, 1);
     this.messageAckTimeout                      = messageAckTimeout;
     this.cloudConnectionIdleTimeout             = cloudConnectionIdleTimeout;
     this.closeCloudConnectionOnIdleTimeout      = closeCloudConnectionOnIdleTimeout;
     this.operationTimeout                       = operationTimeout;
     this.useServerHeartbeat                     = useServerHeartbeat;
     this.minTwinSyncPeriod                      = minTwinSyncPeriod;
     this.reportedPropertiesSyncFrequency        = reportedPropertiesSyncFrequency;
     this.useV1TwinManager                       = useV1TwinManager;
     this.maxUpstreamBatchSize                   = maxUpstreamBatchSize;
     this.upstreamFanOutFactor                   = upstreamFanOutFactor;
     this.encryptTwinStore                       = encryptTwinStore;
     this.configUpdateFrequency                  = configUpdateFrequency;
     this.checkEntireQueueOnCleanup              = checkEntireQueueOnCleanup;
     this.experimentalFeatures                   = experimentalFeatures;
     this.closeCloudConnectionOnDeviceDisconnect = closeCloudConnectionOnDeviceDisconnect;
 }
 public void ConstructorInvalidParameters(
     string schemaVersion,
     Dictionary <string, RouteConfig> routes,
     StoreAndForwardConfiguration configuration,
     BrokerConfig brokerConfig)
 {
     // Act & Assert
     Assert.ThrowsAny <ArgumentException>(() => new EdgeHubConfig(schemaVersion, routes, configuration, Option.Some(brokerConfig)));
 }
        public void ConstructorHappyPath()
        {
            // Arrange
            IEnumerable <(string Name, string Value, Route route)> routes = Enumerable.Empty <(string Name, string Value, Route route)>();
            var snfConfig = new StoreAndForwardConfiguration(1000);

            // Act
            var edgeHubConfig = new EdgeHubConfig("1.0", routes, snfConfig);

            // Assert
            Assert.NotNull(edgeHubConfig);
        }
Exemple #9
0
        public void ConstructorHappyPath()
        {
            // Arrange
            IReadOnlyDictionary <string, RouteConfig> routes = new ReadOnlyDictionary <string, RouteConfig>(new Dictionary <string, RouteConfig>());
            var snfConfig = new StoreAndForwardConfiguration(1000);

            // Act
            var edgeHubConfig = new EdgeHubConfig("1.0", routes, snfConfig);

            // Assert
            Assert.NotNull(edgeHubConfig);
        }
Exemple #10
0
        public void ConstructorHappyPath(string[] signercert, string[] intermediatecacert, string signature, string algo)
        {
            // Arrange
            IReadOnlyDictionary <string, RouteConfig> routes = new ReadOnlyDictionary <string, RouteConfig>(new Dictionary <string, RouteConfig>());
            var snfConfig    = new StoreAndForwardConfiguration(1000);
            var brokerConfig = new BrokerConfig();
            var integrity    = new ManifestIntegrity(new TwinHeader(signercert, intermediatecacert), new TwinSignature(signature, algo));

            // Act
            var edgeHubConfig = new EdgeHubConfig("1.0", routes, snfConfig, Option.Some(brokerConfig), Option.Some(integrity));

            // Assert
            Assert.NotNull(edgeHubConfig);
        }
 public RoutingModule(
     string iotHubName,
     string edgeDeviceId,
     string edgeModuleId,
     Option <string> connectionString,
     IDictionary <string, string> routes,
     bool isStoreAndForwardEnabled,
     StoreAndForwardConfiguration storeAndForwardConfiguration,
     int connectionPoolSize,
     bool useTwinConfig,
     VersionInfo versionInfo,
     Option <UpstreamProtocol> upstreamProtocol,
     TimeSpan connectivityCheckFrequency,
     int maxConnectedClients,
     TimeSpan cloudConnectionIdleTimeout,
     bool closeCloudConnectionOnIdleTimeout,
     TimeSpan operationTimeout,
     Option <TimeSpan> minTwinSyncPeriod,
     Option <TimeSpan> reportedPropertiesSyncFrequency,
     bool useV1TwinManager)
 {
     this.iotHubName                        = Preconditions.CheckNonWhiteSpace(iotHubName, nameof(iotHubName));
     this.edgeDeviceId                      = Preconditions.CheckNonWhiteSpace(edgeDeviceId, nameof(edgeDeviceId));
     this.connectionString                  = Preconditions.CheckNotNull(connectionString, nameof(connectionString));
     this.routes                            = Preconditions.CheckNotNull(routes, nameof(routes));
     this.storeAndForwardConfiguration      = Preconditions.CheckNotNull(storeAndForwardConfiguration, nameof(storeAndForwardConfiguration));
     this.edgeModuleId                      = edgeModuleId;
     this.isStoreAndForwardEnabled          = isStoreAndForwardEnabled;
     this.connectionPoolSize                = connectionPoolSize;
     this.useTwinConfig                     = useTwinConfig;
     this.versionInfo                       = versionInfo ?? VersionInfo.Empty;
     this.upstreamProtocol                  = upstreamProtocol;
     this.connectivityCheckFrequency        = connectivityCheckFrequency;
     this.maxConnectedClients               = Preconditions.CheckRange(maxConnectedClients, 1);
     this.cloudConnectionIdleTimeout        = cloudConnectionIdleTimeout;
     this.closeCloudConnectionOnIdleTimeout = closeCloudConnectionOnIdleTimeout;
     this.operationTimeout                  = operationTimeout;
     this.minTwinSyncPeriod                 = minTwinSyncPeriod;
     this.reportedPropertiesSyncFrequency   = reportedPropertiesSyncFrequency;
     this.useV1TwinManager                  = useV1TwinManager;
 }
Exemple #12
0
 public StoreAndForward(
     bool isEnabled,
     bool usePersistentStorage,
     StoreAndForwardConfiguration config,
     string storagePath,
     bool useBackupAndRestore,
     Option <string> storageBackupPath,
     Option <ulong> storageMaxTotalWalSize,
     Option <int> storageMaxOpenFiles,
     Option <StorageLogLevel> storageLogLevel)
 {
     this.IsEnabled            = isEnabled;
     this.UsePersistentStorage = usePersistentStorage;
     this.Config                 = Preconditions.CheckNotNull(config, nameof(config));
     this.StoragePath            = Preconditions.CheckNonWhiteSpace(storagePath, nameof(storagePath));
     this.UseBackupAndRestore    = useBackupAndRestore;
     this.StorageBackupPath      = storageBackupPath;
     this.StorageMaxTotalWalSize = storageMaxTotalWalSize;
     this.StorageMaxOpenFiles    = storageMaxOpenFiles;
     this.StorageLogLevel        = storageLogLevel;
 }
        public async Task TestInitialConfigUpdate_NoWaitForInit()
        {
            // Arrange
            string id = "id";
            string iotHub = "foo.azure-devices.net";
            var routerConfig = new RouterConfig(Enumerable.Empty<Route>());

            var messageStore = new Mock<IMessageStore>();
            messageStore.Setup(m => m.SetTimeToLive(It.IsAny<TimeSpan>()));

            TimeSpan updateFrequency = TimeSpan.FromMinutes(10);

            Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of<IConnectionManager>(), Mock.Of<Core.IMessageConverter<IMessage>>());
            var endpointFactory = new Mock<IEndpointFactory>();
            endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint);
            var routeFactory = new EdgeRouteFactory(endpointFactory.Object);

            var endpointExecutorFactory = new Mock<IEndpointExecutorFactory>();
            endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny<Endpoint>()))
                    .Returns<Endpoint>(endpoint => Task.FromResult(Mock.Of<IEndpointExecutor>(e => e.Endpoint == endpoint)));
            Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object);

            var routes1 = Routes.Take(2)
                .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1);

            var routes2 = Routes.Take(3)
                .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration2 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig2 = new EdgeHubConfig("1.0", routes2, storeAndForwardConfiguration2);

            var configProvider = new Mock<IConfigSource>();
            configProvider.SetupSequence(c => c.GetConfig())
                .Returns(async () =>
                {
                    await Task.Delay(5000);
                    return Option.Some(edgeHubConfig2);
                });

            configProvider.Setup(c => c.SetConfigUpdatedCallback(It.IsAny<Func<EdgeHubConfig, Task>>()));

            var initialConfigSource = new Mock<IConfigSource>();
            initialConfigSource.Setup(c => c.GetConfig())
                .Returns(() =>
                {
                    return Task.FromResult(Option.Some(edgeHubConfig1));
                });

            // Act
            var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency, Option.Some(initialConfigSource.Object));
            await configUpdater.Init(configProvider.Object);

            // Assert
            // First only has updated from prefeched config
            Assert.Equal(2, router.Routes.Count);

            // After 6 seconds updates from init received
            await Task.Delay(TimeSpan.FromSeconds(6));
            Assert.Equal(3, router.Routes.Count);
        }
        public async Task TestPeriodicAndCallbackConfigUpdate()
        {
            // Arrange
            string id           = "id";
            string iotHub       = "foo.azure-devices.net";
            var    routerConfig = new RouterConfig(Enumerable.Empty <Route>());

            var messageStore = new Mock <IMessageStore>();

            messageStore.Setup(m => m.SetTimeToLive(It.IsAny <TimeSpan>()));

            var storageSpaceChecker = new Mock <IStorageSpaceChecker>();

            storageSpaceChecker.Setup(m => m.SetMaxSizeBytes(It.IsAny <Option <long> >()));

            TimeSpan updateFrequency = TimeSpan.FromSeconds(10);

            Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of <IConnectionManager>(), Mock.Of <Core.IMessageConverter <IMessage> >());

            var endpointFactory = new Mock <IEndpointFactory>();

            endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint);
            var routeFactory = new EdgeRouteFactory(endpointFactory.Object);

            var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>();

            endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()))
            .Returns <Endpoint, IList <uint> >((endpoint, priorities) => Task.FromResult(Mock.Of <IEndpointExecutor>(e => e.Endpoint == endpoint)));
            Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object);

            var routes1 = Routes.Take(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1);

            var routes2 = Routes.Take(3)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration2 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig2 = new EdgeHubConfig("1.0", routes2, storeAndForwardConfiguration2);

            var routes3 = Routes.Take(4)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration3 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig3 = new EdgeHubConfig("1.0", routes3, storeAndForwardConfiguration3);

            Func <EdgeHubConfig, Task> updateCallback = null;
            var configProvider = new Mock <IConfigSource>();

            configProvider.SetupSequence(c => c.GetConfig())
            .ReturnsAsync(Option.Some(edgeHubConfig1))
            .ReturnsAsync(Option.Some(edgeHubConfig2))
            .ReturnsAsync(Option.Some(edgeHubConfig3));
            configProvider.Setup(c => c.SetConfigUpdatedCallback(It.IsAny <Func <EdgeHubConfig, Task> >()))
            .Callback <Func <EdgeHubConfig, Task> >(callback => { updateCallback = callback; });
            configProvider.Setup(c => c.GetCachedConfig())
            .Returns(() => Task.FromResult(Option.None <EdgeHubConfig>()));

            // Act
            var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency, storageSpaceChecker.Object);
            await configUpdater.Init(configProvider.Object);

            // Assert
            configProvider.Verify(c => c.GetConfig(), Times.Once);
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once);
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Once);

            // call update with no changes
            await updateCallback(edgeHubConfig1);

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(1));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once);
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Once);

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(2));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(2));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(2));

            // call update with changes
            await updateCallback(edgeHubConfig3);

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(2));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(3));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(3));

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(3));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(3));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(3));
        }
            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 #16
0
        public static IEnumerable <object[]> GetEdgeHubConfigData()
        {
            var r1 = new Route("id", string.Empty, "iotHub", Mock.Of <IMessageSource>(), new Mock <Endpoint>("endpoint1").Object, 0, 3600);
            var r2 = new Route("id", string.Empty, "iotHub", Mock.Of <IMessageSource>(), new Mock <Endpoint>("endpoint2").Object, 0, 3600);

            var routeConfig1 = new RouteConfig("r1", "FROM /* INTO $upstream", r1);
            var routeConfig2 = new RouteConfig("r2", "FROM /messages/* INTO $upstream", r2);

            var routes1 = new Dictionary <string, RouteConfig>
            {
                [routeConfig1.Name] = routeConfig1,
                [routeConfig2.Name] = routeConfig2
            };

            var routes2 = new Dictionary <string, RouteConfig>
            {
                [routeConfig1.Name] = routeConfig1
            };

            var routes3 = new Dictionary <string, RouteConfig>
            {
                [routeConfig2.Name] = routeConfig2
            };

            var storeAndForwardConfig1 = new StoreAndForwardConfiguration(-1);
            var storeAndForwardConfig2 = new StoreAndForwardConfiguration(7200);
            var storeAndForwardConfig3 = new StoreAndForwardConfiguration(3600);

            StoreLimits s1 = new StoreLimits(100L);
            StoreLimits s2 = new StoreLimits(200L);
            var         storeAndForwardConfig4 = new StoreAndForwardConfiguration(3600, s1);
            var         storeAndForwardConfig5 = new StoreAndForwardConfiguration(3600, s2);
            var         storeAndForwardConfig6 = new StoreAndForwardConfiguration(3600);

            var statement1 = new Statement(
                effect: Effect.Allow,
                identities: new List <string>
            {
                "device_1"
            },
                operations: new List <string>
            {
                "read",
                "write"
            },
                resources: new List <string>
            {
                "file1",
                "file2"
            });

            var statement2 = new Statement(
                effect: Effect.Deny,
                identities: new List <string>
            {
                "device_1"
            },
                operations: new List <string>
            {
                "read"
            },
                resources: new List <string>
            {
                "root1",
                "root2"
            });

            var statement3 = new Statement(
                effect: Effect.Allow,
                identities: new List <string>
            {
                "device_1"
            },
                operations: new List <string>
            {
                "read",
                "write"
            },
                resources: new List <string>
            {
                "file1",
                "file2"
            });

            var brokerConfig1 = new BrokerConfig(
                Option.None <BridgeConfig>(),
                Option.Some(new AuthorizationConfig(new List <Statement> {
                statement1
            })));
            var brokerConfig2 = new BrokerConfig(
                Option.None <BridgeConfig>(),
                Option.Some(new AuthorizationConfig(new List <Statement> {
                statement2
            })));
            var brokerConfig3 = new BrokerConfig(
                Option.None <BridgeConfig>(),
                Option.Some(new AuthorizationConfig(new List <Statement> {
                statement3
            })));

            string version = "1.0";

            var edgeHubConfig1  = new EdgeHubConfig(version, routes1, storeAndForwardConfig1, Option.Some(brokerConfig1));
            var edgeHubConfig2  = new EdgeHubConfig(version, routes2, storeAndForwardConfig1, Option.Some(brokerConfig1));
            var edgeHubConfig3  = new EdgeHubConfig(version, routes3, storeAndForwardConfig1, Option.Some(brokerConfig1));
            var edgeHubConfig4  = new EdgeHubConfig(version, routes1, storeAndForwardConfig1, Option.Some(brokerConfig1));
            var edgeHubConfig5  = new EdgeHubConfig(version, routes1, storeAndForwardConfig2, Option.Some(brokerConfig1));
            var edgeHubConfig6  = new EdgeHubConfig(version, routes1, storeAndForwardConfig3, Option.Some(brokerConfig1));
            var edgeHubConfig7  = new EdgeHubConfig(version, routes2, storeAndForwardConfig2, Option.Some(brokerConfig1));
            var edgeHubConfig8  = new EdgeHubConfig(version, routes2, storeAndForwardConfig3, Option.Some(brokerConfig1));
            var edgeHubConfig9  = new EdgeHubConfig(version, routes3, storeAndForwardConfig3, Option.Some(brokerConfig1));
            var edgeHubConfig10 = new EdgeHubConfig(version, routes3, storeAndForwardConfig3, Option.Some(brokerConfig1));
            var edgeHubConfig11 = new EdgeHubConfig(version, routes3, storeAndForwardConfig4, Option.Some(brokerConfig1));
            var edgeHubConfig12 = new EdgeHubConfig(version, routes3, storeAndForwardConfig5, Option.Some(brokerConfig1));
            var edgeHubConfig13 = new EdgeHubConfig(version, routes3, storeAndForwardConfig6, Option.Some(brokerConfig1));

            yield return(new object[] { edgeHubConfig1, edgeHubConfig2, false });

            yield return(new object[] { edgeHubConfig2, edgeHubConfig3, false });

            yield return(new object[] { edgeHubConfig3, edgeHubConfig4, false });

            yield return(new object[] { edgeHubConfig4, edgeHubConfig5, false });

            yield return(new object[] { edgeHubConfig5, edgeHubConfig6, false });

            yield return(new object[] { edgeHubConfig6, edgeHubConfig7, false });

            yield return(new object[] { edgeHubConfig7, edgeHubConfig8, false });

            yield return(new object[] { edgeHubConfig8, edgeHubConfig9, false });

            yield return(new object[] { edgeHubConfig9, edgeHubConfig10, true });

            yield return(new object[] { edgeHubConfig10, edgeHubConfig11, false });

            yield return(new object[] { edgeHubConfig11, edgeHubConfig12, false });

            yield return(new object[] { edgeHubConfig10, edgeHubConfig13, true });

            yield return(new object[] { edgeHubConfig12, edgeHubConfig13, false });

            // authorization config equality check
            var edgeHubConfig14 = new EdgeHubConfig(version, routes1, storeAndForwardConfig1, Option.Some(brokerConfig2));
            var edgeHubConfig15 = new EdgeHubConfig(version, routes1, storeAndForwardConfig1, Option.Some(brokerConfig3));

            yield return(new object[] { edgeHubConfig1, edgeHubConfig14, false });

            yield return(new object[] { edgeHubConfig1, edgeHubConfig15, true });
        }
 public DesiredProperties(string schemaVersion, IDictionary <string, string> routes, StoreAndForwardConfiguration storeAndForwardConfiguration)
 {
     this.SchemaVersion = schemaVersion;
     this.Routes        = routes;
     this.StoreAndForwardConfiguration = storeAndForwardConfiguration;
 }
Exemple #18
0
        public async Task TestPeriodicConfigUpdate()
        {
            // Arrange
            string id           = "id";
            string iotHub       = "foo.azure-devices.net";
            var    routerConfig = new RouterConfig(Enumerable.Empty <Route>());

            var messageStore = new Mock <IMessageStore>();

            messageStore.Setup(m => m.SetTimeToLive(It.IsAny <TimeSpan>()));

            var storageSpaceChecker = new Mock <IStorageSpaceChecker>();

            storageSpaceChecker.Setup(m => m.SetMaxSizeBytes(It.IsAny <Option <long> >()));

            TimeSpan updateFrequency = TimeSpan.FromSeconds(10);

            Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of <IConnectionManager>(), Mock.Of <Core.IMessageConverter <IMessage> >());

            var endpointFactory = new Mock <IEndpointFactory>();

            endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint);
            var routeFactory = new EdgeRouteFactory(endpointFactory.Object);

            var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>();

            endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()))
            .Returns <Endpoint, IList <uint>, ICheckpointerFactory>((endpoint, priorities, checkpointerFactory) => Task.FromResult(Mock.Of <IEndpointExecutor>(e => e.Endpoint == endpoint)));
            Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object);

            var routes1 = Routes.Take(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>());

            var routes2 = Routes.Take(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration2 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig2 = new EdgeHubConfig("1.0", routes2, storeAndForwardConfiguration2, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>());

            var routes3 = Routes.Take(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration3 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig3 = new EdgeHubConfig("1.0", routes3, storeAndForwardConfiguration3, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>());

            var routes4 = Routes.Skip(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration4 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig4 = new EdgeHubConfig("1.0", routes4, storeAndForwardConfiguration4, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>());

            var routes5 = Routes
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration5 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig5 = new EdgeHubConfig("1.0", routes5, storeAndForwardConfiguration5, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>());

            var routes6 = Routes
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration6 = new StoreAndForwardConfiguration(3600);
            var edgeHubConfig6 = new EdgeHubConfig("1.0", routes6, storeAndForwardConfiguration6, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>());

            var routes7 = Routes
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration7 = new StoreAndForwardConfiguration(3600, new StoreLimits(10L));
            var edgeHubConfig7 = new EdgeHubConfig("1.0", routes7, storeAndForwardConfiguration7, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>());

            var routes8 = Routes
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration8 = new StoreAndForwardConfiguration(3600, new StoreLimits(20L));
            var edgeHubConfig8 = new EdgeHubConfig("1.0", routes8, storeAndForwardConfiguration8, Option.None <BrokerConfig>(), Option.None <ManifestIntegrity>());

            var configProvider = new Mock <IConfigSource>();

            configProvider.SetupSequence(c => c.GetConfig())
            .ReturnsAsync(Option.Some(edgeHubConfig1))
            .ReturnsAsync(Option.Some(edgeHubConfig2))
            .ReturnsAsync(Option.Some(edgeHubConfig3))
            .ReturnsAsync(Option.Some(edgeHubConfig4))
            .ReturnsAsync(Option.Some(edgeHubConfig5))
            .ReturnsAsync(Option.Some(edgeHubConfig6))
            .ReturnsAsync(Option.Some(edgeHubConfig7))
            .ReturnsAsync(Option.Some(edgeHubConfig8))
            .ReturnsAsync(Option.Some(edgeHubConfig8));
            configProvider.Setup(c => c.GetCachedConfig())
            .Returns(() => Task.FromResult(Option.None <EdgeHubConfig>()));

            // Act
            var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency, storageSpaceChecker.Object);
            await configUpdater.Init(configProvider.Object);

            // Assert
            configProvider.Verify(c => c.GetConfig(), Times.Once);
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once);
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Once);

            // After 5 seconds, the periodic task should not have run.
            await Task.Delay(TimeSpan.FromSeconds(5));

            configProvider.Verify(c => c.GetConfig(), Times.Once);
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once);
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Once);

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(3));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(3));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(3));

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(4));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(4));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(4));

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(5));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(5));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(5));

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(6));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(6));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => x.Equals(Option.None <long>()))), Times.Exactly(6));

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(7));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(7));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => !x.Equals(Option.None <long>()))), Times.Exactly(1));

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(8));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(8));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => !x.Equals(Option.None <long>()))), Times.Exactly(2));

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(9));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(8));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => !x.Equals(Option.None <long>()))), Times.Exactly(2));
        }
Exemple #19
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));
        }
Exemple #20
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 #21
0
        public async Task TestPeriodicConfigUpdate()
        {
            // Arrange
            string id           = "id";
            string iotHub       = "foo.azure-devices.net";
            var    routerConfig = new RouterConfig(Enumerable.Empty <Route>());

            var messageStore = new Mock <IMessageStore>();

            messageStore.Setup(m => m.SetTimeToLive(It.IsAny <TimeSpan>()));

            TimeSpan updateFrequency = TimeSpan.FromSeconds(10);

            Endpoint GetEndpoint() => new ModuleEndpoint("id", Guid.NewGuid().ToString(), "in1", Mock.Of <IConnectionManager>(), Mock.Of <Core.IMessageConverter <IMessage> >());

            var endpointFactory = new Mock <IEndpointFactory>();

            endpointFactory.Setup(e => e.CreateSystemEndpoint($"$upstream")).Returns(GetEndpoint);
            var routeFactory = new EdgeRouteFactory(endpointFactory.Object);

            var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>();

            endpointExecutorFactory.Setup(e => e.CreateAsync(It.IsAny <Endpoint>()))
            .Returns <Endpoint>(endpoint => Task.FromResult(Mock.Of <IEndpointExecutor>(e => e.Endpoint == endpoint)));
            Router router = await Router.CreateAsync(id, iotHub, routerConfig, endpointExecutorFactory.Object);

            var routes1 = Routes.Take(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration1 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig1 = new EdgeHubConfig("1.0", routes1, storeAndForwardConfiguration1);

            var routes2 = Routes.Take(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration2 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig2 = new EdgeHubConfig("1.0", routes2, storeAndForwardConfiguration2);

            var routes3 = Routes.Take(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration3 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig3 = new EdgeHubConfig("1.0", routes3, storeAndForwardConfiguration3);

            var routes4 = Routes.Skip(2)
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration4 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig4 = new EdgeHubConfig("1.0", routes4, storeAndForwardConfiguration4);

            var routes5 = Routes
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration5 = new StoreAndForwardConfiguration(7200);
            var edgeHubConfig5 = new EdgeHubConfig("1.0", routes5, storeAndForwardConfiguration5);

            var routes6 = Routes
                          .ToDictionary(r => r.Key, r => new RouteConfig(r.Key, r.Value, routeFactory.Create(r.Value)));
            var storeAndForwardConfiguration6 = new StoreAndForwardConfiguration(3600);
            var edgeHubConfig6 = new EdgeHubConfig("1.0", routes6, storeAndForwardConfiguration6);

            var configProvider = new Mock <IConfigSource>();

            configProvider.SetupSequence(c => c.GetConfig())
            .ReturnsAsync(Option.Some(edgeHubConfig1))
            .ReturnsAsync(Option.Some(edgeHubConfig2))
            .ReturnsAsync(Option.Some(edgeHubConfig3))
            .ReturnsAsync(Option.Some(edgeHubConfig4))
            .ReturnsAsync(Option.Some(edgeHubConfig5))
            .ReturnsAsync(Option.Some(edgeHubConfig6));
            configProvider.Setup(c => c.SetConfigUpdatedCallback(It.IsAny <Func <EdgeHubConfig, Task> >()));

            // Act
            var configUpdater = new ConfigUpdater(router, messageStore.Object, updateFrequency);

            configUpdater.Init(configProvider.Object);

            // Assert
            await Task.Delay(TimeSpan.FromSeconds(8));

            configProvider.Verify(c => c.GetConfig(), Times.Once);
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once);

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(3));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Once);

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(4));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(2));

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(5));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(3));

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(6));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(4));
        }