Beispiel #1
0
        public async Task TestInitialConfigUpdate_WaitForInit()
        {
            // Arrange
            string id           = "id";
            string iotHub       = "foo.azure-devices.net";
            var    routerConfig = new RouterConfig(Enumerable.Empty <Route>());

            var messageStore = new Mock <IMessageStore>();

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

            var storageSpaceChecker = new Mock <IStorageSpaceChecker>();

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

            TimeSpan updateFrequency = TimeSpan.FromSeconds(10);

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

            var endpointFactory = new Mock <IEndpointFactory>();

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

            var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>();

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

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

            var configProvider = new Mock <IConfigSource>();

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

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

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

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

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

            Assert.Equal(2, router.Routes.Count);
        }
        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));
        }
Beispiel #5
0
    /// <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);
        }
Beispiel #8
0
        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();
        }
Beispiel #9
0
        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();
        }
Beispiel #12
0
        /// <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);
        }
Beispiel #13
0
    /// <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);
            }
        });
    }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
        }
Beispiel #16
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();
            }
Beispiel #20
0
        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);
        }
Beispiel #21
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));
        }
Beispiel #23
0
        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);
        }
Beispiel #25
0
        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);
        }
Beispiel #26
0
        public async Task TestPeriodicConfigUpdate()
        {
            // Arrange
            string id           = "id";
            string iotHub       = "foo.azure-devices.net";
            var    routerConfig = new RouterConfig(Enumerable.Empty <Route>());

            var messageStore = new Mock <IMessageStore>();

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

            var storageSpaceChecker = new Mock <IStorageSpaceChecker>();

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

            TimeSpan updateFrequency = TimeSpan.FromSeconds(10);

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

            var endpointFactory = new Mock <IEndpointFactory>();

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

            var endpointExecutorFactory = new Mock <IEndpointExecutorFactory>();

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

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

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

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

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

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

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

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

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

            var configProvider = new Mock <IConfigSource>();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            configProvider.Verify(c => c.GetConfig(), Times.Exactly(9));
            endpointExecutorFactory.Verify(e => e.CreateAsync(It.IsAny <Endpoint>(), It.IsAny <IList <uint> >(), It.IsAny <ICheckpointerFactory>()), Times.Once);
            messageStore.Verify(m => m.SetTimeToLive(It.IsAny <TimeSpan>()), Times.Exactly(8));
            storageSpaceChecker.Verify(m => m.SetMaxSizeBytes(It.Is <Option <long> >(x => !x.Equals(Option.None <long>()))), Times.Exactly(2));
        }
        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);
        }
Beispiel #28
0
        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);
            }
        }
Beispiel #29
0
        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);
        }
Beispiel #30
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;
    }