fhir-server/test/Microsoft.Health.Fhir.Share.../Persistence/SqlServerFhirStorageTestHel...

247 строки
11 KiB
C#
Исходник Обычный вид История

// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------
2020-02-10 20:36:48 +03:00
using System;
using System.Text;
2020-02-10 20:36:48 +03:00
using System.Threading;
using System.Threading.Tasks;
using EnsureThat;
using MediatR;
using Microsoft.Data.SqlClient;
2020-02-10 20:36:48 +03:00
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Health.Fhir.SqlServer.Features.Schema;
using Microsoft.Health.Fhir.SqlServer.Features.Storage;
using Microsoft.Health.SqlServer;
using Microsoft.Health.SqlServer.Configs;
using Microsoft.Health.SqlServer.Features.Schema;
using Microsoft.Health.SqlServer.Features.Schema.Manager;
using NSubstitute;
2020-02-10 20:36:48 +03:00
using Polly;
using Xunit;
2020-02-10 20:36:48 +03:00
using Task = System.Threading.Tasks.Task;
namespace Microsoft.Health.Fhir.Tests.Integration.Persistence
{
2020-02-10 20:36:48 +03:00
public class SqlServerFhirStorageTestHelper : IFhirStorageTestHelper, ISqlServerFhirStorageTestHelper
{
private readonly string _masterDatabaseName;
2020-02-10 20:36:48 +03:00
private readonly string _initialConnectionString;
private readonly SqlServerFhirModel _sqlServerFhirModel;
private readonly ISqlConnectionFactory _sqlConnectionFactory;
public SqlServerFhirStorageTestHelper(
string initialConnectionString,
string masterDatabaseName,
SqlServerFhirModel sqlServerFhirModel,
ISqlConnectionFactory sqlConnectionFactory)
{
EnsureArg.IsNotNull(sqlServerFhirModel, nameof(sqlServerFhirModel));
EnsureArg.IsNotNull(sqlConnectionFactory, nameof(sqlConnectionFactory));
_masterDatabaseName = masterDatabaseName;
2020-02-10 20:36:48 +03:00
_initialConnectionString = initialConnectionString;
_sqlServerFhirModel = sqlServerFhirModel;
_sqlConnectionFactory = sqlConnectionFactory;
2020-02-10 20:36:48 +03:00
}
public async Task CreateAndInitializeDatabase(string databaseName, int maximumSupportedSchemaVersion, bool forceIncrementalSchemaUpgrade, SchemaInitializer schemaInitializer = null, CancellationToken cancellationToken = default)
2020-02-10 20:36:48 +03:00
{
var testConnectionString = new SqlConnectionStringBuilder(_initialConnectionString) { InitialCatalog = databaseName }.ToString();
schemaInitializer = schemaInitializer ?? CreateSchemaInitializer(testConnectionString, maximumSupportedSchemaVersion);
2020-02-10 20:36:48 +03:00
// Create the database.
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync(_masterDatabaseName, cancellationToken))
2020-02-10 20:36:48 +03:00
{
await connection.OpenAsync(cancellationToken);
using (SqlCommand command = connection.CreateCommand())
{
command.CommandTimeout = 600;
command.CommandText = @$"
IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = '{databaseName}')
BEGIN
CREATE DATABASE {databaseName};
END";
2020-02-10 20:36:48 +03:00
await command.ExecuteNonQueryAsync(cancellationToken);
}
}
// Verify that we can connect to the new database. This sometimes does not work right away with Azure SQL.
await Policy
.Handle<SqlException>()
.WaitAndRetryAsync(
retryCount: 7,
sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)))
.ExecuteAsync(async () =>
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync(databaseName, cancellationToken))
2020-02-10 20:36:48 +03:00
{
await connection.OpenAsync(cancellationToken);
using (SqlCommand sqlCommand = connection.CreateCommand())
{
sqlCommand.CommandText = "SELECT 1";
await sqlCommand.ExecuteScalarAsync(cancellationToken);
}
}
});
await schemaInitializer.InitializeAsync(forceIncrementalSchemaUpgrade, cancellationToken);
await _sqlServerFhirModel.Initialize(maximumSupportedSchemaVersion, true, cancellationToken);
2020-02-10 20:36:48 +03:00
}
public async Task DeleteDatabase(string databaseName, CancellationToken cancellationToken = default)
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync(_masterDatabaseName, cancellationToken))
2020-02-10 20:36:48 +03:00
{
await connection.OpenAsync(cancellationToken);
SqlConnection.ClearAllPools();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandTimeout = 600;
command.CommandText = $"DROP DATABASE IF EXISTS {databaseName}";
await command.ExecuteNonQueryAsync(cancellationToken);
}
}
}
public async Task DeleteAllExportJobRecordsAsync(CancellationToken cancellationToken = default)
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync())
2020-02-10 20:36:48 +03:00
{
var command = new SqlCommand("DELETE FROM dbo.ExportJob", connection);
await command.Connection.OpenAsync(cancellationToken);
await command.ExecuteNonQueryAsync(cancellationToken);
}
}
public async Task DeleteExportJobRecordAsync(string id, CancellationToken cancellationToken = default)
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync())
2020-02-10 20:36:48 +03:00
{
var command = new SqlCommand("DELETE FROM dbo.ExportJob WHERE Id = @id", connection);
var parameter = new SqlParameter { ParameterName = "@id", Value = id };
command.Parameters.Add(parameter);
await command.Connection.OpenAsync(cancellationToken);
await command.ExecuteNonQueryAsync(cancellationToken);
}
}
public async Task DeleteSearchParameterStatusAsync(string uri, CancellationToken cancellationToken = default)
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync())
{
var command = new SqlCommand("DELETE FROM dbo.SearchParam WHERE Uri = @uri", connection);
command.Parameters.AddWithValue("@uri", uri);
await command.Connection.OpenAsync(cancellationToken);
await command.ExecuteNonQueryAsync(cancellationToken);
}
_sqlServerFhirModel.RemoveSearchParamIdToUriMapping(uri);
}
public async Task DeleteAllReindexJobRecordsAsync(CancellationToken cancellationToken = default)
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync())
{
var command = new SqlCommand("DELETE FROM dbo.ReindexJob", connection);
await command.Connection.OpenAsync(cancellationToken);
await command.ExecuteNonQueryAsync(cancellationToken);
}
}
public async Task DeleteReindexJobRecordAsync(string id, CancellationToken cancellationToken = default)
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync())
{
var command = new SqlCommand("DELETE FROM dbo.ReindexJob WHERE Id = @id", connection);
var parameter = new SqlParameter { ParameterName = "@id", Value = id };
command.Parameters.Add(parameter);
await command.Connection.OpenAsync(cancellationToken);
await command.ExecuteNonQueryAsync(cancellationToken);
}
}
async Task<object> IFhirStorageTestHelper.GetSnapshotToken()
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync())
{
await connection.OpenAsync();
SqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT MAX(ResourceSurrogateId) FROM dbo.Resource";
return await command.ExecuteScalarAsync();
}
}
async Task IFhirStorageTestHelper.ValidateSnapshotTokenIsCurrent(object snapshotToken)
{
using (var connection = await _sqlConnectionFactory.GetSqlConnectionAsync())
{
await connection.OpenAsync();
var sb = new StringBuilder();
using (SqlCommand outerCommand = connection.CreateCommand())
{
outerCommand.CommandText = @"
SELECT t.name
FROM sys.tables t
INNER JOIN sys.columns c ON c.object_id = t.object_id
WHERE c.name = 'ResourceSurrogateId'";
using (SqlDataReader reader = await outerCommand.ExecuteReaderAsync())
{
while (reader.Read())
{
if (sb.Length > 0)
{
sb.AppendLine("UNION ALL");
}
string tableName = reader.GetString(0);
sb.AppendLine($"SELECT '{tableName}' as TableName, MAX(ResourceSurrogateId) as MaxResourceSurrogateId FROM dbo.{tableName}");
}
}
}
using (var command = connection.CreateCommand())
{
command.CommandText = sb.ToString();
using (var reader = await command.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
Assert.True(reader.IsDBNull(1) || reader.GetInt64(1) <= (long)snapshotToken);
}
}
}
}
}
2020-02-10 20:36:48 +03:00
private SchemaInitializer CreateSchemaInitializer(string testConnectionString, int maxSupportedSchemaVersion)
2020-02-10 20:36:48 +03:00
{
var schemaOptions = new SqlServerSchemaOptions { AutomaticUpdatesEnabled = true };
var config = new SqlServerDataStoreConfiguration { ConnectionString = testConnectionString, Initialize = true, SchemaOptions = schemaOptions };
var schemaInformation = new SchemaInformation(SchemaVersionConstants.Min, maxSupportedSchemaVersion);
var scriptProvider = new ScriptProvider<SchemaVersion>();
var baseScriptProvider = new BaseScriptProvider();
var mediator = Substitute.For<IMediator>();
var sqlConnectionStringProvider = new DefaultSqlConnectionStringProvider(config);
var sqlConnectionFactory = new DefaultSqlConnectionFactory(sqlConnectionStringProvider);
var schemaManagerDataStore = new SchemaManagerDataStore(sqlConnectionFactory);
Bump HealthcareSharedPackageVersion from 2.1.9 to 2.1.14 (#1893) * Bump HealthcareSharedPackageVersion from 2.1.9 to 2.1.14 Bumps `HealthcareSharedPackageVersion` from 2.1.9 to 2.1.14. Updates `Microsoft.Health.Abstractions` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Api` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Extensions.DependencyInjection` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Test.Utilities` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Core` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Extensions.BuildTimeCodeGenerator` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.SqlServer` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.SqlServer.Api` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Client` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Signed-off-by: dependabot[bot] <support@github.com> * Fixes the build Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Richa Bansal <ribans@microsoft.com>
2021-04-28 22:45:47 +03:00
var schemaUpgradeRunner = new SchemaUpgradeRunner(scriptProvider, baseScriptProvider, NullLogger<SchemaUpgradeRunner>.Instance, sqlConnectionFactory, schemaManagerDataStore);
2020-02-10 20:36:48 +03:00
Bump HealthcareSharedPackageVersion from 2.1.9 to 2.1.14 (#1893) * Bump HealthcareSharedPackageVersion from 2.1.9 to 2.1.14 Bumps `HealthcareSharedPackageVersion` from 2.1.9 to 2.1.14. Updates `Microsoft.Health.Abstractions` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Api` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Extensions.DependencyInjection` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Test.Utilities` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Core` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Extensions.BuildTimeCodeGenerator` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.SqlServer` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.SqlServer.Api` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Updates `Microsoft.Health.Client` from 2.1.9 to 2.1.14 - [Release notes](https://github.com/microsoft/healthcare-shared-components/releases) - [Commits](https://github.com/microsoft/healthcare-shared-components/compare/2.1.9...2.1.14) Signed-off-by: dependabot[bot] <support@github.com> * Fixes the build Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Richa Bansal <ribans@microsoft.com>
2021-04-28 22:45:47 +03:00
return new SchemaInitializer(config, schemaUpgradeRunner, schemaInformation, sqlConnectionFactory, sqlConnectionStringProvider, mediator, NullLogger<SchemaInitializer>.Instance);
2020-02-10 20:36:48 +03:00
}
}
}