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 void SupportsMetadataBehaviorTest(string replace, int expected) { var result = new ConfigUpdater(XDocument.Parse(Input.Replace(Metadata, replace)), _logger).SupportsMetadataBehavior(); var http = replace.Contains("httpGetEnabled"); var https = replace.Contains("httpsGetEnabled"); Assert.Equal((MetadataType)expected, result); }
public void UpdateEndpointsTest() { var expected = @"endpoint address=""/SampleService"""; var expected2 = @"endpoint address=""/sample/address/SampleService2"""; var result = new ConfigUpdater(XDocument.Parse(Input), _logger).GenerateNewConfig().ToString(); Assert.True(result.Contains(expected) && result.Contains(expected2)); }
public void UpdateOldConfigTest() { var result = new ConfigUpdater(XDocument.Parse(Input), _logger).UpdateOldConfig(); var expected = @"<?xml version=""1.0"" encoding=""utf-8"" ?> <configuration > <!-- system.serviceModel section is moved to a separate wcf.config file located at the same directory as this file.--> </configuration> "; Assert.True(XNode.DeepEquals(XDocument.Parse(expected), result)); }
/// <summary> /// Raises the we chat send web event. /// </summary> /// <param name="isTimeline"> true 是 朋友圈(分享),false 是 会话(邀请).</param> public static void OnWeChatSendWeb (bool isTimeline, string callbackGameObject, JSONObject _jsonmsg) { JSONObject jsonMsg = new JSONObject(); //jsonMsg.AddField("wxappid", PlatformGameDefine.playform.WXAppId); if (_jsonmsg["wxappid"].IsAvailable()) { jsonMsg.AddField("wxappid", _jsonmsg["wxappid"].str); } jsonMsg.AddField("callbackGameObject", callbackGameObject); jsonMsg.AddField("isTimeline", isTimeline); if (_jsonmsg["title"].IsAvailable()) { jsonMsg.AddField("title", _jsonmsg["title"].str); } if (_jsonmsg["url"].IsAvailable()) { jsonMsg.AddField("url", _jsonmsg["url"].str); } if (_jsonmsg["description"].IsAvailable()) { jsonMsg.AddField("description", _jsonmsg["description"].str); } //jsonMsg.AddField("title", PlatformGameDefine.playform.PlatformName); //jsonMsg.AddField("url", PlatformGameDefine.playform.WXShareUrl); //jsonMsg.AddField("description", PlatformGameDefine.playform.WXShareDescription); string imgPath = Application.persistentDataPath + "/app_icon.png"; // string imgSrcPath = Application.streamingAssetsPath+"/app_icon.png"; if (!System.IO.File.Exists(imgPath)) { string img_bytes_name = PlatformGameDefine.playform.GetPlatformPrefix() + "_app_icon"; TextAsset img_png = Resources.Load <TextAsset> (img_bytes_name); System.IO.File.WriteAllBytes(imgPath, img_png.bytes); } ConfigUpdater.SetNoBackupFlag(imgPath); jsonMsg.AddField("imgPath", imgPath); // jsonMsg.AddField("imgPath", false); UnityEngine.Debug.Log("CK : ------------------------------ OnWeChatSendWeb2?jsonMsg = " + jsonMsg.ToString()); #if UNITY_IOS _OnWeChatSendWeb(jsonMsg.ToString()); #elif UNITY_ANDROID using (AndroidJavaObject jc = new AndroidJavaObject("net.sourceforge.simcpux.wxapi.WeChatPayUtil")) { jc.Call("SendWeb", jsonMsg.ToString()); } #endif }
public void GetBindingsTest() { HashSet <string> expected = new HashSet <string>(); expected.Add("netTcpBinding"); expected.Add("basicHttpsBinding"); expected.Add("mexHttpBinding"); var result = new ConfigUpdater(XDocument.Parse(Input), _logger).GetBindings(); Assert.Equal(expected, result); }
public void GetUriTest() { Dictionary <string, Uri> expected = new Dictionary <string, Uri>(); expected.Add(Uri.UriSchemeHttp, new Uri("http://localhost:80/")); expected.Add(Uri.UriSchemeHttps, new Uri("https://localhost:443/sample/address")); expected.Add(Uri.UriSchemeNetTcp, new Uri("net.tcp://localhost:808/")); var result = new ConfigUpdater(XDocument.Parse(Input), _logger).GetSchemeToAddressMapping(); Assert.Equal(expected, result); }
async Task StartProtocolHead() { string certificateValue = await SecretsHelper.GetSecret("IotHubMqttHeadCert"); byte[] cert = Convert.FromBase64String(certificateValue); var certificate = new X509Certificate2(cert); // TODO for now this is empty as will suffice for SAS X.509 thumbprint auth but we will need other CA certs for X.509 CA validation var trustBundle = new List <X509Certificate2>(); string edgeDeviceConnectionString = await SecretsHelper.GetSecretFromConfigKey("edgeCapableDeviceConnStrKey"); // TODO - After IoTHub supports MQTT, remove this and move to using MQTT for upstream connections await ConnectToIotHub(edgeDeviceConnectionString); ConfigHelper.TestConfig[EdgeHubConstants.ConfigKey.IotHubConnectionString] = edgeDeviceConnectionString; IDependencyManager dependencyManager = new DependencyManager(ConfigHelper.TestConfig, certificate, trustBundle, this.sslProtocols); Hosting hosting = Hosting.Initialize(ConfigHelper.TestConfig, certificate, dependencyManager, true, this.sslProtocols); this.hosting = hosting; IContainer container = hosting.Container; // CloudConnectionProvider and RoutingEdgeHub have a circular dependency. So set the // EdgeHub on the CloudConnectionProvider before any other operation ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); ILogger logger = container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); MqttProtocolHead mqttProtocolHead = await container.Resolve <Task <MqttProtocolHead> >(); AmqpProtocolHead amqpProtocolHead = await container.Resolve <Task <AmqpProtocolHead> >(); var httpProtocolHead = new HttpProtocolHead(hosting.WebHost); this.protocolHead = new EdgeHubProtocolHead(new List <IProtocolHead> { mqttProtocolHead, amqpProtocolHead, httpProtocolHead }, logger); await this.protocolHead.StartAsync(); }
private void button1_Click(object sender, EventArgs e) { richTextLog.Text = ""; ConfigUpdater updater = ConfigUpdater.GetInstance(); updater.OnError += (updaterException) => { richTextLog.Text += $"{DateTime.Now} {updaterException.ToString()}\r\n"; }; updater.OnTaskFinished += (taskName, isTaskSuccess) => { richTextLog.Text += $"{DateTime.Now} TaskName:{taskName} Result:update " + (isTaskSuccess ? "successfully!\r\n" : "error!\r\n"); }; updater.StartUpdating(); }
public static void Decomposition(string[] arg) { ConfigModel model = ConfigImporter.onDeserialize(false); try { for (int i = 0; i < arg.Length; i++) { switch (arg[i]) { case "--clear": ConfigExporter.onTemplateGenerate(); break; case "-a": case "--api-key": apiKey = arg[++i]; break; case "-u": case "--user": userName = arg[++i]; break; case "-p": case "--pass": passWord = arg[++i]; break; case "-ia": case "--ignore-add": ignoreData.Add(CheckRequest.onCheck(model, arg[++i])); break; case "-iaa": case "--ignore-add-array": arg[++i].Split(',').ToList().ForEach(videoId => { ignoreData.Add(CheckRequest.onCheck(model, videoId)); }); break; } } } catch (IndexOutOfRangeException) { AlLite.WriteLine(WriteMode.ERR, "Incorrect Number of Arguments."); } ConfigUpdater.onUpdate(apiKey, userName, passWord, ignoreData); }
public ConfigHubClient(MachineConfig machineConfig, ConfigUpdater configUpdater) : base(machineConfig) { if (configUpdater == null) { throw new ArgumentNullException(nameof(configUpdater)); } this.configUpdater = configUpdater; this.configHub = this.HubConnection.CreateHubProxy("ConfigHub"); Action <string> configUpdate = this.UpdateConfig; this.eventSubscription = this.configHub.On("ConfigUpdate", configUpdate); this.Connect(); }
/// <summary> /// Generates or passes the URL to make the request to GET the config from a server /// </summary> /// <param name="url"></param> void GetConfigFile(string url) { try { // Attempt to parse the URL var parser = new Crestron.SimplSharp.Net.Http.UrlParser(url); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Successfully parsed URL from AppServer message: {0}", parser.Url); } catch (Exception e) { // If unable to parse the URL, generate it from config data Debug.Console(2, "Error parsing URL: {0}", e); Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to parse URL from AppServer message. Generating URL from config data"); url = string.Format("http://{0}/api/system/{1}/config", AppServerController.Config.ServerUrl, AppServerController.SystemUuid); } ConfigUpdater.GetConfigFromServer(url); }
/// <summary> /// 更新所有需要更新的文件 /// </summary> /// <param name="src"></param> /// <param name="des"></param> /// <param name="config"></param> /// <param name="onComplete"></param> /// <param name="isUpdate">true: 从后台更新, false 从StreamingAssets 目录更新</param> public static void UpdateFiles(this MonoBehaviour mono, string src, string des, JSONObject config, JSONObject srcReservedConfig, bool isUpdate, System.Action <string, long, long> onProgressChanged, System.Action <string, JSONObject> onComplete) { ConfigUpdater updater = null; //if (isUpdate) updater = new DownloadConfigUpdater(); if (isUpdate) { updater = new WWWConfigUpdater(); } else { updater = new ExtractConfigUpdater(); } updater.Update(mono, src, des, config, onProgressChanged, (resultConfig, error) => { UpdateConfig(des, resultConfig, srcReservedConfig); if (onComplete != null) { onComplete(error, config); } }); }
protected override void Load(ContainerBuilder builder) { // IMessageConverter<IRoutingMessage> builder.Register(c => new RoutingMessageConverter()) .As <Core.IMessageConverter <IRoutingMessage> >() .SingleInstance(); // IRoutingPerfCounter builder.Register( c => { Routing.PerfCounter = NullRoutingPerfCounter.Instance; return(Routing.PerfCounter); }) .As <IRoutingPerfCounter>() .AutoActivate() .SingleInstance(); // IRoutingUserAnalyticsLogger builder.Register( c => { Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance; return(Routing.UserAnalyticsLogger); }) .As <IRoutingUserAnalyticsLogger>() .AutoActivate() .SingleInstance(); // IRoutingUserMetricLogger builder.Register( c => { Routing.UserMetricLogger = NullRoutingUserMetricLogger.Instance; return(Routing.UserMetricLogger); }) .As <IRoutingUserMetricLogger>() .AutoActivate() .SingleInstance(); // IMessageConverter<Message> builder.Register(c => new DeviceClientMessageConverter()) .As <Core.IMessageConverter <Message> >() .SingleInstance(); // IMessageConverter<Twin> builder.Register(c => new TwinMessageConverter()) .As <Core.IMessageConverter <Twin> >() .SingleInstance(); // IMessageConverter<TwinCollection> builder.Register(c => new TwinCollectionMessageConverter()) .As <Core.IMessageConverter <TwinCollection> >() .SingleInstance(); // IMessageConverterProvider builder.Register( c => new MessageConverterProvider(new Dictionary <Type, IMessageConverter>() { { typeof(Message), c.Resolve <Core.IMessageConverter <Message> >() }, { typeof(Twin), c.Resolve <Core.IMessageConverter <Twin> >() }, { typeof(TwinCollection), c.Resolve <Core.IMessageConverter <TwinCollection> >() } })) .As <IMessageConverterProvider>() .SingleInstance(); // IDeviceConnectivityManager builder.Register( c => { IDeviceConnectivityManager deviceConnectivityManager = new DeviceConnectivityManager(this.connectivityCheckFrequency, TimeSpan.FromMinutes(2)); return(deviceConnectivityManager); }) .As <IDeviceConnectivityManager>() .SingleInstance(); // IDeviceClientProvider builder.Register(c => { IClientProvider underlyingClientProvider = new ClientProvider(); IClientProvider connectivityAwareClientProvider = new ConnectivityAwareClientProvider(underlyingClientProvider, c.Resolve <IDeviceConnectivityManager>()); return(connectivityAwareClientProvider); }) .As <IClientProvider>() .SingleInstance(); // Task<ICloudConnectionProvider> builder.Register( async c => { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); var clientProvider = c.Resolve <IClientProvider>(); var tokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubClientAuthTokenProvider"); IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider( messageConverterProvider, this.connectionPoolSize, clientProvider, this.upstreamProtocol, tokenProvider, deviceScopeIdentitiesCache, TimeSpan.FromMinutes(60)); return(cloudConnectionProvider); }) .As <Task <ICloudConnectionProvider> >() .SingleInstance(); // Task<ICredentialsStore> builder.Register(async c => { if (this.cacheTokens) { IKeyValueStore <string, string> encryptedStore = await c.ResolveNamed <Task <IKeyValueStore <string, string> > >("EncryptedStore"); return(new TokenCredentialsStore(encryptedStore)); } else { return(new NullCredentialsStore() as ICredentialsStore); } }) .As <Task <ICredentialsStore> >() .SingleInstance(); // Task<IConnectionManager> builder.Register( async c => { ICloudConnectionProvider cloudConnectionProvider = await c.Resolve <Task <ICloudConnectionProvider> >(); IConnectionManager connectionManager = new ConnectionManager(cloudConnectionProvider, this.maxConnectedClients); return(connectionManager); }) .As <Task <IConnectionManager> >() .SingleInstance(); // Task<IEndpointFactory> builder.Register(async c => { var messageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(new EndpointFactory(connectionManager, messageConverter, this.edgeDeviceId) as IEndpointFactory); }) .As <Task <IEndpointFactory> >() .SingleInstance(); // Task<RouteFactory> builder.Register(async c => new EdgeRouteFactory(await c.Resolve <Task <IEndpointFactory> >()) as RouteFactory) .As <Task <RouteFactory> >() .SingleInstance(); // RouterConfig builder.Register(c => new RouterConfig(Enumerable.Empty <Route>())) .As <RouterConfig>() .SingleInstance(); if (!this.isStoreAndForwardEnabled) { // EndpointExecutorConfig builder.Register( c => { RetryStrategy defaultRetryStrategy = new FixedInterval(0, TimeSpan.FromSeconds(1)); TimeSpan defaultRevivePeriod = TimeSpan.FromHours(1); TimeSpan defaultTimeout = TimeSpan.FromSeconds(60); return(new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // IEndpointExecutorFactory builder.Register(c => new SyncEndpointExecutorFactory(c.Resolve <EndpointExecutorConfig>())) .As <IEndpointExecutorFactory>() .SingleInstance(); // Task<Router> builder.Register( async c => { var endpointExecutorFactory = c.Resolve <IEndpointExecutorFactory>(); var routerConfig = c.Resolve <RouterConfig>(); Router router = await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory); return(router); }) .As <Task <Router> >() .SingleInstance(); // Task<ITwinManager> builder.Register(async c => { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.None <IStoreProvider>())); }) .As <Task <ITwinManager> >() .SingleInstance(); } else { // EndpointExecutorConfig builder.Register( c => { // Endpoint executor config values - // ExponentialBackoff - minBackoff = 1s, maxBackoff = 60s, delta (used to add randomness to backoff) - 1s (default) // Num of retries = int.MaxValue(we want to keep retrying till the message is sent) // Revive period - period for which the endpoint should be considered dead if it doesn't respond - 1 min (we want to try continuously till the message expires) // Timeout - time for which we want for the ack from the endpoint = 30s // TODO - Should the number of retries be tied to the Store and Forward ttl? Not // doing that right now as that value can be changed at runtime, but these settings // cannot. Need to make the number of retries dynamically configurable for that. TimeSpan minWait = TimeSpan.FromSeconds(1); TimeSpan maxWait = TimeSpan.FromSeconds(60); TimeSpan delta = TimeSpan.FromSeconds(1); int retries = int.MaxValue; RetryStrategy retryStrategy = new ExponentialBackoff(retries, minWait, maxWait, delta); TimeSpan timeout = TimeSpan.FromSeconds(30); TimeSpan revivePeriod = TimeSpan.FromSeconds(30); return(new EndpointExecutorConfig(timeout, retryStrategy, revivePeriod)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // ICheckpointStore builder.Register(c => CheckpointStore.Create(c.Resolve <IDbStoreProvider>())) .As <ICheckpointStore>() .SingleInstance(); // IMessageStore builder.Register( c => { var checkpointStore = c.Resolve <ICheckpointStore>(); var dbStoreProvider = c.Resolve <IDbStoreProvider>(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); IMessageStore messageStore = new MessageStore(storeProvider, checkpointStore, TimeSpan.MaxValue); return(messageStore); }) .As <IMessageStore>() .SingleInstance(); // IEndpointExecutorFactory builder.Register( c => { var endpointExecutorConfig = c.Resolve <EndpointExecutorConfig>(); var messageStore = c.Resolve <IMessageStore>(); IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(10, TimeSpan.FromSeconds(10)), messageStore); return(endpointExecutorFactory); }) .As <IEndpointExecutorFactory>() .SingleInstance(); // Task<Router> builder.Register( async c => { var checkpointStore = c.Resolve <ICheckpointStore>(); var routerConfig = c.Resolve <RouterConfig>(); var endpointExecutorFactory = c.Resolve <IEndpointExecutorFactory>(); return(await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory, checkpointStore)); }) .As <Task <Router> >() .SingleInstance(); // Task<ITwinManager> builder.Register(async c => { var dbStoreProvider = c.Resolve <IDbStoreProvider>(); var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.Some <IStoreProvider>(new StoreProvider(dbStoreProvider)))); }) .As <Task <ITwinManager> >() .SingleInstance(); } // IClientCredentials "EdgeHubCredentials" builder.Register( c => { var identityFactory = c.Resolve <IClientCredentialsFactory>(); IClientCredentials edgeHubCredentials = this.connectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse( () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeModuleId)); return(edgeHubCredentials); }) .Named <IClientCredentials>("EdgeHubCredentials") .SingleInstance(); // Task<ICloudProxy> "EdgeHubCloudProxy" builder.Register( async c => { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); Try <ICloudProxy> cloudProxyTry = await connectionManager.CreateCloudConnectionAsync(edgeHubCredentials); if (!cloudProxyTry.Success) { throw new EdgeHubConnectionException("Edge hub is unable to connect to IoT Hub", cloudProxyTry.Exception); } ICloudProxy cloudProxy = cloudProxyTry.Value; return(cloudProxy); }) .Named <Task <ICloudProxy> >("EdgeHubCloudProxy") .SingleInstance(); // Task<IInvokeMethodHandler> builder.Register(async c => { IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(new InvokeMethodHandler(connectionManager) as IInvokeMethodHandler); }) .As <Task <IInvokeMethodHandler> >() .SingleInstance(); // Task<IEdgeHub> builder.Register( async c => { var routingMessageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >(); var routerTask = c.Resolve <Task <Router> >(); var twinManagerTask = c.Resolve <Task <ITwinManager> >(); var invokeMethodHandlerTask = c.Resolve <Task <IInvokeMethodHandler> >(); var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); Router router = await routerTask; ITwinManager twinManager = await twinManagerTask; IConnectionManager connectionManager = await connectionManagerTask; IInvokeMethodHandler invokeMethodHandler = await invokeMethodHandlerTask; IEdgeHub hub = new RoutingEdgeHub(router, routingMessageConverter, connectionManager, twinManager, this.edgeDeviceId, invokeMethodHandler); return(hub); }) .As <Task <IEdgeHub> >() .SingleInstance(); // Task<ConfigUpdater> builder.Register( async c => { IMessageStore messageStore = this.isStoreAndForwardEnabled ? c.Resolve <IMessageStore>() : null; Router router = await c.Resolve <Task <Router> >(); var configUpdater = new ConfigUpdater(router, messageStore); return(configUpdater); }) .As <Task <ConfigUpdater> >() .SingleInstance(); // Task<IConfigSource> builder.Register( async c => { RouteFactory routeFactory = await c.Resolve <Task <RouteFactory> >(); if (this.useTwinConfig) { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var twinCollectionMessageConverter = c.Resolve <Core.IMessageConverter <TwinCollection> >(); var twinMessageConverter = c.Resolve <Core.IMessageConverter <Twin> >(); ITwinManager twinManager = await c.Resolve <Task <ITwinManager> >(); ICloudProxy cloudProxy = await c.ResolveNamed <Task <ICloudProxy> >("EdgeHubCloudProxy"); IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); IConfigSource edgeHubConnection = await EdgeHubConnection.Create( edgeHubCredentials, edgeHub, twinManager, connectionManager, cloudProxy, routeFactory, twinCollectionMessageConverter, twinMessageConverter, this.versionInfo, deviceScopeIdentitiesCache ); return(edgeHubConnection); } else { return(new LocalConfigSource(routeFactory, this.routes, this.storeAndForwardConfiguration)); } }) .As <Task <IConfigSource> >() .SingleInstance(); // Task<IConnectionProvider> builder.Register( async c => { IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >(); IConnectionProvider connectionProvider = new ConnectionProvider(connectionManager, edgeHub); return(connectionProvider); }) .As <Task <IConnectionProvider> >() .SingleInstance(); base.Load(builder); }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } ILogger logger = Logger.Factory.CreateLogger("EdgeHub"); EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration, logger); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); string sslProtocolsConfig = configuration.GetValue(Constants.ConfigKey.SslProtocols, string.Empty); SslProtocols sslProtocols = SslProtocolsHelper.Parse(sslProtocolsConfig, DefaultSslProtocols, logger); logger.LogInformation($"Enabling SSL protocols: {sslProtocols.Print()}"); IDependencyManager dependencyManager = new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle, certificates.ManifestTrustBundle, sslProtocols); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, dependencyManager, clientCertAuthEnabled, sslProtocols); IContainer container = hosting.Container; logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation($"OptimizeForPerformance={configuration.GetValue("OptimizeForPerformance", true)}"); logger.LogInformation($"MessageAckTimeoutSecs={configuration.GetValue("MessageAckTimeoutSecs", 30)}"); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); var metricsProvider = container.Resolve <IMetricsProvider>(); Metrics.InitWithAspNet(metricsProvider, logger); // Note this requires App.UseMetricServer() to be called in Startup.cs // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Register EdgeHub indentity in device scopes cache. // When we connect upstream, we verify that identity is in scope. // On a fresh start, we may not yet received the scopes from the upstream, so we need // to force add edgeHub in the cache so it is able to connect upstream. // Once we get the scopes from the upstream, this record is replaced. ServiceIdentity edgeHubIdentity = container.ResolveNamed <ServiceIdentity>("EdgeHubIdentity"); IServiceIdentityHierarchy identityScopes = container.Resolve <IServiceIdentityHierarchy>(); await identityScopes.InsertOrUpdate(edgeHubIdentity); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); ExperimentalFeatures experimentalFeatures = CreateExperimentalFeatures(configuration); var configUpdaterStartupFailed = new TaskCompletionSource <bool>(); var configDownloadTask = configUpdater.Init(configSource); _ = configDownloadTask.ContinueWith( _ => configUpdaterStartupFailed.SetResult(false), TaskContinuationOptions.OnlyOnFaulted); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } TimeSpan shutdownWaitPeriod = TimeSpan.FromSeconds(configuration.GetValue("ShutdownWaitPeriod", DefaultShutdownWaitPeriod)); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(shutdownWaitPeriod, logger); using (IProtocolHead mqttBrokerProtocolHead = await GetMqttBrokerProtocolHeadAsync(experimentalFeatures, container)) using (IProtocolHead edgeHubProtocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, experimentalFeatures, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { try { await Task.WhenAll(mqttBrokerProtocolHead.StartAsync(), configDownloadTask); await edgeHubProtocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled(), configUpdaterStartupFailed.Task); } catch (Exception ex) { logger.LogError($"Error starting protocol heads: {ex.Message}"); } logger.LogInformation("Stopping the protocol heads..."); await Task.WhenAll(mqttBrokerProtocolHead.CloseAsync(CancellationToken.None), edgeHubProtocolHead.CloseAsync(CancellationToken.None)); logger.LogInformation("Protocol heads stopped."); await CloseDbStoreProviderAsync(container); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(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)); }
public void SupportsServiceDebugTest(string replace, bool expected) { bool result = new ConfigUpdater(XDocument.Parse(Input.Replace(ServiceDebug, replace)), _logger).SupportsServiceDebug(); Assert.Equal(expected, result); }
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(); }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle), clientCertAuthEnabled); IContainer container = hosting.Container; ILogger logger = container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(ShutdownWaitPeriod, logger); Metrics.BuildMetricsCollector(configuration); using (IProtocolHead protocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { await protocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled()); logger.LogInformation("Stopping the protocol heads..."); await Task.WhenAny(protocolHead.CloseAsync(CancellationToken.None), Task.Delay(TimeSpan.FromSeconds(10), CancellationToken.None)); logger.LogInformation("Protocol heads stopped."); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }
public static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.Core.Routing.LoggerFactory = Logger.Factory; } X509Certificate2 cert; IEnumerable <X509Certificate2> chain; string edgeHubConnectionString = configuration.GetValue <string>(Constants.IotHubConnectionStringVariableName); // When connection string is not set it is edged mode if (string.IsNullOrEmpty(edgeHubConnectionString)) { var workloadUri = new Uri(configuration.GetValue <string>(Constants.WorkloadUriVariableName)); string edgeHubHostname = configuration.GetValue <string>(Constants.EdgeDeviceHostnameVariableName); string moduleId = configuration.GetValue <string>(Constants.ModuleIdVariableName); string generationId = configuration.GetValue <string>(Constants.ModuleGenerationIdVariableName); DateTime expiration = DateTime.UtcNow.AddDays(Constants.CertificateValidityDays); (cert, chain) = await CertificateHelper.GetServerCertificatesFromEdgelet(workloadUri, Constants.WorkloadApiVersion, moduleId, generationId, edgeHubHostname, expiration); } else { string edgeHubCertPath = configuration.GetValue <string>(Constants.EdgeHubServerCertificateFileKey); cert = new X509Certificate2(edgeHubCertPath); string edgeHubCaChainCertPath = configuration.GetValue <string>(Constants.EdgeHubServerCAChainCertificateFileKey); chain = CertificateHelper.GetServerCACertificatesFromFile(edgeHubCaChainCertPath); } // TODO: set certificate for Startup without the cache ServerCertificateCache.X509Certificate = cert; int port = configuration.GetValue("httpSettings:port", 443); Hosting hosting = Hosting.Initialize(port); IContainer container = hosting.Container; ILogger logger = container.Resolve <ILoggerFactory>().CreateLogger("EdgeHub"); logger.LogInformation("Starting Edge Hub"); VersionInfo versionInfo = VersionInfo.Get(Constants.VersionInfoFileName); if (versionInfo != VersionInfo.Empty) { logger.LogInformation($"Version - {versionInfo.ToString(true)}"); } LogLogo(logger); if (chain != null) { logger.LogInformation("Installing intermediate certificates."); CertificateHelper.InstallCerts( RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? StoreName.CertificateAuthority : StoreName.Root, StoreLocation.CurrentUser, chain); } else { logger.LogWarning("Unable to find intermediate certificates."); } // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); var cloudConnectionProvider = container.Resolve <ICloudConnectionProvider>(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); ICloudProxy cloudProxy = await container.ResolveNamed <Task <ICloudProxy> >("EdgeHubCloudProxy"); (deviceConnectivityManager as DeviceConnectivityManager)?.SetTestCloudProxy(cloudProxy); logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(ShutdownWaitPeriod, logger); var protocolHeads = new List <IProtocolHead>(); if (configuration.GetValue("mqttSettings:enabled", true)) { protocolHeads.Add(await container.Resolve <Task <MqttProtocolHead> >()); } if (configuration.GetValue("amqpSettings:enabled", true)) { protocolHeads.Add(await container.Resolve <Task <AmqpProtocolHead> >()); } if (configuration.GetValue("httpSettings:enabled", true)) { protocolHeads.Add(new HttpProtocolHead(hosting.WebHost)); } using (IProtocolHead protocolHead = new EdgeHubProtocolHead(protocolHeads, logger)) { await protocolHead.StartAsync(); await cts.Token.WhenCanceled(); await Task.WhenAny(protocolHead.CloseAsync(CancellationToken.None), Task.Delay(TimeSpan.FromSeconds(10), CancellationToken.None)); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); return(0); }
public void GenerateNewConfigTest() { var result = new ConfigUpdater(XDocument.Parse(Input), _logger).GenerateNewConfig(); Assert.Equal(Output.Replace(" ", string.Empty), result.ToString().Replace(" ", string.Empty)); }
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 void IncludesMexEndpointTest(string replace, bool expected) { bool result = new ConfigUpdater(XDocument.Parse(Input.Replace(MexEndpoint, replace)), _logger).IncludesMexEndpoint(); Assert.Equal(expected, result); }
protected override void Load(ContainerBuilder builder) { // IMessageConverter<IRoutingMessage> builder.Register(c => new RoutingMessageConverter()) .As <Core.IMessageConverter <IRoutingMessage> >() .SingleInstance(); // IRoutingPerfCounter builder.Register( c => { Routing.PerfCounter = NullRoutingPerfCounter.Instance; return(Routing.PerfCounter); }) .As <IRoutingPerfCounter>() .AutoActivate() .SingleInstance(); // IRoutingUserAnalyticsLogger builder.Register( c => { Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance; return(Routing.UserAnalyticsLogger); }) .As <IRoutingUserAnalyticsLogger>() .AutoActivate() .SingleInstance(); // IRoutingUserMetricLogger builder.Register( c => { Routing.UserMetricLogger = NullRoutingUserMetricLogger.Instance; return(Routing.UserMetricLogger); }) .As <IRoutingUserMetricLogger>() .AutoActivate() .SingleInstance(); // IMessageConverter<Message> builder.Register(c => new DeviceClientMessageConverter()) .As <Core.IMessageConverter <Message> >() .SingleInstance(); // IMessageConverter<Twin> builder.Register(c => new TwinMessageConverter()) .As <Core.IMessageConverter <Twin> >() .SingleInstance(); // IMessageConverter<TwinCollection> builder.Register(c => new TwinCollectionMessageConverter()) .As <Core.IMessageConverter <TwinCollection> >() .SingleInstance(); // IMessageConverterProvider builder.Register( c => new MessageConverterProvider( new Dictionary <Type, IMessageConverter>() { { typeof(Message), c.Resolve <Core.IMessageConverter <Message> >() }, { typeof(Twin), c.Resolve <Core.IMessageConverter <Twin> >() }, { typeof(TwinCollection), c.Resolve <Core.IMessageConverter <TwinCollection> >() } })) .As <IMessageConverterProvider>() .SingleInstance(); // IDeviceConnectivityManager builder.Register( c => { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); IDeviceConnectivityManager deviceConnectivityManager = this.experimentalFeatures.DisableConnectivityCheck ? new NullDeviceConnectivityManager() : new DeviceConnectivityManager(this.connectivityCheckFrequency, TimeSpan.FromMinutes(2), edgeHubCredentials.Identity) as IDeviceConnectivityManager; return(deviceConnectivityManager); }) .As <IDeviceConnectivityManager>() .SingleInstance(); // IDeviceClientProvider builder.Register( c => { IClientProvider underlyingClientProvider = new ClientProvider(); IClientProvider connectivityAwareClientProvider = new ConnectivityAwareClientProvider(underlyingClientProvider, c.Resolve <IDeviceConnectivityManager>()); return(connectivityAwareClientProvider); }) .As <IClientProvider>() .SingleInstance(); // Task<ICloudConnectionProvider> builder.Register( async c => { var productInfoStore = await c.Resolve <Task <IProductInfoStore> >(); var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); var clientProvider = c.Resolve <IClientProvider>(); var tokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubClientAuthTokenProvider"); var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var deviceScopeIdentitiesCacheTask = c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); var proxy = c.Resolve <Option <IWebProxy> >(); IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask; ICredentialsCache credentialsCache = await credentialsCacheTask; ICloudConnectionProvider cloudConnectionProvider = new CloudConnectionProvider( messageConverterProvider, this.connectionPoolSize, clientProvider, this.upstreamProtocol, tokenProvider, deviceScopeIdentitiesCache, credentialsCache, edgeHubCredentials.Identity, this.cloudConnectionIdleTimeout, this.closeCloudConnectionOnIdleTimeout, this.operationTimeout, this.useServerHeartbeat, proxy, productInfoStore); return(cloudConnectionProvider); }) .As <Task <ICloudConnectionProvider> >() .SingleInstance(); // IIdentityProvider builder.Register(_ => new IdentityProvider(this.iotHubName)) .As <IIdentityProvider>() .SingleInstance(); // Task<IConnectionManager> builder.Register( async c => { var cloudConnectionProviderTask = c.Resolve <Task <ICloudConnectionProvider> >(); var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >(); var identityProvider = c.Resolve <IIdentityProvider>(); var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>(); ICloudConnectionProvider cloudConnectionProvider = await cloudConnectionProviderTask; ICredentialsCache credentialsCache = await credentialsCacheTask; IConnectionManager connectionManager = new ConnectionManager( cloudConnectionProvider, credentialsCache, identityProvider, deviceConnectivityManager, this.maxConnectedClients, this.closeCloudConnectionOnDeviceDisconnect); return(connectionManager); }) .As <Task <IConnectionManager> >() .SingleInstance(); // Task<IEndpointFactory> builder.Register( async c => { var messageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(new EndpointFactory(connectionManager, messageConverter, this.edgeDeviceId, this.maxUpstreamBatchSize, this.upstreamFanOutFactor) as IEndpointFactory); }) .As <Task <IEndpointFactory> >() .SingleInstance(); // Task<RouteFactory> builder.Register(async c => new EdgeRouteFactory(await c.Resolve <Task <IEndpointFactory> >()) as RouteFactory) .As <Task <RouteFactory> >() .SingleInstance(); // RouterConfig builder.Register(c => new RouterConfig(Enumerable.Empty <Route>())) .As <RouterConfig>() .SingleInstance(); if (!this.isStoreAndForwardEnabled) { // EndpointExecutorConfig builder.Register( c => { RetryStrategy defaultRetryStrategy = new FixedInterval(0, TimeSpan.FromSeconds(1)); TimeSpan defaultRevivePeriod = TimeSpan.FromHours(1); TimeSpan defaultTimeout = TimeSpan.FromSeconds(60); return(new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // IEndpointExecutorFactory builder.Register(c => new SyncEndpointExecutorFactory(c.Resolve <EndpointExecutorConfig>())) .As <IEndpointExecutorFactory>() .SingleInstance(); // Task<Router> builder.Register( async c => { var endpointExecutorFactory = c.Resolve <IEndpointExecutorFactory>(); var routerConfig = c.Resolve <RouterConfig>(); Router router = await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory); return(router); }) .As <Task <Router> >() .SingleInstance(); // Task<ITwinManager> builder.Register( async c => { if (!this.useV1TwinManager) { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); ITwinManager twinManager = new PassThroughTwinManager(connectionManager, messageConverterProvider); return(twinManager); } else { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.None <IStoreProvider>())); } }) .As <Task <ITwinManager> >() .SingleInstance(); } else { // EndpointExecutorConfig builder.Register( c => { // Endpoint executor config values - // ExponentialBackoff - minBackoff = 1s, maxBackoff = 60s, delta (used to add randomness to backoff) - 1s (default) // Num of retries = int.MaxValue(we want to keep retrying till the message is sent) // Revive period - period for which the endpoint should be considered dead if it doesn't respond - 1 min (we want to try continuously till the message expires) // Timeout - time for which we want for the ack from the endpoint = 30s // TODO - Should the number of retries be tied to the Store and Forward ttl? Not // doing that right now as that value can be changed at runtime, but these settings // cannot. Need to make the number of retries dynamically configurable for that. TimeSpan minWait = TimeSpan.FromSeconds(1); TimeSpan maxWait = TimeSpan.FromSeconds(60); TimeSpan delta = TimeSpan.FromSeconds(1); int retries = int.MaxValue; RetryStrategy retryStrategy = new ExponentialBackoff(retries, minWait, maxWait, delta); TimeSpan timeout = TimeSpan.FromSeconds(30); TimeSpan revivePeriod = TimeSpan.FromSeconds(30); return(new EndpointExecutorConfig(timeout, retryStrategy, revivePeriod)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // Task<ICheckpointStore> builder.Register( async c => { var dbStoreProvider = await c.Resolve <Task <IDbStoreProvider> >(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); ICheckpointStore checkpointStore = CheckpointStore.Create(storeProvider); return(checkpointStore); }) .As <Task <ICheckpointStore> >() .SingleInstance(); // Task<IMessageStore> builder.Register( async c => { var checkpointStore = await c.Resolve <Task <ICheckpointStore> >(); var dbStoreProvider = await c.Resolve <Task <IDbStoreProvider> >(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); IMessageStore messageStore = new MessageStore(storeProvider, checkpointStore, this.storeAndForwardConfiguration.TimeToLive, this.checkEntireQueueOnCleanup); return(messageStore); }) .As <Task <IMessageStore> >() .SingleInstance(); // Task<IEndpointExecutorFactory> builder.Register( async c => { var endpointExecutorConfig = c.Resolve <EndpointExecutorConfig>(); var messageStore = await c.Resolve <Task <IMessageStore> >(); IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(10, TimeSpan.FromSeconds(10)), messageStore); return(endpointExecutorFactory); }) .As <Task <IEndpointExecutorFactory> >() .SingleInstance(); // Task<Router> builder.Register( async c => { var checkpointStore = await c.Resolve <Task <ICheckpointStore> >(); var routerConfig = c.Resolve <RouterConfig>(); var endpointExecutorFactory = await c.Resolve <Task <IEndpointExecutorFactory> >(); return(await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory, checkpointStore)); }) .As <Task <Router> >() .SingleInstance(); // Task<ITwinManager> builder.Register( async c => { if (this.useV1TwinManager) { var dbStoreProvider = await c.Resolve <Task <IDbStoreProvider> >(); var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(TwinManager.CreateTwinManager(connectionManager, messageConverterProvider, Option.Some <IStoreProvider>(new StoreProvider(dbStoreProvider)))); } else { var messageConverterProvider = c.Resolve <IMessageConverterProvider>(); var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>(); var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); IEntityStore <string, TwinStoreEntity> entityStore = await this.GetTwinStore(c); IConnectionManager connectionManager = await connectionManagerTask; ITwinManager twinManager = StoringTwinManager.Create( connectionManager, messageConverterProvider, entityStore, deviceConnectivityManager, new ReportedPropertiesValidator(), this.minTwinSyncPeriod, this.reportedPropertiesSyncFrequency); return(twinManager); } }) .As <Task <ITwinManager> >() .SingleInstance(); } // IClientCredentials "EdgeHubCredentials" builder.Register( c => { var identityFactory = c.Resolve <IClientCredentialsFactory>(); IClientCredentials edgeHubCredentials = this.connectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse( () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeModuleId)); return(edgeHubCredentials); }) .Named <IClientCredentials>("EdgeHubCredentials") .SingleInstance(); // Task<IInvokeMethodHandler> builder.Register( async c => { IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); return(new InvokeMethodHandler(connectionManager) as IInvokeMethodHandler); }) .As <Task <IInvokeMethodHandler> >() .SingleInstance(); // Task<ISubscriptionProcessor> builder.Register( async c => { var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); if (this.experimentalFeatures.DisableCloudSubscriptions) { return(new LocalSubscriptionProcessor(await connectionManagerTask) as ISubscriptionProcessor); } else { var invokeMethodHandlerTask = c.Resolve <Task <IInvokeMethodHandler> >(); var deviceConnectivityManager = c.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await connectionManagerTask; IInvokeMethodHandler invokeMethodHandler = await invokeMethodHandlerTask; return(new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager) as ISubscriptionProcessor); } }) .As <Task <ISubscriptionProcessor> >() .SingleInstance(); // Task<IEdgeHub> builder.Register( async c => { var routingMessageConverter = c.Resolve <Core.IMessageConverter <IRoutingMessage> >(); var routerTask = c.Resolve <Task <Router> >(); var twinManagerTask = c.Resolve <Task <ITwinManager> >(); var invokeMethodHandlerTask = c.Resolve <Task <IInvokeMethodHandler> >(); var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); var subscriptionProcessorTask = c.Resolve <Task <ISubscriptionProcessor> >(); Router router = await routerTask; ITwinManager twinManager = await twinManagerTask; IConnectionManager connectionManager = await connectionManagerTask; IInvokeMethodHandler invokeMethodHandler = await invokeMethodHandlerTask; ISubscriptionProcessor subscriptionProcessor = await subscriptionProcessorTask; IEdgeHub hub = new RoutingEdgeHub( router, routingMessageConverter, connectionManager, twinManager, this.edgeDeviceId, invokeMethodHandler, subscriptionProcessor); return(hub); }) .As <Task <IEdgeHub> >() .SingleInstance(); // Task<ConfigUpdater> builder.Register( async c => { IMessageStore messageStore = this.isStoreAndForwardEnabled ? await c.Resolve <Task <IMessageStore> >() : null; var storageSpaceChecker = c.Resolve <IStorageSpaceChecker>(); var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); RouteFactory routeFactory = await c.Resolve <Task <RouteFactory> >(); Router router = await c.Resolve <Task <Router> >(); var twinManagerTask = c.Resolve <Task <ITwinManager> >(); var twinMessageConverter = c.Resolve <Core.IMessageConverter <Twin> >(); var twinManager = await twinManagerTask; var configUpdater = new ConfigUpdater(router, messageStore, this.configUpdateFrequency, storageSpaceChecker); return(configUpdater); }) .As <Task <ConfigUpdater> >() .SingleInstance(); // Task<IConfigSource> builder.Register <Task <IConfigSource> >( async c => { RouteFactory routeFactory = await c.Resolve <Task <RouteFactory> >(); if (this.useTwinConfig) { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var twinCollectionMessageConverter = c.Resolve <Core.IMessageConverter <TwinCollection> >(); var twinMessageConverter = c.Resolve <Core.IMessageConverter <Twin> >(); var twinManagerTask = c.Resolve <Task <ITwinManager> >(); var edgeHubTask = c.Resolve <Task <IEdgeHub> >(); ITwinManager twinManager = await twinManagerTask; IEdgeHub edgeHub = await edgeHubTask; IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >(); IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >(); var edgeHubConnection = await EdgeHubConnection.Create( edgeHubCredentials.Identity, edgeHub, twinManager, connectionManager, routeFactory, twinCollectionMessageConverter, this.versionInfo, deviceScopeIdentitiesCache); return(new TwinConfigSource(edgeHubConnection, edgeHubCredentials.Identity.Id, this.versionInfo, twinManager, twinMessageConverter, twinCollectionMessageConverter, routeFactory)); } else { return(new LocalConfigSource(routeFactory, this.routes, this.storeAndForwardConfiguration)); } }) .As <Task <IConfigSource> >() .SingleInstance(); // Task<IConnectionProvider> builder.Register( async c => { var connectionManagerTask = c.Resolve <Task <IConnectionManager> >(); var edgeHubTask = c.Resolve <Task <IEdgeHub> >(); IConnectionManager connectionManager = await connectionManagerTask; IEdgeHub edgeHub = await edgeHubTask; IConnectionProvider connectionProvider = new ConnectionProvider(connectionManager, edgeHub, this.messageAckTimeout); return(connectionProvider); }) .As <Task <IConnectionProvider> >() .SingleInstance(); base.Load(builder); }
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)); }
protected override void Load(ContainerBuilder builder) { // IMessageConverter<IRoutingMessage> builder.Register(c => new RoutingMessageConverter()) .As <Core.IMessageConverter <IRoutingMessage> >() .SingleInstance(); // IRoutingPerfCounter builder.Register( c => { Routing.PerfCounter = NullRoutingPerfCounter.Instance; return(Routing.PerfCounter); }) .As <IRoutingPerfCounter>() .AutoActivate() .SingleInstance(); // IRoutingUserAnalyticsLogger builder.Register( c => { Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance; return(Routing.UserAnalyticsLogger); }) .As <IRoutingUserAnalyticsLogger>() .AutoActivate() .SingleInstance(); // IRoutingUserMetricLogger builder.Register( c => { Routing.UserMetricLogger = NullRoutingUserMetricLogger.Instance; return(Routing.UserMetricLogger); }) .As <IRoutingUserMetricLogger>() .AutoActivate() .SingleInstance(); // IMessageConverter<Message> builder.Register(c => new DeviceClientMessageConverter()) .As <Core.IMessageConverter <Message> >() .SingleInstance(); // IMessageConverter<Twin> builder.Register(c => new TwinMessageConverter()) .As <Core.IMessageConverter <Twin> >() .SingleInstance(); // IMessageConverter<TwinCollection> builder.Register(c => new TwinCollectionMessageConverter()) .As <Core.IMessageConverter <TwinCollection> >() .SingleInstance(); // IMessageConverterProvider builder.Register( c => new MessageConverterProvider(new Dictionary <Type, IMessageConverter>() { { typeof(Message), c.Resolve <Core.IMessageConverter <Message> >() }, { typeof(Twin), c.Resolve <Core.IMessageConverter <Twin> >() }, { typeof(TwinCollection), c.Resolve <Core.IMessageConverter <TwinCollection> >() } })) .As <Core.IMessageConverterProvider>() .SingleInstance(); // IDeviceConnectivityManager builder.Register( c => { IDeviceConnectivityManager deviceConnectivityManager = new DeviceConnectivityManager(this.connectivityCheckFrequency, TimeSpan.FromMinutes(2)); return(deviceConnectivityManager); }) .As <IDeviceConnectivityManager>() .SingleInstance(); // IDeviceClientProvider builder.Register(c => { IClientProvider underlyingClientProvider = new ClientProvider(); IClientProvider connectivityAwareClientProvider = new ConnectivityAwareClientProvider(underlyingClientProvider, c.Resolve <IDeviceConnectivityManager>()); return(connectivityAwareClientProvider); }) .As <IClientProvider>() .SingleInstance(); // ICloudConnectionProvider builder.Register(c => new CloudConnectionProvider(c.Resolve <Core.IMessageConverterProvider>(), this.connectionPoolSize, c.Resolve <IClientProvider>(), this.upstreamProtocol)) .As <ICloudConnectionProvider>() .SingleInstance(); if (this.isStoreAndForwardEnabled || this.cacheTokens) { // Detect system environment builder.Register(c => new SystemEnvironment()) .As <ISystemEnvironment>() .SingleInstance(); // DataBase options builder.Register(c => new Storage.RocksDb.RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), this.optimizeForPerformance)) .As <Storage.RocksDb.IRocksDbOptionsProvider>() .SingleInstance(); // IDbStore builder.Register( c => { var loggerFactory = c.Resolve <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger(typeof(RoutingModule)); if (this.usePersistentStorage) { // Create partitions for messages and twins var partitionsList = new List <string> { Core.Constants.MessageStorePartitionKey, Core.Constants.TwinStorePartitionKey, Core.Constants.CheckpointStorePartitionKey }; try { IDbStoreProvider dbStoreprovider = Storage.RocksDb.DbStoreProvider.Create(c.Resolve <Storage.RocksDb.IRocksDbOptionsProvider>(), this.storagePath, partitionsList); logger.LogInformation($"Created persistent store at {this.storagePath}"); return(dbStoreprovider); } catch (Exception ex) when(!ExceptionEx.IsFatal(ex)) { logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store."); return(new InMemoryDbStoreProvider()); } } else { logger.LogInformation($"Using in-memory store"); return(new InMemoryDbStoreProvider()); } }) .As <IDbStoreProvider>() .SingleInstance(); } // Task<ICredentialsStore> builder.Register(async c => { if (this.cacheTokens) { var dbStoreProvider = c.Resolve <IDbStoreProvider>(); IEncryptionProvider encryptionProvider = await this.workloadUri.Map( async uri => await EncryptionProvider.CreateAsync( this.storagePath, new Uri(uri), Service.Constants.WorkloadApiVersion, this.edgeModuleId, this.edgeModuleGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")), Service.Constants.InitializationVectorFileName) as IEncryptionProvider) .GetOrElse(() => Task.FromResult <IEncryptionProvider>(NullEncryptionProvider.Instance)); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); IEntityStore <string, string> tokenCredentialsEntityStore = storeProvider.GetEntityStore <string, string>("tokenCredentials"); return(new TokenCredentialsStore(tokenCredentialsEntityStore, encryptionProvider)); } else { return(new NullCredentialsStore() as ICredentialsStore); } }) .As <Task <ICredentialsStore> >() .SingleInstance(); // IConnectionManager builder.Register(c => new ConnectionManager(c.Resolve <ICloudConnectionProvider>(), this.maxConnectedClients)) .As <IConnectionManager>() .SingleInstance(); // IEndpointFactory builder.Register(c => new EndpointFactory(c.Resolve <IConnectionManager>(), c.Resolve <Core.IMessageConverter <IRoutingMessage> >(), this.edgeDeviceId)) .As <IEndpointFactory>() .SingleInstance(); // RouteFactory builder.Register(c => new EdgeRouteFactory(c.Resolve <IEndpointFactory>())) .As <RouteFactory>() .SingleInstance(); // RouterConfig builder.Register(c => new RouterConfig(Enumerable.Empty <Route>())) .As <RouterConfig>() .SingleInstance(); if (!this.isStoreAndForwardEnabled) { // EndpointExecutorConfig builder.Register( c => { RetryStrategy defaultRetryStrategy = new FixedInterval(0, TimeSpan.FromSeconds(1)); TimeSpan defaultRevivePeriod = TimeSpan.FromHours(1); TimeSpan defaultTimeout = TimeSpan.FromSeconds(60); return(new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // IEndpointExecutorFactory builder.Register(c => new SyncEndpointExecutorFactory(c.Resolve <EndpointExecutorConfig>())) .As <IEndpointExecutorFactory>() .SingleInstance(); // Task<Router> builder.Register( async c => { var endpointExecutorFactory = c.Resolve <IEndpointExecutorFactory>(); var routerConfig = c.Resolve <RouterConfig>(); Router router = await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory); return(router); }) .As <Task <Router> >() .SingleInstance(); // ITwinManager builder.Register(c => TwinManager.CreateTwinManager(c.Resolve <IConnectionManager>(), c.Resolve <IMessageConverterProvider>(), Option.None <IStoreProvider>())) .As <ITwinManager>() .SingleInstance(); } else { // EndpointExecutorConfig builder.Register( c => { // Endpoint executor config values - // ExponentialBackoff - minBackoff = 1s, maxBackoff = 60s, delta (used to add randomness to backoff) - 1s (default) // Num of retries = int.MaxValue(we want to keep retrying till the message is sent) // Revive period - period for which the endpoint should be considered dead if it doesn't respond - 1 min (we want to try continuously till the message expires) // Timeout - time for which we want for the ack from the endpoint = 30s // TODO - Should the number of retries be tied to the Store and Forward ttl? Not // doing that right now as that value can be changed at runtime, but these settings // cannot. Need to make the number of retries dynamically configurable for that. TimeSpan minWait = TimeSpan.FromSeconds(1); TimeSpan maxWait = TimeSpan.FromSeconds(60); TimeSpan delta = TimeSpan.FromSeconds(1); int retries = int.MaxValue; RetryStrategy retryStrategy = new ExponentialBackoff(retries, minWait, maxWait, delta); TimeSpan timeout = TimeSpan.FromSeconds(30); TimeSpan revivePeriod = TimeSpan.FromSeconds(30); return(new EndpointExecutorConfig(timeout, retryStrategy, revivePeriod)); }) .As <EndpointExecutorConfig>() .SingleInstance(); // ICheckpointStore builder.Register(c => CheckpointStore.Create(c.Resolve <IDbStoreProvider>())) .As <ICheckpointStore>() .SingleInstance(); // IMessageStore builder.Register( c => { var checkpointStore = c.Resolve <ICheckpointStore>(); var dbStoreProvider = c.Resolve <IDbStoreProvider>(); IStoreProvider storeProvider = new StoreProvider(dbStoreProvider); IMessageStore messageStore = new MessageStore(storeProvider, checkpointStore, TimeSpan.MaxValue); return(messageStore); }) .As <IMessageStore>() .SingleInstance(); // IEndpointExecutorFactory builder.Register( c => { var endpointExecutorConfig = c.Resolve <EndpointExecutorConfig>(); var messageStore = c.Resolve <IMessageStore>(); IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(10, TimeSpan.FromSeconds(10)), messageStore); return(endpointExecutorFactory); }) .As <IEndpointExecutorFactory>() .SingleInstance(); // Task<Router> builder.Register( async c => { var checkpointStore = c.Resolve <ICheckpointStore>(); var routerConfig = c.Resolve <RouterConfig>(); var endpointExecutorFactory = c.Resolve <IEndpointExecutorFactory>(); return(await Router.CreateAsync(Guid.NewGuid().ToString(), this.iotHubName, routerConfig, endpointExecutorFactory, checkpointStore)); }) .As <Task <Router> >() .SingleInstance(); // ITwinManager builder.Register(c => TwinManager.CreateTwinManager(c.Resolve <IConnectionManager>(), c.Resolve <IMessageConverterProvider>(), Option.Some <IStoreProvider>(new StoreProvider(c.Resolve <IDbStoreProvider>())))) .As <ITwinManager>() .SingleInstance(); } // IClientCredentials "EdgeHubCredentials" builder.Register( c => { var identityFactory = c.Resolve <IClientCredentialsFactory>(); IClientCredentials edgeHubCredentials = this.connectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse( () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeModuleId)); return(edgeHubCredentials); }) .Named <IClientCredentials>("EdgeHubCredentials") .SingleInstance(); // Task<ICloudProxy> "EdgeHubCloudProxy" builder.Register( async c => { var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var connectionManager = c.Resolve <IConnectionManager>(); Try <ICloudProxy> cloudProxyTry = await connectionManager.CreateCloudConnectionAsync(edgeHubCredentials); if (!cloudProxyTry.Success) { throw new EdgeHubConnectionException("Edge hub is unable to connect to IoT Hub", cloudProxyTry.Exception); } ICloudProxy cloudProxy = cloudProxyTry.Value; return(cloudProxy); }) .Named <Task <ICloudProxy> >("EdgeHubCloudProxy") .SingleInstance(); // Task<IEdgeHub> builder.Register( async c => { Router router = await c.Resolve <Task <Router> >(); IEdgeHub hub = new RoutingEdgeHub(router, c.Resolve <Core.IMessageConverter <IRoutingMessage> >(), c.Resolve <IConnectionManager>(), c.Resolve <ITwinManager>(), this.edgeDeviceId); return(hub); }) .As <Task <IEdgeHub> >() .SingleInstance(); // Task<ConfigUpdater> builder.Register( async c => { IMessageStore messageStore = this.isStoreAndForwardEnabled ? c.Resolve <IMessageStore>() : null; Router router = await c.Resolve <Task <Router> >(); var configUpdater = new ConfigUpdater(router, messageStore); return(configUpdater); }) .As <Task <ConfigUpdater> >() .SingleInstance(); // Task<IConfigSource> builder.Register( async c => { var routeFactory = c.Resolve <RouteFactory>(); if (this.useTwinConfig) { var connectionManager = c.Resolve <IConnectionManager>(); var edgeHubCredentials = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); var twinCollectionMessageConverter = c.Resolve <Core.IMessageConverter <TwinCollection> >(); var twinMessageConverter = c.Resolve <Core.IMessageConverter <Twin> >(); var twinManager = c.Resolve <ITwinManager>(); ICloudProxy cloudProxy = await c.ResolveNamed <Task <ICloudProxy> >("EdgeHubCloudProxy"); IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >(); IConfigSource edgeHubConnection = await EdgeHubConnection.Create( edgeHubCredentials.Identity as IModuleIdentity, edgeHub, twinManager, connectionManager, cloudProxy, routeFactory, twinCollectionMessageConverter, twinMessageConverter, this.versionInfo ); return(edgeHubConnection); } else { return(new LocalConfigSource(routeFactory, this.routes, this.storeAndForwardConfiguration)); } }) .As <Task <IConfigSource> >() .SingleInstance(); // Task<IConnectionProvider> builder.Register( async c => { IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >(); IConnectionProvider connectionProvider = new ConnectionProvider(c.Resolve <IConnectionManager>(), edgeHub); return(connectionProvider); }) .As <Task <IConnectionProvider> >() .SingleInstance(); base.Load(builder); }
void WhitelistMan(ISender sender, ArgumentList args) { var index = 0; var cmd = args.GetString(index++); string name, ip; switch (cmd) { case "status": case "current": case "?": sender.Message("The whitelist is currently " + (Core.Config.WhitelistEnabled ? "enabled" : "disabled")); break; case "reload": Core.Whitelist.Load(); Utils.NotifyAllOps("The whitelist was reloaded"); break; case "enable": if (!Core.Config.WhitelistEnabled) { Core.Config.WhitelistEnabled = true; if (!ConfigUpdater.IsAvailable || ConfigUpdater.Set("whitelist", Core.Config.WhitelistEnabled)) { Utils.NotifyAllOps("The whitelist was enabled"); } else { sender.Message("Failed to save to config, whitelist is only enabled this session.", Color.Red); } } else { sender.Message("The whitelist is already enabled", Color.Red); } break; case "disable": if (Core.Config.WhitelistEnabled) { Core.Config.WhitelistEnabled = false; if (!ConfigUpdater.IsAvailable || ConfigUpdater.Set("whitelist", Core.Config.WhitelistEnabled)) { Utils.NotifyAllOps("The whitelist was disabled"); } else { sender.Message("Failed to save to config, whitelist is only disabled this session.", Color.Red); } } else { sender.Message("The whitelist is already disabled", Color.Red); } break; case "addplayer": if (!args.TryGetString(index++, out name)) { throw new CommandError("Expected player name after [addplayer]"); } var addName = Prefix_WhitelistName + name; if (Core.Whitelist.Add(addName)) { Utils.NotifyAllOps(String.Format("Player {0} was added to the whitelist", name)); if (!Core.Config.WhitelistEnabled) { sender.Message("Note, the whitelist is not enabled", Color.Orange); } } else { sender.Message("Failed to add " + name + " to the whitelist", Color.Red); } break; case "removeplayer": if (!args.TryGetString(index++, out name)) { throw new CommandError("Expected player name after [removeplayer]"); } var removeName = Prefix_WhitelistName + name; if (Core.Whitelist.Remove(removeName)) { Utils.NotifyAllOps(String.Format("Player {0} was removed from the whitelist", name)); if (!Core.Config.WhitelistEnabled) { sender.Message("Note, the whitelist is not enabled", Color.Orange); } } else { sender.Message("Failed to remove " + name + " from the whitelist", Color.Red); } break; case "addip": if (!args.TryGetString(index++, out ip)) { throw new CommandError("Expected IP after [addip]"); } var addIP = Prefix_WhitelistIp + ip; if (Core.Whitelist.Add(addIP)) { Utils.NotifyAllOps(String.Format("IP {0} was added to the whitelist", ip)); if (!Core.Config.WhitelistEnabled) { sender.Message("Note, the whitelist is not enabled", Color.Orange); } } else { sender.Message("Failed to add " + ip + " to the whitelist", Color.Red); } break; case "removeip": if (!args.TryGetString(index++, out ip)) { throw new CommandError("Expected IP after [removeip]"); } var removeIP = Prefix_WhitelistIp + ip; if (Core.Whitelist.Remove(removeIP)) { Utils.NotifyAllOps(String.Format("IP {0} was removed from the whitelist", ip)); if (!Core.Config.WhitelistEnabled) { sender.Message("Note, the whitelist is not enabled", Color.Orange); } } else { sender.Message("Failed to remove " + ip + " from the whitelist", Color.Red); } break; default: throw new CommandError("Unknown whitelist command: " + cmd); } }
static async Task <int> MainAsync(IConfigurationRoot configuration) { string logLevel = configuration.GetValue($"{Logger.RuntimeLogLevelEnvKey}", "info"); Logger.SetLogLevel(logLevel); // Set the LoggerFactory used by the Routing code. if (configuration.GetValue("EnableRoutingLogging", false)) { Routing.LoggerFactory = Logger.Factory; } ILogger logger = Logger.Factory.CreateLogger("EdgeHub"); EdgeHubCertificates certificates = await EdgeHubCertificates.LoadAsync(configuration, logger); bool clientCertAuthEnabled = configuration.GetValue(Constants.ConfigKey.EdgeHubClientCertAuthEnabled, false); string sslProtocolsConfig = configuration.GetValue(Constants.ConfigKey.SslProtocols, string.Empty); SslProtocols sslProtocols = SslProtocolsHelper.Parse(sslProtocolsConfig, DefaultSslProtocols, logger); logger.LogInformation($"Enabling SSL protocols: {sslProtocols.Print()}"); IDependencyManager dependencyManager = new DependencyManager(configuration, certificates.ServerCertificate, certificates.TrustBundle, sslProtocols); Hosting hosting = Hosting.Initialize(configuration, certificates.ServerCertificate, dependencyManager, clientCertAuthEnabled, sslProtocols); IContainer container = hosting.Container; logger.LogInformation("Initializing Edge Hub"); LogLogo(logger); LogVersionInfo(logger); logger.LogInformation($"OptimizeForPerformance={configuration.GetValue("OptimizeForPerformance", true)}"); logger.LogInformation($"MessageAckTimeoutSecs={configuration.GetValue("MessageAckTimeoutSecs", 30)}"); logger.LogInformation("Loaded server certificate with expiration date of {0}", certificates.ServerCertificate.NotAfter.ToString("o")); var metricsProvider = container.Resolve <IMetricsProvider>(); Metrics.InitWithAspNet(metricsProvider, logger); // Note this requires App.UseMetricServer() to be called in Startup.cs // Init V0 Metrics MetricsV0.BuildMetricsCollector(configuration); // EdgeHub and CloudConnectionProvider have a circular dependency. So need to Bind the EdgeHub to the CloudConnectionProvider. IEdgeHub edgeHub = await container.Resolve <Task <IEdgeHub> >(); ICloudConnectionProvider cloudConnectionProvider = await container.Resolve <Task <ICloudConnectionProvider> >(); cloudConnectionProvider.BindEdgeHub(edgeHub); // EdgeHub cloud proxy and DeviceConnectivityManager have a circular dependency, // so the cloud proxy has to be set on the DeviceConnectivityManager after both have been initialized. var deviceConnectivityManager = container.Resolve <IDeviceConnectivityManager>(); IConnectionManager connectionManager = await container.Resolve <Task <IConnectionManager> >(); (deviceConnectivityManager as DeviceConnectivityManager)?.SetConnectionManager(connectionManager); // Register EdgeHub credentials var edgeHubCredentials = container.ResolveNamed <IClientCredentials>("EdgeHubCredentials"); ICredentialsCache credentialsCache = await container.Resolve <Task <ICredentialsCache> >(); await credentialsCache.Add(edgeHubCredentials); // Initializing configuration logger.LogInformation("Initializing configuration"); IConfigSource configSource = await container.Resolve <Task <IConfigSource> >(); ConfigUpdater configUpdater = await container.Resolve <Task <ConfigUpdater> >(); await configUpdater.Init(configSource); if (!Enum.TryParse(configuration.GetValue("AuthenticationMode", string.Empty), true, out AuthenticationMode authenticationMode) || authenticationMode != AuthenticationMode.Cloud) { ConnectionReauthenticator connectionReauthenticator = await container.Resolve <Task <ConnectionReauthenticator> >(); connectionReauthenticator.Init(); } TimeSpan shutdownWaitPeriod = TimeSpan.FromSeconds(configuration.GetValue("ShutdownWaitPeriod", DefaultShutdownWaitPeriod)); (CancellationTokenSource cts, ManualResetEventSlim completed, Option <object> handler) = ShutdownHandler.Init(shutdownWaitPeriod, logger); using (IProtocolHead protocolHead = await GetEdgeHubProtocolHeadAsync(logger, configuration, container, hosting)) using (var renewal = new CertificateRenewal(certificates, logger)) { await protocolHead.StartAsync(); await Task.WhenAny(cts.Token.WhenCanceled(), renewal.Token.WhenCanceled()); logger.LogInformation("Stopping the protocol heads..."); await protocolHead.CloseAsync(CancellationToken.None); logger.LogInformation("Protocol heads stopped."); await CloseDbStoreProviderAsync(container); } completed.Set(); handler.ForEach(h => GC.KeepAlive(h)); logger.LogInformation("Shutdown complete."); return(0); }
private void DoDownload() { try { m_DownloadHelper_list.Add(this); string fileDir = Path.GetDirectoryName(m_filePath); if (!Directory.Exists(fileDir)) { Directory.CreateDirectory(fileDir); } //string filePath = m_filePath + m_url.Substring(m_url.LastIndexOf('/') + 1); if (!File.Exists(m_filePath)) { FileStream fs = File.Create(m_filePath); fs.Close(); } SetNoBackupFlagAction = () => ConfigUpdater.SetNoBackupFlag(m_filePath); FileStream fileStream = File.OpenWrite(m_filePath); //new FileStream(m_filePath, FileMode.OpenOrCreate, FileAccess.Write);// fileLength = fileStream.Length; totalLength = GetLength(m_url); UnityEngine.Debug.Log("CK : ------------------------------ fileLength = " + fileLength + ", totalLength = " + totalLength); if (fileLength < totalLength) { UnityEngine.Debug.Log("CK : ------------------------------ startdownload fileLength = " + fileLength + ", totalLength = " + totalLength); //UnityEngine.Debug.Log("CK : ------------------------------ start = "); HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_url); request.Timeout = 5000; request.AddRange((int)fileLength); //UnityEngine.Debug.Log("CK : ------------------------------ request = "); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); //UnityEngine.Debug.Log("CK : ------------------------------ response = "); fileStream.Seek(fileLength, SeekOrigin.Begin); Stream httpStream = response.GetResponseStream(); byte[] buffer = new byte[1024]; int length = httpStream.Read(buffer, 0, buffer.Length); while (length > 0) { if (isStop) { break; } fileStream.Write(buffer, 0, length); fileStream.Flush(); fileLength += length; progress = (fileLength + 0f) / totalLength * 100; //UnityEngine.Debug.Log("CK : ------------------------------ response = " + 3); length = httpStream.Read(buffer, 0, buffer.Length); } httpStream.Close(); httpStream.Dispose(); } else { progress = (fileLength + 0f) / totalLength * 100; } fileStream.Close(); fileStream.Dispose(); m_DownloadHelper_list.Remove(this); } catch (System.Exception e) { UnityEngine.Debug.Log("CK : ------------------------------ downloadhelper exeption = " + e.Message); if (string.IsNullOrEmpty(m_Error)) { m_Error = "下载异常 @ " + e.Message; } } m_IsDownloadComplete = true; }