public void ReliableConnectionHelperTest() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { var result = LiveConnectionHelper.InitLiveConnectionInfo(null, queryTempFile.FilePath); ConnectionInfo connInfo = result.ConnectionInfo; DbConnection connection = connInfo.ConnectionTypeToConnectionMap[ConnectionType.Default]; connection.Open(); Assert.True(connection.State == ConnectionState.Open, "Connection should be open."); Assert.True(ReliableConnectionHelper.IsAuthenticatingDatabaseMaster(connection)); SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); Assert.True(ReliableConnectionHelper.IsAuthenticatingDatabaseMaster(builder, null)); ReliableConnectionHelper.TryAddAlwaysOnConnectionProperties(builder, new SqlConnectionStringBuilder()); Assert.NotNull(ReliableConnectionHelper.GetServerName(connection)); Assert.NotNull(ReliableConnectionHelper.ReadServerVersion(connection)); Assert.NotNull(ReliableConnectionHelper.GetAsSqlConnection(connection)); ReliableConnectionHelper.ServerInfo info = ReliableConnectionHelper.GetServerVersion(connection); Assert.NotNull(ReliableConnectionHelper.IsVersionGreaterThan2012RTM(info)); } }
public void TestGetServerVersion() { TestUtils.RunIfWindows(() => { using (var connection = CreateTestConnection()) { Assert.NotNull(connection); connection.Open(); ReliableConnectionHelper.ServerInfo serverInfo = ReliableConnectionHelper.GetServerVersion(connection); ReliableConnectionHelper.ServerInfo serverInfo2; using (var connection2 = CreateTestConnection()) { connection2.Open(); serverInfo2 = ReliableConnectionHelper.GetServerVersion(connection); } Assert.NotNull(serverInfo); Assert.NotNull(serverInfo2); Assert.True(serverInfo.ServerMajorVersion != 0); Assert.True(serverInfo.ServerMajorVersion == serverInfo2.ServerMajorVersion); Assert.True(serverInfo.ServerMinorVersion == serverInfo2.ServerMinorVersion); Assert.True(serverInfo.ServerReleaseVersion == serverInfo2.ServerReleaseVersion); Assert.True(serverInfo.ServerEdition == serverInfo2.ServerEdition); Assert.True(serverInfo.IsCloud == serverInfo2.IsCloud); Assert.True(serverInfo.AzureVersion == serverInfo2.AzureVersion); } }); }
public async void InvokeSqlAssessmentServerTest() { var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo("master"); var connection = liveConnection.ConnectionInfo.AllConnections.FirstOrDefault(); Debug.Assert(connection != null, "Live connection is always expected providing a connection"); var serverInfo = ReliableConnectionHelper.GetServerVersion(connection); var response = await CallAssessment <AssessmentResultItem>( nameof(SqlAssessmentService.InvokeSqlAssessment), SqlObjectType.Server, liveConnection); Assert.All( response.Items, i => { Assert.NotNull(i.Message); Assert.NotEmpty(i.Message); Assert.Equal(serverInfo.ServerName, i.TargetName); if (i.Kind == 0) { AssertInfoPresent(i); } }); }
/// <summary> /// Creates a ConnectionCompleteParams as a response to a successful connection. /// Also sets the DatabaseName and IsAzure properties of ConnectionInfo. /// </summary> /// <returns>A ConnectionCompleteParams in response to the successful connection</returns> private ConnectionCompleteParams GetConnectionCompleteParams(string connectionType, ConnectionInfo connectionInfo) { ConnectionCompleteParams response = new ConnectionCompleteParams { OwnerUri = connectionInfo.OwnerUri, Type = connectionType }; try { DbConnection connection; connectionInfo.TryGetConnection(connectionType, out connection); // Update with the actual database name in connectionInfo and result // Doing this here as we know the connection is open - expect to do this only on connecting connectionInfo.ConnectionDetails.DatabaseName = connection.Database; response.ConnectionSummary = new ConnectionSummary { ServerName = connectionInfo.ConnectionDetails.ServerName, DatabaseName = connectionInfo.ConnectionDetails.DatabaseName, UserName = connectionInfo.ConnectionDetails.UserName, }; response.ConnectionId = connectionInfo.ConnectionId.ToString(); var reliableConnection = connection as ReliableSqlConnection; DbConnection underlyingConnection = reliableConnection != null ? reliableConnection.GetUnderlyingConnection() : connection; ReliableConnectionHelper.ServerInfo serverInfo = ReliableConnectionHelper.GetServerVersion(underlyingConnection); response.ServerInfo = new ServerInfo { ServerMajorVersion = serverInfo.ServerMajorVersion, ServerMinorVersion = serverInfo.ServerMinorVersion, ServerReleaseVersion = serverInfo.ServerReleaseVersion, EngineEditionId = serverInfo.EngineEditionId, ServerVersion = serverInfo.ServerVersion, ServerLevel = serverInfo.ServerLevel, ServerEdition = serverInfo.ServerEdition, IsCloud = serverInfo.IsCloud, AzureVersion = serverInfo.AzureVersion, OsVersion = serverInfo.OsVersion }; connectionInfo.IsAzure = serverInfo.IsCloud; connectionInfo.MajorVersion = serverInfo.ServerMajorVersion; connectionInfo.IsSqlDW = (serverInfo.EngineEditionId == (int)DatabaseEngineEdition.SqlDataWarehouse); } catch (Exception ex) { response.Messages = ex.ToString(); } return(response); }
public void ReliableConnectionHelperTest() { ScriptFile scriptFile; ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile); Assert.True(ReliableConnectionHelper.IsAuthenticatingDatabaseMaster(connInfo.SqlConnection)); SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); Assert.True(ReliableConnectionHelper.IsAuthenticatingDatabaseMaster(builder)); ReliableConnectionHelper.TryAddAlwaysOnConnectionProperties(builder, new SqlConnectionStringBuilder()); Assert.NotNull(ReliableConnectionHelper.GetServerName(connInfo.SqlConnection)); Assert.NotNull(ReliableConnectionHelper.ReadServerVersion(connInfo.SqlConnection)); Assert.NotNull(ReliableConnectionHelper.GetAsSqlConnection(connInfo.SqlConnection)); ServerInfo info = ReliableConnectionHelper.GetServerVersion(connInfo.SqlConnection); Assert.NotNull(ReliableConnectionHelper.IsVersionGreaterThan2012RTM(info)); }
public void ReliableConnectionHelperTest() { var result = LiveConnectionHelper.InitLiveConnectionInfo(); ConnectionInfo connInfo = result.ConnectionInfo; DbConnection connection = connInfo.ConnectionTypeToConnectionMap[ConnectionType.Default]; Assert.True(ReliableConnectionHelper.IsAuthenticatingDatabaseMaster(connection)); SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); Assert.True(ReliableConnectionHelper.IsAuthenticatingDatabaseMaster(builder)); ReliableConnectionHelper.TryAddAlwaysOnConnectionProperties(builder, new SqlConnectionStringBuilder()); Assert.NotNull(ReliableConnectionHelper.GetServerName(connection)); Assert.NotNull(ReliableConnectionHelper.ReadServerVersion(connection)); Assert.NotNull(ReliableConnectionHelper.GetAsSqlConnection(connection)); ReliableConnectionHelper.ServerInfo info = ReliableConnectionHelper.GetServerVersion(connection); Assert.NotNull(ReliableConnectionHelper.IsVersionGreaterThan2012RTM(info)); }
public async void GetAssessmentItemsServerTest() { var liveConnection = LiveConnectionHelper.InitLiveConnectionInfo("master"); var connection = liveConnection.ConnectionInfo.AllConnections.FirstOrDefault(); Debug.Assert(connection != null, "Live connection is always expected providing a connection"); var serverInfo = ReliableConnectionHelper.GetServerVersion(connection); var response = await CallAssessment <CheckInfo>( nameof(SqlAssessmentService.GetAssessmentItems), SqlObjectType.Server, liveConnection); Assert.All( response.Items, i => { AssertInfoPresent(i); Assert.Equal(serverInfo.ServerName, i.TargetName); }); }
/// <summary> /// Open a connection with the specified connection details /// </summary> /// <param name="connectionParams"></param> public async Task <ConnectionCompleteParams> Connect(ConnectParams connectionParams) { // Validate parameters string paramValidationErrorMessage; if (connectionParams == null) { return(new ConnectionCompleteParams { Messages = SR.ConnectionServiceConnectErrorNullParams }); } if (!connectionParams.IsValid(out paramValidationErrorMessage)) { return(new ConnectionCompleteParams { OwnerUri = connectionParams.OwnerUri, Messages = paramValidationErrorMessage }); } // Resolve if it is an existing connection // Disconnect active connection if the URI is already connected ConnectionInfo connectionInfo; if (ownerToConnectionMap.TryGetValue(connectionParams.OwnerUri, out connectionInfo)) { var disconnectParams = new DisconnectParams() { OwnerUri = connectionParams.OwnerUri }; Disconnect(disconnectParams); } connectionInfo = new ConnectionInfo(ConnectionFactory, connectionParams.OwnerUri, connectionParams.Connection); // try to connect var response = new ConnectionCompleteParams { OwnerUri = connectionParams.OwnerUri }; CancellationTokenSource source = null; try { // build the connection string from the input parameters string connectionString = BuildConnectionString(connectionInfo.ConnectionDetails); // create a sql connection instance connectionInfo.SqlConnection = connectionInfo.Factory.CreateSqlConnection(connectionString); // Add a cancellation token source so that the connection OpenAsync() can be cancelled using (source = new CancellationTokenSource()) { // Locking here to perform two operations as one atomic operation lock (cancellationTokenSourceLock) { // If the URI is currently connecting from a different request, cancel it before we try to connect CancellationTokenSource currentSource; if (ownerToCancellationTokenSourceMap.TryGetValue(connectionParams.OwnerUri, out currentSource)) { currentSource.Cancel(); } ownerToCancellationTokenSourceMap[connectionParams.OwnerUri] = source; } // Create a task to handle cancellation requests var cancellationTask = Task.Run(() => { source.Token.WaitHandle.WaitOne(); try { source.Token.ThrowIfCancellationRequested(); } catch (ObjectDisposedException) { // Ignore } }); var openTask = Task.Run(async() => { await connectionInfo.SqlConnection.OpenAsync(source.Token); }); // Open the connection await Task.WhenAny(openTask, cancellationTask).Unwrap(); source.Cancel(); } } catch (SqlException ex) { response.ErrorNumber = ex.Number; response.ErrorMessage = ex.Message; response.Messages = ex.ToString(); return(response); } catch (OperationCanceledException) { // OpenAsync was cancelled response.Messages = SR.ConnectionServiceConnectionCanceled; return(response); } catch (Exception ex) { response.ErrorMessage = ex.Message; response.Messages = ex.ToString(); return(response); } finally { // Remove our cancellation token from the map since we're no longer connecting // Using a lock here to perform two operations as one atomic operation lock (cancellationTokenSourceLock) { // Only remove the token from the map if it is the same one created by this request CancellationTokenSource sourceValue; if (ownerToCancellationTokenSourceMap.TryGetValue(connectionParams.OwnerUri, out sourceValue) && sourceValue == source) { ownerToCancellationTokenSourceMap.TryRemove(connectionParams.OwnerUri, out sourceValue); } } } ownerToConnectionMap[connectionParams.OwnerUri] = connectionInfo; // Update with the actual database name in connectionInfo and result // Doing this here as we know the connection is open - expect to do this only on connecting connectionInfo.ConnectionDetails.DatabaseName = connectionInfo.SqlConnection.Database; response.ConnectionSummary = new ConnectionSummary { ServerName = connectionInfo.ConnectionDetails.ServerName, DatabaseName = connectionInfo.ConnectionDetails.DatabaseName, UserName = connectionInfo.ConnectionDetails.UserName, }; // invoke callback notifications InvokeOnConnectionActivities(connectionInfo); // try to get information about the connected SQL Server instance try { var reliableConnection = connectionInfo.SqlConnection as ReliableSqlConnection; DbConnection connection = reliableConnection != null?reliableConnection.GetUnderlyingConnection() : connectionInfo.SqlConnection; ReliableConnectionHelper.ServerInfo serverInfo = ReliableConnectionHelper.GetServerVersion(connection); response.ServerInfo = new ServerInfo { ServerMajorVersion = serverInfo.ServerMajorVersion, ServerMinorVersion = serverInfo.ServerMinorVersion, ServerReleaseVersion = serverInfo.ServerReleaseVersion, EngineEditionId = serverInfo.EngineEditionId, ServerVersion = serverInfo.ServerVersion, ServerLevel = serverInfo.ServerLevel, ServerEdition = serverInfo.ServerEdition, IsCloud = serverInfo.IsCloud, AzureVersion = serverInfo.AzureVersion, OsVersion = serverInfo.OsVersion }; connectionInfo.IsAzure = serverInfo.IsCloud; } catch (Exception ex) { response.Messages = ex.ToString(); } // return the connection result response.ConnectionId = connectionInfo.ConnectionId.ToString(); return(response); }
/// <summary> /// This function obtains a live connection, then calls /// an assessment operation specified by <paramref name="assessmentFunc"/> /// </summary> /// <typeparam name="TResult"> /// SQL Assessment result item type. /// </typeparam> /// <param name="requestParams"> /// Request parameters passed from the host. /// </param> /// <param name="connectParams"> /// Connection parameters used to identify and access the target. /// </param> /// <param name="taskUri"> /// An URI identifying the request task to enable concurrent execution. /// </param> /// <param name="assessmentFunc"> /// A function performing assessment operation for given target. /// </param> /// <returns> /// Returns <see cref="AssessmentResult{TResult}"/> for given target. /// </returns> internal async Task <AssessmentResult <TResult> > CallAssessmentEngine <TResult>( AssessmentParams requestParams, ConnectParams connectParams, string taskUri, Func <SqlObjectLocator, Task <List <TResult> > > assessmentFunc) where TResult : AssessmentItemInfo { var result = new AssessmentResult <TResult> { ApiVersion = ApiVersion }; await ConnectionService.Connect(connectParams); var connection = await ConnectionService.Instance.GetOrOpenConnection(taskUri, ConnectionType.Query); try { var serverInfo = ReliableConnectionHelper.GetServerVersion(connection); var hostInfo = ReliableConnectionHelper.GetServerHostInfo(connection); var server = new SqlObjectLocator { Connection = connection, EngineEdition = GetEngineEdition(serverInfo.EngineEditionId), Name = serverInfo.ServerName, ServerName = serverInfo.ServerName, Type = SqlObjectType.Server, Urn = serverInfo.ServerName, Version = Version.Parse(serverInfo.ServerVersion), Platform = hostInfo.Platform }; switch (requestParams.TargetType) { case SqlObjectType.Server: Logger.Write( TraceEventType.Verbose, $"SQL Assessment: running an operation on a server, platform:{server.Platform}, edition:{server.EngineEdition.ToString()}, version:{server.Version}"); result.Items.AddRange(await assessmentFunc(server)); Logger.Write( TraceEventType.Verbose, $"SQL Assessment: finished an operation on a server, platform:{server.Platform}, edition:{server.EngineEdition.ToString()}, version:{server.Version}"); break; case SqlObjectType.Database: var db = GetDatabaseLocator(server, connection.Database); Logger.Write( TraceEventType.Verbose, $"SQL Assessment: running an operation on a database, platform:{server.Platform}, edition:{server.EngineEdition.ToString()}, version:{server.Version}"); result.Items.AddRange(await assessmentFunc(db)); Logger.Write( TraceEventType.Verbose, $"SQL Assessment: finished an operation on a database, platform:{server.Platform}, edition:{server.EngineEdition.ToString()}, version:{server.Version}"); break; } result.Success = true; } finally { ActiveRequests.TryRemove(taskUri, out _); ConnectionService.Disconnect(new DisconnectParams { OwnerUri = taskUri, Type = null }); } return(result); }