Skip to content

Commit

Permalink
added restore options (#423)
Browse files Browse the repository at this point in the history
* added restore options
  • Loading branch information
llali authored Jul 28, 2017
1 parent e1395cb commit e453a19
Show file tree
Hide file tree
Showing 15 changed files with 505 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.SqlTools.Hosting.Hosting.Contracts;

namespace Microsoft.SqlTools.Hosting.Contracts
{
/// <summary>
Expand All @@ -19,5 +21,10 @@ public class DmpServerCapabilities
public ConnectionProviderOptions ConnectionProvider { get; set; }

public AdminServicesProviderOptions AdminServicesProvider { get; set; }

/// <summary>
/// List of features
/// </summary>
public FeatureMetadataProvider[] Features { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

using Microsoft.SqlTools.Hosting.Contracts;

namespace Microsoft.SqlTools.Hosting.Hosting.Contracts
{
/// <summary>
/// Includes the metadata for a feature
/// </summary>
public class FeatureMetadataProvider
{
/// <summary>
/// Indicates whether the feature is enabled
/// </summary>
public bool Enabled { get; set; }

/// <summary>
/// Feature name
/// </summary>
public string FeatureName { get; set; }

/// <summary>
/// The options metadata avaialble for this feature
/// </summary>
public ServiceOption[] OptionsMetadata { get; set; }

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public DatabaseFileInfo(LocalizedPropertyInfo[] properties)
var idProperty = this.Properties.FirstOrDefault(x => x.PropertyName == IdPropertyName);
Id = idProperty == null || idProperty.PropertyValue == null ? string.Empty : idProperty.PropertyValue.ToString();
}
IsSelected = true;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.Contracts
/// </summary>
public class RestoreParams : GeneralRequestDetails
{
public string SessionId
/// <summary>
/// Restore session id. The parameter is optional and if passed, an existing plan will be used
/// </summary>
internal string SessionId
{
get
{
return GetOptionValue<string>("sessionId");
return GetOptionValue<string>(RestoreOptionsHelper.SessionId);
}
set
{
SetOptionValue("sessionId", value);
SetOptionValue(RestoreOptionsHelper.SessionId, value);
}
}

Expand All @@ -34,75 +37,75 @@ public string SessionId
/// <summary>
/// Comma delimited list of backup files
/// </summary>
public string BackupFilePaths
internal string BackupFilePaths
{
get
{
return GetOptionValue<string>("backupFilePaths");
return GetOptionValue<string>(RestoreOptionsHelper.BackupFilePaths);
}
set
{
SetOptionValue("backupFilePaths", value);
SetOptionValue(RestoreOptionsHelper.BackupFilePaths, value);
}
}

/// <summary>
/// Target Database name to restore to
/// </summary>
public string TargetDatabaseName
internal string TargetDatabaseName
{
get
{
return GetOptionValue<string>("targetDatabaseName");
return GetOptionValue<string>(RestoreOptionsHelper.TargetDatabaseName);
}
set
{
SetOptionValue("targetDatabaseName", value);
SetOptionValue(RestoreOptionsHelper.TargetDatabaseName, value);
}
}

/// <summary>
/// Source Database name to restore from
/// </summary>
public string SourceDatabaseName
internal string SourceDatabaseName
{
get
{
return GetOptionValue<string>("sourceDatabaseName");
return GetOptionValue<string>(RestoreOptionsHelper.SourceDatabaseName);
}
set
{
SetOptionValue("sourceDatabaseName", value);
SetOptionValue(RestoreOptionsHelper.SourceDatabaseName, value);
}
}

/// <summary>
/// If set to true, the db files will be relocated to default data location in the server
/// </summary>
public bool RelocateDbFiles
internal bool RelocateDbFiles
{
get
{
return GetOptionValue<bool>("relocateDbFiles");
return GetOptionValue<bool>(RestoreOptionsHelper.RelocateDbFiles);
}
set
{
SetOptionValue("relocateDbFiles", value);
SetOptionValue(RestoreOptionsHelper.RelocateDbFiles, value);
}
}

/// <summary>
/// Ids of the backup set to restore
/// </summary>
public string[] SelectedBackupSets
internal string[] SelectedBackupSets
{
get
{
return GetOptionValue<string[]>("selectedBackupSets");
return GetOptionValue<string[]>(RestoreOptionsHelper.SelectedBackupSets);
}
set
{
SetOptionValue("selectedBackupSets", value);
SetOptionValue(RestoreOptionsHelper.SelectedBackupSets, value);
}
}
}
Expand Down Expand Up @@ -160,8 +163,15 @@ public class RestoreDatabaseFileInfo
/// </summary>
public class RestorePlanResponse
{
public string RestoreSessionId { get; set; }
/// <summary>
/// Restore session id, can be used in restore request to use an existing restore plan
/// </summary>
public string SessionId { get; set; }


/// <summary>
/// The list of backup sets to restore
/// </summary>
public DatabaseFileInfo[] BackupSetsToRestore { get; set; }

/// <summary>
Expand All @@ -185,30 +195,14 @@ public class RestorePlanResponse
public string[] DatabaseNamesFromBackupSets { get; set; }

/// <summary>
/// Server name
/// </summary>
public string ServerName { get; set; }

/// <summary>
/// Database name to restore to
/// </summary>
public string DatabaseName { get; set; }

/// <summary>
/// Indicates whether relocating the db files is required
/// because the original file paths are not valid in the target server
/// </summary>
public bool RelocateFilesNeeded { get; set; }

/// <summary>
/// Default Data folder path in the target server
/// For testing purpose to verify the target database
/// </summary>
public string DefaultDataFolder { get; set; }
internal string DatabaseName { get; set; }

/// <summary>
/// Default log folder path in the target server
/// Plan details
/// </summary>
public string DefaultLogFolder { get; set; }
public Dictionary<string, object> PlanDetails { get; set; }
}

public class RestoreRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DisasterRecovery.RestoreOperation
/// </summary>
public class RestoreDatabaseHelper
{

public const string LastBackupTaken = "lastBackupTaken";
private static RestoreDatabaseHelper instance = new RestoreDatabaseHelper();
private ConcurrentDictionary<string, RestoreDatabaseTaskDataObject> restoreSessions = new ConcurrentDictionary<string, RestoreDatabaseTaskDataObject>();

Expand Down Expand Up @@ -152,7 +152,8 @@ public RestorePlanResponse CreateRestorePlanResponse(RestoreDatabaseTaskDataObje
{
RestorePlanResponse response = new RestorePlanResponse()
{
DatabaseName = restoreDataObject.RestoreParams.TargetDatabaseName
DatabaseName = restoreDataObject.RestoreParams.TargetDatabaseName,
PlanDetails = new System.Collections.Generic.Dictionary<string, object>()
};
try
{
Expand All @@ -162,7 +163,7 @@ public RestorePlanResponse CreateRestorePlanResponse(RestoreDatabaseTaskDataObje

if (restoreDataObject != null && restoreDataObject.IsValid)
{
response.RestoreSessionId = restoreDataObject.SessionId;
response.SessionId = restoreDataObject.SessionId;
response.DatabaseName = restoreDataObject.TargetDatabase;
response.DbFiles = restoreDataObject.DbFiles.Select(x => new RestoreDatabaseFileInfo
{
Expand All @@ -178,12 +179,25 @@ public RestorePlanResponse CreateRestorePlanResponse(RestoreDatabaseTaskDataObje
response.ErrorMessage = SR.RestoreNotSupported;
}

response.PlanDetails.Add(LastBackupTaken, restoreDataObject.GetLastBackupTaken());

response.BackupSetsToRestore = restoreDataObject.GetBackupSetInfo().Select(x => new DatabaseFileInfo(x.ConvertPropertiesToArray())).ToArray();
var dbNames = restoreDataObject.GetSourceDbNames();
response.DatabaseNamesFromBackupSets = dbNames == null ? new string[] { } : dbNames.ToArray();
response.RelocateFilesNeeded = !restoreDataObject.DbFilesLocationAreValid();
response.DefaultDataFolder = restoreDataObject.DefaultDataFileFolder;
response.DefaultLogFolder = restoreDataObject.DefaultLogFileFolder;

// Adding the default values for some of the options in the plan details
bool isTailLogBackupPossible = restoreDataObject.IsTailLogBackupPossible(restoreDataObject.RestorePlanner.DatabaseName);
// Default backup tail-log. It's true when tail-log backup is possible for the source database
response.PlanDetails.Add(RestoreOptionsHelper.DefaultBackupTailLog, isTailLogBackupPossible);
// Default backup file for tail-log bacup when Tail-Log bachup is set to true
response.PlanDetails.Add(RestoreOptionsHelper.DefaultTailLogBackupFile,
restoreDataObject.Util.GetDefaultTailLogbackupFile(restoreDataObject.RestorePlan.DatabaseName));
// Default stand by file path for when RESTORE WITH STANDBY is selected
response.PlanDetails.Add(RestoreOptionsHelper.DefaultStandbyFile, restoreDataObject.Util.GetDefaultStandbyFile(restoreDataObject.RestorePlan.DatabaseName));
// Default Data folder path in the target server
response.PlanDetails.Add(RestoreOptionsHelper.DefaultDataFileFolder, restoreDataObject.DefaultDataFileFolder);
// Default log folder path in the target server
response.PlanDetails.Add(RestoreOptionsHelper.DefaultLogFileFolder, restoreDataObject.DefaultLogFileFolder);
}
else
{
Expand Down Expand Up @@ -314,12 +328,29 @@ private void UpdateRestorePlan(RestoreDatabaseTaskDataObject restoreDataObject)
restoreDataObject.RestorePlanner.DatabaseName = restoreDataObject.RestoreParams.SourceDatabaseName;
}
restoreDataObject.TargetDatabase = restoreDataObject.RestoreParams.TargetDatabaseName;
//TODO: used for other types of restore
/*bool isTailLogBackupPossible = restoreDataObject.RestorePlanner.IsTailLogBackupPossible(restoreDataObject.RestorePlanner.DatabaseName);
restoreDataObject.RestorePlanner.BackupTailLog = isTailLogBackupPossible;
restoreDataObject.TailLogBackupFile = restoreDataObject.Util.GetDefaultTailLogbackupFile(dbName);
restoreDataObject.RestorePlanner.TailLogBackupFile = restoreDataObject.TailLogBackupFile;
*/

restoreDataObject.RestoreOptions.KeepReplication = restoreDataObject.RestoreParams.GetOptionValue<bool>(RestoreOptionsHelper.KeepReplication);
restoreDataObject.RestoreOptions.ReplaceDatabase = restoreDataObject.RestoreParams.GetOptionValue<bool>(RestoreOptionsHelper.ReplaceDatabase);
restoreDataObject.RestoreOptions.SetRestrictedUser = restoreDataObject.RestoreParams.GetOptionValue<bool>(RestoreOptionsHelper.SetRestrictedUser);
string recoveryState = restoreDataObject.RestoreParams.GetOptionValue<string>(RestoreOptionsHelper.RecoveryState);
object databaseRecoveryState;
if (Enum.TryParse(typeof(DatabaseRecoveryState), recoveryState, out databaseRecoveryState))
{
restoreDataObject.RestoreOptions.RecoveryState = (DatabaseRecoveryState)databaseRecoveryState;
}
bool isTailLogBackupPossible = restoreDataObject.IsTailLogBackupPossible(restoreDataObject.RestorePlanner.DatabaseName);
if (isTailLogBackupPossible)
{
restoreDataObject.RestorePlanner.BackupTailLog = restoreDataObject.RestoreParams.GetOptionValue<bool>(RestoreOptionsHelper.BackupTailLog);
restoreDataObject.TailLogBackupFile = restoreDataObject.RestoreParams.GetOptionValue<string>(RestoreOptionsHelper.TailLogBackupFile);
restoreDataObject.TailLogWithNoRecovery = restoreDataObject.RestoreParams.GetOptionValue<bool>(RestoreOptionsHelper.TailLogWithNoRecovery);
}
else
{
restoreDataObject.RestorePlanner.BackupTailLog = false;
}

restoreDataObject.CloseExistingConnections = restoreDataObject.RestoreParams.GetOptionValue<bool>(RestoreOptionsHelper.CloseExistingConnections);

restoreDataObject.UpdateRestorePlan(restoreDataObject.RestoreParams.RelocateDbFiles);
}
Expand All @@ -340,6 +371,8 @@ public void ExecuteRestore(RestoreDatabaseTaskDataObject restoreDataObject, SqlT
{
restoreDataObject.SqlTask = sqlTask;
restoreDataObject.Execute();
RestoreDatabaseTaskDataObject cachedRestoreDataObject;
this.restoreSessions.TryRemove(restoreDataObject.SessionId, out cachedRestoreDataObject);
}
catch(Exception ex)
{
Expand Down
Loading

0 comments on commit e453a19

Please sign in to comment.