mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-13 17:23:02 -05:00
Feature/cms backend (#776)
* First cut of CMS get Server Api - returns only names * Adding Proper naming and some more functions * Adding add remove Server and tests for it * Changing relative path to derive from KeyChain.Urn and Nuget update * Adding async thread for requests * Addressing CR comments and adding one more test * Adressed PR comments around naming
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||||
<SmoPackageVersion>150.18040.0-preview</SmoPackageVersion>
|
<SmoPackageVersion>150.18085.0-preview</SmoPackageVersion>
|
||||||
<HighEntropyVA>true</HighEntropyVA>
|
<HighEntropyVA>true</HighEntropyVA>
|
||||||
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration >
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<clear />
|
<clear />
|
||||||
<add key="Nuget Preview" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
|
<add key="Nuget Preview" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
|
||||||
<add key="Nuget" value="https://www.nuget.org/api/v2" />
|
<add key="Nuget" value="https://www.nuget.org/api/v2" />
|
||||||
<add key="DataTools Nuget" value="./bin/nuget" />
|
<add key="DataTools Nuget" value="./bin/nuget" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<Import Project="../../Common.props" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
@@ -8,7 +9,7 @@
|
|||||||
<Folder Include="Localization\transXliff\" />
|
<Folder Include="Localization\transXliff\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.SqlServer.SqlManagementObjects" Version="150.18040.0-preview" />
|
<PackageReference Include="Microsoft.SqlServer.SqlManagementObjects" Version="$(SmoPackageVersion)" />
|
||||||
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
|
<PackageReference Include="System.Data.SqlClient" Version="4.6.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
410
src/Microsoft.SqlTools.ServiceLayer/Cms/CmsService.cs
Normal file
410
src/Microsoft.SqlTools.ServiceLayer/Cms/CmsService.cs
Normal file
@@ -0,0 +1,410 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
using Microsoft.SqlServer.Management.Common;
|
||||||
|
using Microsoft.SqlServer.Management.RegisteredServers;
|
||||||
|
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||||
|
using Microsoft.SqlTools.Hosting.Protocol;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Cms.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||||
|
using Microsoft.SqlTools.Utility;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.Cms
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Main class for CmsService
|
||||||
|
/// </summary>
|
||||||
|
public class CmsService
|
||||||
|
{
|
||||||
|
private static ConnectionService connectionService = null;
|
||||||
|
private static readonly Lazy<CmsService> instance = new Lazy<CmsService>(() => new CmsService());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the singleton instance object
|
||||||
|
/// </summary>
|
||||||
|
public static CmsService Instance
|
||||||
|
{
|
||||||
|
get { return instance.Value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Public methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the service instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="serviceHost"></param>
|
||||||
|
public void InitializeService(ServiceHost serviceHost)
|
||||||
|
{
|
||||||
|
serviceHost.SetRequestHandler(CreateCentralManagementServerRequest.Type, this.HandleCreateCentralManagementServerRequest);
|
||||||
|
serviceHost.SetRequestHandler(ListRegisteredServersRequest.Type, this.HandleListRegisteredServersRequest);
|
||||||
|
serviceHost.SetRequestHandler(AddRegisteredServerRequest.Type, this.HandleAddRegisteredServerRequest);
|
||||||
|
serviceHost.SetRequestHandler(RemoveRegisteredServerRequest.Type, this.HandleRemoveRegisteredServerRequest);
|
||||||
|
serviceHost.SetRequestHandler(AddServerGroupRequest.Type, this.HandleAddServerGroupRequest);
|
||||||
|
serviceHost.SetRequestHandler(RemoveServerGroupRequest.Type, this.HandleRemoveServerGroupRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HandleCreateCentralManagementServerRequest(CreateCentralManagementServerParams createCmsParams, RequestContext<ListRegisteredServersResult> requestContext)
|
||||||
|
{
|
||||||
|
Logger.Write(TraceEventType.Verbose, "HandleCreateCentralManagementServerRequest");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CmsTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Validate params and connect
|
||||||
|
ServerConnection conn = await ValidateAndCreateConnection(createCmsParams.ConnectParams);
|
||||||
|
|
||||||
|
// Get Current Reg Servers on CMS
|
||||||
|
RegisteredServersStore store = new RegisteredServersStore(conn);
|
||||||
|
ServerGroup parentGroup = store.DatabaseEngineServerGroup;
|
||||||
|
ListRegisteredServersResult result = GetChildrenfromParentGroup(parentGroup);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
await requestContext.SendResult(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Exception related to connection/creation will only be caught here. Note that the outer catch will not catch them
|
||||||
|
await requestContext.SendError(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// Exception related to run task will be captured here
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HandleAddRegisteredServerRequest(AddRegisteredServerParams cmsCreateParams, RequestContext<bool> requestContext)
|
||||||
|
{
|
||||||
|
Logger.Write(TraceEventType.Verbose, "HandleAddRegisteredServerRequest");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CmsTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ServerConnection serverConn = ValidateAndCreateConnection(cmsCreateParams.ParentOwnerUri);
|
||||||
|
if (serverConn != null)
|
||||||
|
{
|
||||||
|
// Get Current Reg Servers
|
||||||
|
RegisteredServersStore store = new RegisteredServersStore(serverConn);
|
||||||
|
ServerGroup parentGroup = NavigateToServerGroup(store, cmsCreateParams.RelativePath);
|
||||||
|
RegisteredServerCollection servers = parentGroup.RegisteredServers;
|
||||||
|
|
||||||
|
// Add the new server (intentionally not cheching existence to reuse the exception message)
|
||||||
|
RegisteredServer registeredServer = new RegisteredServer(parentGroup, cmsCreateParams.RegisteredServerName);
|
||||||
|
if (cmsCreateParams.RegisteredServerConnectionDetails != null)
|
||||||
|
{
|
||||||
|
registeredServer.ServerName = cmsCreateParams.RegisteredServerConnectionDetails.ServerName;
|
||||||
|
registeredServer.Description = cmsCreateParams.RegisteredServerDescription;
|
||||||
|
registeredServer.ConnectionString = ConnectionService.CreateConnectionStringBuilder(cmsCreateParams.RegisteredServerConnectionDetails).ToString();
|
||||||
|
}
|
||||||
|
registeredServer.Description = cmsCreateParams.RegisteredServerDescription;
|
||||||
|
registeredServer.Create();
|
||||||
|
await requestContext.SendResult(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await requestContext.SendResult(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HandleListRegisteredServersRequest(ListRegisteredServerParams listServerParams, RequestContext<ListRegisteredServersResult> requestContext)
|
||||||
|
{
|
||||||
|
Logger.Write(TraceEventType.Verbose, "HandleListRegisteredServersRequest");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CmsTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//Validate and create connection
|
||||||
|
ServerConnection serverConn = ValidateAndCreateConnection(listServerParams.ParentOwnerUri);
|
||||||
|
|
||||||
|
if (serverConn != null)
|
||||||
|
{
|
||||||
|
// Get registered Servers
|
||||||
|
RegisteredServersStore store = new RegisteredServersStore(serverConn);
|
||||||
|
ServerGroup parentGroup = NavigateToServerGroup(store, listServerParams.RelativePath);
|
||||||
|
|
||||||
|
ListRegisteredServersResult result = GetChildrenfromParentGroup(parentGroup);
|
||||||
|
await requestContext.SendResult(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await requestContext.SendResult(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HandleRemoveRegisteredServerRequest(RemoveRegisteredServerParams removeServerParams, RequestContext<bool> requestContext)
|
||||||
|
{
|
||||||
|
Logger.Write(TraceEventType.Verbose, "HandleRemoveServerRequest");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CmsTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Validate and Connect
|
||||||
|
ServerConnection serverConn = ValidateAndCreateConnection(removeServerParams.ParentOwnerUri);
|
||||||
|
if (serverConn != null)
|
||||||
|
{
|
||||||
|
// Get list of registered Servers
|
||||||
|
RegisteredServersStore store = new RegisteredServersStore(serverConn);
|
||||||
|
ServerGroup parentGroup = NavigateToServerGroup(store, removeServerParams.RelativePath, false);
|
||||||
|
if (parentGroup != null)
|
||||||
|
{
|
||||||
|
RegisteredServer regServ = parentGroup.RegisteredServers.OfType<RegisteredServer>().FirstOrDefault(r => r.Name == removeServerParams.RegisteredServerName); // since duplicates are not allowed
|
||||||
|
regServ?.Drop();
|
||||||
|
await requestContext.SendResult(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await requestContext.SendResult(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HandleAddServerGroupRequest(AddServerGroupParams addServerGroupParams, RequestContext<bool> requestContext)
|
||||||
|
{
|
||||||
|
Logger.Write(TraceEventType.Verbose, "HandleAddServerGroupRequest");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CmsTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ServerConnection serverConn = ValidateAndCreateConnection(addServerGroupParams.ParentOwnerUri);
|
||||||
|
RegisteredServersStore store = new RegisteredServersStore(serverConn);
|
||||||
|
ServerGroup parentGroup = NavigateToServerGroup(store, addServerGroupParams.RelativePath);
|
||||||
|
|
||||||
|
// Add the new group (intentionally not cheching existence to reuse the exception message)
|
||||||
|
ServerGroup serverGroup = new ServerGroup(parentGroup, addServerGroupParams.GroupName)
|
||||||
|
{
|
||||||
|
Description = addServerGroupParams.GroupDescription
|
||||||
|
};
|
||||||
|
serverGroup.Create();
|
||||||
|
await requestContext.SendResult(true);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HandleRemoveServerGroupRequest(RemoveServerGroupParams removeServerGroupParams, RequestContext<bool> requestContext)
|
||||||
|
{
|
||||||
|
Logger.Write(TraceEventType.Verbose, "HandleRemoveServerGroupRequest");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CmsTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ServerConnection serverConn = ValidateAndCreateConnection(removeServerGroupParams.ParentOwnerUri);
|
||||||
|
if (serverConn != null)
|
||||||
|
{
|
||||||
|
RegisteredServersStore store = new RegisteredServersStore(serverConn);
|
||||||
|
|
||||||
|
ServerGroup parentGroup = NavigateToServerGroup(store, removeServerGroupParams.RelativePath, false);
|
||||||
|
ServerGroup serverGrouptoRemove = parentGroup.ServerGroups.OfType<ServerGroup>().FirstOrDefault(r => r.Name == removeServerGroupParams.GroupName); // since duplicates are not allowed
|
||||||
|
serverGrouptoRemove?.Drop();
|
||||||
|
await requestContext.SendResult(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await requestContext.SendResult(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
await requestContext.SendError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private methods
|
||||||
|
|
||||||
|
private ServerGroup NavigateToServerGroup(RegisteredServersStore store, string relativePath, bool alreadyParent = true)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(relativePath))
|
||||||
|
{
|
||||||
|
return store.DatabaseEngineServerGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get key chain from URN
|
||||||
|
Urn urn = new Urn(relativePath);
|
||||||
|
SfcKeyChain keyChain = alreadyParent ? new SfcKeyChain(urn, store as ISfcDomain) : new SfcKeyChain(urn, store as ISfcDomain).Parent;
|
||||||
|
|
||||||
|
ServerGroup parentGroup = GetNodeFromKeyChain(keyChain, store.DatabaseEngineServerGroup);
|
||||||
|
return parentGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerGroup GetNodeFromKeyChain(SfcKeyChain keyChain, ServerGroup rootServerGroup)
|
||||||
|
{
|
||||||
|
if (keyChain == rootServerGroup.KeyChain)
|
||||||
|
{
|
||||||
|
return rootServerGroup;
|
||||||
|
}
|
||||||
|
if (keyChain != rootServerGroup.KeyChain)
|
||||||
|
{
|
||||||
|
var parent = GetNodeFromKeyChain(keyChain.Parent, rootServerGroup);
|
||||||
|
if (parent != null && parent is ServerGroup)
|
||||||
|
{
|
||||||
|
var server = (parent as ServerGroup).ServerGroups.FirstOrDefault(x => x.KeyChain == keyChain);
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<ServerConnection> ValidateAndCreateConnection(ConnectParams connectionParams)
|
||||||
|
{
|
||||||
|
// Validate Parameters and Create Connection
|
||||||
|
ConnectionCompleteParams connectionCompleteParams = await ConnectionServiceInstance.Connect(connectionParams);
|
||||||
|
if (!string.IsNullOrEmpty(connectionCompleteParams.Messages))
|
||||||
|
{
|
||||||
|
throw new Exception(connectionCompleteParams.Messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Connection
|
||||||
|
ConnectionInfo connectionInfo = ConnectionServiceInstance.OwnerToConnectionMap[connectionParams.OwnerUri];
|
||||||
|
ServerConnection serverConn = ConnectionService.OpenServerConnection(connectionInfo);
|
||||||
|
|
||||||
|
return serverConn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServerConnection ValidateAndCreateConnection(string ownerUri)
|
||||||
|
{
|
||||||
|
ServerConnection serverConn = null;
|
||||||
|
if (ownerUri != null)
|
||||||
|
{
|
||||||
|
ConnectionInfo connInfo = null;
|
||||||
|
if (ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo))
|
||||||
|
{
|
||||||
|
serverConn = ConnectionService.OpenServerConnection(connInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return serverConn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListRegisteredServersResult GetChildrenfromParentGroup(ServerGroup parentGroup)
|
||||||
|
{
|
||||||
|
var servers = parentGroup.RegisteredServers;
|
||||||
|
var groups = parentGroup.ServerGroups;
|
||||||
|
|
||||||
|
// Convert to appropriate variables and return
|
||||||
|
var serverResults = new List<RegisteredServerResult>();
|
||||||
|
foreach (var s in servers)
|
||||||
|
{
|
||||||
|
serverResults.Add(new RegisteredServerResult
|
||||||
|
{
|
||||||
|
Name = s.Name,
|
||||||
|
ServerName = s.ServerName,
|
||||||
|
Description = s.Description,
|
||||||
|
ConnectionDetails = ConnectionServiceInstance.ParseConnectionString(s.ConnectionString),
|
||||||
|
RelativePath = s.KeyChain.Urn.SafeToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var groupsResults = new List<RegisteredServerGroup>();
|
||||||
|
foreach (var s in groups)
|
||||||
|
{
|
||||||
|
groupsResults.Add(new RegisteredServerGroup
|
||||||
|
{
|
||||||
|
Name = s.Name,
|
||||||
|
Description = s.Description,
|
||||||
|
RelativePath = s.KeyChain.Urn.SafeToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ListRegisteredServersResult result = new ListRegisteredServersResult() { RegisteredServersList = serverResults, RegisteredServerGroups = groupsResults };
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Internal for testing purposes only
|
||||||
|
/// </summary>
|
||||||
|
internal static ConnectionService ConnectionServiceInstance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (connectionService == null)
|
||||||
|
{
|
||||||
|
connectionService = ConnectionService.Instance;
|
||||||
|
}
|
||||||
|
return connectionService;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
connectionService = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Internal variable for testability
|
||||||
|
/// </summary>
|
||||||
|
internal Task CmsTask { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
//
|
||||||
|
// 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.ServiceLayer.Connection.Contracts;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.Cms.Contracts
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Paramaters to create Top level Central Management Server
|
||||||
|
/// </summary>
|
||||||
|
public class CreateCentralManagementServerParams
|
||||||
|
{
|
||||||
|
public string RegisteredServerName { get; set; }
|
||||||
|
|
||||||
|
public string RegisteredServerDescription { get; set; }
|
||||||
|
|
||||||
|
public ConnectParams ConnectParams { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parameters to Add Registered Server to top level CMS
|
||||||
|
/// </summary>
|
||||||
|
public class AddRegisteredServerParams
|
||||||
|
{
|
||||||
|
public string RegisteredServerName { get; set; }
|
||||||
|
|
||||||
|
public string RegisteredServerDescription { get; set; }
|
||||||
|
|
||||||
|
public ConnectionDetails RegisteredServerConnectionDetails { get; set; }
|
||||||
|
|
||||||
|
public string ParentOwnerUri { get; set; }
|
||||||
|
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parameters to Add Server Group to top level CMS
|
||||||
|
/// </summary>
|
||||||
|
public class AddServerGroupParams
|
||||||
|
{
|
||||||
|
public string GroupName { get; set; }
|
||||||
|
|
||||||
|
public string GroupDescription { get; set; }
|
||||||
|
|
||||||
|
public string ParentOwnerUri { get; set; }
|
||||||
|
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parameters to Remove Server Group from CMS
|
||||||
|
/// </summary>
|
||||||
|
public class RemoveServerGroupParams
|
||||||
|
{
|
||||||
|
public string GroupName { get; set; }
|
||||||
|
|
||||||
|
public string ParentOwnerUri { get; set; }
|
||||||
|
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Paramaters to remove a Registered Server from CMS tree
|
||||||
|
/// </summary>
|
||||||
|
public class RemoveRegisteredServerParams
|
||||||
|
{
|
||||||
|
public string RegisteredServerName { get; set; }
|
||||||
|
|
||||||
|
public string ParentOwnerUri { get; set; }
|
||||||
|
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Paramaters to list a Registered Server from CMS tree
|
||||||
|
/// </summary>
|
||||||
|
public class ListRegisteredServerParams
|
||||||
|
{
|
||||||
|
public string ParentOwnerUri { get; set; }
|
||||||
|
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// 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.Protocol.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.Cms.Contracts
|
||||||
|
{
|
||||||
|
|
||||||
|
public class CreateCentralManagementServerRequest
|
||||||
|
{
|
||||||
|
public static readonly RequestType<CreateCentralManagementServerParams, ListRegisteredServersResult> Type =
|
||||||
|
RequestType<CreateCentralManagementServerParams, ListRegisteredServersResult>.Create("cms/createCms");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ListRegisteredServersRequest
|
||||||
|
{
|
||||||
|
public static readonly RequestType<ListRegisteredServerParams, ListRegisteredServersResult> Type =
|
||||||
|
RequestType<ListRegisteredServerParams, ListRegisteredServersResult>.Create("cms/listRegisteredServers");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddRegisteredServerRequest
|
||||||
|
{
|
||||||
|
public static readonly RequestType<AddRegisteredServerParams, bool> Type =
|
||||||
|
RequestType<AddRegisteredServerParams, bool>.Create("cms/addRegisteredServer");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AddServerGroupRequest
|
||||||
|
{
|
||||||
|
public static readonly RequestType<AddServerGroupParams, bool> Type =
|
||||||
|
RequestType<AddServerGroupParams, bool>.Create("cms/addCmsServerGroup");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RemoveServerGroupRequest
|
||||||
|
{
|
||||||
|
public static readonly RequestType<RemoveServerGroupParams, bool> Type =
|
||||||
|
RequestType<RemoveServerGroupParams, bool>.Create("cms/removeCmsServerGroup");
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RemoveRegisteredServerRequest
|
||||||
|
{
|
||||||
|
public static readonly RequestType<RemoveRegisteredServerParams, bool> Type =
|
||||||
|
RequestType<RemoveRegisteredServerParams, bool>.Create("cms/removeRegisteredServer");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// 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.ServiceLayer.Connection.Contracts;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.Cms.Contracts
|
||||||
|
{
|
||||||
|
public class ListRegisteredServersResult
|
||||||
|
{
|
||||||
|
public List<RegisteredServerResult> RegisteredServersList { get; set; }
|
||||||
|
|
||||||
|
public List<RegisteredServerGroup> RegisteredServerGroups { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegisteredServerResult
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string ServerName { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
|
||||||
|
public ConnectionDetails ConnectionDetails { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RegisteredServerGroup
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1284,7 +1284,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
|
|||||||
{
|
{
|
||||||
await requestContext.SendResult(ParseConnectionString(connectionString));
|
await requestContext.SendResult(ParseConnectionString(connectionString));
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
// If theres an error in the parse, it means we just can't parse, so we return undefined
|
// If theres an error in the parse, it means we just can't parse, so we return undefined
|
||||||
// rather than an error.
|
// rather than an error.
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Microsoft.SqlTools.Hosting;
|
|||||||
using Microsoft.SqlTools.Hosting.Protocol;
|
using Microsoft.SqlTools.Hosting.Protocol;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Agent;
|
using Microsoft.SqlTools.ServiceLayer.Agent;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Cms;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
using Microsoft.SqlTools.ServiceLayer.DacFx;
|
using Microsoft.SqlTools.ServiceLayer.DacFx;
|
||||||
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery;
|
using Microsoft.SqlTools.ServiceLayer.DisasterRecovery;
|
||||||
@@ -114,6 +115,9 @@ namespace Microsoft.SqlTools.ServiceLayer
|
|||||||
DacFxService.Instance.InitializeService(serviceHost);
|
DacFxService.Instance.InitializeService(serviceHost);
|
||||||
serviceProvider.RegisterSingleService(DacFxService.Instance);
|
serviceProvider.RegisterSingleService(DacFxService.Instance);
|
||||||
|
|
||||||
|
CmsService.Instance.InitializeService(serviceHost);
|
||||||
|
serviceProvider.RegisterSingleService(CmsService.Instance);
|
||||||
|
|
||||||
InitializeHostedServices(serviceProvider, serviceHost);
|
InitializeHostedServices(serviceProvider, serviceHost);
|
||||||
serviceHost.ServiceProvider = serviceProvider;
|
serviceHost.ServiceProvider = serviceProvider;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,280 @@
|
|||||||
|
//
|
||||||
|
// 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.Protocol;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Cms;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Cms.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
||||||
|
using Moq;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Cms
|
||||||
|
{
|
||||||
|
public class CmsServiceTests
|
||||||
|
{
|
||||||
|
private ConnectParams CreateConnectParams()
|
||||||
|
{
|
||||||
|
ConnectParams connectParams = TestServiceProvider.Instance.ConnectionProfileService.GetConnectionParameters(TestServerType.OnPrem, "master");
|
||||||
|
connectParams.OwnerUri = LiveConnectionHelper.GetTestSqlFile();
|
||||||
|
connectParams.Connection.DatabaseName = null;
|
||||||
|
connectParams.Connection.DatabaseDisplayName = null;
|
||||||
|
|
||||||
|
return connectParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<ConnectParams> CreateAndConnectWithConnectParams()
|
||||||
|
{
|
||||||
|
ConnectParams connectParams = CreateConnectParams();
|
||||||
|
ConnectionService connService = ConnectionService.Instance;
|
||||||
|
await connService.Connect(connectParams);
|
||||||
|
|
||||||
|
return connectParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
private async void TestAddCMS()
|
||||||
|
{
|
||||||
|
string name = "TestAddCMS" + DateTime.Now.ToString();
|
||||||
|
ConnectParams connectParams = CreateConnectParams();
|
||||||
|
|
||||||
|
// Prepare for list servers (may or may not have servers but will have listCmsServersResult)
|
||||||
|
var requestContext = new Mock<RequestContext<ListRegisteredServersResult>>();
|
||||||
|
requestContext.Setup((RequestContext<ListRegisteredServersResult> x) => x.SendResult(It.Is<ListRegisteredServersResult>((listCmsServersResult) => listCmsServersResult.RegisteredServersList != null))).Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
CreateCentralManagementServerParams connectToCMS = new CreateCentralManagementServerParams
|
||||||
|
{
|
||||||
|
RegisteredServerName = name,
|
||||||
|
RegisteredServerDescription = "My Registered Test Server",
|
||||||
|
ConnectParams = connectParams
|
||||||
|
};
|
||||||
|
|
||||||
|
// Actual test after preparation start here
|
||||||
|
CmsService cmsService = CmsService.Instance;
|
||||||
|
|
||||||
|
// Connect to CMS
|
||||||
|
await cmsService.HandleCreateCentralManagementServerRequest(connectToCMS, requestContext.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContext.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
private async void TestAddRemoveRegisteredServer()
|
||||||
|
{
|
||||||
|
string name = "TestAddRemoveRegisteredServer" + DateTime.Now.ToString();
|
||||||
|
ConnectParams connectParams = await CreateAndConnectWithConnectParams();
|
||||||
|
|
||||||
|
// Prepare for Add Reg Server
|
||||||
|
var requestContext1 = new Mock<RequestContext<bool>>();
|
||||||
|
requestContext1.Setup((RequestContext<bool> x) => x.SendResult(It.Is<bool>((result) => result == true))).Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
AddRegisteredServerParams addRegServerParams = new AddRegisteredServerParams
|
||||||
|
{
|
||||||
|
RegisteredServerName = name,
|
||||||
|
RegisteredServerDescription = "My Registered Test Server",
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
RelativePath = "RegisteredServersStore/ServerGroup[@Name='DatabaseEngineServerGroup']" //Top level
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prepare for list servers
|
||||||
|
var requestContext2 = new Mock<RequestContext<ListRegisteredServersResult>>();
|
||||||
|
requestContext2.Setup((RequestContext<ListRegisteredServersResult> x) => x.SendResult(It.Is<ListRegisteredServersResult>((listCmsServersResult) => listCmsServersResult.RegisteredServersList.Find(p => p.Name.Contains(name)) != null))).Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
ListRegisteredServerParams listServersParams = new ListRegisteredServerParams
|
||||||
|
{
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
RelativePath = "RegisteredServersStore/ServerGroup[@Name='DatabaseEngineServerGroup']"
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prepare for remove Server
|
||||||
|
var requestContext3 = new Mock<RequestContext<bool>>();
|
||||||
|
requestContext1.Setup((RequestContext<bool> x) => x.SendResult(It.Is<bool>((result) => result == true))).Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
RemoveRegisteredServerParams removeRegServerParams = new RemoveRegisteredServerParams
|
||||||
|
{
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
RegisteredServerName = name,
|
||||||
|
RelativePath = string.Format("RegisteredServersStore/ServerGroup[@Name='DatabaseEngineServerGroup']/RegisteredServer[@Name='{0}']", name)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Actual test after preparation start here
|
||||||
|
CmsService cmsService = CmsService.Instance;
|
||||||
|
|
||||||
|
// Add Reg Server
|
||||||
|
await cmsService.HandleAddRegisteredServerRequest(addRegServerParams, requestContext1.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContext1.VerifyAll();
|
||||||
|
|
||||||
|
// List to validate
|
||||||
|
await cmsService.HandleListRegisteredServersRequest(listServersParams, requestContext2.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContext2.VerifyAll();
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
await cmsService.HandleRemoveRegisteredServerRequest(removeRegServerParams, requestContext3.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContext3.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
private async void TestAddRemoveServerGroup()
|
||||||
|
{
|
||||||
|
string name = "TestAddRemoveServerGroup" + DateTime.Now.ToString();
|
||||||
|
ConnectParams connectParams = await CreateAndConnectWithConnectParams();
|
||||||
|
|
||||||
|
// Prepare for Server group add
|
||||||
|
var requestContext1 = new Mock<RequestContext<bool>>();
|
||||||
|
requestContext1.Setup((RequestContext<bool> x) => x.SendResult(It.Is<bool>((result) => result == true))).Returns(Task.FromResult(new object()));
|
||||||
|
AddServerGroupParams addRegServerParams = new AddServerGroupParams
|
||||||
|
{
|
||||||
|
GroupName = name,
|
||||||
|
GroupDescription = "My Registered Test Server Group",
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
RelativePath = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
// prepare for Server group list
|
||||||
|
var requestContext2 = new Mock<RequestContext<ListRegisteredServersResult>>();
|
||||||
|
requestContext2.Setup((RequestContext<ListRegisteredServersResult> x) => x.SendResult(It.Is<ListRegisteredServersResult>((listCmsServersResult) => listCmsServersResult.RegisteredServerGroups.Find(p => p.Name.Contains(name)) != null))).Returns(Task.FromResult(new object()));
|
||||||
|
ListRegisteredServerParams listServersParams = new ListRegisteredServerParams
|
||||||
|
{
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
RelativePath = null
|
||||||
|
};
|
||||||
|
|
||||||
|
// prepare for server group remove
|
||||||
|
var requestContext3 = new Mock<RequestContext<bool>>();
|
||||||
|
requestContext1.Setup((RequestContext<bool> x) => x.SendResult(It.Is<bool>((result) => result == true))).Returns(Task.FromResult(new object()));
|
||||||
|
RemoveServerGroupParams removeRegServerParams = new RemoveServerGroupParams
|
||||||
|
{
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
GroupName = name,
|
||||||
|
RelativePath = null
|
||||||
|
};
|
||||||
|
|
||||||
|
// Actual test start here
|
||||||
|
CmsService cmsService = CmsService.Instance;
|
||||||
|
|
||||||
|
await cmsService.HandleAddServerGroupRequest(addRegServerParams, requestContext1.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContext1.VerifyAll();
|
||||||
|
|
||||||
|
await cmsService.HandleListRegisteredServersRequest(listServersParams, requestContext2.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContext2.VerifyAll();
|
||||||
|
|
||||||
|
await cmsService.HandleRemoveServerGroupRequest(removeRegServerParams, requestContext3.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContext3.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
private async void TestAddRemoveNestedGroup()
|
||||||
|
{
|
||||||
|
string name = "TestAddRemoveNestedGroup" + DateTime.Now.ToString();
|
||||||
|
ConnectParams connectParams = await CreateAndConnectWithConnectParams();
|
||||||
|
|
||||||
|
// prepare for multi level server group add
|
||||||
|
var requestContextAdd = new Mock<RequestContext<bool>>();
|
||||||
|
requestContextAdd.Setup((RequestContext<bool> x) => x.SendResult(It.Is<bool>((result) => result == true))).Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
AddServerGroupParams addRegServerParams1 = new AddServerGroupParams
|
||||||
|
{
|
||||||
|
GroupName = name + "_level1",
|
||||||
|
GroupDescription = "My Registered Test Server Group Level 1",
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
RelativePath = null, // can do with null on level 1
|
||||||
|
};
|
||||||
|
|
||||||
|
AddServerGroupParams addRegServerParams2 = new AddServerGroupParams
|
||||||
|
{
|
||||||
|
GroupName = name + "_level2",
|
||||||
|
GroupDescription = "My Registered Test Server Group Level 2",
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
RelativePath = string.Format("RegisteredServersStore/ServerGroup[@Name='DatabaseEngineServerGroup']/ServerGroup[@Name='{0}']", name + "_level1") // parent URN
|
||||||
|
};
|
||||||
|
|
||||||
|
AddServerGroupParams addRegServerParams3 = new AddServerGroupParams
|
||||||
|
{
|
||||||
|
GroupName = name + "_level3",
|
||||||
|
GroupDescription = "My Registered Test Server Group Level 3",
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
RelativePath = string.Format("RegisteredServersStore/ServerGroup[@Name='DatabaseEngineServerGroup']/ServerGroup[@Name='{0}']/ServerGroup[@Name='{1}']", name + "_level1", name + "_level2") // parent URN
|
||||||
|
};
|
||||||
|
|
||||||
|
// prepare for multi level server group list
|
||||||
|
|
||||||
|
var requestContextList1 = new Mock<RequestContext<ListRegisteredServersResult>>();
|
||||||
|
requestContextList1.Setup((RequestContext<ListRegisteredServersResult> x) => x.SendResult(It.Is<ListRegisteredServersResult>((listCmsServersResult) => listCmsServersResult.RegisteredServerGroups.Find(p => p.Name.Contains(name + "_level3")) != null))).Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
var requestContextList2 = new Mock<RequestContext<ListRegisteredServersResult>>();
|
||||||
|
requestContextList2.Setup((RequestContext<ListRegisteredServersResult> x) => x.SendResult(It.Is<ListRegisteredServersResult>((listCmsServersResult) => listCmsServersResult.RegisteredServerGroups.Find(p => p.Name.Contains(name + "_level3")) == null))).Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
ListRegisteredServerParams listServersParams = new ListRegisteredServerParams
|
||||||
|
{
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
RelativePath = string.Format("RegisteredServersStore/ServerGroup[@Name='DatabaseEngineServerGroup']/ServerGroup[@Name='{0}']/ServerGroup[@Name='{1}']", name + "_level1", name + "_level2") // parent URN
|
||||||
|
};
|
||||||
|
|
||||||
|
// prepare for multi level server group remove at level 3 and then at level 1
|
||||||
|
var requestContextRemove = new Mock<RequestContext<bool>>();
|
||||||
|
requestContextRemove.Setup((RequestContext<bool> x) => x.SendResult(It.Is<bool>((result) => result == true))).Returns(Task.FromResult(new object()));
|
||||||
|
|
||||||
|
RemoveServerGroupParams removeRegServerParams = new RemoveServerGroupParams
|
||||||
|
{
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
GroupName = name + "_level3",
|
||||||
|
RelativePath = string.Format("RegisteredServersStore/ServerGroup[@Name='DatabaseEngineServerGroup']/ServerGroup[@Name='{0}']/ServerGroup[@Name='{1}']/ServerGroup[@Name='{2}']", name + "_level1", name + "_level2", name + "_level3") // own URN
|
||||||
|
};
|
||||||
|
|
||||||
|
RemoveServerGroupParams removeRegServerParamsCleanup = new RemoveServerGroupParams
|
||||||
|
{
|
||||||
|
ParentOwnerUri = connectParams.OwnerUri,
|
||||||
|
GroupName = name + "_level1",
|
||||||
|
RelativePath = string.Format("RegisteredServersStore/ServerGroup[@Name='DatabaseEngineServerGroup']/ServerGroup[@Name='{0}']", name + "_level1") // own URN
|
||||||
|
};
|
||||||
|
|
||||||
|
// Actual test starts here
|
||||||
|
CmsService cmsService = CmsService.Instance;
|
||||||
|
|
||||||
|
// Add three levels
|
||||||
|
await cmsService.HandleAddServerGroupRequest(addRegServerParams1, requestContextAdd.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContextAdd.VerifyAll();
|
||||||
|
|
||||||
|
await cmsService.HandleAddServerGroupRequest(addRegServerParams2, requestContextAdd.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContextAdd.VerifyAll();
|
||||||
|
|
||||||
|
await cmsService.HandleAddServerGroupRequest(addRegServerParams3, requestContextAdd.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContextAdd.VerifyAll();
|
||||||
|
|
||||||
|
// List Level 2 to find level three
|
||||||
|
await cmsService.HandleListRegisteredServersRequest(listServersParams, requestContextList1.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContextList1.VerifyAll();
|
||||||
|
|
||||||
|
// Remove level 3
|
||||||
|
await cmsService.HandleRemoveServerGroupRequest(removeRegServerParams, requestContextRemove.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContextRemove.VerifyAll();
|
||||||
|
|
||||||
|
// List Level 2 to validate Level 3 removal
|
||||||
|
await cmsService.HandleListRegisteredServersRequest(listServersParams, requestContextList2.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContextList2.VerifyAll();
|
||||||
|
|
||||||
|
// Clean up - Remove Level 1
|
||||||
|
await cmsService.HandleRemoveServerGroupRequest(removeRegServerParamsCleanup, requestContextRemove.Object);
|
||||||
|
await cmsService.CmsTask;
|
||||||
|
requestContextRemove.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user