mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-17 17:23:48 -05:00
Feature/restore db (#403)
* Added service handlers for restore database operations
This commit is contained in:
@@ -13,6 +13,9 @@ using Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||
using Microsoft.SqlTools.ServiceLayer.TaskServices;
|
||||
using System.Threading;
|
||||
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
||||
{
|
||||
@@ -23,6 +26,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
||||
{
|
||||
private static readonly Lazy<DisasterRecoveryService> instance = new Lazy<DisasterRecoveryService>(() => new DisasterRecoveryService());
|
||||
private static ConnectionService connectionService = null;
|
||||
private RestoreDatabaseHelper restoreDatabaseService = new RestoreDatabaseHelper();
|
||||
|
||||
/// <summary>
|
||||
/// Default, parameterless constructor.
|
||||
@@ -61,12 +65,17 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
||||
/// <summary>
|
||||
/// Initializes the service instance
|
||||
/// </summary>
|
||||
public void InitializeService(ServiceHost serviceHost)
|
||||
public void InitializeService(IProtocolEndpoint serviceHost)
|
||||
{
|
||||
// Get database info
|
||||
serviceHost.SetRequestHandler(BackupConfigInfoRequest.Type, HandleBackupConfigInfoRequest);
|
||||
// Create backup
|
||||
serviceHost.SetRequestHandler(BackupRequest.Type, HandleBackupRequest);
|
||||
|
||||
// Create respore task
|
||||
serviceHost.SetRequestHandler(RestoreRequest.Type, HandleRestoreRequest);
|
||||
// Create respore plan
|
||||
serviceHost.SetRequestHandler(RestorePlanRequest.Type, HandleRestorePlanRequest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -100,6 +109,81 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
||||
await requestContext.SendResult(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles a restore request
|
||||
/// </summary>
|
||||
internal async Task HandleRestorePlanRequest(
|
||||
RestoreParams restoreParams,
|
||||
RequestContext<RestorePlanResponse> requestContext)
|
||||
{
|
||||
RestorePlanResponse response = new RestorePlanResponse();
|
||||
ConnectionInfo connInfo;
|
||||
bool supported = IsBackupRestoreOperationSupported(restoreParams, out connInfo);
|
||||
|
||||
if (supported && connInfo != null)
|
||||
{
|
||||
RestoreDatabaseTaskDataObject restoreDataObject = this.restoreDatabaseService.CreateRestoreDatabaseTaskDataObject(restoreParams);
|
||||
response = this.restoreDatabaseService.CreateRestorePlanResponse(restoreDataObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.CanRestore = false;
|
||||
response.ErrorMessage = "Restore is not supported"; //TOOD: have a better error message
|
||||
}
|
||||
await requestContext.SendResult(response);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles a restore request
|
||||
/// </summary>
|
||||
internal async Task HandleRestoreRequest(
|
||||
RestoreParams restoreParams,
|
||||
RequestContext<RestoreResponse> requestContext)
|
||||
{
|
||||
RestoreResponse response = new RestoreResponse();
|
||||
ConnectionInfo connInfo;
|
||||
bool supported = IsBackupRestoreOperationSupported(restoreParams, out connInfo);
|
||||
|
||||
if (supported && connInfo != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
RestoreDatabaseTaskDataObject restoreDataObject = this.restoreDatabaseService.CreateRestoreDatabaseTaskDataObject(restoreParams);
|
||||
|
||||
if (restoreDataObject != null)
|
||||
{
|
||||
// create task metadata
|
||||
TaskMetadata metadata = new TaskMetadata();
|
||||
metadata.ServerName = connInfo.ConnectionDetails.ServerName;
|
||||
metadata.DatabaseName = connInfo.ConnectionDetails.DatabaseName;
|
||||
metadata.Name = SR.Backup_TaskName;
|
||||
metadata.IsCancelable = true;
|
||||
metadata.Data = restoreDataObject;
|
||||
|
||||
|
||||
// create restore task and perform
|
||||
SqlTask sqlTask = SqlTaskManager.Instance.CreateAndRun(metadata, this.restoreDatabaseService.RestoreTaskAsync, restoreDatabaseService.CancelTaskAsync);
|
||||
response.TaskId = sqlTask.TaskId.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
response.ErrorMessage = "Failed to create restore task";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
response.ErrorMessage = ex.Message;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
response.ErrorMessage = "Restore database is not supported"; //TOOD: have a better error message
|
||||
}
|
||||
|
||||
await requestContext.SendResult(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles a backup request
|
||||
/// </summary>
|
||||
@@ -163,6 +247,37 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool IsBackupRestoreOperationSupported(RestoreParams restoreParams, out ConnectionInfo connectionInfo)
|
||||
{
|
||||
SqlConnection sqlConn = null;
|
||||
try
|
||||
{
|
||||
ConnectionInfo connInfo;
|
||||
DisasterRecoveryService.ConnectionServiceInstance.TryFindConnection(
|
||||
restoreParams.OwnerUri,
|
||||
out connInfo);
|
||||
|
||||
if (connInfo != null)
|
||||
{
|
||||
sqlConn = GetSqlConnection(connInfo);
|
||||
if ((sqlConn != null) && !connInfo.IsSqlDW && !connInfo.IsAzure)
|
||||
{
|
||||
connectionInfo = connInfo;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if(sqlConn != null)
|
||||
{
|
||||
sqlConn.Close();
|
||||
}
|
||||
}
|
||||
connectionInfo = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
internal BackupConfigInfo GetBackupConfigInfo(CDataContainer dataContainer, SqlConnection sqlConnection, string databaseName)
|
||||
{
|
||||
BackupOperation backupOperation = new BackupOperation();
|
||||
|
||||
Reference in New Issue
Block a user