public async void RestoreShouldFailIfThereAreOtherConnectionsToDatabase2() { await GetBackupFilesToRecoverDatabaseCreated(); var testDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, null, "RestoreTest"); ConnectionService connectionService = LiveConnectionHelper.GetLiveTestConnectionService(); using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { //OE connection will be closed after conneced TestConnectionResult connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync(testDb.DatabaseName, queryTempFile.FilePath, ConnectionType.ObjectExplorer); //Opening a connection to db to lock the db ConnectionService.OpenSqlConnection(connectionResult.ConnectionInfo); try { bool restoreShouldFail = true; Dictionary <string, object> options = new Dictionary <string, object>(); options.Add(RestoreOptionsHelper.ReplaceDatabase, true); await VerifyRestore(null, databaseNameToRestoreFrom, true, TaskExecutionModeFlag.Execute, testDb.DatabaseName, null, options, null, restoreShouldFail); } finally { connectionService.Disconnect(new ServiceLayer.Connection.Contracts.DisconnectParams { OwnerUri = queryTempFile.FilePath, Type = ConnectionType.Default }); testDb.Cleanup(); } } }
private void CloseConnection(object sender, TaskEventArgs <SqlTaskStatus> e) { SqlTask sqlTask = e.SqlTask; if (sqlTask != null && sqlTask.IsCompleted) { connectionService.Disconnect(new DisconnectParams() { OwnerUri = sqlTask.TaskMetadata.OwnerUri }); } }
private async Task VerifyScriptAs(string query, ScriptingObject scriptingObject, string scriptCreateDrop, string expectedScript) { var testDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, query, "ScriptingTests"); try { var requestContext = new Mock <RequestContext <ScriptingResult> >(); requestContext.Setup(x => x.SendResult(It.IsAny <ScriptingResult>())).Returns(Task.FromResult(new object())); ConnectionService connectionService = LiveConnectionHelper.GetLiveTestConnectionService(); using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { //Opening a connection to db to lock the db TestConnectionResult connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync(testDb.DatabaseName, queryTempFile.FilePath, ConnectionType.Default); var scriptingParams = new ScriptingParams { OwnerUri = queryTempFile.FilePath, ScriptDestination = "ToEditor" }; scriptingParams.ScriptOptions = new ScriptOptions { ScriptCreateDrop = scriptCreateDrop, }; scriptingParams.ScriptingObjects = new List <ScriptingObject> { scriptingObject }; ScriptingService service = new ScriptingService(); await service.HandleScriptingScriptAsRequest(scriptingParams, requestContext.Object); Thread.Sleep(2000); await service.ScriptingTask; requestContext.Verify(x => x.SendResult(It.Is <ScriptingResult>(r => VerifyScriptingResult(r, expectedScript)))); connectionService.Disconnect(new ServiceLayer.Connection.Contracts.DisconnectParams { OwnerUri = queryTempFile.FilePath }); } } catch { throw; } finally { await testDb.CleanupAsync(); } }
/// <summary> /// Redirects the connection to the details in /// the <see cref="ConnectionDetails"/> model. /// </summary> public void Redirect() { //absolutely critical that the encryption be uninitialaized CryptoInitializer.DecryptionInitializable.Uninitialize(); CryptoInitializer.EncryptionInitializable.Uninitialize(); //We actually DO want to block everything until we connect. ConnectionService.Disconnect(); //Just create a new client GameObjectFactory.Create(NetworkClientPrefab) .GetComponent <GameNetworkClient>() .StartConnection(); }
public void RunningMultipleQueriesCreatesOnlyOneConnection() { // Connect/disconnect twice to ensure reconnection can occur ConnectionService service = ConnectionService.Instance; service.OwnerToConnectionMap.Clear(); for (int i = 0; i < 2; i++) { var result = LiveConnectionHelper.InitLiveConnectionInfo(); ConnectionInfo connectionInfo = result.ConnectionInfo; string uri = connectionInfo.OwnerUri; // We should see one ConnectionInfo and one DbConnection Assert.Equal(1, connectionInfo.CountConnections); Assert.Equal(1, service.OwnerToConnectionMap.Count); // If we run a query var fileStreamFactory = MemoryFileSystem.GetFileStreamFactory(); Query query = new Query(Constants.StandardQuery, connectionInfo, new QueryExecutionSettings(), fileStreamFactory); query.Execute(); query.ExecutionTask.Wait(); // We should see two DbConnections Assert.Equal(2, connectionInfo.CountConnections); // If we run another query query = new Query(Constants.StandardQuery, connectionInfo, new QueryExecutionSettings(), fileStreamFactory); query.Execute(); query.ExecutionTask.Wait(); // We should still have 2 DbConnections Assert.Equal(2, connectionInfo.CountConnections); // If we disconnect, we should remain in a consistent state to do it over again // e.g. loop and do it over again service.Disconnect(new DisconnectParams() { OwnerUri = connectionInfo.OwnerUri }); // We should be left with an empty connection map Assert.Equal(0, service.OwnerToConnectionMap.Count); } }
public async void RestoreShouldCloseOtherConnectionsBeforeExecuting() { await GetBackupFilesToRecoverDatabaseCreated(); var testDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, null, "RestoreTest"); ConnectionService connectionService = LiveConnectionHelper.GetLiveTestConnectionService(); TestConnectionResult connectionResult; using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { //OE connection will be closed after conneced connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync(testDb.DatabaseName, queryTempFile.FilePath, ConnectionType.ObjectExplorer); //Opening a connection to db to lock the db connectionService.ConnectionQueue.AddConnectionContext(connectionResult.ConnectionInfo, "", true); try { Dictionary <string, object> options = new Dictionary <string, object>(); options.Add(RestoreOptionsHelper.ReplaceDatabase, true); await VerifyRestore(null, databaseNameToRestoreFrom, true, TaskExecutionModeFlag.Execute, testDb.DatabaseName, null, options , (database) => { return(database.Tables.Contains("tb1", "test")); }); } finally { connectionService.Disconnect(new ServiceLayer.Connection.Contracts.DisconnectParams { OwnerUri = queryTempFile.FilePath, Type = ConnectionType.Default }); testDb.Cleanup(); } } }
private async Task VerifyMetadataListCore(string query, List <ObjectMetadata> expectedMetadataList) { var testDb = await SqlTestDb.CreateNewAsync(TestServerType.OnPrem, false, null, query, "MetadataTests"); try { var requestContext = new Mock <RequestContext <MetadataQueryResult> >(); requestContext.Setup(x => x.SendResult(It.IsAny <MetadataQueryResult>())).Returns(Task.FromResult(new object())); ConnectionService connectionService = LiveConnectionHelper.GetLiveTestConnectionService(); using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { //Opening a connection to db to lock the db TestConnectionResult connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync(testDb.DatabaseName, queryTempFile.FilePath, ConnectionType.Default); MetadataService service = new MetadataService(); await service.HandleMetadataListRequest(new MetadataQueryParams { OwnerUri = queryTempFile.FilePath }, requestContext.Object); Thread.Sleep(2000); await service.MetadataListTask; requestContext.Verify(x => x.SendResult(It.Is <MetadataQueryResult>(r => VerifyResult(r, expectedMetadataList)))); connectionService.Disconnect(new ServiceLayer.Connection.Contracts.DisconnectParams { OwnerUri = queryTempFile.FilePath }); } } catch { throw; } finally { await testDb.CleanupAsync(); } }
/// <summary> /// Handles a request to execute a string and return the result /// </summary> internal async Task HandleSimpleExecuteRequest(SimpleExecuteParams executeParams, RequestContext <SimpleExecuteResult> requestContext) { try { string randomUri = Guid.NewGuid().ToString(); ExecuteStringParams executeStringParams = new ExecuteStringParams { Query = executeParams.QueryString, // generate guid as the owner uri to make sure every query is unique OwnerUri = randomUri }; // get connection ConnectionInfo connInfo; if (!ConnectionService.TryFindConnection(executeParams.OwnerUri, out connInfo)) { await requestContext.SendError(SR.QueryServiceQueryInvalidOwnerUri); return; } ConnectParams connectParams = new ConnectParams { OwnerUri = randomUri, Connection = connInfo.ConnectionDetails, Type = ConnectionType.Default }; Task workTask = Task.Run(async() => { await ConnectionService.Connect(connectParams); ConnectionInfo newConn; ConnectionService.TryFindConnection(randomUri, out newConn); Func <string, Task> queryCreateFailureAction = message => requestContext.SendError(message); ResultOnlyContext <SimpleExecuteResult> newContext = new ResultOnlyContext <SimpleExecuteResult>(requestContext); // handle sending event back when the query completes Query.QueryAsyncEventHandler queryComplete = async query => { try { // check to make sure any results were recieved if (query.Batches.Length == 0 || query.Batches[0].ResultSets.Count == 0) { await requestContext.SendError(SR.QueryServiceResultSetHasNoResults); return; } long rowCount = query.Batches[0].ResultSets[0].RowCount; // check to make sure there is a safe amount of rows to load into memory if (rowCount > Int32.MaxValue) { await requestContext.SendError(SR.QueryServiceResultSetTooLarge); return; } SimpleExecuteResult result = new SimpleExecuteResult { RowCount = rowCount, ColumnInfo = query.Batches[0].ResultSets[0].Columns, Rows = new DbCellValue[0][] }; if (rowCount > 0) { SubsetParams subsetRequestParams = new SubsetParams { OwnerUri = randomUri, BatchIndex = 0, ResultSetIndex = 0, RowsStartIndex = 0, RowsCount = Convert.ToInt32(rowCount) }; // get the data to send back ResultSetSubset subset = await InterServiceResultSubset(subsetRequestParams); result.Rows = subset.Rows; } await requestContext.SendResult(result); } finally { Query removedQuery; Task removedTask; // remove the active query since we are done with it ActiveQueries.TryRemove(randomUri, out removedQuery); ActiveSimpleExecuteRequests.TryRemove(randomUri, out removedTask); ConnectionService.Disconnect(new DisconnectParams() { OwnerUri = randomUri, Type = null }); } }; // handle sending error back when query fails Query.QueryAsyncErrorEventHandler queryFail = async(q, e) => { await requestContext.SendError(e); }; await InterServiceExecuteQuery(executeStringParams, newConn, newContext, null, queryCreateFailureAction, queryComplete, queryFail); }); ActiveSimpleExecuteRequests.TryAdd(randomUri, workTask); } catch (Exception ex) { await requestContext.SendError(ex.ToString()); } }
public void CanCancelConnectRequestByDisconnecting() { var testFile = "file:///my/test/file.sql"; // Given a connection that times out and responds to cancellation var mockConnection = new Mock <DbConnection> { CallBase = true }; CancellationToken token; bool ready = false; mockConnection.Setup(x => x.OpenAsync(Moq.It.IsAny <CancellationToken>())) .Callback <CancellationToken>(t => { // Pass the token to the return handler and signal the main thread to cancel token = t; ready = true; }) .Returns(() => { if (TestUtils.WaitFor(() => token.IsCancellationRequested)) { throw new OperationCanceledException(); } else { return(Task.FromResult(true)); } }); var mockFactory = new Mock <ISqlConnectionFactory>(); mockFactory.Setup(factory => factory.CreateSqlConnection(It.IsAny <string>())) .Returns(mockConnection.Object); var connectionService = new ConnectionService(mockFactory.Object); // Connect the first connection asynchronously in a background thread var connectionDetails = TestObjects.GetTestConnectionDetails(); var connectTask = Task.Run(async() => { return(await connectionService .Connect(new ConnectParams() { OwnerUri = testFile, Connection = connectionDetails })); }); // Wait for the connection to call OpenAsync() Assert.True(TestUtils.WaitFor(() => ready)); // Send a cancellation by trying to disconnect var disconnectResult = connectionService .Disconnect(new DisconnectParams() { OwnerUri = testFile }); // Wait for the first connection task to finish connectTask.Wait(); // Verify that the first connection was cancelled (no connection was created) Assert.Null(connectTask.Result.ConnectionId); // Verify that the disconnect failed (since it caused a cancellation) Assert.False(disconnectResult); }
/// <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); }