Consolidate context request endpoints into a single request endpoint (#2205)

* Create new endpoint consolidating previous 2

* Clarify comment

* Removes two separate endpoints to get and generate

* Rename classes for get context request

* Update src/Microsoft.SqlTools.ServiceLayer/Metadata/MetadataService.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Update src/Microsoft.SqlTools.ServiceLayer/Metadata/MetadataService.cs

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>

* Code review changes

* Throw exception and localize ex messages

---------

Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
This commit is contained in:
Lewis Sanchez
2023-09-05 15:56:35 -07:00
committed by GitHub
parent 42bbfdc418
commit a56cf5a277
8 changed files with 66 additions and 177 deletions

View File

@@ -445,6 +445,14 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
public static string FailedToFindConnectionInfoAboutTheServer
{
get
{
return Keys.GetString(Keys.FailedToFindConnectionInfoAboutTheServer);
}
}
public static string PeekDefinitionNoResultsError
{
get
@@ -11450,6 +11458,9 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string FailedToGenerateServerContextualizationScripts = "FailedToGenerateServerContextualizationScripts";
public const string FailedToFindConnectionInfoAboutTheServer = "FailedToFindConnectionInfoAboutTheServer";
public const string SerializationServiceUnsupportedFormat = "SerializationServiceUnsupportedFormat";

View File

@@ -435,6 +435,10 @@
<value>Failed to generate server contextualization scripts</value>
<comment></comment>
</data>
<data name="FailedToFindConnectionInfoAboutTheServer" xml:space="preserve">
<value>Failed to find connection info about the server</value>
<comment></comment>
</data>
<data name="SerializationServiceUnsupportedFormat" xml:space="preserve">
<value>Unsupported Save Format: {0}</value>
<comment>.

View File

@@ -195,6 +195,8 @@ WritingServerContextualizationToCacheError (string message) = An error was encou
FailedToGenerateServerContextualizationScripts = Failed to generate server contextualization scripts
FailedToFindConnectionInfoAboutTheServer = Failed to find connection info about the server
############################################################################
# Serialization Service

View File

@@ -7259,6 +7259,11 @@ The Query Processor estimates that implementing the following index could improv
<target state="new">Failed to generate server contextualization scripts</target>
<note></note>
</trans-unit>
<trans-unit id="FailedToFindConnectionInfoAboutTheServer">
<source>Failed to find connection info about the server</source>
<target state="new">Failed to find connection info about the server</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -1,34 +0,0 @@
//
// 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;
namespace Microsoft.SqlTools.ServiceLayer.Metadata.Contracts
{
public class GenerateServerContextualizationParams
{
/// <summary>
/// The URI of the connection to generate context for.
/// </summary>
public string OwnerUri { get; set; }
}
public class GenerateServerContextualizationResult
{
/// <summary>
/// The generated server context.
/// </summary>
public string? Context { get; set; }
}
/// <summary>
/// Generate server context request endpoint.
/// </summary>
public class GenerateServerContextualizationRequest
{
public static readonly RequestType<GenerateServerContextualizationParams, GenerateServerContextualizationResult> Type =
RequestType<GenerateServerContextualizationParams, GenerateServerContextualizationResult>.Create("metadata/generateServerContext");
}
}

View File

@@ -1,4 +1,4 @@
//
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
@@ -10,7 +10,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Metadata.Contracts
public class GetServerContextualizationParams
{
/// <summary>
/// The URI of the connection to generate scripts for.
/// The URI to generate and retrieve server contextualization for.
/// </summary>
public string OwnerUri { get; set; }
}
@@ -18,9 +18,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Metadata.Contracts
public class GetServerContextualizationResult
{
/// <summary>
/// The generated server context.
/// The generated context.
/// </summary>
public string? Context { get; set; }
public string Context { get; set; }
}
public class GetServerContextualizationRequest

View File

@@ -59,7 +59,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Metadata
serviceHost.SetRequestHandler(MetadataListRequest.Type, HandleMetadataListRequest, true);
serviceHost.SetRequestHandler(TableMetadataRequest.Type, HandleGetTableRequest, true);
serviceHost.SetRequestHandler(ViewMetadataRequest.Type, HandleGetViewRequest, true);
serviceHost.SetRequestHandler(GenerateServerContextualizationRequest.Type, HandleGenerateServerContextualizationNotification, true);
serviceHost.SetRequestHandler(GetServerContextualizationRequest.Type, HandleGetServerContextualizationRequest, true);
}
@@ -121,79 +120,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Metadata
await HandleGetTableOrViewRequest(metadataParams, "view", requestContext);
}
/// <summary>
/// Handles the event for generating server contextualization scripts.
/// </summary>
internal static Task HandleGenerateServerContextualizationNotification(GenerateServerContextualizationParams contextualizationParams,
RequestContext<GenerateServerContextualizationResult> requestContext)
{
_ = Task.Factory.StartNew(async () =>
{
await GenerateServerContextualization(contextualizationParams, requestContext);
},
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.Default);
return Task.CompletedTask;
}
/// <summary>
/// Generates the contextualization scripts for a server. The generated context is in the form of create scripts for
/// database objects like tables and views.
/// </summary>
/// <param name="contextualizationParams">The contextualization parameters.</param>
internal static async Task GenerateServerContextualization(GenerateServerContextualizationParams contextualizationParams, RequestContext<GenerateServerContextualizationResult> requestContext)
{
MetadataService.ConnectionServiceInstance.TryFindConnection(contextualizationParams.OwnerUri, out ConnectionInfo connectionInfo);
if (connectionInfo != null)
{
using (SqlConnection sqlConn = ConnectionService.OpenSqlConnection(connectionInfo, "metadata"))
{
// If scripts have been generated within the last 30 days then there isn't a need to go through the process
// of generating scripts again.
if (MetadataScriptTempFileStream.IsScriptTempFileUpdateNeeded(connectionInfo.ConnectionDetails.ServerName))
{
var scripts = SmoScripterHelpers.GenerateAllServerTableScripts(sqlConn)?.ToArray();
if (scripts != null)
{
try
{
await requestContext.SendResult(new GenerateServerContextualizationResult()
{
Context = string.Join('\n', scripts)
});
MetadataScriptTempFileStream.Write(connectionInfo.ConnectionDetails.ServerName, scripts);
}
catch (Exception ex)
{
Logger.Error($"An error was encountered while writing server contextualization scripts to the cache. Error: {ex.Message}");
await requestContext.SendError(ex);
}
}
else
{
Logger.Error("Failed to generate server contextualization scripts");
await requestContext.SendError(SR.FailedToGenerateServerContextualizationScripts);
}
}
else
{
var generateContextResult = new GenerateServerContextualizationResult()
{
Context = null
};
await requestContext.SendResult(generateContextResult);
}
}
}
}
/// <summary>
/// Handles the request for getting database server contextualization scripts.
/// </summary>
internal static Task HandleGetServerContextualizationRequest(GetServerContextualizationParams contextualizationParams,
RequestContext<GetServerContextualizationResult> requestContext)
{
@@ -208,26 +139,46 @@ namespace Microsoft.SqlTools.ServiceLayer.Metadata
return Task.CompletedTask;
}
/// <summary>
/// Gets server contextualization scripts. The retrieved scripts are create scripts for database objects like tables and views.
/// </summary>
/// <param name="contextualizationParams">The contextualization parameters to get context.</param>
/// <param name="requestContext">The request context for the request.</param>
/// <returns></returns>
internal static async Task GetServerContextualization(GetServerContextualizationParams contextualizationParams, RequestContext<GetServerContextualizationResult> requestContext)
{
MetadataService.ConnectionServiceInstance.TryFindConnection(contextualizationParams.OwnerUri, out ConnectionInfo connectionInfo);
// When the filed context is too old don't read it
if (MetadataScriptTempFileStream.IsScriptTempFileUpdateNeeded(connectionInfo.ConnectionDetails.ServerName))
if (connectionInfo == null)
{
await requestContext.SendResult(new GetServerContextualizationResult
{
Context = null
});
Logger.Error("Failed to find connection info about the server.");
throw new Exception(SR.FailedToFindConnectionInfoAboutTheServer);
}
else
{
if (connectionInfo != null)
if (MetadataScriptTempFileStream.IsScriptTempFileUpdateNeeded(connectionInfo.ConnectionDetails.ServerName))
{
using (SqlConnection sqlConn = ConnectionService.OpenSqlConnection(connectionInfo, "metadata"))
{
var scripts = SmoScripterHelpers.GenerateAllServerTableScripts(sqlConn)?.ToArray();
if (scripts != null)
{
try
{
await requestContext.SendResult(new GetServerContextualizationResult()
{
Context = string.Join('\n', scripts)
});
MetadataScriptTempFileStream.Write(connectionInfo.ConnectionDetails.ServerName, scripts);
}
catch (Exception ex)
{
Logger.Error($"An error was encountered while generating server contextualization scripts. Error: {ex.Message}");
throw;
}
}
else
{
Logger.Error("Failed to generate server contextualization scripts");
throw new Exception(SR.FailedToGenerateServerContextualizationScripts);
}
}
}
else
{
try
{
@@ -240,14 +191,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Metadata
catch (Exception ex)
{
Logger.Error("Failed to read scripts from the script cache");
await requestContext.SendError(ex);
throw;
}
}
else
{
Logger.Error("Failed to find connection info about the server.");
await requestContext.SendError("Failed to find connection info about the server.");
}
}
}