Files
sqltoolsservice/src/Microsoft.SqlTools.ResourceProvider/ResourceProviderHostLoader.cs
Kevin Cunnane 7acc668c04 Create Firewall Rule support with a simple Resource Provider implementation
Implementation of the resource provider APIs in order to support Create Firewall Rule. Provides definition for a ResourceProvider and Authentication service. The ResourceProvider supports firewall rules for now, and since authentication is routed through that method it will call into the auth service to set up the current account to be used.

Additional notes:
- Fixed deserialization by adding an Accept header. This shouldn't be necessary, but for some reason the firewall rule defaults to XML without this
- Use generic server list and parse the ID to get the resource group, avoiding a large number of extra calls for each RG
- Errors now include error message from the API
2017-10-09 15:45:33 -07:00

92 lines
4.0 KiB
C#

//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using System.Reflection;
using Microsoft.SqlTools.Extensibility;
using Microsoft.SqlTools.Hosting;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.Utility;
namespace Microsoft.SqlTools.ResourceProvider
{
/// <summary>
/// Provides support for starting up a service host. This is a common responsibility
/// for both the main service program and test driver that interacts with it
/// </summary>
public static class ResourceProviderHostLoader
{
private static object lockObject = new object();
private static bool isLoaded;
internal static UtilityServiceHost CreateAndStartServiceHost(SqlToolsContext sqlToolsContext)
{
UtilityServiceHost serviceHost = UtilityServiceHost.Instance;
lock (lockObject)
{
if (!isLoaded)
{
// Grab the instance of the service host
serviceHost.Initialize();
InitializeRequestHandlersAndServices(serviceHost, sqlToolsContext);
// Start the service only after all request handlers are setup. This is vital
// as otherwise the Initialize event can be lost - it's processed and discarded before the handler
// is hooked up to receive the message
serviceHost.Start().Wait();
isLoaded = true;
}
}
return serviceHost;
}
private static void InitializeRequestHandlersAndServices(UtilityServiceHost serviceHost, SqlToolsContext sqlToolsContext)
{
// Load extension provider, which currently finds all exports in current DLL. Can be changed to find based
// on directory or assembly list quite easily in the future
ExtensionServiceProvider serviceProvider = ExtensionServiceProvider.CreateFromAssembliesInDirectory(GetResourceProviderExtensionDlls());
serviceProvider.RegisterSingleService(sqlToolsContext);
serviceProvider.RegisterSingleService(serviceHost);
InitializeHostedServices(serviceProvider, serviceHost);
serviceHost.InitializeRequestHandlers();
}
public static IEnumerable<string> GetResourceProviderExtensionDlls()
{
return new string[] {
"SqlToolsResourceProviderService.dll",
"Microsoft.SqlTools.ResourceProvider.Core.dll",
"Microsoft.SqlTools.ResourceProvider.DefaultImpl.dll"
};
}
/// <summary>
/// Internal to support testing. Initializes <see cref="IHostedService"/> instances in the service,
/// and registers them for their preferred service type
/// </summary>
internal static void InitializeHostedServices(RegisteredServiceProvider provider, IProtocolEndpoint host)
{
// Pre-register all services before initializing. This ensures that if one service wishes to reference
// another one during initialization, it will be able to safely do so
foreach (IHostedService service in provider.GetServices<IHostedService>())
{
provider.RegisterSingleService(service.ServiceType, service);
}
foreach (IHostedService service in provider.GetServices<IHostedService>())
{
// Initialize all hosted services, and register them in the service provider for their requested
// service type. This ensures that when searching for the ConnectionService you can get it without
// searching for an IHostedService of type ConnectionService
service.InitializeService(host);
}
}
}
}