Feature/restore db (#403)

* Added service handlers for restore database operations
This commit is contained in:
Leila Lali
2017-07-10 17:28:57 -07:00
committed by GitHub
parent dd8f600bd4
commit 05775a6089
30 changed files with 2451 additions and 144 deletions

View File

@@ -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();