in edge-hub/core/src/Microsoft.Azure.Devices.Edge.Hub.Service/modules/CommonModule.cs [115:487]
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.storageMaxManifestFileSize,
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);
}