//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using System.Xml;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Admin.Contracts;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Hosting;
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Admin
{
///
/// Admin task service class
///
public class AdminService
{
private static readonly Lazy instance = new Lazy(() => new AdminService());
private static ConnectionService connectionService = null;
private static readonly ConcurrentDictionary serverTaskHelperMap =
new ConcurrentDictionary();
///
/// Default, parameterless constructor.
///
internal AdminService()
{
}
///
/// Internal for testing purposes only
///
internal static ConnectionService ConnectionServiceInstance
{
get
{
if (AdminService.connectionService == null)
{
AdminService.connectionService = ConnectionService.Instance;
}
return AdminService.connectionService;
}
set
{
AdminService.connectionService = value;
}
}
///
/// Gets the singleton instance object
///
public static AdminService Instance
{
get { return instance.Value; }
}
///
/// Initializes the service instance
///
public void InitializeService(ServiceHost serviceHost)
{
serviceHost.SetRequestHandler(CreateDatabaseRequest.Type, HandleCreateDatabaseRequest);
serviceHost.SetRequestHandler(CreateLoginRequest.Type, HandleCreateLoginRequest);
serviceHost.SetRequestHandler(DefaultDatabaseInfoRequest.Type, HandleDefaultDatabaseInfoRequest);
serviceHost.SetRequestHandler(GetDatabaseInfoRequest.Type, HandleGetDatabaseInfoRequest);
}
///
/// Handle a request for the default database prototype info
///
public static async Task HandleDefaultDatabaseInfoRequest(
DefaultDatabaseInfoParams optionsParams,
RequestContext requestContext)
{
try
{
var response = new DefaultDatabaseInfoResponse();
ConnectionInfo connInfo;
AdminService.ConnectionServiceInstance.TryFindConnection(
optionsParams.OwnerUri,
out connInfo);
using (var taskHelper = CreateDatabaseTaskHelper(connInfo))
{
response.DefaultDatabaseInfo = DatabaseTaskHelper.DatabasePrototypeToDatabaseInfo(taskHelper.Prototype);
await requestContext.SendResult(response);
}
}
catch (Exception ex)
{
await requestContext.SendError(ex.ToString());
}
}
///
/// Handles a create database request
///
internal static async Task HandleCreateDatabaseRequest(
CreateDatabaseParams databaseParams,
RequestContext requestContext)
{
try
{
var response = new DefaultDatabaseInfoResponse();
ConnectionInfo connInfo;
AdminService.ConnectionServiceInstance.TryFindConnection(
databaseParams.OwnerUri,
out connInfo);
using (var taskHelper = CreateDatabaseTaskHelper(connInfo))
{
DatabasePrototype prototype = taskHelper.Prototype;
DatabaseTaskHelper.ApplyToPrototype(databaseParams.DatabaseInfo, taskHelper.Prototype);
Database db = prototype.ApplyChanges();
await requestContext.SendResult(new CreateDatabaseResponse()
{
Result = true,
TaskId = 0
});
}
}
catch (Exception ex)
{
await requestContext.SendError(ex.ToString());
}
}
///
/// Handle get database info request
///
internal static async Task HandleGetDatabaseInfoRequest(
GetDatabaseInfoParams databaseParams,
RequestContext requestContext)
{
try
{
Func requestHandler = async () =>
{
ConnectionInfo connInfo;
AdminService.ConnectionServiceInstance.TryFindConnection(
databaseParams.OwnerUri,
out connInfo);
DatabaseInfo info = null;
if (connInfo != null)
{
info = GetDatabaseInfo(connInfo);
}
await requestContext.SendResult(new GetDatabaseInfoResponse()
{
DatabaseInfo = info
});
};
Task task = Task.Run(async () => await requestHandler()).ContinueWithOnFaulted(async t =>
{
await requestContext.SendError(t.Exception.ToString());
});
}
catch (Exception ex)
{
await requestContext.SendError(ex.ToString());
}
}
///
/// Return database info for a specific database
///
///
///
internal static DatabaseInfo GetDatabaseInfo(ConnectionInfo connInfo)
{
using (DatabaseTaskHelper taskHelper = CreateDatabaseTaskHelper(connInfo, true))
{
return DatabaseTaskHelper.DatabasePrototypeToDatabaseInfo(taskHelper.Prototype);
}
}
///
/// Create database task helper
///
/// connection info
/// flag indicating whether to create taskhelper for existing database or not
///
internal static DatabaseTaskHelper CreateDatabaseTaskHelper(ConnectionInfo connInfo, bool databaseExists = false)
{
var dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists);
var taskHelper = new DatabaseTaskHelper(dataContainer);
return taskHelper;
}
///
/// Handles a create login request
///
internal static async Task HandleCreateLoginRequest(
CreateLoginParams loginParams,
RequestContext requestContext)
{
await requestContext.SendResult(new CreateLoginResponse());
}
}
}