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; }
/// <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, }; }
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)); }
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 }); }
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); }
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); }
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); }
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; }
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(); }
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; }
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)); }
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)); }
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)); }
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)); }