diff --git a/extensions/mssql/src/constants.ts b/extensions/mssql/src/constants.ts index f56111d4fb..4a4ac34575 100644 --- a/extensions/mssql/src/constants.ts +++ b/extensions/mssql/src/constants.ts @@ -39,6 +39,7 @@ export const SchemaCompareService = 'schemaCompareService'; export const LanguageExtensionService = 'languageExtensionService'; export const objectExplorerPrefix: string = 'objectexplorer://'; export const ViewType = 'view'; +export const SqlAssessmentService = 'sqlAssessmentService'; export enum BuiltInCommands { SetContext = 'setContext' diff --git a/extensions/mssql/src/contracts.ts b/extensions/mssql/src/contracts.ts index 21576cc574..0b25952351 100644 --- a/extensions/mssql/src/contracts.ts +++ b/extensions/mssql/src/contracts.ts @@ -674,6 +674,35 @@ export namespace SchemaCompareCancellationRequest { // ------------------------------- ----------------------------- +// ------------------------------- ----------------------------- + +export interface SqlAssessmentParams { + ownerUri: string; + targetType: mssql.SqlAssessmentTargetType +} + +export interface GenerateSqlAssessmentScriptParams { + items: mssql.SqlAssessmentResultItem[]; + taskExecutionMode: azdata.TaskExecutionMode; + targetServerName: string; + targetDatabaseName: string; +} + +export namespace SqlAssessmentInvokeRequest { + export const type = new RequestType('assessment/invoke'); +} + +export namespace GetSqlAssessmentItemsRequest { + export const type = new RequestType('assessment/getAssessmentItems'); +} + +export namespace GenerateSqlAssessmentScriptRequest { + export const type = new RequestType('assessment/generateScript'); +} + +// ------------------------------- ----------------------------- + + // ------------------------------- ----------------------------- export namespace SerializeDataStartRequest { export const type = new RequestType('serialize/start'); diff --git a/extensions/mssql/src/mssql.d.ts b/extensions/mssql/src/mssql.d.ts index 9664284ec1..0a0e62825a 100644 --- a/extensions/mssql/src/mssql.d.ts +++ b/extensions/mssql/src/mssql.d.ts @@ -41,6 +41,8 @@ export interface IExtension { readonly languageExtension: ILanguageExtensionService; readonly dacFx: IDacFxService; + + readonly sqlAssessment: ISqlAssessmentService; } /** @@ -463,3 +465,47 @@ export interface ListRegisteredServersResult { registeredServerGroups: Array; } //#endregion + +/** + * Sql Assessment + */ + +// SqlAssessment interfaces ----------------------------------------------------------------------- + +export const enum SqlAssessmentTargetType { + Server = 1, + Database = 2 +} + +export const enum SqlAssessmentResultItemKind { + RealResult = 0, + Warning = 1, + Error = 2 +} + +export interface SqlAssessmentResultItem { + rulesetVersion: string; + rulesetName: string; + targetType: SqlAssessmentTargetType; + targetName: string; + checkId: string; + tags: string[]; + displayName: string; + description: string; + message: string; + helpLink: string; + level: string; + timestamp: string; + kind: SqlAssessmentResultItemKind; +} + +export interface SqlAssessmentResult extends azdata.ResultStatus { + items: SqlAssessmentResultItem[]; + apiVersion: string; +} + +export interface ISqlAssessmentService { + assessmentInvoke(ownerUri: string, targetType: SqlAssessmentTargetType): Promise; + getAssessmentItems(ownerUri: string, targetType: SqlAssessmentTargetType): Promise; + generateAssessmentScript(items: SqlAssessmentResultItem[], targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Promise; +} diff --git a/extensions/mssql/src/mssqlApiFactory.ts b/extensions/mssql/src/mssqlApiFactory.ts index 0684823583..8402eab20c 100644 --- a/extensions/mssql/src/mssqlApiFactory.ts +++ b/extensions/mssql/src/mssqlApiFactory.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { AppContext } from './appContext'; -import { IExtension, ICmsService, IDacFxService, ISchemaCompareService, MssqlObjectExplorerBrowser, ILanguageExtensionService } from './mssql'; +import { IExtension, ICmsService, IDacFxService, ISchemaCompareService, MssqlObjectExplorerBrowser, ILanguageExtensionService, ISqlAssessmentService } from './mssql'; import * as constants from './constants'; import { MssqlObjectExplorerNodeProvider } from './objectExplorerNodeProvider/objectExplorerNodeProvider'; import * as azdata from 'azdata'; @@ -30,6 +30,9 @@ export function createMssqlApi(context: AppContext): IExtension { return oeProvider.findSqlClusterNodeByContext(explorerContext); } }; + }, + get sqlAssessment() { + return context.getService(constants.SqlAssessmentService); } }; } diff --git a/extensions/mssql/src/sqlAssessment/sqlAssessmentService.ts b/extensions/mssql/src/sqlAssessment/sqlAssessmentService.ts new file mode 100644 index 0000000000..6bc22fb492 --- /dev/null +++ b/extensions/mssql/src/sqlAssessment/sqlAssessmentService.ts @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as mssql from '../mssql'; +import { AppContext } from '../appContext'; +import { SqlOpsDataClient, ISqlOpsFeature } from 'dataprotocol-client'; +import { ClientCapabilities } from 'vscode-languageclient'; +import * as constants from '../constants'; +import * as azdata from 'azdata'; +import * as contracts from '../contracts'; + + +export class SqlAssessmentService implements mssql.ISqlAssessmentService { + public static asFeature(context: AppContext): ISqlOpsFeature { + return class extends SqlAssessmentService { + constructor(client: SqlOpsDataClient) { + super(context, client); + } + + fillClientCapabilities(capabilities: ClientCapabilities): void { + } + + initialize(): void { + } + }; + } + + private constructor(context: AppContext, protected readonly client: SqlOpsDataClient) { + context.registerService(constants.SqlAssessmentService, this); + } + async assessmentInvoke(ownerUri: string, targetType: mssql.SqlAssessmentTargetType): Promise { + let params: contracts.SqlAssessmentParams = { ownerUri: ownerUri, targetType: targetType }; + try { + return this.client.sendRequest(contracts.SqlAssessmentInvokeRequest.type, params); + } + catch (e) { + this.client.logFailedRequest(contracts.SqlAssessmentInvokeRequest.type, e); + } + + return undefined; + } + async getAssessmentItems(ownerUri: string, targetType: mssql.SqlAssessmentTargetType): Promise { + let params: contracts.SqlAssessmentParams = { ownerUri: ownerUri, targetType: targetType }; + try { + return this.client.sendRequest(contracts.GetSqlAssessmentItemsRequest.type, params); + } + catch (e) { + this.client.logFailedRequest(contracts.GetSqlAssessmentItemsRequest.type, e); + } + + return undefined; + } + async generateAssessmentScript(items: mssql.SqlAssessmentResultItem[], targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Promise { + let params: contracts.GenerateSqlAssessmentScriptParams = { items: items, targetServerName: targetServerName, targetDatabaseName: targetDatabaseName, taskExecutionMode: taskExecutionMode }; + try { + return this.client.sendRequest(contracts.GenerateSqlAssessmentScriptRequest.type, params); + } + catch (e) { + this.client.logFailedRequest(contracts.GenerateSqlAssessmentScriptRequest.type, e); + } + + return undefined; + } + +} diff --git a/extensions/mssql/src/sqlToolsServer.ts b/extensions/mssql/src/sqlToolsServer.ts index e78b6fc14d..c0ed6444a8 100644 --- a/extensions/mssql/src/sqlToolsServer.ts +++ b/extensions/mssql/src/sqlToolsServer.ts @@ -22,6 +22,7 @@ import { CompletionExtensionParams, CompletionExtLoadRequest } from './contracts import { promises as fs } from 'fs'; import * as nls from 'vscode-nls'; import { LanguageExtensionService } from './languageExtension/languageExtensionService'; +import { SqlAssessmentService } from './sqlAssessment/sqlAssessmentService'; const localize = nls.loadMessageBundle(); const outputChannel = vscode.window.createOutputChannel(Constants.serviceName); @@ -157,7 +158,8 @@ function getClientOptions(context: AppContext): ClientOptions { SchemaCompareService.asFeature(context), LanguageExtensionService.asFeature(context), DacFxService.asFeature(context), - CmsService.asFeature(context) + CmsService.asFeature(context), + SqlAssessmentService.asFeature(context) ], outputChannel: new CustomOutputChannel() }; diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts index 2e2835e8fe..de53026283 100644 --- a/src/sql/workbench/api/common/sqlExtHostTypes.ts +++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts @@ -842,3 +842,14 @@ export interface TabbedPanelLayout { showIcon: boolean; alwaysShowTabs: boolean; } + +export const enum SqlAssessmentTargetType { + Server = 1, + Database = 2 +} + +export const enum SqlAssessmentResultItemKind { + RealResult = 0, + Warning = 1, + Error = 2 +}