Exemple #1
0
        public static IFhirServerBuilder AddKeyVaultSecretStore(this IFhirServerBuilder fhirServerBuilder, IConfiguration configuration)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));
            EnsureArg.IsNotNull(configuration, nameof(configuration));

            // Get the KeyVault endpoint mentioned in the config. It is not necessary the KeyVault config
            // section is present (depending on how we choose to implement ISecretStore). But even if it is
            // not present, GetSection will return an empty IConfigurationSection. And we will end up creating
            // an InMemoryKeyVaultSecretStore in that scenario also.
            var keyVaultConfig = new KeyVaultConfiguration();

            configuration.GetSection(KeyVaultConfigurationName).Bind(keyVaultConfig);

            if (string.IsNullOrWhiteSpace(keyVaultConfig.Endpoint))
            {
                fhirServerBuilder.Services.Add <InMemorySecretStore>()
                .Singleton()
                .AsService <ISecretStore>();
            }
            else
            {
                fhirServerBuilder.Services.Add <KeyVaultSecretStore>((sp) =>
                {
                    var tokenProvider = new AzureServiceTokenProvider();
                    var kvClient      = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback));

                    return(new KeyVaultSecretStore(kvClient, new Uri(keyVaultConfig.Endpoint)));
                })
                .Singleton()
                .AsService <ISecretStore>();
            }

            return(fhirServerBuilder);
        }
        private static IFhirServerBuilder AddCosmosDbPersistence(this IFhirServerBuilder fhirServerBuilder, IConfiguration configuration)
        {
            IServiceCollection services = fhirServerBuilder.Services;

            services.AddCosmosDb();

            services.Configure <CosmosCollectionConfiguration>(Constants.CollectionConfigurationName, cosmosCollectionConfiguration => configuration.GetSection("FhirServer:CosmosDb").Bind(cosmosCollectionConfiguration));

            services.Add <CosmosFhirDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <FhirCollectionUpgradeManager>()
            .Singleton()
            .AsSelf()
            .AsService <IUpgradeManager>();

            services.Add <FhirDocumentQueryLogger>()
            .Singleton()
            .AsService <IFhirDocumentQueryLogger>();

            services.Add <CollectionInitializer>(sp =>
            {
                var config         = sp.GetService <CosmosDataStoreConfiguration>();
                var upgradeManager = sp.GetService <FhirCollectionUpgradeManager>();
                var loggerFactory  = sp.GetService <ILoggerFactory>();
                var namedCosmosCollectionConfiguration = sp.GetService <IOptionsMonitor <CosmosCollectionConfiguration> >();
                var cosmosCollectionConfiguration      = namedCosmosCollectionConfiguration.Get(Constants.CollectionConfigurationName);

                return(new CollectionInitializer(
                           cosmosCollectionConfiguration.CollectionId,
                           config,
                           cosmosCollectionConfiguration.InitialCollectionThroughput,
                           upgradeManager,
                           loggerFactory.CreateLogger <CollectionInitializer>()));
            })
            .Singleton()
            .AsService <ICollectionInitializer>();

            services.Add <FhirCollectionSettingsUpdater>()
            .Singleton()
            .AsService <IFhirCollectionUpdater>();

            services.Add <FhirStoredProcedureInstaller>()
            .Singleton()
            .AsService <IFhirCollectionUpdater>();

            services.TypesInSameAssemblyAs <IFhirStoredProcedure>()
            .AssignableTo <IStoredProcedure>()
            .Singleton()
            .AsSelf()
            .AsService <IFhirStoredProcedure>();

            services.Add <FhirCosmosDocumentQueryFactory>()
            .Singleton()
            .AsSelf();

            return(fhirServerBuilder);
        }
Exemple #3
0
        private static IFhirServerBuilder AddCosmosDbHealthCheck(this IFhirServerBuilder fhirServerBuilder)
        {
            fhirServerBuilder.Services.AddHealthChecks()
            .AddCheck <CosmosHealthCheck>(name: nameof(CosmosHealthCheck));

            return(fhirServerBuilder);
        }
Exemple #4
0
        /// <summary>
        /// Customer can use this DataStore to integrate with other Azure services for data purpose.
        /// </summary>
        /// <param name="fhirServerBuilder">Service builder for FHIR server</param>
        /// <param name="configuration">Configuration for FHIR server</param>
        public static IFhirServerBuilder AddAzureIntegrationDataStoreClient(this IFhirServerBuilder fhirServerBuilder, IConfiguration configuration)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));

            var integrationDataStoreConfiguration = new IntegrationDataStoreConfiguration();

            configuration.GetSection(IntegrationDataStoreConfigurationName).Bind(integrationDataStoreConfiguration);

            if (!string.IsNullOrWhiteSpace(integrationDataStoreConfiguration.StorageAccountUri))
            {
                fhirServerBuilder.Services.Add <AzureAccessTokenClientInitializerV2>()
                .Transient()
                .AsService <IIntegrationDataStoreClientInitilizer <CloudBlobClient> >();

                fhirServerBuilder.Services.Add <AzureAccessTokenProvider>()
                .Transient()
                .AsService <IAccessTokenProvider>();
            }
            else
            {
                fhirServerBuilder.Services.Add <AzureConnectionStringClientInitializerV2>()
                .Transient()
                .AsService <IIntegrationDataStoreClientInitilizer <CloudBlobClient> >();
            }

            fhirServerBuilder.Services.Add <AzureBlobIntegrationDataStoreClient>()
            .Transient()
            .AsImplementedInterfaces();

            return(fhirServerBuilder);
        }
Exemple #5
0
        public static IFhirServerBuilder AddAzureExportClientInitializer(this IFhirServerBuilder fhirServerBuilder, IConfiguration configuration)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));
            EnsureArg.IsNotNull(configuration, nameof(configuration));

            var exportJobConfiguration = new ExportJobConfiguration();

            configuration.GetSection(ExportConfigurationName).Bind(exportJobConfiguration);

            if (!string.IsNullOrWhiteSpace(exportJobConfiguration.StorageAccountUri))
            {
                fhirServerBuilder.Services.Add <AzureAccessTokenClientInitializer>()
                .Transient()
                .AsService <IExportClientInitializer <CloudBlobClient> >();

                fhirServerBuilder.Services.Add <AzureAccessTokenProvider>()
                .Transient()
                .AsService <IAccessTokenProvider>();
            }
            else
            {
                fhirServerBuilder.Services.Add <AzureConnectionStringClientInitializer>()
                .Transient()
                .AsService <IExportClientInitializer <CloudBlobClient> >();
            }

            return(fhirServerBuilder);
        }
Exemple #6
0
        public static IFhirServerBuilder AddMemberMatch(this IFhirServerBuilder fhirServerBuilder)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));
            fhirServerBuilder.Services.AddSingleton <IMemberMatchService, MemberMatchService>();

            return(fhirServerBuilder);
        }
        /// <summary>
        /// Adds the export worker background service.
        /// </summary>
        /// <param name="fhirServerBuilder">The FHIR server builder.</param>
        /// <returns>The builder.</returns>
        public static IFhirServerBuilder AddExportWorker(
            this IFhirServerBuilder fhirServerBuilder)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));

            fhirServerBuilder.Services.AddHostedService <ExportJobWorkerBackgroundService>();

            return(fhirServerBuilder);
        }
        public static IFhirServerBuilder AddSqlServer(this IFhirServerBuilder fhirServerBuilder, Action <SqlServerDataStoreConfiguration> configureAction = null)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));
            IServiceCollection services = fhirServerBuilder.Services;

            services.AddSqlServerBase <SchemaVersion>(configureAction);
            services.AddSqlServerApi();

            services.Add(provider => new SchemaInformation((int)SchemaVersion.V1, (int)SchemaVersion.V3))
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerFhirModel>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SearchParameterToSearchValueTypeMap>()
            .Singleton()
            .AsSelf();

            services.Add <SqlServerFhirDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerFhirOperationDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerSearchService>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            AddSqlServerTableRowParameterGenerators(services);

            services.Add <NormalizedSearchParameterQueryGeneratorFactory>()
            .Singleton()
            .AsSelf();

            services.Add <SqlRootExpressionRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <ChainFlatteningRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <StringOverflowRewriter>()
            .Singleton()
            .AsSelf();

            return(fhirServerBuilder);
        }
Exemple #9
0
        /// <summary>
        /// Adds Cosmos Db as the data store for the FHIR server.
        /// </summary>
        /// <param name="fhirServerBuilder">The FHIR server builder.</param>
        /// <param name="configureAction">Configure action. Defaulted to null.</param>
        /// <returns>The builder.</returns>
        public static IFhirServerBuilder AddCosmosDb(this IFhirServerBuilder fhirServerBuilder, Action <CosmosDataStoreConfiguration> configureAction = null)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));

            return(fhirServerBuilder
                   .AddCosmosDbPersistence(configureAction)
                   .AddCosmosDbSearch()
                   .AddCosmosDbHealthCheck());
        }
        public static IFhirServerBuilder AddConvertData(this IFhirServerBuilder fhirServerBuilder)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));

            fhirServerBuilder.AddConvertDataTemplateProvider()
            .AddConvertDataEngine();

            return(fhirServerBuilder);
        }
        /// <summary>
        /// Adds Cosmos Db as the data store for the FHIR server.
        /// </summary>
        /// <param name="fhirServerBuilder">The FHIR server builder.</param>
        /// <param name="configuration">The configuration for the server</param>
        /// <returns>The builder.</returns>
        public static IFhirServerBuilder AddCosmosDb(this IFhirServerBuilder fhirServerBuilder, IConfiguration configuration)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));
            EnsureArg.IsNotNull(configuration, nameof(configuration));

            return(fhirServerBuilder
                   .AddCosmosDbPersistence(configuration)
                   .AddCosmosDbSearch()
                   .AddCosmosDbHealthCheck());
        }
        public static IFhirServerBuilder AddAzureExportDestinationClient(this IFhirServerBuilder fhirServerBuilder)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));

            fhirServerBuilder.Services.Add <AzureExportDestinationClient>()
            .Transient()
            .AsService <IExportDestinationClient>();

            return(fhirServerBuilder);
        }
Exemple #13
0
        private static IFhirServerBuilder AddCosmosDbSearch(this IFhirServerBuilder fhirServerBuilder)
        {
            fhirServerBuilder.Services.Add <FhirCosmosSearchService>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            fhirServerBuilder.Services.AddSingleton <IQueryBuilder, QueryBuilder>();

            return(fhirServerBuilder);
        }
Exemple #14
0
        private static IFhirServerBuilder AddCosmosDbHealthCheck(this IFhirServerBuilder fhirServerBuilder)
        {
            // We can move to framework such as https://github.com/dotnet-architecture/HealthChecks
            // once they are released to do health check on multiple dependencies.
            fhirServerBuilder.Services.Add <CosmosHealthCheck>()
            .Scoped()
            .AsSelf()
            .AsService <IHealthCheck>();

            return(fhirServerBuilder);
        }
Exemple #15
0
        public static IFhirServerBuilder AddContainerRegistryTokenProvider(this IFhirServerBuilder fhirServerBuilder)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));

            fhirServerBuilder.Services.Add <AzureAccessTokenProvider>()
            .Transient()
            .AsService <IAccessTokenProvider>();
            fhirServerBuilder.Services.Add <AzureContainerRegistryAccessTokenProvider>()
            .Singleton()
            .AsService <IContainerRegistryTokenProvider>();

            return(fhirServerBuilder);
        }
Exemple #16
0
        public static IFhirServerBuilder AddAzureExportDestinationClient(this IFhirServerBuilder fhirServerBuilder)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));

            fhirServerBuilder.Services.Add <AzureExportDestinationClient>()
            .Transient()
            .AsSelf();

            fhirServerBuilder.Services.Add <Func <IExportDestinationClient> >(sp => () => sp.GetRequiredService <AzureExportDestinationClient>())
            .Transient()
            .AsSelf();

            return(fhirServerBuilder);
        }
        public static IFhirServerBuilder AddExperimentalPostgresql(this IFhirServerBuilder fhirServerBuilder, Action <PostgresqlDataStoreConfiguration> configureAction = null)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));
            IServiceCollection services = fhirServerBuilder.Services;

            services.Add(provider =>
            {
                var config = new PostgresqlDataStoreConfiguration();
                provider.GetService <IConfiguration>().GetSection("Postgresql").Bind(config);
                configureAction?.Invoke(config);
                return(config);
            })
            .Singleton()
            .AsSelf();

            services.Add <PostgresqlFhirDatastoreContext>()
            .Transient()
            .AsSelf();

            services.Add <SchemaInitializer>()
            .Singleton()
            .AsService <IStartable>();

            services.Add <PostgresqlFhirDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <PostgresqlFhirOperationDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <PostgresqlSearchService>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services
            .AddHealthChecks()
            .AddCheck <PostgresqlHealthCheck>(nameof(PostgresqlHealthCheck));

            // This is only needed while adding in the ConfigureServices call in the E2E TestServer scenario
            // During normal usage, the controller should be automatically discovered.
            // services.AddMvc().AddApplicationPart(typeof(SchemaController).Assembly);

            return(fhirServerBuilder);
        }
        private static IFhirServerBuilder AddCosmosDbSearch(this IFhirServerBuilder fhirServerBuilder)
        {
            fhirServerBuilder.Services.Add<FhirCosmosSearchService>()
                .Scoped()
                .AsSelf()
                .AsImplementedInterfaces();

            fhirServerBuilder.Services.AddSingleton<IQueryBuilder, QueryBuilder>();

            fhirServerBuilder.Services.Add<CosmosDbSortingValidator>()
                .Singleton()
                .AsImplementedInterfaces();

            fhirServerBuilder.Services.Add<CosmosDbSearchParameterValidator>()
                .Singleton()
                .AsImplementedInterfaces();

            return fhirServerBuilder;
        }
Exemple #19
0
    // This method gets called by the runtime. Use this method to add services to the container.
    public virtual void ConfigureServices(IServiceCollection services)
    {
        IFhirServerBuilder fhirServerBuilder = services.AddFhirServer(Configuration);

        // .AddBackgroundWorkers()
        // .AddAzureExportDestinationClient()
        // .AddAzureExportClientInitializer(Configuration);

        string dataStore = Configuration["DataStore"];

        if (dataStore.Equals("CosmosDb", StringComparison.InvariantCultureIgnoreCase))
        {
            fhirServerBuilder.AddCosmosDb();
        }
        else if (dataStore.Equals("SqlServer", StringComparison.InvariantCultureIgnoreCase))
        {
            // fhirServerBuilder.AddSqlServer();
        }

        if (string.Equals(Configuration["ASPNETCORE_FORWARDEDHEADERS_ENABLED"], "true", StringComparison.OrdinalIgnoreCase))
        {
            services.Configure <ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
                                           ForwardedHeaders.XForwardedProto;

                // Only loopback proxies are allowed by default.
                // Clear that restriction because forwarders are enabled by explicit
                // configuration.
                options.KnownNetworks.Clear();
                options.KnownProxies.Clear();
            });
        }

        services.AddMvc()
        .AddApplicationPart(typeof(FhirController).Assembly)
        .AddApplicationPart(typeof(AadSmartOnFhirProxyController).Assembly);
    }
        public static IFhirServerBuilder AddSqlServer(this IFhirServerBuilder fhirServerBuilder, Action <SqlServerDataStoreConfiguration> configureAction = null)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));
            IServiceCollection services = fhirServerBuilder.Services;

            services.AddSqlServerConnection(configureAction);
            services.AddSqlServerManagement <SchemaVersion>();
            services.AddSqlServerApi();

            services.Add(provider => new SchemaInformation(SchemaVersionConstants.Min, SchemaVersionConstants.Max))
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerSearchParameterStatusDataStore>()
            .Singleton()
            .AsSelf()
            .ReplaceService <ISearchParameterStatusDataStore>();

            services.Add <SearchParameterToSearchValueTypeMap>()
            .Singleton()
            .AsSelf();

            services.Add <SqlServerFhirDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerFhirOperationDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerSearchService>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            AddSqlServerTableRowParameterGenerators(services);

            services.Add <SearchParamTableExpressionQueryGeneratorFactory>()
            .Singleton()
            .AsSelf();

            services.Add <SqlRootExpressionRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <ChainFlatteningRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <SortRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <PartitionEliminationRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <SqlServerSortingValidator>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.AddFactory <IScoped <SqlConnectionWrapperFactory> >();

            services.Add <SqlServerFhirModel>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SchemaUpgradedHandler>()
            .Transient()
            .AsImplementedInterfaces();

            services.Add <SqlServerSearchParameterValidator>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <ReindexJobSqlThrottlingController>()
            .Singleton()
            .AsImplementedInterfaces();

            services.Add <SqlServerTaskManager>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerTaskConsumer>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerTaskContextUpdaterFactory>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlImportOperation>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlResourceBulkImporter>()
            .Transient()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlResourceMetaPopulator>()
            .Transient()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <CompressedRawResourceConverter>()
            .Transient()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlBulkCopyDataWrapperFactory>()
            .Transient()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <DateTimeSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <NumberSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <QuantitySearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <ReferenceSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <ReferenceTokenCompositeSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <StringSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <TokenDateTimeCompositeSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <TokenNumberNumberCompositeSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <TokenQuantityCompositeSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <TokenSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <TokenStringCompositeSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <TokenTextSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <TokenTokenCompositeSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <UriSearchParamsTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <ResourceWriteClaimTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <CompartmentAssignmentTableBulkCopyDataGenerator>()
            .Transient()
            .AsSelf();

            services.Add <SqlStoreSequenceIdGenerator>()
            .Transient()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <PurgeOperationCapabilityProvider>()
            .Transient()
            .AsImplementedInterfaces();

            return(fhirServerBuilder);
        }
Exemple #21
0
        private static IFhirServerBuilder AddCosmosDbPersistence(this IFhirServerBuilder fhirServerBuilder, Action <CosmosDataStoreConfiguration> configureAction = null)
        {
            IServiceCollection services = fhirServerBuilder.Services;

            if (services.Any(x => x.ImplementationType == typeof(CosmosContainerProvider)))
            {
                return(fhirServerBuilder);
            }

            services.Add(provider =>
            {
                var config = new CosmosDataStoreConfiguration();
                provider.GetService <IConfiguration>().GetSection("CosmosDb").Bind(config);
                configureAction?.Invoke(config);
                return(config);
            })
            .Singleton()
            .AsSelf();

            services.Add <CosmosContainerProvider>()
            .Singleton()
            .AsSelf()
            .AsService <IStartable>()                            // so that it starts initializing ASAP
            .AsService <IRequireInitializationOnFirstRequest>(); // so that web requests block on its initialization.

            services.Add <CosmosClientReadWriteTestProvider>()
            .Singleton()
            .AsService <ICosmosClientTestProvider>();

            // Register Container
            // We are intentionally not registering Container directly, because
            // we want this codebase to support different configurations, where the
            // lifetime of the document clients can be managed outside of the IoC
            // container, which will automatically dispose it if exposed as a scoped
            // service or as transient but consumed from another scoped service.

            services.Add <IScoped <Container> >(sp => sp.GetService <CosmosContainerProvider>().CreateContainerScope())
            .Transient()
            .AsSelf()
            .AsFactory();

            services.Add <CosmosQueryFactory>()
            .Singleton()
            .AsService <ICosmosQueryFactory>();

            services.Add <CosmosDbDistributedLockFactory>()
            .Singleton()
            .AsService <ICosmosDbDistributedLockFactory>();

            services.Add <RetryExceptionPolicyFactory>()
            .Singleton()
            .AsSelf();

            services.AddTransient <IConfigureOptions <CosmosCollectionConfiguration> >(
                provider => new ConfigureNamedOptions <CosmosCollectionConfiguration>(
                    Constants.CollectionConfigurationName,
                    cosmosCollectionConfiguration =>
            {
                var configuration = provider.GetRequiredService <IConfiguration>();
                configuration.GetSection("FhirServer:CosmosDb").Bind(cosmosCollectionConfiguration);
                if (string.IsNullOrWhiteSpace(cosmosCollectionConfiguration.CollectionId))
                {
                    IModelInfoProvider modelInfoProvider       = provider.GetRequiredService <IModelInfoProvider>();
                    cosmosCollectionConfiguration.CollectionId = modelInfoProvider.Version == FhirSpecification.Stu3 ? "fhir" : $"fhir{modelInfoProvider.Version}";
                }
            }));

            services.Add <CosmosFhirDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <CosmosTransactionHandler>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <CollectionUpgradeManager>()
            .Singleton()
            .AsSelf()
            .AsService <IUpgradeManager>();

            services.Add <CosmosQueryLogger>()
            .Singleton()
            .AsService <ICosmosQueryLogger>();

            services.Add <CollectionInitializer>(sp =>
            {
                var config         = sp.GetService <CosmosDataStoreConfiguration>();
                var upgradeManager = sp.GetService <CollectionUpgradeManager>();
                var loggerFactory  = sp.GetService <ILoggerFactory>();
                var namedCosmosCollectionConfiguration = sp.GetService <IOptionsMonitor <CosmosCollectionConfiguration> >();
                var cosmosCollectionConfiguration      = namedCosmosCollectionConfiguration.Get(Constants.CollectionConfigurationName);

                return(new CollectionInitializer(
                           cosmosCollectionConfiguration.CollectionId,
                           config,
                           cosmosCollectionConfiguration.InitialCollectionThroughput,
                           upgradeManager,
                           loggerFactory.CreateLogger <CollectionInitializer>()));
            })
            .Singleton()
            .AsService <ICollectionInitializer>();

            services.Add <FhirCollectionSettingsUpdater>()
            .Transient()
            .AsService <ICollectionUpdater>();

            services.Add <StoredProcedureInstaller>()
            .Transient()
            .AsService <ICollectionUpdater>();

            services.Add <CosmosDbStatusRegistryInitializer>()
            .Transient()
            .AsService <ICollectionUpdater>();

            services.TypesInSameAssemblyAs <IStoredProcedure>()
            .AssignableTo <IStoredProcedure>()
            .Singleton()
            .AsSelf()
            .AsService <IStoredProcedure>();

            services.Add <CosmosFhirOperationDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <FhirCosmosClientInitializer>()
            .Singleton()
            .AsService <ICosmosClientInitializer>();

            services.Add <CosmosResponseProcessor>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <CosmosDbStatusRegistry>()
            .Singleton()
            .AsSelf()
            .ReplaceService <ISearchParameterRegistry>();

            services.TypesInSameAssemblyAs <FhirCosmosClientInitializer>()
            .AssignableTo <RequestHandler>()
            .Singleton()
            .AsService <RequestHandler>();

            return(fhirServerBuilder);
        }
        private static IFhirServerBuilder AddConvertDataEngine(this IFhirServerBuilder fhirServerBuilder)
        {
            fhirServerBuilder.Services.AddSingleton <IConvertDataEngine, ConvertDataEngine>();

            return(fhirServerBuilder);
        }
        private static IFhirServerBuilder AddConvertDataTemplateProvider(this IFhirServerBuilder fhirServerBuilder)
        {
            fhirServerBuilder.Services.AddSingleton <IConvertDataTemplateProvider, ContainerRegistryTemplateProvider>();

            return(fhirServerBuilder);
        }
        public static IFhirServerBuilder AddSqlServer(this IFhirServerBuilder fhirServerBuilder, IConfiguration configuration, Action <SqlServerDataStoreConfiguration> configureAction = null)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));
            IServiceCollection services = fhirServerBuilder.Services;

            services.AddSqlServerBase <SchemaVersion>(configuration, configureAction);
            services.AddSqlServerApi();

            services.Add(provider => new SchemaInformation(SchemaVersionConstants.Min, SchemaVersionConstants.Max))
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerSearchParameterStatusDataStore>()
            .Singleton()
            .AsSelf()
            .ReplaceService <ISearchParameterStatusDataStore>();

            services.Add <SqlServerFhirModel>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SearchParameterToSearchValueTypeMap>()
            .Singleton()
            .AsSelf();

            services.Add <SqlServerFhirDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerFhirOperationDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerSearchService>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            AddSqlServerTableRowParameterGenerators(services);

            services.Add <SearchParamTableExpressionQueryGeneratorFactory>()
            .Singleton()
            .AsSelf();

            services.Add <SqlRootExpressionRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <ChainFlatteningRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <SortRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <SqlServerSortingValidator>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.AddFactory <IScoped <SqlConnectionWrapperFactory> >();

            services.Add <SchemaUpgradedHandler>()
            .Transient()
            .AsImplementedInterfaces();

            services.Add <SqlServerSearchParameterValidator>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            return(fhirServerBuilder);
        }
        private static IFhirServerBuilder AddCosmosDbPersistence(this IFhirServerBuilder fhirServerBuilder, IConfiguration configuration)
        {
            IServiceCollection services = fhirServerBuilder.Services;

            services.AddCosmosDb();

            services.AddTransient <IConfigureOptions <CosmosCollectionConfiguration> >(
                sp => new ConfigureNamedOptions <CosmosCollectionConfiguration>(
                    Constants.CollectionConfigurationName,
                    cosmosCollectionConfiguration =>
            {
                configuration.GetSection("FhirServer:CosmosDb").Bind(cosmosCollectionConfiguration);
                if (string.IsNullOrWhiteSpace(cosmosCollectionConfiguration.CollectionId))
                {
                    IModelInfoProvider modelInfoProvider       = sp.GetRequiredService <IModelInfoProvider>();
                    cosmosCollectionConfiguration.CollectionId = modelInfoProvider.Version == FhirSpecification.Stu3 ? "fhir" : $"fhir{modelInfoProvider.Version}";
                }
            }));

            services.Add <CosmosFhirDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <CosmosTransactionHandler>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <FhirCollectionUpgradeManager>()
            .Singleton()
            .AsSelf()
            .AsService <IUpgradeManager>();

            services.Add <FhirDocumentQueryLogger>()
            .Singleton()
            .AsService <IFhirDocumentQueryLogger>();

            services.Add <CollectionInitializer>(sp =>
            {
                var config         = sp.GetService <CosmosDataStoreConfiguration>();
                var upgradeManager = sp.GetService <FhirCollectionUpgradeManager>();
                var loggerFactory  = sp.GetService <ILoggerFactory>();
                var namedCosmosCollectionConfiguration = sp.GetService <IOptionsMonitor <CosmosCollectionConfiguration> >();
                var cosmosCollectionConfiguration      = namedCosmosCollectionConfiguration.Get(Constants.CollectionConfigurationName);

                return(new CollectionInitializer(
                           cosmosCollectionConfiguration.CollectionId,
                           config,
                           cosmosCollectionConfiguration.InitialCollectionThroughput,
                           upgradeManager,
                           loggerFactory.CreateLogger <CollectionInitializer>()));
            })
            .Singleton()
            .AsService <ICollectionInitializer>();

            services.Add <FhirCollectionSettingsUpdater>()
            .Transient()
            .AsService <IFhirCollectionUpdater>();

            services.Add <FhirStoredProcedureInstaller>()
            .Transient()
            .AsService <IFhirCollectionUpdater>();

            services.Add <CosmosDbStatusRegistryInitializer>()
            .Transient()
            .AsService <IFhirCollectionUpdater>();

            services.TypesInSameAssemblyAs <IFhirStoredProcedure>()
            .AssignableTo <IStoredProcedure>()
            .Singleton()
            .AsSelf()
            .AsService <IFhirStoredProcedure>();

            services.Add <FhirCosmosDocumentQueryFactory>()
            .Singleton()
            .AsSelf();

            services.Add <CosmosFhirOperationDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <FhirDocumentClientInitializer>()
            .Singleton()
            .AsService <IDocumentClientInitializer>();

            services.Add <CosmosResponseProcessor>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <CosmosDbStatusRegistry>()
            .Singleton()
            .AsSelf()
            .ReplaceService <ISearchParameterRegistry>();

            return(fhirServerBuilder);
        }
Exemple #26
0
        public static IFhirServerBuilder AddExperimentalSqlServer(this IFhirServerBuilder fhirServerBuilder, Action <SqlServerDataStoreConfiguration> configureAction = null)
        {
            EnsureArg.IsNotNull(fhirServerBuilder, nameof(fhirServerBuilder));
            IServiceCollection services = fhirServerBuilder.Services;

            services.Add(provider =>
            {
                var config = new SqlServerDataStoreConfiguration();
                provider.GetService <IConfiguration>().GetSection("SqlServer").Bind(config);
                configureAction?.Invoke(config);

                return(config);
            })
            .Singleton()
            .AsSelf();

            services.Add <SchemaUpgradeRunner>()
            .Singleton()
            .AsSelf();

            services.Add <SchemaInformation>()
            .Singleton()
            .AsSelf();

            services.Add <SchemaInitializer>()
            .Singleton()
            .AsService <IStartable>();

            services.Add <SqlServerFhirModel>()
            .Singleton()
            .AsSelf();

            services.Add <SearchParameterToSearchValueTypeMap>()
            .Singleton()
            .AsSelf();

            services.Add <SqlServerFhirDataStore>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerFhirOperationDataStore>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <SqlServerSearchService>()
            .Singleton()
            .AsSelf()
            .AsImplementedInterfaces();

            services
            .AddHealthChecks()
            .AddCheck <SqlServerHealthCheck>(nameof(SqlServerHealthCheck));

            // This is only needed while adding in the ConfigureServices call in the E2E TestServer scenario
            // During normal usage, the controller should be automatically discovered.
            services.AddMvc().AddApplicationPart(typeof(SchemaController).Assembly);

            AddSqlServerTableRowParameterGenerators(services);

            services.Add <NormalizedSearchParameterQueryGeneratorFactory>()
            .Singleton()
            .AsSelf();

            services.Add <SqlRootExpressionRewriter>()
            .Singleton()
            .AsSelf();

            services.Add <ChainFlatteningRewriter>()
            .Singleton()
            .AsSelf();

            return(fhirServerBuilder);
        }
Exemple #27
0
        private static IFhirServerBuilder AddCosmosDbPersistence(this IFhirServerBuilder fhirServerBuilder, Action <CosmosDataStoreConfiguration> configureAction)
        {
            IServiceCollection services = fhirServerBuilder.Services;

            services.Add(provider =>
            {
                var config = new CosmosDataStoreConfiguration();
                provider.GetService <IConfiguration>().GetSection("CosmosDb").Bind(config);
                configureAction?.Invoke(config);

                if (string.IsNullOrEmpty(config.Host))
                {
                    config.Host = CosmosDbLocalEmulator.Host;
                    config.Key  = CosmosDbLocalEmulator.Key;
                }

                return(config);
            })
            .Singleton()
            .AsSelf();

            services.Add <CosmosDataStore>()
            .Scoped()
            .AsSelf()
            .AsImplementedInterfaces();

            services.Add <DocumentClientProvider>()
            .Singleton()
            .AsSelf()
            .AsService <IStartable>()                            // so that it starts initializing ASAP
            .AsService <IRequireInitializationOnFirstRequest>(); // so that web requests block on its initialization.

            services.Add <DocumentClientReadWriteTestProvider>()
            .Singleton()
            .AsService <IDocumentClientTestProvider>();

            // Register IDocumentClient
            // We are intentionally not registering IDocumentClient directly, because
            // we want this codebase to support different configurations, where the
            // lifetime of the document clients can be managed outside of the IoC
            // container, which will automatically dispose it if exposed as a scoped
            // service or as transient but consumed from another scoped service.

            services.Add(sp => sp.GetService <DocumentClientProvider>().CreateDocumentClientScope())
            .Transient()
            .AsSelf()
            .AsFactory();

            services.Add <DocumentClientInitializer>()
            .Singleton()
            .AsService <IDocumentClientInitializer>();

            services.Add <CosmosDocumentQueryFactory>()
            .Singleton()
            .AsService <ICosmosDocumentQueryFactory>();

            services.Add <CosmosDocumentQueryLogger>()
            .Singleton()
            .AsService <ICosmosDocumentQueryLogger>();

            services.Add <CollectionUpgradeManager>()
            .Singleton()
            .AsService <IUpgradeManager>();

            services.TypesInSameAssemblyAs <ICollectionUpdater>()
            .AssignableTo <ICollectionUpdater>()
            .Singleton()
            .AsSelf()
            .AsService <ICollectionUpdater>();

            services.Add <CosmosDbDistributedLockFactory>()
            .Singleton()
            .AsService <ICosmosDbDistributedLockFactory>();

            services.Add <RetryExceptionPolicyFactory>()
            .Singleton()
            .AsSelf();

            return(fhirServerBuilder);
        }