Beispiel #1
0
        public async Task InitAsync(string storagePath, ISystemEnvironment systemEnvironment, bool optimizeForPerformance)
        {
            StoreProvider storeProvider;

            try
            {
                var partitionsList = new List <string> {
                    "messages", "directMethods", "twins"
                };
                IDbStoreProvider dbStoreprovider = DbStoreProvider.Create(
                    new RocksDbOptionsProvider(systemEnvironment, optimizeForPerformance, Option.None <ulong>(), Option.None <int>(), Option.None <StorageLogLevel>()),
                    this.GetStoragePath(storagePath),
                    partitionsList);

                storeProvider = new StoreProvider(dbStoreprovider);
            }
            catch (Exception ex) when(!ExceptionEx.IsFatal(ex))
            {
                Logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store.");
                storeProvider = new StoreProvider(new InMemoryDbStoreProvider());
            }

            this.messagesStore = await storeProvider.GetSequentialStore <MessageDetails>(MessageStorePartitionKey);

            this.directMethodsStore = await storeProvider.GetSequentialStore <TestOperationResult>(DirectMethodsStorePartitionKey);

            this.twinsStore = await storeProvider.GetSequentialStore <TestOperationResult>(TwinsStorePartitionKey);
        }
Beispiel #2
0
        public void Init(string storagePath, ISystemEnvironment systemEnvironment, bool optimizeForPerformance)
        {
            StoreProvider storeProvider;

            try
            {
                var partitionsList = new List <string> {
                    "desiredPropertyUpdated", "desiredPropertyReceived", "reportedPropertyUpdated"
                };
                IDbStoreProvider dbStoreprovider = DbStoreProvider.Create(
                    new RocksDbOptionsProvider(systemEnvironment, optimizeForPerformance, Option.None <ulong>()),
                    this.GetStoragePath(storagePath),
                    partitionsList);

                storeProvider = new StoreProvider(dbStoreprovider);
            }
            catch (Exception ex) when(!ExceptionEx.IsFatal(ex))
            {
                Logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store.");
                storeProvider = new StoreProvider(new InMemoryDbStoreProvider());
            }

            this.desiredPropertyUpdateCache   = storeProvider.GetEntityStore <string, DateTime>(DesiredPropertyUpdatePartitionKey);
            this.desiredPropertyReceivedCache = storeProvider.GetEntityStore <string, DateTime>(DesiredPropertyReceivedPartitionKey);
            this.reportedPropertyUpdateCache  = storeProvider.GetEntityStore <string, DateTime>(ReportedPropertyUpdatePartitionKey);
        }
Beispiel #3
0
        public void CreateTest()
        {
            var options = new RocksDbOptionsProvider(new SystemEnvironment(), true);

            var partitionsList1 = new[]
            {
                "Partition1",
                "Partition2",
                "Partition3",
            };

            using (IDbStoreProvider rocksDbStoreProvider = DbStoreProvider.Create(options, this.rocksDbFolder, partitionsList1))
            {
                Assert.NotNull(rocksDbStoreProvider);
            }

            var partitionsList2 = new[]
            {
                "Partition3",
                "Partition4"
            };

            using (IDbStoreProvider rocksDbStoreProvider = DbStoreProvider.Create(options, this.rocksDbFolder, partitionsList2))
            {
                Assert.NotNull(rocksDbStoreProvider);
            }

            var partitionsList3 = new string[0];

            using (IDbStoreProvider rocksDbStoreProvider = DbStoreProvider.Create(options, this.rocksDbFolder, partitionsList3))
            {
                Assert.NotNull(rocksDbStoreProvider);
            }
        }
Beispiel #4
0
        public async Task GetRemoveDefaultPartitionTestAsync()
        {
            var options = new RocksDbOptionsProvider(new SystemEnvironment(), true);

            var partitionsList = new[]
            {
                "Partition1"
            };

            using (IDbStoreProvider rocksDbStoreProvider = DbStoreProvider.Create(options, this.rocksDbFolder, partitionsList))
            {
                Assert.NotNull(rocksDbStoreProvider);

                IDbStore store = rocksDbStoreProvider.GetDbStore();

                string key      = "key";
                string val      = "val";
                byte[] valBytes = val.ToBytes();
                await store.Put(key.ToBytes(), valBytes);

                Option <byte[]> valRetrieved = await store.Get("key".ToBytes());

                byte[] valRetrievedBytes = valRetrieved.GetOrElse(string.Empty.ToBytes());
                Assert.True(valRetrievedBytes.SequenceEqual(valBytes));
            }
        }
Beispiel #5
0
        public static CheckpointStore Create(IDbStoreProvider dbStoreProvider)
        {
            IDbStore dbStore = Preconditions.CheckNotNull(dbStoreProvider, nameof(dbStoreProvider)).GetDbStore(Constants.CheckpointStorePartitionKey);
            IEntityStore <string, CheckpointEntity> underlyingStore = new EntityStore <string, CheckpointEntity>(dbStore, nameof(CheckpointEntity), 12);

            return(new CheckpointStore(underlyingStore));
        }
 public static async Task <IDbStoreProvider> WithBackupRestore(
     this IDbStoreProvider dbStoreProvider,
     string backupPath,
     IDataBackupRestore dataBackupRestore)
 {
     return(await DbStoreProviderWithBackupRestore.CreateAsync(dbStoreProvider, backupPath, dataBackupRestore));
 }
        public static async Task <IDbStoreProvider> CreateAsync(
            IDbStoreProvider dbStoreProvider,
            string backupPath,
            IDataBackupRestore dataBackupRestore)
        {
            DbStoreProviderWithBackupRestore provider = new DbStoreProviderWithBackupRestore(dbStoreProvider, backupPath, dataBackupRestore);
            await provider.RestoreAsync();

            return(provider);
        }
        public async Task BackupRestoreSuccessTest()
        {
            var dataBackupRestore = new Mock <IDataBackupRestore>();
            var dbStoreProvider   = new Mock <IDbStoreProvider>();

            IDbStoreProvider dbStoreProviderWithBackupRestore =
                await DbStoreProviderWithBackupRestore.CreateAsync(dbStoreProvider.Object, this.backupFolder, dataBackupRestore.Object);

            dbStoreProvider.Setup(x => x.GetDbStore()).Returns(Mock.Of <IDbStore>());
            dbStoreProvider.Setup(x => x.GetDbStore(It.IsAny <string>())).Returns(Mock.Of <IDbStore>());

            // Get default DB store.
            dbStoreProviderWithBackupRestore.GetDbStore();

            // Create custom DB stores.
            string[] storeNames = new[] { "store1", "store2", "store3" };
            storeNames.Select(x => dbStoreProviderWithBackupRestore.GetDbStore(x)).ToList();

            // Remove one of the created stores.
            dbStoreProviderWithBackupRestore.RemoveDbStore(storeNames[0]);

            // Since we added 3 stores and then removed 1, the total number of stores now will be 3 (2 custom + 1 default).

            // Create mock backup directories in the backup folder to test if the backup operation cleans up older backups or not.
            IList <DirectoryInfo> mockBackupDirectories = new List <DirectoryInfo>(2);

            for (int i = 0; i < 2; i++)
            {
                mockBackupDirectories.Add(Directory.CreateDirectory(Path.Combine(this.backupFolder, Guid.NewGuid().ToString())));
            }

            // Close the DB store provider now. This should execute the backup operations.
            await dbStoreProviderWithBackupRestore.CloseAsync();

            // Assert that all the remaining stores created above were backed up.
            dataBackupRestore.Verify(m => m.BackupAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IList <Item> >()), Times.Exactly(3));

            ValidateBackupArtifacts(this.backupFolder);

            // Validate that other backups have been deleted.
            foreach (DirectoryInfo mockBackupDir in mockBackupDirectories)
            {
                mockBackupDir.Refresh();
                Assert.False(mockBackupDir.Exists);
            }

            // Test restore.
            dbStoreProviderWithBackupRestore =
                await DbStoreProviderWithBackupRestore.CreateAsync(dbStoreProvider.Object, this.backupFolder, dataBackupRestore.Object);

            dataBackupRestore.Verify(m => m.RestoreAsync <IList <Item> >(It.IsAny <string>(), It.IsAny <string>()), Times.Exactly(3));

            // All backups should be deleted after a successful restore.
            IsDirectoryEmpty(this.backupFolder);
        }
        public async Task RestoreCorruptMetadataFailureTest()
        {
            var dataBackupRestore = new Mock <IDataBackupRestore>();
            var dbStoreProvider   = new Mock <IDbStoreProvider>();

            IDbStoreProvider dbStoreProviderWithBackupRestore =
                await DbStoreProviderWithBackupRestore.CreateAsync(dbStoreProvider.Object, this.backupFolder, dataBackupRestore.Object);

            dbStoreProvider.Setup(x => x.GetDbStore()).Returns(Mock.Of <IDbStore>());
            dbStoreProvider.Setup(x => x.GetDbStore(It.IsAny <string>())).Returns(Mock.Of <IDbStore>());

            // Get default DB store.
            dbStoreProviderWithBackupRestore.GetDbStore();

            // Create custom DB stores.
            string[] storeNames = new[] { "store1", "store2", "store3" };
            storeNames.Select(x => dbStoreProviderWithBackupRestore.GetDbStore(x)).ToList();

            // Close the DB store provider now. This should execute the backup operations.
            await dbStoreProviderWithBackupRestore.CloseAsync();

            // Assert that all the remaining stores created above were backed up.
            dataBackupRestore.Verify(m => m.BackupAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IList <Item> >()), Times.Exactly(storeNames.Length + 1));

            ValidateBackupArtifacts(this.backupFolder);

            // Create mock directories in the backup folder to test if the restore failure operation cleans up all artifacts or not.
            IList <DirectoryInfo> mockBackupDirectories = new List <DirectoryInfo>(2);

            for (int i = 0; i < 2; i++)
            {
                mockBackupDirectories.Add(Directory.CreateDirectory(Path.Combine(this.backupFolder, Guid.NewGuid().ToString())));
            }

            // Corrupt the backup metadata.
            using (FileStream file = File.OpenWrite(Path.Combine(this.backupFolder, "meta.json")))
            {
                file.Write(new byte[] { 1, 2 }, 1, 1);
            }

            // Test restore failure.
            dbStoreProviderWithBackupRestore =
                await DbStoreProviderWithBackupRestore.CreateAsync(dbStoreProvider.Object, this.backupFolder, dataBackupRestore.Object);

            // No attempts to restore a DB should have been made as the metadata itself was bad.
            dataBackupRestore.Verify(m => m.RestoreAsync <IList <Item> >(It.IsAny <string>(), It.IsAny <string>()), Times.Never);

            // Attempts to remove only the default DB stores should have been made.
            dbStoreProvider.Verify(x => x.RemoveDbStore(), Times.Once);
            dbStoreProvider.Verify(x => x.RemoveDbStore(It.IsAny <string>()), Times.Never);

            // All backups should be deleted after a successful restore.
            IsDirectoryEmpty(this.backupFolder);
        }
 DbStoreProviderWithBackupRestore(
     IDbStoreProvider dbStoreProvider,
     string backupPath,
     IDataBackupRestore dataBackupRestore)
     : base(dbStoreProvider)
 {
     this.backupPath        = Preconditions.CheckNonWhiteSpace(backupPath, nameof(backupPath));
     this.dataBackupRestore = Preconditions.CheckNotNull(dataBackupRestore, nameof(dataBackupRestore));
     this.dbStores          = new ConcurrentDictionary <string, byte>();
     this.events            = new Events(this.Log);
 }
Beispiel #11
0
        public async Task CloseAsync()
        {
            await this.protocolHead?.CloseAsync(CancellationToken.None);

            if (this.hosting != null)
            {
                IContainer       container       = this.hosting.Container;
                IDbStoreProvider dbStoreProvider = await container.Resolve <Task <IDbStoreProvider> >();

                await dbStoreProvider.CloseAsync();
            }
        }
Beispiel #12
0
        async Task <IDbStoreProvider> BuildInMemoryDbStoreProvider(IComponentContext container)
        {
            IDbStoreProvider dbStoreProvider = DbStoreProviderFactory.GetInMemoryDbStore();

            if (this.useBackupAndRestore)
            {
                var    backupRestore   = container.Resolve <IDataBackupRestore>();
                string backupPathValue = this.storageBackupPath.Expect(() => new InvalidOperationException("Storage backup path missing"));
                dbStoreProvider = await dbStoreProvider.WithBackupRestore(backupPathValue, backupRestore);
            }

            return(dbStoreProvider);
        }
        public async Task CreateInvalidInputTestAsync()
        {
            // Invalid DbStoreProvider.
            IDataBackupRestore dataBackupRestore = Mock.Of <IDataBackupRestore>();
            await Assert.ThrowsAsync <ArgumentNullException>(() => DbStoreProviderWithBackupRestore.CreateAsync(null, this.backupFolder, dataBackupRestore));

            // Invalid backup path.
            IDbStoreProvider dbStoreProvider = Mock.Of <IDbStoreProvider>();
            await Assert.ThrowsAsync <ArgumentException>(() => DbStoreProviderWithBackupRestore.CreateAsync(dbStoreProvider, null, dataBackupRestore));

            await Assert.ThrowsAsync <ArgumentException>(() => DbStoreProviderWithBackupRestore.CreateAsync(dbStoreProvider, " ", dataBackupRestore));

            // Invalid dataBackupRestore.
            await Assert.ThrowsAsync <ArgumentNullException>(() => DbStoreProviderWithBackupRestore.CreateAsync(dbStoreProvider, this.backupFolder, null));
        }
Beispiel #14
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            Logger.LogInformation("Calling Startup.ConfigureServices");

            services.AddControllers().AddNewtonsoftJson();

            HashSet <string> sources = Settings.Current.GetResultSourcesAsync(Logger).Result;

            Logger.LogInformation($"Result sources defined:{Environment.NewLine} {string.Join(Environment.NewLine + Enumerable.Repeat(" ", 5), sources)}");

            IStoreProvider storeProvider;

            try
            {
                IDbStoreProvider dbStoreprovider = DbStoreProvider.Create(
                    new RocksDbOptionsProvider(
                        new SystemEnvironment(),
                        Settings.Current.OptimizeForPerformance,
                        Option.None <ulong>(),
                        Option.None <ulong>(),
                        Option.None <int>(),
                        Option.None <StorageLogLevel>()),
                    this.GetStoragePath(Settings.Current.StoragePath),
                    sources);

                storeProvider = new StoreProvider(dbStoreprovider);
            }
            catch (Exception ex) when(!ExceptionEx.IsFatal(ex))
            {
                Logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store.");
                storeProvider = new StoreProvider(new InMemoryDbStoreProvider());
            }

            services.AddSingleton <ITestOperationResultStorage>(
                TestOperationResultStorage.CreateAsync(
                    storeProvider,
                    sources).Result);

            Settings.Current.TestResultReportingServiceSettings.ForEach(() => services.AddHostedService <TestResultReportingService>());
            Settings.Current.TestResultEventReceivingServiceSettings.ForEach(() => services.AddHostedService <TestResultEventReceivingService>());

            Logger.LogInformation("Calling Startup.ConfigureServices Completed.");
        }
        public async Task BackupFailureCleanupTest()
        {
            var dataBackupRestore = new Mock <IDataBackupRestore>();
            var dbStoreProvider   = new Mock <IDbStoreProvider>();

            dataBackupRestore.Setup(x => x.BackupAsync(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IList <Item> >())).Throws(new IOException());
            IDbStoreProvider dbStoreProviderWithBackupRestore =
                await DbStoreProviderWithBackupRestore.CreateAsync(dbStoreProvider.Object, this.backupFolder, dataBackupRestore.Object);

            dbStoreProvider.Setup(x => x.GetDbStore()).Returns(Mock.Of <IDbStore>());

            // Get the default DB store.
            dbStoreProviderWithBackupRestore.GetDbStore();

            // Create mock backup directories in the backup folder to test if the backup operation cleans up older backups or not.
            IList <DirectoryInfo> mockBackupDirectories = new List <DirectoryInfo>(2);

            for (int i = 0; i < 2; i++)
            {
                mockBackupDirectories.Add(Directory.CreateDirectory(Path.Combine(this.backupFolder, Guid.NewGuid().ToString())));
            }

            // Close the DB store provider now. This should execute the backup operations which will fail.
            await dbStoreProviderWithBackupRestore.CloseAsync();

            int numberOfDirs = 0;

            // Validate that other artifacts have not been deleted.
            foreach (DirectoryInfo mockBackupDir in mockBackupDirectories)
            {
                mockBackupDir.Refresh();
                Assert.True(mockBackupDir.Exists);
                numberOfDirs++;
            }

            // No new backups artifacts should be present.
            Assert.Equal(mockBackupDirectories.Count, numberOfDirs);
        }
Beispiel #16
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            Logger.LogInformation("Calling Startup.ConfigureServices");

            services.AddMvc();

            IStoreProvider storeProvider;

            try
            {
                IDbStoreProvider dbStoreprovider = DbStoreProvider.Create(
                    new RocksDbOptionsProvider(
                        new SystemEnvironment(),
                        Settings.Current.OptimizeForPerformance,
                        Option.None <ulong>()),
                    this.GetStoragePath(Settings.Current.StoragePath),
                    Settings.Current.GetResultSources());

                storeProvider = new StoreProvider(dbStoreprovider);
            }
            catch (Exception ex) when(!ExceptionEx.IsFatal(ex))
            {
                Logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store.");
                storeProvider = new StoreProvider(new InMemoryDbStoreProvider());
            }

            services.AddSingleton <ITestOperationResultStorage>(
                TestOperationResultStorage.CreateAsync(
                    storeProvider,
                    Settings.Current.GetResultSources()).Result);

            services.AddHostedService <TestResultReportingService>();
            services.AddHostedService <TestResultEventReceivingService>();

            Logger.LogInformation("Calling Startup.ConfigureServices Completed.");
        }
Beispiel #17
0
        static async Task CloseDbStoreProviderAsync(IContainer container)
        {
            IDbStoreProvider dbStoreProvider = await container.Resolve <Task <IDbStoreProvider> >();

            await dbStoreProvider.CloseAsync();
        }
        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 #19
0
        protected override void Load(ContainerBuilder builder)
        {
            // ISignatureProvider
            builder.Register(
                c =>
            {
                ISignatureProvider signatureProvider = this.edgeHubConnectionString.Map(
                    cs =>
                {
                    IotHubConnectionStringBuilder csBuilder = IotHubConnectionStringBuilder.Create(cs);
                    return(new SharedAccessKeySignatureProvider(csBuilder.SharedAccessKey) as ISignatureProvider);
                })
                                                       .GetOrElse(
                    () =>
                {
                    string edgeHubGenerationId = this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Generation ID missing"));
                    string workloadUri         = this.workloadUri.Expect(() => new InvalidOperationException("workloadUri is missing"));
                    return(new HttpHsmSignatureProvider(this.edgeHubModuleId, edgeHubGenerationId, workloadUri, Constants.WorkloadApiVersion) as ISignatureProvider);
                });
                return(signatureProvider);
            })
            .As <ISignatureProvider>()
            .SingleInstance();

            // Detect system environment
            builder.Register(c => new SystemEnvironment())
            .As <ISystemEnvironment>()
            .SingleInstance();

            // DataBase options
            builder.Register(c => new RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), this.optimizeForPerformance))
            .As <IRocksDbOptionsProvider>()
            .SingleInstance();

            // IDbStoreProvider
            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 = DbStoreProvider.Create(
                            c.Resolve <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<Option<IEncryptionProvider>>
            builder.Register(
                async c =>
            {
                Option <IEncryptionProvider> encryptionProviderOption = await this.workloadUri
                                                                        .Map(
                    async uri =>
                {
                    var encryptionProvider = await EncryptionProvider.CreateAsync(
                        this.storagePath,
                        new Uri(uri),
                        Constants.WorkloadApiVersion,
                        this.edgeHubModuleId,
                        this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")),
                        Constants.InitializationVectorFileName) as IEncryptionProvider;
                    return(Option.Some(encryptionProvider));
                })
                                                                        .GetOrElse(() => Task.FromResult(Option.None <IEncryptionProvider>()));
                return(encryptionProviderOption);
            })
            .As <Task <Option <IEncryptionProvider> > >()
            .SingleInstance();

            // IStoreProvider
            builder.Register(c => new StoreProvider(c.Resolve <IDbStoreProvider>()))
            .As <IStoreProvider>()
            .SingleInstance();

            // ITokenProvider
            builder.Register(c => new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, TimeSpan.FromHours(1)))
            .Named <ITokenProvider>("EdgeHubClientAuthTokenProvider")
            .SingleInstance();

            // ITokenProvider
            builder.Register(
                c =>
            {
                string deviceId = WebUtility.UrlEncode(this.edgeDeviceId);
                string moduleId = WebUtility.UrlEncode(this.edgeHubModuleId);
                return(new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1)));
            })
            .Named <ITokenProvider>("EdgeHubServiceAuthTokenProvider")
            .SingleInstance();

            // Task<IDeviceScopeIdentitiesCache>
            builder.Register(
                async c =>
            {
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                if (this.authenticationMode == AuthenticationMode.CloudAndScope || this.authenticationMode == AuthenticationMode.Scope)
                {
                    var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider");
                    IDeviceScopeApiClient securityScopesApiClient = new DeviceScopeApiClient(this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, 10, edgeHubTokenProvider);
                    IServiceProxy serviceProxy = new ServiceProxy(securityScopesApiClient);
                    IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "DeviceScopeCache");
                    deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy, encryptedStore, this.scopeCacheRefreshRate);
                }
                else
                {
                    deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache();
                }

                return(deviceScopeIdentitiesCache);
            })
            .As <Task <IDeviceScopeIdentitiesCache> >()
            .AutoActivate()
            .SingleInstance();

            // Task<ICredentialsCache>
            builder.Register(
                async c =>
            {
                ICredentialsCache underlyingCredentialsCache;
                if (this.persistTokens)
                {
                    IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "CredentialsCache");
                    return(new PersistedTokenCredentialsCache(encryptedStore));
                }
                else
                {
                    underlyingCredentialsCache = new NullCredentialsCache();
                }

                ICredentialsCache credentialsCache = new CredentialsCache(underlyingCredentialsCache);
                return(credentialsCache);
            })
            .As <Task <ICredentialsCache> >()
            .SingleInstance();

            // Task<IAuthenticator>
            builder.Register(
                async c =>
            {
                IAuthenticator tokenAuthenticator;
                IAuthenticator certificateAuthenticator;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >();
                // by default regardless of how the authenticationMode, X.509 certificate validation will always be scoped
                deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                certificateAuthenticator   = new DeviceScopeCertificateAuthenticator(deviceScopeIdentitiesCache, new NullAuthenticator(), this.trustBundle, true);
                switch (this.authenticationMode)
                {
                case AuthenticationMode.Cloud:
                    tokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                    break;

                case AuthenticationMode.Scope:
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), true, true);
                    break;

                default:
                    IAuthenticator cloudTokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudTokenAuthenticator, true, true);
                    break;
                }

                ICredentialsCache credentialsCache = await credentialsCacheTask;
                return(new Authenticator(tokenAuthenticator, certificateAuthenticator, credentialsCache) as IAuthenticator);
            })
            .As <Task <IAuthenticator> >()
            .SingleInstance();

            // IClientCredentialsFactory
            builder.Register(c => new ClientCredentialsFactory(c.Resolve <IIdentityProvider>(), this.productInfo))
            .As <IClientCredentialsFactory>()
            .SingleInstance();

            // ConnectionReauthenticator
            builder.Register(
                async c =>
            {
                var edgeHubCredentials               = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials");
                var connectionManagerTask            = c.Resolve <Task <IConnectionManager> >();
                var authenticatorTask                = c.Resolve <Task <IAuthenticator> >();
                var credentialsCacheTask             = c.Resolve <Task <ICredentialsCache> >();
                var deviceScopeIdentitiesCacheTask   = c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                var deviceConnectivityManager        = c.Resolve <IDeviceConnectivityManager>();
                IConnectionManager connectionManager = await connectionManagerTask;
                IAuthenticator authenticator         = await authenticatorTask;
                ICredentialsCache credentialsCache   = await credentialsCacheTask;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask;
                var connectionReauthenticator = new ConnectionReauthenticator(
                    connectionManager,
                    authenticator,
                    credentialsCache,
                    deviceScopeIdentitiesCache,
                    TimeSpan.FromMinutes(5),
                    edgeHubCredentials.Identity,
                    deviceConnectivityManager);
                return(connectionReauthenticator);
            })
            .As <Task <ConnectionReauthenticator> >()
            .SingleInstance();

            base.Load(builder);
        }
 public DbStoreProviderDecorator(IDbStoreProvider dbStoreProvider)
 {
     Preconditions.CheckNotNull(dbStoreProvider, nameof(dbStoreProvider));
     this.dbStoreProvider = dbStoreProvider;
 }
Beispiel #21
0
        protected override void Load(ContainerBuilder builder)
        {
            // IMetricsListener
            builder.Register(
                c =>
                this.metricsConfig.Enabled
                            ? new MetricsListener(this.metricsConfig.ListenerConfig, c.Resolve <IMetricsProvider>())
                            : new NullMetricsListener() as IMetricsListener)
            .As <IMetricsListener>()
            .SingleInstance();

            // IMetricsProvider
            builder.Register(
                c =>
                this.metricsConfig.Enabled
                            ? new MetricsProvider(MetricsConstants.EdgeHubMetricPrefix, this.iothubHostName, this.edgeDeviceId, this.metricsConfig.HistogramMaxAge)
                            : new NullMetricsProvider() as IMetricsProvider)
            .As <IMetricsProvider>()
            .SingleInstance();

            // ISignatureProvider
            builder.Register(
                c =>
            {
                ISignatureProvider signatureProvider = this.edgeHubConnectionString.Map(
                    cs =>
                {
                    IotHubConnectionStringBuilder csBuilder = IotHubConnectionStringBuilder.Create(cs);
                    return(new SharedAccessKeySignatureProvider(csBuilder.SharedAccessKey) as ISignatureProvider);
                })
                                                       .GetOrElse(
                    () =>
                {
                    string edgeHubGenerationId = this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Generation ID missing"));
                    string workloadUri         = this.workloadUri.Expect(() => new InvalidOperationException("workloadUri is missing"));
                    string workloadApiVersion  = this.workloadApiVersion.Expect(() => new InvalidOperationException("workloadUri version is missing"));
                    return(new HttpHsmSignatureProvider(this.edgeHubModuleId, edgeHubGenerationId, workloadUri, workloadApiVersion, Constants.WorkloadApiVersion) as ISignatureProvider);
                });
                return(signatureProvider);
            })
            .As <ISignatureProvider>()
            .SingleInstance();

            // Detect system environment
            builder.Register(c => new SystemEnvironment())
            .As <ISystemEnvironment>()
            .SingleInstance();

            // DataBase options
            builder.Register(c => new RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), this.optimizeForPerformance, this.storageMaxTotalWalSize, this.storageMaxOpenFiles, this.storageLogLevel))
            .As <IRocksDbOptionsProvider>()
            .SingleInstance();

            if (!this.usePersistentStorage && this.useBackupAndRestore)
            {
                // Backup and restore serialization
                builder.Register(c => new ProtoBufDataBackupRestore())
                .As <IDataBackupRestore>()
                .SingleInstance();
            }

            // IStorageSpaceChecker
            builder.Register(
                c =>
            {
                IStorageSpaceChecker spaceChecker = !this.usePersistentStorage
                       ? new MemorySpaceChecker(() => 0L) as IStorageSpaceChecker
                       : new NullStorageSpaceChecker();
                return(spaceChecker);
            })
            .As <IStorageSpaceChecker>()
            .SingleInstance();

            // IDbStoreProvider
            builder.Register(
                async 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 = DbStoreProvider.Create(
                            c.Resolve <IRocksDbOptionsProvider>(),
                            this.storagePath,
                            partitionsList);
                        logger.LogInformation($"Created persistent store at {this.storagePath}");
                        return(dbStoreProvider);
                    }
                    catch (Exception ex) when(!ex.IsFatal())
                    {
                        logger.LogError(ex, "Error creating RocksDB store. Falling back to in-memory store.");
                        IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c);
                        return(dbStoreProvider);
                    }
                }
                else
                {
                    logger.LogInformation($"Using in-memory store");
                    IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c);
                    return(dbStoreProvider);
                }
            })
            .As <Task <IDbStoreProvider> >()
            .SingleInstance();

            // Task<Option<IEncryptionProvider>>
            builder.Register(
                async c =>
            {
                Option <IEncryptionProvider> encryptionProviderOption = await this.workloadUri
                                                                        .Map(
                    async uri =>
                {
                    var encryptionProvider = await EncryptionProvider.CreateAsync(
                        this.storagePath,
                        new Uri(uri),
                        this.workloadApiVersion.Expect(() => new InvalidOperationException("Missing workload API version")),
                        Constants.WorkloadApiVersion,
                        this.edgeHubModuleId,
                        this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")),
                        Constants.InitializationVectorFileName) as IEncryptionProvider;
                    return(Option.Some(encryptionProvider));
                })
                                                                        .GetOrElse(() => Task.FromResult(Option.None <IEncryptionProvider>()));
                return(encryptionProviderOption);
            })
            .As <Task <Option <IEncryptionProvider> > >()
            .SingleInstance();

            // Task<IStoreProvider>
            builder.Register(async c =>
            {
                var dbStoreProvider          = await c.Resolve <Task <IDbStoreProvider> >();
                IStoreProvider storeProvider = new StoreProvider(dbStoreProvider);
                return(storeProvider);
            })
            .As <Task <IStoreProvider> >()
            .SingleInstance();

            // Task<IMetadataStore>
            builder.Register(
                async c =>
            {
                var storeProvider = await c.Resolve <Task <IStoreProvider> >();
                IKeyValueStore <string, string> entityStore = storeProvider.GetEntityStore <string, string>("ProductInfo", "MetadataStore");
                IMetadataStore metadataStore = new MetadataStore(entityStore, this.productInfo);
                return(metadataStore);
            })
            .As <Task <IMetadataStore> >()
            .SingleInstance();

            // ITokenProvider
            builder.Register(c => new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, TimeSpan.FromHours(1)))
            .Named <ITokenProvider>("EdgeHubClientAuthTokenProvider")
            .SingleInstance();

            // ITokenProvider
            builder.Register(
                c =>
            {
                string deviceId = WebUtility.UrlEncode(this.edgeDeviceId);
                string moduleId = WebUtility.UrlEncode(this.edgeHubModuleId);
                return(new ClientTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1)));
            })
            .Named <ITokenProvider>("EdgeHubServiceAuthTokenProvider")
            .SingleInstance();

            builder.Register(
                c =>
            {
                var loggerFactory = c.Resolve <ILoggerFactory>();
                var logger        = loggerFactory.CreateLogger <RoutingModule>();
                return(Proxy.Parse(this.proxy, logger));
            })
            .As <Option <IWebProxy> >()
            .SingleInstance();

            // IServiceIdentityHierarchy
            builder.Register <IServiceIdentityHierarchy>(
                c =>
            {
                if (this.nestedEdgeEnabled)
                {
                    return(new ServiceIdentityTree(this.edgeDeviceId));
                }
                else
                {
                    return(new ServiceIdentityDictionary(this.edgeDeviceId));
                }
            })
            .As <IServiceIdentityHierarchy>()
            .SingleInstance();

            // Task<IDeviceScopeIdentitiesCache>
            builder.Register(
                async c =>
            {
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                if (this.authenticationMode == AuthenticationMode.CloudAndScope || this.authenticationMode == AuthenticationMode.Scope)
                {
                    var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider");
                    var proxy = c.Resolve <Option <IWebProxy> >();

                    IServiceIdentityHierarchy serviceIdentityHierarchy = c.Resolve <IServiceIdentityHierarchy>();

                    string hostName = this.gatewayHostName.GetOrElse(this.iothubHostName);
                    IDeviceScopeApiClientProvider securityScopesApiClientProvider = new DeviceScopeApiClientProvider(hostName, this.edgeDeviceId, this.edgeHubModuleId, 10, edgeHubTokenProvider, serviceIdentityHierarchy, proxy);
                    IServiceProxy serviceProxy = new ServiceProxy(securityScopesApiClientProvider, this.nestedEdgeEnabled);
                    IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "DeviceScopeCache");
                    deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceIdentityHierarchy, serviceProxy, encryptedStore, this.scopeCacheRefreshRate, this.scopeCacheRefreshDelay);
                }
                else
                {
                    deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache();
                }

                return(deviceScopeIdentitiesCache);
            })
            .As <Task <IDeviceScopeIdentitiesCache> >()
            .AutoActivate()
            .SingleInstance();

            // IRegistryApiClient
            builder.Register(
                c =>
            {
                string upstreamHostname = this.gatewayHostName.GetOrElse(this.iothubHostName);
                var proxy = c.Resolve <Option <IWebProxy> >();
                var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider");
                return(new RegistryOnBehalfOfApiClient(upstreamHostname, proxy, edgeHubTokenProvider));
            })
            .As <IRegistryOnBehalfOfApiClient>()
            .SingleInstance();

            // Task<ICredentialsCache>
            builder.Register(
                async c =>
            {
                ICredentialsCache underlyingCredentialsCache;
                if (this.persistTokens)
                {
                    IKeyValueStore <string, string> encryptedStore = await GetEncryptedStore(c, "CredentialsCache");
                    return(new PersistedTokenCredentialsCache(encryptedStore));
                }
                else
                {
                    underlyingCredentialsCache = new NullCredentialsCache();
                }

                ICredentialsCache credentialsCache;

                if (this.nestedEdgeEnabled)
                {
                    credentialsCache = new NestedCredentialsCache(underlyingCredentialsCache);
                }
                else
                {
                    credentialsCache = new CredentialsCache(underlyingCredentialsCache);
                }

                return(credentialsCache);
            })
            .As <Task <ICredentialsCache> >()
            .SingleInstance();

            // Task<IAuthenticator>
            builder.Register(
                async c =>
            {
                IAuthenticator tokenAuthenticator;
                IAuthenticator certificateAuthenticator;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                var credentialsCacheTask = c.Resolve <Task <ICredentialsCache> >();
                // by default regardless of how the authenticationMode, X.509 certificate validation will always be scoped
                deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                certificateAuthenticator   = new DeviceScopeCertificateAuthenticator(deviceScopeIdentitiesCache, new NullAuthenticator(), this.trustBundle, true, this.nestedEdgeEnabled);
                switch (this.authenticationMode)
                {
                case AuthenticationMode.Cloud:
                    tokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                    break;

                case AuthenticationMode.Scope:
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), true, true, this.nestedEdgeEnabled);
                    break;

                default:
                    IAuthenticator cloudTokenAuthenticator = await this.GetCloudTokenAuthenticator(c);
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudTokenAuthenticator, true, true, this.nestedEdgeEnabled);
                    break;
                }

                ICredentialsCache credentialsCache = await credentialsCacheTask;
                return(new Authenticator(tokenAuthenticator, certificateAuthenticator, credentialsCache) as IAuthenticator);
            })
            .As <Task <IAuthenticator> >()
            .SingleInstance();

            // IClientCredentialsFactory
            builder.Register(c => new ClientCredentialsFactory(c.Resolve <IIdentityProvider>(), this.productInfo))
            .As <IClientCredentialsFactory>()
            .SingleInstance();

            // IClientCredentials "EdgeHubCredentials"
            builder.Register(
                c =>
            {
                var identityFactory = c.Resolve <IClientCredentialsFactory>();
                IClientCredentials edgeHubCredentials = this.edgeHubConnectionString.Map(cs => identityFactory.GetWithConnectionString(cs)).GetOrElse(
                    () => identityFactory.GetWithIotEdged(this.edgeDeviceId, this.edgeHubModuleId));
                return(edgeHubCredentials);
            })
            .Named <IClientCredentials>("EdgeHubCredentials")
            .SingleInstance();

            // ServiceIdentity "EdgeHubIdentity"
            builder.Register(
                c =>
            {
                return(new ServiceIdentity(
                           this.edgeDeviceId,
                           this.edgeHubModuleId,
                           deviceScope: null,
                           parentScopes: new List <string>(),
                           this.edgeHubGenerationId.GetOrElse("0"),
                           capabilities: new List <string>(),
                           new ServiceAuthentication(ServiceAuthenticationType.None),
                           ServiceIdentityStatus.Enabled));
            })
            .Named <ServiceIdentity>("EdgeHubIdentity")
            .SingleInstance();

            // ConnectionReauthenticator
            builder.Register(
                async c =>
            {
                var edgeHubCredentials               = c.ResolveNamed <IClientCredentials>("EdgeHubCredentials");
                var connectionManagerTask            = c.Resolve <Task <IConnectionManager> >();
                var authenticatorTask                = c.Resolve <Task <IAuthenticator> >();
                var credentialsCacheTask             = c.Resolve <Task <ICredentialsCache> >();
                var deviceScopeIdentitiesCacheTask   = c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                var deviceConnectivityManager        = c.Resolve <IDeviceConnectivityManager>();
                IConnectionManager connectionManager = await connectionManagerTask;
                IAuthenticator authenticator         = await authenticatorTask;
                ICredentialsCache credentialsCache   = await credentialsCacheTask;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache = await deviceScopeIdentitiesCacheTask;
                var connectionReauthenticator = new ConnectionReauthenticator(
                    connectionManager,
                    authenticator,
                    credentialsCache,
                    deviceScopeIdentitiesCache,
                    TimeSpan.FromMinutes(5),
                    edgeHubCredentials.Identity,
                    deviceConnectivityManager);
                return(connectionReauthenticator);
            })
            .As <Task <ConnectionReauthenticator> >()
            .SingleInstance();

            base.Load(builder);
        }
Beispiel #22
0
        protected override void Load(ContainerBuilder builder)
        {
            // ISignatureProvider
            builder.Register(
                c =>
            {
                ISignatureProvider signatureProvider = this.edgeHubConnectionString.Map(
                    cs =>
                {
                    IotHubConnectionStringBuilder csBuilder = IotHubConnectionStringBuilder.Create(cs);
                    return(new SharedAccessKeySignatureProvider(csBuilder.SharedAccessKey) as ISignatureProvider);
                })
                                                       .GetOrElse(
                    () =>
                {
                    string edgeHubGenerationId = this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Generation ID missing"));
                    string workloadUri         = this.workloadUri.Expect(() => new InvalidOperationException("workloadUri is missing"));
                    return(new HttpHsmSignatureProvider(this.edgeHubModuleId, edgeHubGenerationId, workloadUri, Service.Constants.WorkloadApiVersion) as ISignatureProvider);
                });
                return(signatureProvider);
            })
            .As <ISignatureProvider>()
            .SingleInstance();

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

            // IDbStoreProvider
            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<IEncryptionProvider>
            builder.Register(
                async c =>
            {
                IEncryptionProvider encryptionProvider = await this.workloadUri.Map(
                    async uri => await EncryptionProvider.CreateAsync(
                        this.storagePath,
                        new Uri(uri),
                        Service.Constants.WorkloadApiVersion,
                        this.edgeHubModuleId,
                        this.edgeHubGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")),
                        Service.Constants.InitializationVectorFileName) as IEncryptionProvider)
                                                         .GetOrElse(() => Task.FromResult <IEncryptionProvider>(NullEncryptionProvider.Instance));
                return(encryptionProvider);
            })
            .As <Task <IEncryptionProvider> >()
            .SingleInstance();

            // IStoreProvider
            builder.Register(c => new StoreProvider(c.Resolve <IDbStoreProvider>()))
            .As <IStoreProvider>()
            .SingleInstance();

            // ITokenProvider
            builder.Register(c => new ModuleTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, TimeSpan.FromHours(1)))
            .Named <ITokenProvider>("EdgeHubClientAuthTokenProvider")
            .SingleInstance();

            // ITokenProvider
            builder.Register(c =>
            {
                string deviceId = WebUtility.UrlEncode(this.edgeDeviceId);
                string moduleId = WebUtility.UrlEncode(this.edgeHubModuleId);
                return(new ModuleTokenProvider(c.Resolve <ISignatureProvider>(), this.iothubHostName, deviceId, moduleId, TimeSpan.FromHours(1)));
            })
            .Named <ITokenProvider>("EdgeHubServiceAuthTokenProvider")
            .SingleInstance();

            // Task<IKeyValueStore<string, string>> - EncryptedStore
            builder.Register(
                async c =>
            {
                var storeProvider = c.Resolve <IStoreProvider>();
                IEncryptionProvider encryptionProvider         = await c.Resolve <Task <IEncryptionProvider> >();
                IEntityStore <string, string> entityStore      = storeProvider.GetEntityStore <string, string>("SecurityScopeCache");
                IKeyValueStore <string, string> encryptedStore = new EncryptedStore <string, string>(entityStore, encryptionProvider);
                return(encryptedStore);
            })
            .Named <Task <IKeyValueStore <string, string> > >("EncryptedStore")
            .SingleInstance();


            // Task<IDeviceScopeIdentitiesCache>
            builder.Register(
                async c =>
            {
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                if (this.authenticationMode == AuthenticationMode.CloudAndScope || this.authenticationMode == AuthenticationMode.Scope)
                {
                    var edgeHubTokenProvider = c.ResolveNamed <ITokenProvider>("EdgeHubServiceAuthTokenProvider");
                    IDeviceScopeApiClient securityScopesApiClient = new DeviceScopeApiClient(this.iothubHostName, this.edgeDeviceId, this.edgeHubModuleId, 10, edgeHubTokenProvider);
                    IServiceProxy serviceProxy = new ServiceProxy(securityScopesApiClient);
                    IKeyValueStore <string, string> encryptedStore = await c.ResolveNamed <Task <IKeyValueStore <string, string> > >("EncryptedStore");
                    deviceScopeIdentitiesCache = await DeviceScopeIdentitiesCache.Create(serviceProxy, encryptedStore, this.scopeCacheRefreshRate);
                }
                else
                {
                    deviceScopeIdentitiesCache = new NullDeviceScopeIdentitiesCache();
                }

                return(deviceScopeIdentitiesCache);
            })
            .As <Task <IDeviceScopeIdentitiesCache> >()
            .SingleInstance();

            // Task<IAuthenticator>
            builder.Register(async c =>
            {
                IConnectionManager connectionManager = await c.Resolve <Task <IConnectionManager> >();
                IAuthenticator tokenAuthenticator;
                IDeviceScopeIdentitiesCache deviceScopeIdentitiesCache;
                switch (this.authenticationMode)
                {
                case AuthenticationMode.Cloud:
                    if (this.cacheTokens)
                    {
                        ICredentialsStore credentialsStore = await c.Resolve <Task <ICredentialsStore> >();
                        IAuthenticator authenticator       = new CloudTokenAuthenticator(connectionManager);
                        tokenAuthenticator = new TokenCacheAuthenticator(authenticator, credentialsStore, this.iothubHostName);
                    }
                    else
                    {
                        tokenAuthenticator = new CloudTokenAuthenticator(connectionManager);
                    }
                    break;

                case AuthenticationMode.Scope:
                    deviceScopeIdentitiesCache = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                    tokenAuthenticator         = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, new NullAuthenticator(), connectionManager);
                    break;

                default:
                    deviceScopeIdentitiesCache        = await c.Resolve <Task <IDeviceScopeIdentitiesCache> >();
                    IAuthenticator cloudAuthenticator = new CloudTokenAuthenticator(connectionManager);
                    tokenAuthenticator = new DeviceScopeTokenAuthenticator(deviceScopeIdentitiesCache, this.iothubHostName, this.edgeDeviceHostName, cloudAuthenticator, connectionManager);
                    break;
                }

                return(new Authenticator(tokenAuthenticator, this.edgeDeviceId, connectionManager) as IAuthenticator);
            })
            .As <Task <IAuthenticator> >()
            .SingleInstance();

            // IClientCredentialsFactory
            builder.Register(c => new ClientCredentialsFactory(this.iothubHostName, this.productInfo))
            .As <IClientCredentialsFactory>()
            .SingleInstance();

            base.Load(builder);
        }
Beispiel #23
0
        protected override void Load(ContainerBuilder builder)
        {
            // IByteBufferAllocator
            builder.Register(
                c =>
            {
                // TODO - We should probably also use some heuristics to make this determination, like how much memory does the system have.
                return(this.optimizeForPerformance ? PooledByteBufferAllocator.Default : UnpooledByteBufferAllocator.Default as IByteBufferAllocator);
            })
            .As <IByteBufferAllocator>()
            .SingleInstance();

            builder.Register(c => new ByteBufferConverter(c.Resolve <IByteBufferAllocator>()))
            .As <IByteBufferConverter>()
            .SingleInstance();

            // MessageAddressConverter
            builder.Register(c => new MessageAddressConverter(this.conversionConfiguration))
            .As <MessageAddressConverter>()
            .SingleInstance();

            // IMessageConverter<IProtocolGatewayMessage>
            builder.Register(c => new ProtocolGatewayMessageConverter(c.Resolve <MessageAddressConverter>(), c.Resolve <IByteBufferConverter>()))
            .As <IMessageConverter <IProtocolGatewayMessage> >()
            .SingleInstance();

            // ISettingsProvider
            builder.Register(c => new MqttSettingsProvider(this.mqttSettingsConfiguration))
            .As <ISettingsProvider>()
            .SingleInstance();

            // Task<IMqttConnectionProvider>
            builder.Register(
                async c =>
            {
                var pgMessageConverter  = c.Resolve <IMessageConverter <IProtocolGatewayMessage> >();
                var byteBufferConverter = c.Resolve <IByteBufferConverter>();
                IConnectionProvider connectionProvider = await c.Resolve <Task <IConnectionProvider> >();
                IMqttConnectionProvider mqtt           = new MqttConnectionProvider(connectionProvider, pgMessageConverter, byteBufferConverter);
                return(mqtt);
            })
            .As <Task <IMqttConnectionProvider> >()
            .SingleInstance();

            // Task<ISessionStatePersistenceProvider>
            builder.Register(
                async c =>
            {
                if (this.isStoreAndForwardEnabled)
                {
                    IDbStoreProvider dbStoreProvider = await c.Resolve <Task <IDbStoreProvider> >();
                    IEntityStore <string, SessionState> entityStore = new StoreProvider(dbStoreProvider).GetEntityStore <string, SessionState>(Constants.SessionStorePartitionKey);
                    IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >();
                    return(new SessionStateStoragePersistenceProvider(edgeHub, entityStore) as ISessionStatePersistenceProvider);
                }
                else
                {
                    IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >();
                    return(new SessionStatePersistenceProvider(edgeHub) as ISessionStatePersistenceProvider);
                }
            })
            .As <Task <ISessionStatePersistenceProvider> >()
            .SingleInstance();

            // MqttProtocolHead
            builder.Register(
                async c =>
            {
                var productInfoStore                                = await c.Resolve <Task <IProductInfoStore> >();
                var settingsProvider                                = c.Resolve <ISettingsProvider>();
                var websocketListenerRegistry                       = c.Resolve <IWebSocketListenerRegistry>();
                var byteBufferAllocator                             = c.Resolve <IByteBufferAllocator>();
                var mqttConnectionProviderTask                      = c.Resolve <Task <IMqttConnectionProvider> >();
                var sessionStatePersistenceProviderTask             = c.Resolve <Task <ISessionStatePersistenceProvider> >();
                var authenticatorProviderTask                       = c.Resolve <Task <IAuthenticator> >();
                IClientCredentialsFactory clientCredentialsProvider = c.Resolve <IClientCredentialsFactory>();
                IMqttConnectionProvider mqttConnectionProvider      = await mqttConnectionProviderTask;
                ISessionStatePersistenceProvider sessionStatePersistenceProvider = await sessionStatePersistenceProviderTask;
                IAuthenticator authenticator = await authenticatorProviderTask;
                return(new MqttProtocolHead(
                           settingsProvider,
                           this.tlsCertificate,
                           mqttConnectionProvider,
                           authenticator,
                           clientCredentialsProvider,
                           sessionStatePersistenceProvider,
                           websocketListenerRegistry,
                           byteBufferAllocator,
                           productInfoStore,
                           this.clientCertAuthAllowed,
                           this.sslProtocols));
            })
            .As <Task <MqttProtocolHead> >()
            .SingleInstance();

            base.Load(builder);
        }
Beispiel #24
0
        protected override void Load(ContainerBuilder builder)
        {
            // ISerde<ModuleSet>
            builder.Register(
                c => new ModuleSetSerde(
                    new Dictionary <string, Type>
            {
                { DockerType, typeof(DockerModule) }
            }))
            .As <ISerde <ModuleSet> >()
            .SingleInstance();

            // ISerde<DeploymentConfig>
            builder.Register(
                c =>
            {
                ISerde <DeploymentConfig> serde = new TypeSpecificSerDe <DeploymentConfig>(DeploymentConfigTypeMapping);
                return(serde);
            })
            .As <ISerde <DeploymentConfig> >()
            .SingleInstance();

            // ISerde<DeploymentConfigInfo>
            builder.Register(
                c =>
            {
                ISerde <DeploymentConfigInfo> serde = new TypeSpecificSerDe <DeploymentConfigInfo>(DeploymentConfigTypeMapping);
                return(serde);
            })
            .As <ISerde <DeploymentConfigInfo> >()
            .SingleInstance();

            // Detect system environment
            builder.Register(c => new SystemEnvironment())
            .As <ISystemEnvironment>()
            .SingleInstance();

            // IRocksDbOptionsProvider
            // For EdgeAgent, we don't need high performance from RocksDb, so always turn off optimizeForPerformance
            builder.Register(c => new RocksDbOptionsProvider(c.Resolve <ISystemEnvironment>(), false))
            .As <IRocksDbOptionsProvider>()
            .SingleInstance();

            if (!this.usePersistentStorage && this.useBackupAndRestore)
            {
                // Backup and restore serialization
                builder.Register(c => new ProtoBufDataBackupRestore())
                .As <IDataBackupRestore>()
                .SingleInstance();
            }

            // IDbStoreProvider
            builder.Register(
                async c =>
            {
                var loggerFactory = c.Resolve <ILoggerFactory>();
                ILogger logger    = loggerFactory.CreateLogger(typeof(AgentModule));

                if (this.usePersistentStorage)
                {
                    // Create partition for mma
                    var partitionsList = new List <string> {
                        "moduleState", "deploymentConfig"
                    };
                    try
                    {
                        IDbStoreProvider dbStoreprovider = DbStoreProvider.Create(
                            c.Resolve <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.");
                        IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c);
                        return(dbStoreProvider);
                    }
                }
                else
                {
                    logger.LogInformation($"Using in-memory store");
                    IDbStoreProvider dbStoreProvider = await this.BuildInMemoryDbStoreProvider(c);
                    return(dbStoreProvider);
                }
            })
            .As <Task <IDbStoreProvider> >()
            .SingleInstance();

            // Task<IStoreProvider>
            builder.Register(async c =>
            {
                var dbStoreProvider          = await c.Resolve <Task <IDbStoreProvider> >();
                IStoreProvider storeProvider = new StoreProvider(dbStoreProvider);
                return(storeProvider);
            })
            .As <Task <IStoreProvider> >()
            .SingleInstance();

            // IEntityStore<string, ModuleState>
            builder.Register(async c =>
            {
                IStoreProvider storeProvider = await c.Resolve <Task <IStoreProvider> >();
                return(storeProvider.GetEntityStore <string, ModuleState>("moduleState"));
            })
            .As <Task <IEntityStore <string, ModuleState> > >()
            .SingleInstance();

            // IEntityStore<string, DeploymentConfigInfo>
            builder.Register(async c =>
            {
                IStoreProvider storeProvider = await c.Resolve <Task <IStoreProvider> >();
                return(storeProvider.GetEntityStore <string, string>("deploymentConfig"));
            })
            .As <Task <IEntityStore <string, string> > >()
            .SingleInstance();

            // IRestartManager
            builder.Register(c => new RestartPolicyManager(this.maxRestartCount, this.coolOffTimeUnitInSeconds))
            .As <IRestartPolicyManager>()
            .SingleInstance();

            // IPlanner
            builder.Register(
                async c => new HealthRestartPlanner(
                    await c.Resolve <Task <ICommandFactory> >(),
                    await c.Resolve <Task <IEntityStore <string, ModuleState> > >(),
                    this.intensiveCareTime,
                    c.Resolve <IRestartPolicyManager>()) as IPlanner)
            .As <Task <IPlanner> >()
            .SingleInstance();

            // IPlanRunner
            builder.Register(c => new OrderedRetryPlanRunner(this.maxRestartCount, this.coolOffTimeUnitInSeconds, SystemTime.Instance))
            .As <IPlanRunner>()
            .SingleInstance();

            // IEncryptionDecryptionProvider
            builder.Register(
                async c =>
            {
                IEncryptionProvider provider = await this.workloadUri.Map(
                    async uri =>
                {
                    IEncryptionProvider encryptionProvider = await EncryptionProvider.CreateAsync(
                        this.storagePath,
                        uri,
                        this.workloadApiVersion.Expect(() => new InvalidOperationException("Missing workload API version")),
                        Constants.EdgeletClientApiVersion,
                        this.moduleId,
                        this.moduleGenerationId.Expect(() => new InvalidOperationException("Missing generation ID")),
                        Constants.EdgeletInitializationVectorFileName);
                    return(encryptionProvider);
                }).GetOrElse(() => Task.FromResult <IEncryptionProvider>(NullEncryptionProvider.Instance));

                return(provider);
            })
            .As <Task <IEncryptionProvider> >()
            .SingleInstance();

            // IAvailabilityMetric
            builder.Register(c => new AvailabilityMetrics(c.Resolve <IMetricsProvider>(), this.storagePath))
            .As <IAvailabilityMetric>()
            .SingleInstance();

            // Task<Agent>
            builder.Register(
                async c =>
            {
                var configSource                   = c.Resolve <Task <IConfigSource> >();
                var environmentProvider            = c.Resolve <Task <IEnvironmentProvider> >();
                var planner                        = c.Resolve <Task <IPlanner> >();
                var planRunner                     = c.Resolve <IPlanRunner>();
                var reporter                       = c.Resolve <IReporter>();
                var moduleIdentityLifecycleManager = c.Resolve <IModuleIdentityLifecycleManager>();
                var deploymentConfigInfoSerde      = c.Resolve <ISerde <DeploymentConfigInfo> >();
                var deploymentConfigInfoStore      = await c.Resolve <Task <IEntityStore <string, string> > >();
                var encryptionProvider             = c.Resolve <Task <IEncryptionProvider> >();
                var availabilityMetric             = c.Resolve <IAvailabilityMetric>();
                return(await Agent.Create(
                           await configSource,
                           await planner,
                           planRunner,
                           reporter,
                           moduleIdentityLifecycleManager,
                           await environmentProvider,
                           deploymentConfigInfoStore,
                           deploymentConfigInfoSerde,
                           await encryptionProvider,
                           availabilityMetric));
            })
            .As <Task <Agent> >()
            .SingleInstance();

            base.Load(builder);
        }
Beispiel #25
0
 public StoreProvider(IDbStoreProvider dbStoreProvider, TimeSpan operationTimeout)
 {
     this.dbStoreProvider  = Preconditions.CheckNotNull(dbStoreProvider, nameof(dbStoreProvider));
     this.operationTimeout = operationTimeout;
 }
Beispiel #26
0
        protected override void Load(ContainerBuilder builder)
        {
            // IByteBufferAllocator
            builder.Register(
                c =>
            {
                var usePooledBuffers = this.mqttSettingsConfiguration.GetValue("UsePooledBuffers", false);
                return(usePooledBuffers ? PooledByteBufferAllocator.Default : UnpooledByteBufferAllocator.Default as IByteBufferAllocator);
            })
            .As <IByteBufferAllocator>()
            .SingleInstance();

            builder.Register(c => new ByteBufferConverter(c.Resolve <IByteBufferAllocator>()))
            .As <IByteBufferConverter>()
            .SingleInstance();

            // MessageAddressConverter
            builder.Register(c => new MessageAddressConverter(this.conversionConfiguration))
            .As <MessageAddressConverter>()
            .SingleInstance();

            // IMessageConverter<IProtocolGatewayMessage>
            builder.Register(c => new ProtocolGatewayMessageConverter(c.Resolve <MessageAddressConverter>(), c.Resolve <IByteBufferConverter>()))
            .As <IMessageConverter <IProtocolGatewayMessage> >()
            .SingleInstance();

            // ISettingsProvider
            builder.Register(c => new MqttSettingsProvider(this.mqttSettingsConfiguration))
            .As <ISettingsProvider>()
            .SingleInstance();

            // Task<IMqttConnectionProvider>
            builder.Register(
                async c =>
            {
                var pgMessageConverter  = c.Resolve <IMessageConverter <IProtocolGatewayMessage> >();
                var byteBufferConverter = c.Resolve <IByteBufferConverter>();
                IConnectionProvider connectionProvider = await c.Resolve <Task <IConnectionProvider> >();
                ISessionStatePersistenceProvider sessionStatePersistenceProvider = await c.Resolve <Task <ISessionStatePersistenceProvider> >();
                IMqttConnectionProvider mqtt = new MqttConnectionProvider(connectionProvider, pgMessageConverter, byteBufferConverter, sessionStatePersistenceProvider);
                return(mqtt);
            })
            .As <Task <IMqttConnectionProvider> >()
            .SingleInstance();

            // Task<ISessionStatePersistenceProvider>
            builder.Register(
                async c =>
            {
                if (this.isStoreAndForwardEnabled)
                {
                    IDbStoreProvider dbStoreProvider = await c.Resolve <Task <IDbStoreProvider> >();
                    IEntityStore <string, SessionState> entityStore = new StoreProvider(dbStoreProvider).GetEntityStore <string, SessionState>(Constants.SessionStorePartitionKey);
                    IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >();
                    return(new SessionStateStoragePersistenceProvider(edgeHub, entityStore) as ISessionStatePersistenceProvider);
                }
                else
                {
                    IEdgeHub edgeHub = await c.Resolve <Task <IEdgeHub> >();
                    return(new SessionStatePersistenceProvider(edgeHub) as ISessionStatePersistenceProvider);
                }
            })
            .As <Task <ISessionStatePersistenceProvider> >()
            .SingleInstance();

            // MqttProtocolHead
            builder.Register(
                async c =>
            {
                var metadataStore                                   = await c.Resolve <Task <IMetadataStore> >();
                var settingsProvider                                = c.Resolve <ISettingsProvider>();
                var websocketListenerRegistry                       = c.Resolve <IWebSocketListenerRegistry>();
                var byteBufferAllocator                             = c.Resolve <IByteBufferAllocator>();
                var mqttConnectionProviderTask                      = c.Resolve <Task <IMqttConnectionProvider> >();
                var sessionStatePersistenceProviderTask             = c.Resolve <Task <ISessionStatePersistenceProvider> >();
                var authenticatorProviderTask                       = c.Resolve <Task <IAuthenticator> >();
                var usernameParser                                  = c.Resolve <IUsernameParser>();
                IClientCredentialsFactory clientCredentialsProvider = c.Resolve <IClientCredentialsFactory>();
                IMqttConnectionProvider mqttConnectionProvider      = await mqttConnectionProviderTask;
                ISessionStatePersistenceProvider sessionStatePersistenceProvider = await sessionStatePersistenceProviderTask;
                IAuthenticator authenticator = await authenticatorProviderTask;
                return(new MqttProtocolHead(
                           settingsProvider,
                           this.tlsCertificate,
                           mqttConnectionProvider,
                           authenticator,
                           usernameParser,
                           clientCredentialsProvider,
                           sessionStatePersistenceProvider,
                           websocketListenerRegistry,
                           byteBufferAllocator,
                           metadataStore,
                           this.clientCertAuthAllowed,
                           this.sslProtocols));
            })
            .As <Task <MqttProtocolHead> >()
            .SingleInstance();

            base.Load(builder);
        }
Beispiel #27
0
 public StoreProvider(IDbStoreProvider dbStoreProvider)
 {
     this.dbStoreProvider = Preconditions.CheckNotNull(dbStoreProvider, nameof(dbStoreProvider));
 }
Beispiel #28
0
 public StoreProvider(IDbStoreProvider dbStoreProvider)
     : this(dbStoreProvider, TimeSpan.FromMinutes(2))
 {
     this.dbStoreProvider = Preconditions.CheckNotNull(dbStoreProvider, nameof(dbStoreProvider));
 }