public DatabaseConnections()
        {
            _masterDatabaseName   = "master";
            _platformDatabaseName = "Platform";
            _accountsDatabaseName = "Accounts";
            //_membershipTableName = ""; // <-- Set based on Account Partition
            //_accountDatabasePartitionName = ""; //< -- Set based on user
            //_inventoryUserName = ""; //< -- Set based on user

            //Retry Policies=================================
            // Get an instance of the RetryManager class.
            //var retryManager = EnterpriseLibraryContainer.Current.GetInstance<RetryManager>();

            // Create a retry policy that uses a default retry strategy from the
            // configuration.
            retryPolicy = new RetryPolicy <DefaultRetryStrategy>(5, new TimeSpan(0, 0, 3));

            var retryInterval = TimeSpan.FromSeconds(3);
            var strategy      = new FixedInterval("fixed", 4, retryInterval);
            var strategies    = new List <RetryStrategy> {
                strategy
            };
            var manager = new RetryManager(strategies, "fixed");

            RetryManager.SetDefault(manager);
        }
        private static RetryPolicy CreateRetryPolicy(IMongoErrorHandlingFactory errorHandlingFactory)
        {
            var errorDetectionStrategy = errorHandlingFactory.CreateErrorDetectionStrategy();
            var retryStrategy          = new FixedInterval(MAX_ATTEMPTS, ATTEMPT_DELAY);

            return(new RetryPolicy(errorDetectionStrategy, retryStrategy));
        }
Exemple #3
0
        private static RetryPolicy <TransientErrorDetectionStrategy> GetPolicy(int retryCount, TimeSpan interval)
        {
            FixedInterval strategy = new FixedInterval(retryCount, interval);
            RetryPolicy <TransientErrorDetectionStrategy> policy = new RetryPolicy <TransientErrorDetectionStrategy>(strategy);

            return(policy);
        }
Exemple #4
0
        public bool DeleteFile(string filename, string personFolder, string containerDirectory)
        {
            //var targetFilename = Path.Combine(@"C:\Development\MediClinic\BlobStorage", personFolder, filename);
            //File.Delete(targetFilename);
            //return true;

            var destinationBlobName = IsNullOrEmpty(personFolder) ? filename : Format("{0}/{1}", personFolder, filename);
            var connectionString    = _applicationConfiguration.GetSetting("storage_connection_string");
            var retryStrategy       = new FixedInterval(3, TimeSpan.FromSeconds(1));
            var retryPolicy         = new RetryPolicy <StorageTransientErrorDetectionStrategy>(retryStrategy);

            try
            {
                retryPolicy.ExecuteAction(
                    () =>
                {
                    var account   = CloudStorageAccount.Parse(connectionString);
                    var client    = account.CreateCloudBlobClient();
                    var container = client.GetContainerReference(containerDirectory);
                    var blob      = container.GetBlockBlobReference(destinationBlobName);
                    blob.Delete();
                    return(true);
                });
            }
            catch (Exception exception)
            {
                //We will catch deletes as it just means it doesnt exist
                var e = exception.Message;
                //_logger.Error(string.Format("Blob storage exception {0}", e.Message), e);
            }
            return(false);
        }
Exemple #5
0
        public string GetContainerSasUri(string containerDirectory)
        {
            var connectionString  = _applicationConfiguration.GetSetting("storage_connection_string");
            var retryStrategy     = new FixedInterval(3, TimeSpan.FromSeconds(1));
            var retryPolicy       = new RetryPolicy <StorageTransientErrorDetectionStrategy>(retryStrategy);
            var sasContainerToken = Empty;

            try
            {
                retryPolicy.ExecuteAction(
                    () =>
                {
                    var storageAccount     = CloudStorageAccount.Parse(connectionString);
                    var cloudBlobClient    = storageAccount.CreateCloudBlobClient();
                    var cloudBlobContainer = cloudBlobClient.GetContainerReference(containerDirectory);
                    cloudBlobContainer.CreateIfNotExists();
                    cloudBlobContainer.SetPermissions(new BlobContainerPermissions {
                        PublicAccess = BlobContainerPublicAccessType.Off
                    });
                    var adHocPolicy = new SharedAccessBlobPolicy()
                    {
                        SharedAccessExpiryTime = DateTime.UtcNow.AddHours(3),
                        Permissions            = SharedAccessBlobPermissions.Read
                    };
                    sasContainerToken = cloudBlobContainer.GetSharedAccessSignature(adHocPolicy, null);
                });
            }
            catch (Exception exception)
            {
                var e = exception.Message;
                return(sasContainerToken);
            }
            return(sasContainerToken);
        }
Exemple #6
0
        public ClientProxyRetryInterceptor()
        {
            var           retryCount       = 3;
            var           retryIntervalSec = 1;
            RetryStrategy strategy         = new FixedInterval(retryCount, TimeSpan.FromSeconds(retryIntervalSec));

            retryPolicy = new RetryPolicy <WcfTransientErrorDetectionStrategy>(strategy);
        }
        static RetryPolicyFactory()
        {
            var strategy   = new FixedInterval("fixed", 10, TimeSpan.FromSeconds(3));
            var strategies = new List <RetryStrategy> {
                strategy
            };
            var manager = new RetryManager(strategies, "fixed");

            RetryManager.SetDefault(manager);
        }
Exemple #8
0
        /// <summary>
        ///     构建redis锁对象,
        /// </summary>
        /// <param name="database">Redis Database实例</param>
        /// <param name="maxRetryCount">最大重试次数</param>
        /// <param name="retryEveryMilliseconds">每次获取锁的时间间隔(毫秒)</param>
        public RedisLockHelper(IDatabase database, int maxRetryCount = 6, int retryEveryMilliseconds = 500)
        {
            this.database               = database;
            this.maxRetryCount          = maxRetryCount;
            this.retryEveryMilliseconds = retryEveryMilliseconds;

            FixedInterval fixedInterval = new FixedInterval(maxRetryCount, TimeSpan.FromMilliseconds(retryEveryMilliseconds));

            this.retryPolicy = new RetryPolicy(new RedisTransientErrorDetectionStrategy(), fixedInterval);
        }
Exemple #9
0
        public AccessControlRepository(string connectionString)
        {
            // Define your retry strategy: retry 3 times, 1 second apart.
            var retryStrategy = new FixedInterval(3, TimeSpan.FromSeconds(1));

            // Define your retry policy using the retry strategy and the Azure storage
            // transient fault detection strategy.
            retryPolicy           = new RetryPolicy <SqlDatabaseTransientErrorDetectionStrategy>(retryStrategy);
            retryPolicy.Retrying += testEHandler;
            _sqlConnection        = new ReliableSqlConnection(connectionString, retryPolicy, retryPolicy);
        }
Exemple #10
0
        public void DoTest2()
        {
            var retry = new FixedInterval(3, new TimeSpan(0, 0, 3), false);
            var i     = 0;

            retry.DoExecute(() => { if (i++ < 3)
                                    {
                                        throw new Exception("test");
                                    }
                            });
        }
Exemple #11
0
        public void DoTest1()
        {
            var retry = new FixedInterval();
            var i     = 0;

            retry.DoExecute(() => { if (i++ < 3)
                                    {
                                        throw new Exception("test");
                                    }
                            });
        }
Exemple #12
0
        public RedisCacheManager(string connectionString, TimeSpan?cacheTime = null, int errorRetryCount = 0,
                                 TimeSpan?errorRetryInterval = null)
        {
            _redis       = ConnectionMultiplexer.Connect(connectionString);
            _cacheClient = new StackExchangeRedisCacheClient(_redis, new MsgPackObjectSerializer());

            var retryStrategy = new FixedInterval(errorRetryCount, errorRetryInterval ?? TimeSpan.Zero);

            _retryPolicy = new RetryPolicy <RedisCacheTransientErrorDetectionStrategy>(retryStrategy);
            _cacheTime   = cacheTime ?? TimeSpan.FromDays(7);
        }
Exemple #13
0
        // The purpose of this method is to make less noise in logs when the broker
        // is not connected upstream for a short interim time period.
        // This mainly happens during startup, when edgeHub core starts connecting upstream,
        // but some collaborating components are not ready yet, or the parent device is not
        // available yet.
        async Task <bool> IsConnected()
        {
            var shouldRetry = new FixedInterval(50, TimeSpan.FromMilliseconds(100)).GetShouldRetry();
            var retryCount  = 0;

            while (!this.cloudProxyDispatcher.IsConnected && shouldRetry(retryCount++, null, out var delay))
            {
                await Task.Delay(delay);
            }

            return(this.cloudProxyDispatcher.IsConnected);
        }
Exemple #14
0
        public void DoTest3()
        {
            var retry = new FixedInterval(3, new TimeSpan(0, 0, 3), false);

            try
            {
                retry.DoExecute(() => { throw new Exception("test"); });
            }
            catch (Exception e)
            {
                Assert.AreEqual(e.Message, "test");
            }
        }
Exemple #15
0
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            var strategy   = new FixedInterval("fixed", 10, TimeSpan.FromSeconds(3));
            var strategies = new List <RetryStrategy> {
                strategy
            };
            var manager = new RetryManager(strategies, "fixed");

            RetryManager.SetDefault(manager);
        }
Exemple #16
0
        /// <summary>
        /// Creates a retry manager for every connection
        /// </summary>
        private void SetupRetryManager()
        {
            const string defaultRetryStrategyName = "fixed";
            const int    retryCount = 10;

            var retryInterval = TimeSpan.FromSeconds(6);

            var strategy   = new FixedInterval(defaultRetryStrategyName, retryCount, retryInterval);
            var strategies = new List <RetryStrategy> {
                strategy
            };
            var manager = new RetryManager(strategies, defaultRetryStrategyName);

            RetryManager.SetDefault(manager, false);
            retryPolicy = (retryPolicy != null) ? retryPolicy : new RetryPolicy <SqlDatabaseTransientErrorDetectionStrategy>(strategies[0]);
        }
Exemple #17
0
        public static RetryPolicy GetRetryPolicy()
        {
            //Set retry policy
            var retryPolicy = new RetryPolicy <DefaultRetryStrategy>(5, new TimeSpan(0, 0, 3));

            var retryInterval = TimeSpan.FromSeconds(3);
            var strategy      = new FixedInterval("fixed", 4, retryInterval);
            var strategies    = new List <RetryStrategy> {
                strategy
            };
            var manager = new RetryManager(strategies, "fixed");

            RetryManager.SetDefault(manager);

            return(retryPolicy);
        }
Exemple #18
0
        static async Task <(IEdgeHub, IConnectionManager)> SetupEdgeHub(IEnumerable <string> routes, IoTHub iotHub, string edgeDeviceId)
        {
            string iotHubName = "testHub";

            Routing.UserMetricLogger    = NullRoutingUserMetricLogger.Instance;
            Routing.PerfCounter         = NullRoutingPerfCounter.Instance;
            Routing.UserAnalyticsLogger = NullUserAnalyticsLogger.Instance;

            RetryStrategy defaultRetryStrategy   = new FixedInterval(0, TimeSpan.FromSeconds(1));
            TimeSpan      defaultRevivePeriod    = TimeSpan.FromHours(1);
            TimeSpan      defaultTimeout         = TimeSpan.FromSeconds(60);
            var           endpointExecutorConfig = new EndpointExecutorConfig(defaultTimeout, defaultRetryStrategy, defaultRevivePeriod, true);

            var cloudProxy = new Mock <ICloudProxy>();

            cloudProxy.Setup(c => c.SendMessageAsync(It.IsAny <IMessage>())).Callback <IMessage>(m => iotHub.ReceivedMessages.Add(m)).Returns(Task.CompletedTask);
            cloudProxy.Setup(c => c.SendMessageBatchAsync(It.IsAny <IEnumerable <IMessage> >())).Callback <IEnumerable <IMessage> >(m => iotHub.ReceivedMessages.AddRange(m)).Returns(Task.CompletedTask);
            cloudProxy.Setup(c => c.UpdateReportedPropertiesAsync(It.IsAny <IMessage>())).Callback <IMessage>(m => iotHub.ReceivedMessages.Add(m)).Returns(Task.CompletedTask);
            cloudProxy.SetupGet(c => c.IsActive).Returns(true);
            var cloudConnection = Mock.Of <ICloudConnection>(c => c.IsActive && c.CloudProxy == Option.Some(cloudProxy.Object));

            var cloudConnectionProvider = new Mock <ICloudConnectionProvider>();

            cloudConnectionProvider.Setup(c => c.Connect(It.IsAny <IClientCredentials>(), It.IsAny <Action <string, CloudConnectionStatus> >())).ReturnsAsync(Try.Success(cloudConnection));

            var deviceConnectivityManager                    = Mock.Of <IDeviceConnectivityManager>();
            IConnectionManager connectionManager             = new ConnectionManager(cloudConnectionProvider.Object, Mock.Of <ICredentialsCache>(), new IdentityProvider(iotHubName), deviceConnectivityManager);
            var                      routingMessageConverter = new RoutingMessageConverter();
            RouteFactory             routeFactory            = new EdgeRouteFactory(new EndpointFactory(connectionManager, routingMessageConverter, edgeDeviceId, 10, 10));
            IEnumerable <Route>      routesList              = routeFactory.Create(routes).ToList();
            IEnumerable <Endpoint>   endpoints               = routesList.Select(r => r.Endpoint);
            var                      routerConfig            = new RouterConfig(endpoints, routesList);
            IDbStoreProvider         dbStoreProvider         = new InMemoryDbStoreProvider();
            IStoreProvider           storeProvider           = new StoreProvider(dbStoreProvider);
            IMessageStore            messageStore            = new MessageStore(storeProvider, CheckpointStore.Create(storeProvider), TimeSpan.MaxValue);
            IEndpointExecutorFactory endpointExecutorFactory = new StoringAsyncEndpointExecutorFactory(endpointExecutorConfig, new AsyncEndpointExecutorOptions(1, TimeSpan.FromMilliseconds(10)), messageStore);
            Router                   router                  = await Router.CreateAsync(Guid.NewGuid().ToString(), iotHubName, routerConfig, endpointExecutorFactory);

            ITwinManager twinManager           = new TwinManager(connectionManager, new TwinCollectionMessageConverter(), new TwinMessageConverter(), Option.None <IEntityStore <string, TwinInfo> >());
            var          invokeMethodHandler   = Mock.Of <IInvokeMethodHandler>();
            var          subscriptionProcessor = new SubscriptionProcessor(connectionManager, invokeMethodHandler, deviceConnectivityManager);
            IEdgeHub     edgeHub = new RoutingEdgeHub(router, routingMessageConverter, connectionManager, twinManager, edgeDeviceId, invokeMethodHandler, subscriptionProcessor);

            return(edgeHub, connectionManager);
        }
Exemple #19
0
        public static void SetRetryManager(int retryCount, int retryInterval)
        {
            RetryCount = retryCount;
            const string defaultRetryStrategyName = "fixed";
            var          fixedInterval            = new FixedInterval(
                defaultRetryStrategyName,
                RetryCount,
                TimeSpan.FromSeconds(retryInterval));
            var retryStrategyCollection = new List <RetryStrategy>
            {
                fixedInterval
            };
            var retryManager = new RetryManager(
                retryStrategyCollection,
                defaultRetryStrategyName);

            RetryManager.SetDefault(retryManager);
        }
Exemple #20
0
        public void DoTest4()
        {
            var retry = new FixedInterval(5, new TimeSpan(0, 0, 2));
            var list  = new List <TimeSpan>();
            var i     = 0;

            retry.OnRetrying += (sender, e) => { list.Add(e.Delay); };
            retry.DoExecute(() => { if (i++ < 4)
                                    {
                                        throw new Exception("test");
                                    }
                            });

            Assert.AreEqual(list.Count, 4);
            Assert.AreEqual(list[0], new TimeSpan(0, 0, 2));
            Assert.AreEqual(list[1], new TimeSpan(0, 0, 2));
            Assert.AreEqual(list[2], new TimeSpan(0, 0, 2));
            Assert.AreEqual(list[3], new TimeSpan(0, 0, 2));
        }
Exemple #21
0
        public async Task TestFailedEndpoint()
        {
            var      retryStrategy = new FixedInterval(10, TimeSpan.FromSeconds(1));
            TimeSpan revivePeriod  = TimeSpan.FromHours(1);
            TimeSpan execTimeout   = TimeSpan.FromSeconds(60);
            var      config        = new EndpointExecutorConfig(execTimeout, retryStrategy, revivePeriod, true);
            var      factory       = new SyncEndpointExecutorFactory(config);

            var endpoint  = new FailedEndpoint("endpoint1");
            var endpoints = new Dictionary <Endpoint, IList <uint> > {
                { endpoint, new List <uint>()
                  {
                      0
                  } }
            };

            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1)))
            {
                Dispatcher dispatcher = await Dispatcher.CreateAsync("dispatcher", "hub", endpoints, factory);

                // Because the buffer size is one and we are failing we should block on the dispatch
                Task dispatching = dispatcher.DispatchAsync(Message1, new HashSet <RouteResult> {
                    new RouteResult(endpoint, 0, 3600)
                });

                var  endpoint2 = new TestEndpoint("endpoint1");
                Task setting   = dispatcher.SetEndpoint(endpoint2, new List <uint>()
                {
                    0
                });

                Task timeout = Task.Delay(TimeSpan.FromSeconds(1), cts.Token);
                await Task.WhenAny(dispatching, setting, timeout);

                await dispatcher.CloseAsync(CancellationToken.None);

                var expected = new List <IMessage> {
                    Message1
                };
                Assert.Equal(expected, endpoint2.Processed);
            }
        }
Exemple #22
0
        public async Task TestFailedEndpoint()
        {
            var message1 = new Message(TelemetryMessageSource.Instance, new byte[] { 1, 2, 3 }, new Dictionary <string, string> {
                { "key1", "value1" }, { "key2", "value2" }
            });
            var      retryStrategy = new FixedInterval(10, TimeSpan.FromSeconds(1));
            TimeSpan revivePeriod  = TimeSpan.FromHours(1);
            TimeSpan execTimeout   = TimeSpan.FromSeconds(60);
            var      config        = new EndpointExecutorConfig(execTimeout, retryStrategy, revivePeriod, true);
            var      factory       = new SyncEndpointExecutorFactory(config);

            var endpoint  = new FailedEndpoint("endpoint1");
            var endpoints = new HashSet <Endpoint> {
                endpoint
            };
            var route = new Route("route1", "true", "hub", TelemetryMessageSource.Instance, endpoints);

            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1)))
                using (Router router = await Router.CreateAsync("router1", "hub", new RouterConfig(endpoints, new HashSet <Route> {
                    route
                }, Fallback), factory))
                {
                    // Because the buffer size is one and we are failing we should block on the dispatch
                    Task routing = router.RouteAsync(message1);

                    var endpoint2 = new TestEndpoint("endpoint1");
                    var newRoute  = new Route("id", "true", "hub", TelemetryMessageSource.Instance, new HashSet <Endpoint> {
                        endpoint2
                    });
                    Task setting = router.SetRoute(newRoute);

                    Task timeout = Task.Delay(TimeSpan.FromSeconds(1), cts.Token);
                    await Task.WhenAny(routing, setting, timeout);

                    await router.CloseAsync(CancellationToken.None);

                    var expected = new List <IMessage> {
                        message1
                    };
                    Assert.Equal(expected, endpoint2.Processed);
                }
        }
Exemple #23
0
        public async Task TestCancellation()
        {
            var      retryStrategy = new FixedInterval(10, TimeSpan.FromSeconds(1));
            TimeSpan revivePeriod  = TimeSpan.FromHours(1);
            TimeSpan execTimeout   = TimeSpan.FromSeconds(60);
            var      config        = new EndpointExecutorConfig(execTimeout, retryStrategy, revivePeriod, true);

            var endpoint = new FailedEndpoint("id");

            IProcessor processor = endpoint.CreateProcessor();

            Assert.Equal(endpoint, processor.Endpoint);

            IEndpointExecutor executor = new SyncEndpointExecutor(endpoint, new NullCheckpointer(), config);
            Task running = executor.Invoke(Default);
            await executor.CloseAsync();

            await running;

            Assert.True(running.IsCompleted);
        }
Exemple #24
0
        private static void Main(string[] args)
        {
            const int retryCount             = 5;
            const int retryIntervalInSeconds = 1;

            // define the strategy for retrying
            var retryStrategy = new FixedInterval(
                retryCount,
                TimeSpan.FromSeconds(retryIntervalInSeconds));

            // define the policy
            var retryPolicy =
                new RetryPolicy <MyTransientErrorDetectionStrategy>(retryStrategy);

            retryPolicy.Retrying += retryPolicy_Retrying;

            for (int i = 0; i < 50; i++)
            {
                // try this a few times just to illustrate

                try
                {
                    retryPolicy.ExecuteAction(SomeMethodThatCanSometimesFail);

                    // (the retry policy has async support as well)
                }
                catch (Exception)
                {
                    // if it got to this point, your retries were exhausted
                    // the original exception is rethrown
                    throw;
                }
            }

            Console.WriteLine("Press Enter to Exit");

            Console.ReadLine();
        }
Exemple #25
0
        /// <summary>
        /// Initialize the task context resulting in any timed tasks starting.
        /// </summary>
        public void Initialize()
        {
            var components = FrameworkContext.Current.ComponentContext;

            foreach (var component in components.GetAllComponents())
            {
                var timed = ReflectionHelper.GetMethodsWithAttribute <ScheduledAttribute>(component.Type, binding: ReflectionHelper.All);

                if (timed.Any())
                {
                    foreach (var method in timed)
                    {
                        var instance   = method.IsStatic ? null : component.Designer.GetComponent();
                        var decoration = ReflectionHelper.GetAttributeInherited <ScheduledAttribute>(method);

                        /*if (decoration.CronInterval != null)
                         * {
                         *  var interval = new CronInterval(decoration.CronInterval);
                         *  Register(interval, method, instance);
                         * }
                         * else*/
                        {
                            var interval = new FixedInterval(decoration.FixedInterval.TotalMilliseconds);
                            Register(interval, method, instance);
                        }
                    }
                }
            }

            foreach (var task in timedTasks)
            {
                task.Start();
            }

            timedThread.Start();
        }
Exemple #26
0
        public string UploadFile(string filename, byte[] fileData, string folder, string containerDirectory)
        {
            var destinationBlobName = $"{filename}";
            var connectionString    = _applicationConfiguration.GetSetting("storage_connection_string");
            var retryStrategy       = new FixedInterval(3, TimeSpan.FromSeconds(1));
            var retryPolicy         = new RetryPolicy <StorageTransientErrorDetectionStrategy>(retryStrategy);

            try
            {
                retryPolicy.ExecuteAction(
                    () =>
                {
                    var storageAccount     = CloudStorageAccount.Parse(connectionString);
                    var cloudBlobClient    = storageAccount.CreateCloudBlobClient();
                    var cloudBlobContainer = cloudBlobClient.GetContainerReference(containerDirectory);
                    cloudBlobContainer.CreateIfNotExists();
                    cloudBlobContainer.SetPermissions(new BlobContainerPermissions
                    {
                        PublicAccess = BlobContainerPublicAccessType.Off
                    });
                    var cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(destinationBlobName);
                    cloudBlockBlob.Properties.ContentType  = MimeMapping.GetMimeMapping(filename);
                    cloudBlockBlob.Properties.CacheControl = BlobCacheControl;
                    cloudBlockBlob.UploadFromByteArray(fileData, 0, fileData.Length);
                    return(filename);
                });
            }
            catch (Exception exception)
            {
                //_logger.Error(string.Format("Signature Blob storage exception {0}", e.Message), e);
                var e = exception.Message;
                throw;
            }

            return(filename);
        }
        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);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="retryCount"></param>
        /// <param name="retryIntervalSeconds"></param>
        /// <returns></returns>
        private RetryPolicy GetFixedRetryPolicy(int retryCount, int retryIntervalSeconds)
        {
            FixedInterval interval = new FixedInterval(retryCount, TimeSpan.FromSeconds(retryIntervalSeconds));

            return(new RetryPolicy(RetryPolicy.DefaultFixed.ErrorDetectionStrategy, interval));
        }
Exemple #29
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);
        }
Exemple #30
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);
        }