More layering and compile strictness (#8973)

* add more folders to strictire compile, add more strict compile options

* update ci

* wip

* add more layering and fix issues

* add more strictness

* remove unnecessary assertion

* add missing checks

* fix indentation

* remove jsdoc
This commit is contained in:
Anthony Dresser
2020-01-29 20:35:11 -08:00
committed by GitHub
parent ddfdd43fc3
commit 56695be14a
185 changed files with 725 additions and 635 deletions

View File

@@ -0,0 +1,735 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Action } from 'vs/base/common/actions';
import * as nls from 'vs/nls';
import * as azdata from 'azdata';
import { INotificationService } from 'vs/platform/notification/common/notification';
import Severity from 'vs/base/common/severity';
import { JobHistoryComponent } from 'sql/workbench/contrib/jobManagement/browser/jobHistory.component';
import { IJobManagementService } from '../common/interfaces';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { JobsViewComponent } from 'sql/workbench/contrib/jobManagement/browser/jobsView.component';
import { AlertsViewComponent } from 'sql/workbench/contrib/jobManagement/browser/alertsView.component';
import { OperatorsViewComponent } from 'sql/workbench/contrib/jobManagement/browser/operatorsView.component';
import { ProxiesViewComponent } from 'sql/workbench/contrib/jobManagement/browser/proxiesView.component';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { IErrorMessageService } from 'sql/platform/errorMessage/common/errorMessageService';
import { JobManagementView } from 'sql/workbench/contrib/jobManagement/browser/jobManagementView';
import { NotebooksViewComponent } from 'sql/workbench/contrib/jobManagement/browser/notebooksView.component';
export const successLabel: string = nls.localize('jobaction.successLabel', "Success");
export const errorLabel: string = nls.localize('jobaction.faillabel', "Error");
export enum JobActions {
Run = 'run',
Stop = 'stop'
}
export class IJobActionInfo {
ownerUri?: string;
targetObject?: any;
component: JobManagementView;
}
// Job actions
export class JobsRefreshAction extends Action {
public static ID = 'jobaction.refresh';
public static LABEL = nls.localize('jobaction.refresh', "Refresh");
constructor(
) {
super(JobsRefreshAction.ID, JobsRefreshAction.LABEL, 'refreshIcon');
}
public run(context: IJobActionInfo): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
if (context) {
if (context.component) {
context.component.refreshJobs();
}
resolve(true);
} else {
reject(false);
}
});
}
}
export class NewJobAction extends Action {
public static ID = 'jobaction.newJob';
public static LABEL = nls.localize('jobaction.newJob', "New Job");
constructor(
) {
super(NewJobAction.ID, NewJobAction.LABEL, 'newStepIcon');
}
public run(context: IJobActionInfo): Promise<boolean> {
let component = context.component as JobsViewComponent;
return new Promise<boolean>(async (resolve, reject) => {
try {
await component.openCreateJobDialog();
resolve(true);
} catch (e) {
reject(e);
}
});
}
}
export class RunJobAction extends Action {
public static ID = 'jobaction.runJob';
public static LABEL = nls.localize('jobaction.run', "Run");
constructor(
@INotificationService private notificationService: INotificationService,
@IErrorMessageService private errorMessageService: IErrorMessageService,
@IJobManagementService private jobManagementService: IJobManagementService,
@IInstantiationService private instantationService: IInstantiationService,
@ITelemetryService private telemetryService: ITelemetryService
) {
super(RunJobAction.ID, RunJobAction.LABEL, 'start');
}
public run(context: IJobActionInfo): Promise<boolean> {
let jobName = context.targetObject.job.name;
let ownerUri = context.ownerUri;
let refreshAction = this.instantationService.createInstance(JobsRefreshAction);
this.telemetryService.publicLog(TelemetryKeys.RunAgentJob);
return new Promise<boolean>((resolve, reject) => {
this.jobManagementService.jobAction(ownerUri, jobName, JobActions.Run).then(async (result) => {
if (result.success) {
let startMsg = nls.localize('jobSuccessfullyStarted', ": The job was successfully started.");
this.notificationService.info(jobName + startMsg);
await refreshAction.run(context);
resolve(true);
} else {
this.errorMessageService.showDialog(Severity.Error, errorLabel, result.errorMessage);
resolve(false);
}
});
});
}
}
export class StopJobAction extends Action {
public static ID = 'jobaction.stopJob';
public static LABEL = nls.localize('jobaction.stop', "Stop");
constructor(
@INotificationService private notificationService: INotificationService,
@IErrorMessageService private errorMessageService: IErrorMessageService,
@IJobManagementService private jobManagementService: IJobManagementService,
@IInstantiationService private instantationService: IInstantiationService,
@ITelemetryService private telemetryService: ITelemetryService
) {
super(StopJobAction.ID, StopJobAction.LABEL, 'stop');
}
public run(context: IJobActionInfo): Promise<boolean> {
let jobName = context.targetObject.name;
let ownerUri = context.ownerUri;
let refreshAction = this.instantationService.createInstance(JobsRefreshAction);
this.telemetryService.publicLog(TelemetryKeys.StopAgentJob);
return new Promise<boolean>((resolve, reject) => {
this.jobManagementService.jobAction(ownerUri, jobName, JobActions.Stop).then(async (result) => {
if (result.success) {
await refreshAction.run(context);
let stopMsg = nls.localize('jobSuccessfullyStopped', ": The job was successfully stopped.");
this.notificationService.info(jobName + stopMsg);
resolve(true);
} else {
this.errorMessageService.showDialog(Severity.Error, 'Error', result.errorMessage);
resolve(false);
}
});
});
}
}
export class EditJobAction extends Action {
public static ID = 'jobaction.editJob';
public static LABEL = nls.localize('jobaction.editJob', "Edit Job");
constructor(
@ICommandService private _commandService: ICommandService
) {
super(EditJobAction.ID, EditJobAction.LABEL, 'edit');
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
this._commandService.executeCommand(
'agent.openJobDialog',
actionInfo.ownerUri,
actionInfo.targetObject.job);
return Promise.resolve(true);
}
}
export class OpenMaterializedNotebookAction extends Action {
public static ID = 'notebookAction.openNotebook';
public static LABEL = nls.localize('notebookAction.openNotebook', "Open");
constructor() {
super(OpenMaterializedNotebookAction.ID, OpenMaterializedNotebookAction.LABEL, 'openNotebook');
}
public run(context: any): Promise<boolean> {
context.component.openNotebook(context.history);
return Promise.resolve(true);
}
}
export class DeleteJobAction extends Action {
public static ID = 'jobaction.deleteJob';
public static LABEL = nls.localize('jobaction.deleteJob', "Delete Job");
constructor(
@INotificationService private _notificationService: INotificationService,
@IErrorMessageService private _errorMessageService: IErrorMessageService,
@IJobManagementService private _jobService: IJobManagementService,
@ITelemetryService private _telemetryService: ITelemetryService
) {
super(DeleteJobAction.ID, DeleteJobAction.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
let self = this;
let job = actionInfo.targetObject.job as azdata.AgentJobInfo;
self._notificationService.prompt(
Severity.Info,
nls.localize('jobaction.deleteJobConfirm', "Are you sure you'd like to delete the job '{0}'?", job.name),
[{
label: DeleteJobAction.LABEL,
run: () => {
this._telemetryService.publicLog(TelemetryKeys.DeleteAgentJob);
self._jobService.deleteJob(actionInfo.ownerUri, actionInfo.targetObject.job).then(result => {
if (!result || !result.success) {
let errorMessage = nls.localize("jobaction.failedToDeleteJob", "Could not delete job '{0}'.\nError: {1}",
job.name, result.errorMessage ? result.errorMessage : 'Unknown error');
self._errorMessageService.showDialog(Severity.Error, errorLabel, errorMessage);
} else {
let successMessage = nls.localize('jobaction.deletedJob', "The job was successfully deleted");
self._notificationService.info(successMessage);
}
});
}
}, {
label: DeleteAlertAction.CancelLabel,
run: () => { }
}]
);
return Promise.resolve(true);
}
}
// Step Actions
export class NewStepAction extends Action {
public static ID = 'jobaction.newStep';
public static LABEL = nls.localize('jobaction.newStep', "New Step");
constructor(
@ICommandService private _commandService: ICommandService
) {
super(NewStepAction.ID, NewStepAction.LABEL, 'newStepIcon');
}
public run(context: JobHistoryComponent): Promise<boolean> {
let ownerUri = context.ownerUri;
let server = context.serverName;
let jobInfo = context.agentJobInfo;
return new Promise<boolean>((resolve, reject) => {
resolve(this._commandService.executeCommand('agent.openNewStepDialog', ownerUri, server, jobInfo, null));
});
}
}
export class DeleteStepAction extends Action {
public static ID = 'jobaction.deleteStep';
public static LABEL = nls.localize('jobaction.deleteStep', "Delete Step");
constructor(
@INotificationService private _notificationService: INotificationService,
@IErrorMessageService private _errorMessageService: IErrorMessageService,
@IJobManagementService private _jobService: IJobManagementService,
@IInstantiationService private instantationService: IInstantiationService,
@ITelemetryService private _telemetryService: ITelemetryService
) {
super(DeleteStepAction.ID, DeleteStepAction.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
let self = this;
let step = actionInfo.targetObject as azdata.AgentJobStepInfo;
let refreshAction = this.instantationService.createInstance(JobsRefreshAction);
self._notificationService.prompt(
Severity.Info,
nls.localize('jobaction.deleteStepConfirm', "Are you sure you'd like to delete the step '{0}'?", step.stepName),
[{
label: DeleteStepAction.LABEL,
run: () => {
this._telemetryService.publicLog(TelemetryKeys.DeleteAgentJobStep);
self._jobService.deleteJobStep(actionInfo.ownerUri, actionInfo.targetObject).then(async (result) => {
if (!result || !result.success) {
let errorMessage = nls.localize('jobaction.failedToDeleteStep', "Could not delete step '{0}'.\nError: {1}",
step.stepName, result.errorMessage ? result.errorMessage : 'Unknown error');
self._errorMessageService.showDialog(Severity.Error, errorLabel, errorMessage);
await refreshAction.run(actionInfo);
} else {
let successMessage = nls.localize('jobaction.deletedStep', "The job step was successfully deleted");
self._notificationService.info(successMessage);
}
});
}
}, {
label: DeleteAlertAction.CancelLabel,
run: () => { }
}]
);
return Promise.resolve(true);
}
}
// Alert Actions
export class NewAlertAction extends Action {
public static ID = 'jobaction.newAlert';
public static LABEL = nls.localize('jobaction.newAlert', "New Alert");
constructor(
) {
super(NewAlertAction.ID, NewAlertAction.LABEL, 'newStepIcon');
}
public run(context: IJobActionInfo): Promise<boolean> {
let component = context.component as AlertsViewComponent;
return new Promise<boolean>((resolve, reject) => {
try {
component.openCreateAlertDialog();
resolve(true);
} catch (e) {
reject(e);
}
});
}
}
export class EditAlertAction extends Action {
public static ID = 'jobaction.editAlert';
public static LABEL = nls.localize('jobaction.editAlert', "Edit Alert");
constructor(
@ICommandService private _commandService: ICommandService
) {
super(EditAlertAction.ID, EditAlertAction.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
this._commandService.executeCommand(
'agent.openAlertDialog',
actionInfo.ownerUri,
actionInfo.targetObject.jobInfo,
actionInfo.targetObject.alertInfo);
return Promise.resolve(true);
}
}
export class DeleteAlertAction extends Action {
public static ID = 'jobaction.deleteAlert';
public static LABEL = nls.localize('jobaction.deleteAlert', "Delete Alert");
public static CancelLabel = nls.localize('jobaction.Cancel', "Cancel");
constructor(
@INotificationService private _notificationService: INotificationService,
@IErrorMessageService private _errorMessageService: IErrorMessageService,
@IJobManagementService private _jobService: IJobManagementService,
@ITelemetryService private _telemetryService: ITelemetryService
) {
super(DeleteAlertAction.ID, DeleteAlertAction.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
let self = this;
let alert = actionInfo.targetObject.alertInfo as azdata.AgentAlertInfo;
self._notificationService.prompt(
Severity.Info,
nls.localize('jobaction.deleteAlertConfirm', "Are you sure you'd like to delete the alert '{0}'?", alert.name),
[{
label: DeleteAlertAction.LABEL,
run: () => {
this._telemetryService.publicLog(TelemetryKeys.DeleteAgentAlert);
self._jobService.deleteAlert(actionInfo.ownerUri, alert).then(result => {
if (!result || !result.success) {
let errorMessage = nls.localize("jobaction.failedToDeleteAlert", "Could not delete alert '{0}'.\nError: {1}",
alert.name, result.errorMessage ? result.errorMessage : 'Unknown error');
self._errorMessageService.showDialog(Severity.Error, errorLabel, errorMessage);
} else {
let successMessage = nls.localize('jobaction.deletedAlert', "The alert was successfully deleted");
self._notificationService.info(successMessage);
}
});
}
}, {
label: DeleteAlertAction.CancelLabel,
run: () => { }
}]
);
return Promise.resolve(true);
}
}
// Operator Actions
export class NewOperatorAction extends Action {
public static ID = 'jobaction.newOperator';
public static LABEL = nls.localize('jobaction.newOperator', "New Operator");
constructor(
) {
super(NewOperatorAction.ID, NewOperatorAction.LABEL, 'newStepIcon');
}
public run(context: IJobActionInfo): Promise<boolean> {
let component = context.component as OperatorsViewComponent;
return new Promise<boolean>((resolve, reject) => {
try {
component.openCreateOperatorDialog();
resolve(true);
} catch (e) {
reject(e);
}
});
}
}
export class EditOperatorAction extends Action {
public static ID = 'jobaction.editAlert';
public static LABEL = nls.localize('jobaction.editOperator', "Edit Operator");
constructor(
@ICommandService private _commandService: ICommandService
) {
super(EditOperatorAction.ID, EditOperatorAction.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
this._commandService.executeCommand(
'agent.openOperatorDialog',
actionInfo.ownerUri,
actionInfo.targetObject);
return Promise.resolve(true);
}
}
export class DeleteOperatorAction extends Action {
public static ID = 'jobaction.deleteOperator';
public static LABEL = nls.localize('jobaction.deleteOperator', "Delete Operator");
constructor(
@INotificationService private _notificationService: INotificationService,
@IErrorMessageService private _errorMessageService: IErrorMessageService,
@IJobManagementService private _jobService: IJobManagementService,
@ITelemetryService private _telemetryService: ITelemetryService
) {
super(DeleteOperatorAction.ID, DeleteOperatorAction.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
const self = this;
let operator = actionInfo.targetObject as azdata.AgentOperatorInfo;
self._notificationService.prompt(
Severity.Info,
nls.localize('jobaction.deleteOperatorConfirm', "Are you sure you'd like to delete the operator '{0}'?", operator.name),
[{
label: DeleteOperatorAction.LABEL,
run: () => {
self._telemetryService.publicLog(TelemetryKeys.DeleteAgentOperator);
self._jobService.deleteOperator(actionInfo.ownerUri, actionInfo.targetObject).then(result => {
if (!result || !result.success) {
let errorMessage = nls.localize("jobaction.failedToDeleteOperator", "Could not delete operator '{0}'.\nError: {1}",
operator.name, result.errorMessage ? result.errorMessage : 'Unknown error');
self._errorMessageService.showDialog(Severity.Error, errorLabel, errorMessage);
} else {
let successMessage = nls.localize('joaction.deletedOperator', "The operator was deleted successfully");
self._notificationService.info(successMessage);
}
});
}
}, {
label: DeleteAlertAction.CancelLabel,
run: () => { }
}]
);
return Promise.resolve(true);
}
}
// Proxy Actions
export class NewProxyAction extends Action {
public static ID = 'jobaction.newProxy';
public static LABEL = nls.localize('jobaction.newProxy', "New Proxy");
constructor(
) {
super(NewProxyAction.ID, NewProxyAction.LABEL, 'newStepIcon');
}
public run(context: IJobActionInfo): Promise<boolean> {
let component = context.component as ProxiesViewComponent;
return new Promise<boolean>((resolve, reject) => {
try {
component.openCreateProxyDialog();
resolve(true);
} catch (e) {
reject(e);
}
});
}
}
export class EditProxyAction extends Action {
public static ID = 'jobaction.editProxy';
public static LABEL = nls.localize('jobaction.editProxy', "Edit Proxy");
constructor(
@ICommandService private _commandService: ICommandService,
@IJobManagementService private _jobManagementService: IJobManagementService
) {
super(EditProxyAction.ID, EditProxyAction.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
return Promise.resolve(this._jobManagementService.getCredentials(actionInfo.ownerUri).then((result) => {
if (result && result.credentials) {
this._commandService.executeCommand(
'agent.openProxyDialog',
actionInfo.ownerUri,
actionInfo.targetObject,
result.credentials);
return true;
} else {
return false;
}
}));
}
}
export class DeleteProxyAction extends Action {
public static ID = 'jobaction.deleteProxy';
public static LABEL = nls.localize('jobaction.deleteProxy', "Delete Proxy");
constructor(
@INotificationService private _notificationService: INotificationService,
@IErrorMessageService private _errorMessageService: IErrorMessageService,
@IJobManagementService private _jobService: IJobManagementService,
@ITelemetryService private _telemetryService: ITelemetryService
) {
super(DeleteProxyAction.ID, DeleteProxyAction.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
let self = this;
let proxy = actionInfo.targetObject as azdata.AgentProxyInfo;
self._notificationService.prompt(
Severity.Info,
nls.localize('jobaction.deleteProxyConfirm', "Are you sure you'd like to delete the proxy '{0}'?", proxy.accountName),
[{
label: DeleteProxyAction.LABEL,
run: () => {
this._telemetryService.publicLog(TelemetryKeys.DeleteAgentProxy);
self._jobService.deleteProxy(actionInfo.ownerUri, actionInfo.targetObject).then(result => {
if (!result || !result.success) {
let errorMessage = nls.localize("jobaction.failedToDeleteProxy", "Could not delete proxy '{0}'.\nError: {1}",
proxy.accountName, result.errorMessage ? result.errorMessage : 'Unknown error');
self._errorMessageService.showDialog(Severity.Error, errorLabel, errorMessage);
} else {
let successMessage = nls.localize('jobaction.deletedProxy', "The proxy was deleted successfully");
self._notificationService.info(successMessage);
}
});
}
}, {
label: DeleteAlertAction.CancelLabel,
run: () => { }
}]
);
return Promise.resolve(true);
}
}
//Notebook Actions
export class NewNotebookJobAction extends Action {
public static ID = 'notebookaction.newJob';
public static LABEL = nls.localize('notebookaction.newJob', "New Notebook Job");
constructor(
) {
super(NewNotebookJobAction.ID, NewNotebookJobAction.LABEL, 'newStepIcon');
}
public async run(context: IJobActionInfo): Promise<boolean> {
let component = context.component as NotebooksViewComponent;
await component.openCreateNotebookDialog();
return true;
}
}
export class EditNotebookJobAction extends Action {
public static ID = 'notebookaction.editNotebook';
public static LABEL = nls.localize('notebookaction.editJob', "Edit");
constructor(
@ICommandService private _commandService: ICommandService
) {
super(EditNotebookJobAction.ID, EditNotebookJobAction.LABEL, 'edit');
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
this._commandService.executeCommand(
'agent.openNotebookDialog',
actionInfo.ownerUri,
actionInfo.targetObject.job);
return Promise.resolve(true);
}
}
export class OpenTemplateNotebookAction extends Action {
public static ID = 'notebookaction.openTemplate';
public static LABEL = nls.localize('notebookaction.openNotebook', "Open Template Notebook");
constructor() {
super(OpenTemplateNotebookAction.ID, OpenTemplateNotebookAction.LABEL, 'opennotebook');
}
public run(actionInfo: any): Promise<boolean> {
actionInfo.component.openTemplateNotebook();
return Promise.resolve(true);
}
}
export class DeleteNotebookAction extends Action {
public static ID = 'notebookaction.deleteNotebook';
public static LABEL = nls.localize('notebookaction.deleteNotebook', "Delete");
constructor(
@INotificationService private _notificationService: INotificationService,
@IErrorMessageService private _errorMessageService: IErrorMessageService,
@IJobManagementService private _jobService: IJobManagementService,
@IInstantiationService private instantationService: IInstantiationService,
@ITelemetryService private _telemetryService: ITelemetryService
) {
super(DeleteNotebookAction.ID, DeleteNotebookAction.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
let self = this;
let notebook = actionInfo.targetObject.job as azdata.AgentNotebookInfo;
let refreshAction = this.instantationService.createInstance(JobsRefreshAction);
self._notificationService.prompt(
Severity.Info,
nls.localize('jobaction.deleteNotebookConfirm', "Are you sure you'd like to delete the notebook '{0}'?", notebook.name),
[{
label: DeleteNotebookAction.LABEL,
run: () => {
this._telemetryService.publicLog(TelemetryKeys.DeleteAgentJob);
self._jobService.deleteNotebook(actionInfo.ownerUri, actionInfo.targetObject.job).then(async (result) => {
if (!result || !result.success) {
await refreshAction.run(actionInfo);
let errorMessage = nls.localize("jobaction.failedToDeleteNotebook", "Could not delete notebook '{0}'.\nError: {1}",
notebook.name, result.errorMessage ? result.errorMessage : 'Unknown error');
self._errorMessageService.showDialog(Severity.Error, errorLabel, errorMessage);
} else {
let successMessage = nls.localize('jobaction.deletedNotebook', "The notebook was successfully deleted");
self._notificationService.info(successMessage);
}
});
}
}, {
label: DeleteAlertAction.CancelLabel,
run: () => { }
}]
);
return Promise.resolve(true);
}
}
export class PinNotebookMaterializedAction extends Action {
public static ID = 'notebookaction.openTemplate';
public static LABEL = nls.localize('notebookaction.pinNotebook', "Pin");
constructor() {
super(PinNotebookMaterializedAction.ID, PinNotebookMaterializedAction.LABEL);
}
public run(actionInfo: any): Promise<boolean> {
actionInfo.component.toggleNotebookPin(actionInfo.history, true);
return Promise.resolve(true);
}
}
export class DeleteMaterializedNotebookAction extends Action {
public static ID = 'notebookaction.deleteMaterializedNotebook';
public static LABEL = nls.localize('notebookaction.deleteMaterializedNotebook', "Delete");
constructor() {
super(DeleteMaterializedNotebookAction.ID, DeleteMaterializedNotebookAction.LABEL);
}
public run(actionInfo: any): Promise<boolean> {
actionInfo.component.deleteMaterializedNotebook(actionInfo.history);
return Promise.resolve(true);
}
}
export class UnpinNotebookMaterializedAction extends Action {
public static ID = 'notebookaction.unpinNotebook';
public static LABEL = nls.localize('notebookaction.unpinNotebook', "Unpin");
constructor() {
super(UnpinNotebookMaterializedAction.ID, UnpinNotebookMaterializedAction.LABEL);
}
public run(actionInfo: any): Promise<boolean> {
actionInfo.component.toggleNotebookPin(actionInfo.history, false);
return Promise.resolve(true);
}
}
export class RenameNotebookMaterializedAction extends Action {
public static ID = 'notebookaction.openTemplate';
public static LABEL = nls.localize('notebookaction.renameNotebook', "Rename");
constructor() {
super(RenameNotebookMaterializedAction.ID, RenameNotebookMaterializedAction.LABEL);
}
public run(actionInfo: any): Promise<boolean> {
actionInfo.component.renameNotebook(actionInfo.history);
return Promise.resolve(true);
}
}
export class OpenLatestRunMaterializedNotebook extends Action {
public static ID = 'notebookaction.openLatestRun';
public static LABEL = nls.localize('notebookaction.openLatestRun', "Open Latest Run");
constructor() {
super(OpenLatestRunMaterializedNotebook.ID, OpenLatestRunMaterializedNotebook.LABEL);
}
public run(actionInfo: IJobActionInfo): Promise<boolean> {
actionInfo.component.openLastNRun(actionInfo.targetObject.job, 0, 1);
return Promise.resolve(true);
}
}

View File

@@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { find } from 'vs/base/common/arrays';
export class JobManagementUtilities {
public static startIconClass: string = 'action-label codicon runJobIcon';
public static stopIconClass: string = 'action-label codicon stopJobIcon';
public static jobMessageLength: number = 110;
public static convertToStatusString(status: number): string {
switch (status) {
case (0): return nls.localize('agentUtilities.failed', "Failed");
case (1): return nls.localize('agentUtilities.succeeded', "Succeeded");
case (2): return nls.localize('agentUtilities.retry', "Retry");
case (3): return nls.localize('agentUtilities.canceled', "Cancelled");
case (4): return nls.localize('agentUtilities.inProgress', "In Progress");
case (5): return nls.localize('agentUtilities.statusUnknown', "Status Unknown");
default: return nls.localize('agentUtilities.statusUnknown', "Status Unknown");
}
}
public static convertToExecutionStatusString(status: number): string {
switch (status) {
case (1): return nls.localize('agentUtilities.executing', "Executing");
case (2): return nls.localize('agentUtilities.waitingForThread', "Waiting for Thread");
case (3): return nls.localize('agentUtilities.betweenRetries', "Between Retries");
case (4): return nls.localize('agentUtilities.idle', "Idle");
case (5): return nls.localize('agentUtilities.suspended', "Suspended");
case (6): return nls.localize('agentUtilities.obsolete', "[Obsolete]");
case (7): return 'PerformingCompletionActions';
default: return nls.localize('agentUtilities.statusUnknown', "Status Unknown");
}
}
public static convertToResponse(bool: boolean) {
return bool ? nls.localize('agentUtilities.yes', "Yes") : nls.localize('agentUtilities.no', "No");
}
public static convertToNextRun(date: string) {
if (find(date, x => x === '1/1/0001')) {
return nls.localize('agentUtilities.notScheduled', "Not Scheduled");
} else {
return date;
}
}
public static convertToLastRun(date: string) {
if (find(date, x => x === '1/1/0001')) {
return nls.localize('agentUtilities.neverRun', "Never Run");
} else {
return date;
}
}
public static setRunnable(icon: HTMLElement, index: number) {
if (find(icon.className, x => x === 'non-runnable')) {
icon.className = icon.className.slice(0, index);
}
}
public static getActionIconClassName(startIcon: HTMLElement, stopIcon: HTMLElement, executionStatus: number) {
this.setRunnable(startIcon, JobManagementUtilities.startIconClass.length);
this.setRunnable(stopIcon, JobManagementUtilities.stopIconClass.length);
switch (executionStatus) {
case (1): // executing
startIcon.className += ' non-runnable';
return;
case (2): // Waiting for thread
startIcon.className += ' non-runnable';
return;
case (3): // Between retries
startIcon.className += ' non-runnable';
return;
case (4): //Idle
stopIcon.className += ' non-runnable';
return;
case (5): // Suspended
stopIcon.className += ' non-runnable';
return;
case (6): //obsolete
startIcon.className += ' non-runnable';
stopIcon.className += ' non-runnable';
return;
case (7): //Performing Completion Actions
startIcon.className += ' non-runnable';
return;
default:
return;
}
}
public static convertDurationToSeconds(duration: string): number {
let split = duration.split(':');
let seconds = (+split[0]) * 60 * 60 + (+split[1]) * 60 + (+split[2]);
return seconds;
}
public static convertColFieldToName(colField: string) {
switch (colField) {
case ('name'):
return 'Name';
case ('lastRun'):
return 'Last Run';
case ('nextRun'):
return 'Next Run';
case ('enabled'):
return 'Enabled';
case ('status'):
return 'Status';
case ('category'):
return 'Category';
case ('runnable'):
return 'Runnable';
case ('schedule'):
return 'Schedule';
case ('lastRunOutcome'):
return 'Last Run Outcome';
}
return '';
}
public static convertColNameToField(columnName: string) {
switch (columnName) {
case ('Name'):
return 'name';
case ('Last Run'):
return 'lastRun';
case ('Next Run'):
return 'nextRun';
case ('Enabled'):
return 'enabled';
case ('Status'):
return 'status';
case ('Category'):
return 'category';
case ('Runnable'):
return 'runnable';
case ('Schedule'):
return 'schedule';
case ('Last Run Outcome'):
return 'lastRunOutcome';
}
return '';
}
}

View File

@@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { JobCacheObject, AlertsCacheObject, ProxiesCacheObject, OperatorsCacheObject, NotebookCacheObject } from './jobManagementService';
import { Event } from 'vs/base/common/event';
export const SERVICE_ID = 'jobManagementService';
export const IJobManagementService = createDecorator<IJobManagementService>(SERVICE_ID);
export interface IJobManagementService {
_serviceBrand: undefined;
onDidChange: Event<void>;
registerProvider(providerId: string, provider: azdata.AgentServicesProvider): void;
fireOnDidChange(): void;
getJobs(connectionUri: string): Thenable<azdata.AgentJobsResult>;
getJobHistory(connectionUri: string, jobID: string, jobName: string): Thenable<azdata.AgentJobHistoryResult>;
deleteJob(connectionUri: string, job: azdata.AgentJobInfo): Thenable<azdata.ResultStatus>;
deleteJobStep(connectionUri: string, step: azdata.AgentJobStepInfo): Thenable<azdata.ResultStatus>;
getNotebooks(connectionUri: string): Thenable<azdata.AgentNotebooksResult>;
getNotebookHistory(connectionUri: string, jobId: string, jobName: string, targetDatabase: string): Thenable<azdata.AgentNotebookHistoryResult>;
getMaterialziedNotebook(connectionUri: string, targetDatabase: string, notebookMaterializedId: number): Thenable<azdata.AgentNotebookMaterializedResult>;
getTemplateNotebook(connectionUri: string, targetDatabase: string, jobId: string): Thenable<azdata.AgentNotebookTemplateResult>;
deleteNotebook(connectionUri: string, notebook: azdata.AgentNotebookInfo): Thenable<azdata.ResultStatus>;
deleteMaterializedNotebook(connectionUri: string, agentNotebookHistory: azdata.AgentNotebookHistoryInfo, targetDatabase: string): Thenable<azdata.ResultStatus>;
updateNotebookMaterializedName(connectionUri: string, agentNotebookHistory: azdata.AgentNotebookHistoryInfo, targetDatabase: string, name: string);
updateNotebookMaterializedPin(connectionUri: string, agentNotebookHistory: azdata.AgentNotebookHistoryInfo, targetDatabase: string, pin: boolean);
getAlerts(connectionUri: string): Thenable<azdata.AgentAlertsResult>;
deleteAlert(connectionUri: string, alert: azdata.AgentAlertInfo): Thenable<azdata.ResultStatus>;
getOperators(connectionUri: string): Thenable<azdata.AgentOperatorsResult>;
deleteOperator(connectionUri: string, operator: azdata.AgentOperatorInfo): Thenable<azdata.ResultStatus>;
getProxies(connectionUri: string): Thenable<azdata.AgentProxiesResult>;
deleteProxy(connectionUri: string, proxy: azdata.AgentProxyInfo): Thenable<azdata.ResultStatus>;
getCredentials(connectionUri: string): Thenable<azdata.GetCredentialsResult>;
jobAction(connectionUri: string, jobName: string, action: string): Thenable<azdata.ResultStatus>;
addToCache(server: string, cache: JobCacheObject | OperatorsCacheObject | NotebookCacheObject);
jobCacheObjectMap: { [server: string]: JobCacheObject; };
notebookCacheObjectMap: { [server: string]: NotebookCacheObject; };
operatorsCacheObjectMap: { [server: string]: OperatorsCacheObject; };
alertsCacheObjectMap: { [server: string]: AlertsCacheObject; };
proxiesCacheObjectMap: { [server: string]: ProxiesCacheObject };
addToCache(server: string, cache: JobCacheObject | ProxiesCacheObject | AlertsCacheObject | OperatorsCacheObject | NotebookCacheObject);
}

View File

@@ -0,0 +1,509 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls';
import * as azdata from 'azdata';
import { IJobManagementService } from 'sql/workbench/services/jobManagement/common/interfaces';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { Event, Emitter } from 'vs/base/common/event';
export class JobManagementService implements IJobManagementService {
_serviceBrand: undefined;
private _onDidChange = new Emitter<void>();
public readonly onDidChange: Event<void> = this._onDidChange.event;
private _providers: { [handle: string]: azdata.AgentServicesProvider; } = Object.create(null);
private _jobCacheObjectMap: { [server: string]: JobCacheObject; } = {};
private _operatorsCacheObjectMap: { [server: string]: OperatorsCacheObject; } = {};
private _alertsCacheObject: { [server: string]: AlertsCacheObject; } = {};
private _proxiesCacheObjectMap: { [server: string]: ProxiesCacheObject; } = {};
private _notebookCacheObjectMap: { [server: string]: NotebookCacheObject; } = {};
constructor(
@IConnectionManagementService private _connectionService: IConnectionManagementService
) {
}
public fireOnDidChange(): void {
this._onDidChange.fire(void 0);
}
// Jobs
public getJobs(connectionUri: string): Thenable<azdata.AgentJobsResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getJobs(connectionUri);
});
}
public deleteJob(connectionUri: string, job: azdata.AgentJobInfo): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.deleteJob(connectionUri, job);
});
}
public getJobHistory(connectionUri: string, jobID: string, jobName: string): Thenable<azdata.AgentJobHistoryResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getJobHistory(connectionUri, jobID, jobName);
});
}
public jobAction(connectionUri: string, jobName: string, action: string): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.jobAction(connectionUri, jobName, action);
});
}
// Steps
public deleteJobStep(connectionUri: string, stepInfo: azdata.AgentJobStepInfo): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.deleteJobStep(connectionUri, stepInfo);
});
}
// Notebooks
public getNotebooks(connectionUri: string): Thenable<azdata.AgentNotebooksResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getNotebooks(connectionUri);
});
}
public getNotebookHistory(connectionUri: string, jobID: string, jobName: string, targetDatabase: string): Thenable<azdata.AgentNotebookHistoryResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getNotebookHistory(connectionUri, jobID, jobName, targetDatabase);
});
}
public getMaterialziedNotebook(connectionUri: string, targetDatabase: string, notebookMaterializedId: number): Thenable<azdata.AgentNotebookMaterializedResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getMaterializedNotebook(connectionUri, targetDatabase, notebookMaterializedId);
});
}
public getTemplateNotebook(connectionUri: string, targetDatabase: string, jobId: string): Thenable<azdata.AgentNotebookTemplateResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getTemplateNotebook(connectionUri, targetDatabase, jobId);
});
}
public deleteNotebook(connectionUri: string, notebook: azdata.AgentNotebookInfo): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.deleteNotebook(connectionUri, notebook);
});
}
public deleteMaterializedNotebook(connectionUri: string, agentNotebookHistory: azdata.AgentNotebookHistoryInfo, targetDatabase: string): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.deleteMaterializedNotebook(connectionUri, agentNotebookHistory, targetDatabase);
});
}
public updateNotebookMaterializedName(connectionUri: string, agentNotebookHistory: azdata.AgentNotebookHistoryInfo, targetDatabase: string, name: string): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.updateNotebookMaterializedName(connectionUri, agentNotebookHistory, targetDatabase, name);
});
}
public updateNotebookMaterializedPin(connectionUri: string, agentNotebookHistory: azdata.AgentNotebookHistoryInfo, targetDatabase: string, pin: boolean): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.updateNotebookMaterializedPin(connectionUri, agentNotebookHistory, targetDatabase, pin);
});
}
// Alerts
public getAlerts(connectionUri: string): Thenable<azdata.AgentAlertsResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getAlerts(connectionUri);
});
}
public deleteAlert(connectionUri: string, alert: azdata.AgentAlertInfo): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.deleteAlert(connectionUri, alert);
});
}
// Operators
public getOperators(connectionUri: string): Thenable<azdata.AgentOperatorsResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getOperators(connectionUri);
});
}
public deleteOperator(connectionUri: string, operator: azdata.AgentOperatorInfo): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.deleteOperator(connectionUri, operator);
});
}
// Proxies
public getProxies(connectionUri: string): Thenable<azdata.AgentProxiesResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getProxies(connectionUri);
});
}
public deleteProxy(connectionUri: string, proxy: azdata.AgentProxyInfo): Thenable<azdata.ResultStatus> {
return this._runAction(connectionUri, (runner) => {
return runner.deleteProxy(connectionUri, proxy);
});
}
public getCredentials(connectionUri: string): Thenable<azdata.GetCredentialsResult> {
return this._runAction(connectionUri, (runner) => {
return runner.getCredentials(connectionUri);
});
}
private _runAction<T>(uri: string, action: (handler: azdata.AgentServicesProvider) => Thenable<T>): Thenable<T> {
let providerId: string = this._connectionService.getProviderIdFromUri(uri);
if (!providerId) {
return Promise.reject(new Error(localize('providerIdNotValidError', "Connection is required in order to interact with JobManagementService")));
}
let handler = this._providers[providerId];
if (handler) {
return action(handler);
} else {
return Promise.reject(new Error(localize('noHandlerRegistered', "No Handler Registered")));
}
}
public registerProvider(providerId: string, provider: azdata.AgentServicesProvider): void {
this._providers[providerId] = provider;
}
public get jobCacheObjectMap(): { [server: string]: JobCacheObject; } {
return this._jobCacheObjectMap;
}
public get alertsCacheObjectMap(): { [server: string]: AlertsCacheObject; } {
return this._alertsCacheObject;
}
public get notebookCacheObjectMap(): { [server: string]: NotebookCacheObject; } {
return this._notebookCacheObjectMap;
}
public get proxiesCacheObjectMap(): { [server: string]: ProxiesCacheObject; } {
return this._proxiesCacheObjectMap;
}
public get operatorsCacheObjectMap(): { [server: string]: OperatorsCacheObject } {
return this._operatorsCacheObjectMap;
}
public addToCache(server: string, cacheObject: JobCacheObject | OperatorsCacheObject | ProxiesCacheObject | AlertsCacheObject | NotebookCacheObject) {
if (cacheObject instanceof JobCacheObject) {
this._jobCacheObjectMap[server] = cacheObject;
} else if (cacheObject instanceof OperatorsCacheObject) {
this._operatorsCacheObjectMap[server] = cacheObject;
} else if (cacheObject instanceof AlertsCacheObject) {
this._alertsCacheObject[server] = cacheObject;
} else if (cacheObject instanceof ProxiesCacheObject) {
this._proxiesCacheObjectMap[server] = cacheObject;
} else if (cacheObject instanceof NotebookCacheObject) {
this._notebookCacheObjectMap[server] = cacheObject;
}
}
}
/**
* Server level caching of jobs/job histories and their views
*/
export class JobCacheObject {
_serviceBrand: undefined;
private _jobs: azdata.AgentJobInfo[] = [];
private _jobHistories: { [jobID: string]: azdata.AgentJobHistoryInfo[]; } = {};
private _jobSteps: { [jobID: string]: azdata.AgentJobStepInfo[]; } = {};
private _jobAlerts: { [jobID: string]: azdata.AgentAlertInfo[]; } = {};
private _jobSchedules: { [jobID: string]: azdata.AgentJobScheduleInfo[]; } = {};
private _runCharts: { [jobID: string]: string[]; } = {};
private _prevJobID: string;
private _serverName: string;
private _dataView: Slick.Data.DataView<any>;
/* Getters */
public get jobs(): azdata.AgentJobInfo[] {
return this._jobs;
}
public get jobHistories(): { [jobID: string]: azdata.AgentJobHistoryInfo[] } {
return this._jobHistories;
}
public get prevJobID(): string {
return this._prevJobID;
}
public getJobHistory(jobID: string): azdata.AgentJobHistoryInfo[] {
return this._jobHistories[jobID];
}
public get serverName(): string {
return this._serverName;
}
public get dataView(): Slick.Data.DataView<any> {
return this._dataView;
}
public getRunChart(jobID: string): string[] {
return this._runCharts[jobID];
}
public getJobSteps(jobID: string): azdata.AgentJobStepInfo[] {
return this._jobSteps[jobID];
}
public getJobAlerts(jobID: string): azdata.AgentAlertInfo[] {
return this._jobAlerts[jobID];
}
public getJobSchedules(jobID: string): azdata.AgentJobScheduleInfo[] {
return this._jobSchedules[jobID];
}
/* Setters */
public set jobs(value: azdata.AgentJobInfo[]) {
this._jobs = value;
}
public set jobHistories(value: { [jobID: string]: azdata.AgentJobHistoryInfo[]; }) {
this._jobHistories = value;
}
public set prevJobID(value: string) {
this._prevJobID = value;
}
public setJobHistory(jobID: string, value: azdata.AgentJobHistoryInfo[]) {
this._jobHistories[jobID] = value;
}
public setRunChart(jobID: string, value: string[]) {
this._runCharts[jobID] = value;
}
public set serverName(value: string) {
this._serverName = value;
}
public set dataView(value: Slick.Data.DataView<any>) {
this._dataView = value;
}
public setJobSteps(jobID: string, value: azdata.AgentJobStepInfo[]) {
this._jobSteps[jobID] = value;
}
public setJobAlerts(jobID: string, value: azdata.AgentAlertInfo[]) {
this._jobAlerts[jobID] = value;
}
public setJobSchedules(jobID: string, value: azdata.AgentJobScheduleInfo[]) {
this._jobSchedules[jobID] = value;
}
}
/**
* Server level caching of Operators
*/
export class NotebookCacheObject {
_serviceBrand: any;
private _notebooks: azdata.AgentNotebookInfo[] = [];
private _notebookHistories: { [jobID: string]: azdata.AgentNotebookHistoryInfo[]; } = {};
private _jobSteps: { [jobID: string]: azdata.AgentJobStepInfo[]; } = {};
private _jobSchedules: { [jobID: string]: azdata.AgentJobScheduleInfo[]; } = {};
private _runCharts: { [jobID: string]: string[]; } = {};
private _prevJobID: string;
private _serverName: string;
private _dataView: Slick.Data.DataView<any>;
/* Getters */
public get notebooks(): azdata.AgentNotebookInfo[] {
return this._notebooks;
}
public get notebookHistories(): { [jobID: string]: azdata.AgentNotebookHistoryInfo[] } {
return this._notebookHistories;
}
public get prevJobID(): string {
return this._prevJobID;
}
public getNotebookHistory(jobID: string): azdata.AgentNotebookHistoryInfo[] {
return this._notebookHistories[jobID];
}
public get serverName(): string {
return this._serverName;
}
public get dataView(): Slick.Data.DataView<any> {
return this._dataView;
}
public getRunChart(jobID: string): string[] {
return this._runCharts[jobID];
}
public getJobSteps(jobID: string): azdata.AgentJobStepInfo[] {
return this._jobSteps[jobID];
}
public getJobSchedules(jobID: string): azdata.AgentJobScheduleInfo[] {
return this._jobSchedules[jobID];
}
/* Setters */
public set notebooks(value: azdata.AgentNotebookInfo[]) {
this._notebooks = value;
}
public set notebookHistories(value: { [jobID: string]: azdata.AgentNotebookHistoryInfo[]; }) {
this._notebookHistories = value;
}
public set prevJobID(value: string) {
this._prevJobID = value;
}
public setNotebookHistory(jobID: string, value: azdata.AgentNotebookHistoryInfo[]) {
this._notebookHistories[jobID] = value;
}
public setRunChart(jobID: string, value: string[]) {
this._runCharts[jobID] = value;
}
public set serverName(value: string) {
this._serverName = value;
}
public set dataView(value: Slick.Data.DataView<any>) {
this._dataView = value;
}
public setJobSteps(jobID: string, value: azdata.AgentJobStepInfo[]) {
this._jobSteps[jobID] = value;
}
public setJobSchedules(jobID: string, value: azdata.AgentJobScheduleInfo[]) {
this._jobSchedules[jobID] = value;
}
}
/**
* Server level caching of Operators
*/
export class OperatorsCacheObject {
_serviceBrand: undefined;
private _operators: azdata.AgentOperatorInfo[];
private _dataView: Slick.Data.DataView<any>;
private _serverName: string;
/** Getters */
public get operators(): azdata.AgentOperatorInfo[] {
return this._operators;
}
public get dataview(): Slick.Data.DataView<any> {
return this._dataView;
}
public get serverName(): string {
return this._serverName;
}
/** Setters */
public set operators(value: azdata.AgentOperatorInfo[]) {
this._operators = value;
}
public set dataview(value: Slick.Data.DataView<any>) {
this._dataView = value;
}
public set serverName(value: string) {
this._serverName = value;
}
}
/*
* Server level caching of job alerts and the alerts view
*/
export class AlertsCacheObject {
_serviceBrand: undefined;
private _alerts: azdata.AgentAlertInfo[];
private _dataView: Slick.Data.DataView<any>;
private _serverName: string;
/** Getters */
public get alerts(): azdata.AgentAlertInfo[] {
return this._alerts;
}
public get dataview(): Slick.Data.DataView<any> {
return this._dataView;
}
public get serverName(): string {
return this._serverName;
}
/** Setters */
public set alerts(value: azdata.AgentAlertInfo[]) {
this._alerts = value;
}
public set dataview(value: Slick.Data.DataView<any>) {
this._dataView = value;
}
public set serverName(value: string) {
this._serverName = value;
}
}
/**
* Server level caching of job proxies and proxies view
*/
export class ProxiesCacheObject {
_serviceBrand: undefined;
private _proxies: azdata.AgentProxyInfo[];
private _dataView: Slick.Data.DataView<any>;
private _serverName: string;
/**
* Getters
*/
public get proxies(): azdata.AgentProxyInfo[] {
return this._proxies;
}
public get dataview(): Slick.Data.DataView<any> {
return this._dataView;
}
public get serverName(): string {
return this._serverName;
}
/** Setters */
public set proxies(value: azdata.AgentProxyInfo[]) {
this._proxies = value;
}
public set dataview(value: Slick.Data.DataView<any>) {
this._dataView = value;
}
public set serverName(value: string) {
this._serverName = value;
}
}

View File

@@ -0,0 +1,19 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { JobManagementService } from 'sql/workbench/services/jobManagement/common/jobManagementService';
import * as assert from 'assert';
// TESTS ///////////////////////////////////////////////////////////////////
suite('Job Management service tests', () => {
setup(() => {
});
test('Construction - Job Service Initialization', () => {
// ... Create instance of the service and reder account picker
let service = new JobManagementService(undefined);
assert(service);
});
});

View File

@@ -0,0 +1,363 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as TypeMoq from 'typemoq';
import * as assert from 'assert';
import { JobsRefreshAction, NewJobAction, EditJobAction, RunJobAction, StopJobAction, DeleteJobAction, NewStepAction, DeleteStepAction, NewAlertAction, EditAlertAction, DeleteAlertAction, NewOperatorAction, EditOperatorAction, DeleteOperatorAction, NewProxyAction, EditProxyAction, DeleteProxyAction } from 'sql/workbench/services/jobManagement/browser/jobActions';
import { JobManagementService } from 'sql/workbench/services/jobManagement/common/jobManagementService';
// Mock View Components
let mockJobsViewComponent: TypeMoq.Mock<TestJobManagementView>;
let mockAlertsViewComponent: TypeMoq.Mock<TestJobManagementView>;
let mockOperatorsViewComponent: TypeMoq.Mock<TestJobManagementView>;
let mockProxiesViewComponent: TypeMoq.Mock<TestJobManagementView>;
let mockJobManagementService: TypeMoq.Mock<JobManagementService>;
// Mock Job Actions
let mockRefreshAction: TypeMoq.Mock<JobsRefreshAction>;
let mockNewJobAction: TypeMoq.Mock<NewJobAction>;
let mockEditJobAction: TypeMoq.Mock<EditJobAction>;
let mockRunJobAction: TypeMoq.Mock<RunJobAction>;
let mockStopJobAction: TypeMoq.Mock<StopJobAction>;
let mockDeleteJobAction: TypeMoq.Mock<DeleteJobAction>;
// Mock Step Actions
let mockNewStepAction: TypeMoq.Mock<NewStepAction>;
let mockDeleteStepAction: TypeMoq.Mock<DeleteStepAction>;
// Mock Alert Actions
let mockNewAlertAction: TypeMoq.Mock<NewAlertAction>;
let mockEditAlertAction: TypeMoq.Mock<EditAlertAction>;
let mockDeleteAlertAction: TypeMoq.Mock<DeleteAlertAction>;
// Mock Operator Actions
let mockNewOperatorAction: TypeMoq.Mock<NewOperatorAction>;
let mockEditOperatorAction: TypeMoq.Mock<EditOperatorAction>;
let mockDeleteOperatorAction: TypeMoq.Mock<DeleteOperatorAction>;
// Mock Proxy Actions
let mockNewProxyAction: TypeMoq.Mock<NewProxyAction>;
let mockEditProxyAction: TypeMoq.Mock<EditProxyAction>;
let mockDeleteProxyAction: TypeMoq.Mock<DeleteProxyAction>;
/**
* Class to test Job Management Views
*/
class TestJobManagementView {
refreshJobs() { return undefined; }
openCreateJobDialog() { return undefined; }
openCreateAlertDialog() { return undefined; }
openCreateOperatorDialog() { return undefined; }
openCreateProxyDialog() { return undefined; }
}
// Tests
suite('Job Management Actions', () => {
// Job Actions
setup(() => {
mockJobsViewComponent = TypeMoq.Mock.ofType<TestJobManagementView>(TestJobManagementView);
mockAlertsViewComponent = TypeMoq.Mock.ofType<TestJobManagementView>(TestJobManagementView);
mockOperatorsViewComponent = TypeMoq.Mock.ofType<TestJobManagementView>(TestJobManagementView);
mockProxiesViewComponent = TypeMoq.Mock.ofType<TestJobManagementView>(TestJobManagementView);
mockJobManagementService = TypeMoq.Mock.ofType<JobManagementService>(JobManagementService);
let resultStatus: azdata.ResultStatus = {
success: true,
errorMessage: null
};
mockJobManagementService.setup(s => s.jobAction(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(resultStatus));
mockJobManagementService.setup(s => s.deleteJobStep(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(resultStatus));
mockJobManagementService.setup(s => s.deleteProxy(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(resultStatus));
mockJobManagementService.setup(s => s.deleteOperator(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(resultStatus));
mockJobManagementService.setup(s => s.deleteAlert(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve(resultStatus));
});
test('Jobs Refresh Action', async () => {
mockRefreshAction = TypeMoq.Mock.ofType(JobsRefreshAction, TypeMoq.MockBehavior.Strict, JobsRefreshAction.ID, JobsRefreshAction.LABEL);
mockRefreshAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => mockJobsViewComponent.object.refreshJobs());
mockRefreshAction.setup(s => s.id).returns(() => JobsRefreshAction.ID);
mockRefreshAction.setup(s => s.label).returns(() => JobsRefreshAction.LABEL);
assert.equal(mockRefreshAction.object.id, JobsRefreshAction.ID);
assert.equal(mockRefreshAction.object.label, JobsRefreshAction.LABEL);
// Job Refresh Action from Jobs View should refresh the component
await mockRefreshAction.object.run(null);
mockJobsViewComponent.verify(c => c.refreshJobs(), TypeMoq.Times.once());
});
test('New Job Action', async () => {
mockNewJobAction = TypeMoq.Mock.ofType(NewJobAction, TypeMoq.MockBehavior.Strict, NewJobAction.ID, NewJobAction.LABEL);
mockNewJobAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => mockJobsViewComponent.object.openCreateJobDialog());
mockNewJobAction.setup(s => s.id).returns(() => NewJobAction.ID);
mockNewJobAction.setup(s => s.label).returns(() => NewJobAction.LABEL);
assert.equal(mockNewJobAction.object.id, NewJobAction.ID);
assert.equal(mockNewJobAction.object.label, NewJobAction.LABEL);
// New Job Action from Jobs View should open a dialog
await mockNewJobAction.object.run(null);
mockJobsViewComponent.verify(c => c.openCreateJobDialog(), TypeMoq.Times.once());
});
test('Edit Job Action', async () => {
mockEditJobAction = TypeMoq.Mock.ofType(EditJobAction, TypeMoq.MockBehavior.Strict, EditJobAction.ID, EditJobAction.LABEL);
let commandServiceCalled: boolean = false;
mockEditJobAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => {
commandServiceCalled = true;
return Promise.resolve(commandServiceCalled);
});
mockEditJobAction.setup(s => s.id).returns(() => EditJobAction.ID);
mockEditJobAction.setup(s => s.label).returns(() => EditJobAction.LABEL);
assert.equal(mockEditJobAction.object.id, EditJobAction.ID);
assert.equal(mockEditJobAction.object.label, EditJobAction.LABEL);
// Edit Job Action from Jobs View should open a dialog
await mockEditJobAction.object.run(null);
assert(commandServiceCalled);
});
test('Run Job Action', async () => {
mockRunJobAction = TypeMoq.Mock.ofType(RunJobAction, TypeMoq.MockBehavior.Strict, RunJobAction.ID, RunJobAction.LABEL, null, null, mockJobManagementService);
mockRunJobAction.setup(s => s.run(TypeMoq.It.isAny())).returns(async () => {
let result = await mockJobManagementService.object.jobAction(null, null, null).then((result) => result.success);
return result;
});
mockRunJobAction.setup(s => s.id).returns(() => RunJobAction.ID);
mockRunJobAction.setup(s => s.label).returns(() => RunJobAction.LABEL);
assert.equal(mockRunJobAction.object.id, RunJobAction.ID);
assert.equal(mockRunJobAction.object.label, RunJobAction.LABEL);
// Run Job Action should make the Job Management service call job action
await mockRunJobAction.object.run(null);
mockJobManagementService.verify(s => s.jobAction(null, null, null), TypeMoq.Times.once());
});
test('Stop Job Action', async () => {
mockStopJobAction = TypeMoq.Mock.ofType(StopJobAction, TypeMoq.MockBehavior.Strict, StopJobAction.ID, StopJobAction.LABEL, null, null, mockJobManagementService);
mockStopJobAction.setup(s => s.run(TypeMoq.It.isAny())).returns(async () => {
let result = await mockJobManagementService.object.jobAction(null, null, null).then((result) => result.success);
return result;
});
mockStopJobAction.setup(s => s.id).returns(() => RunJobAction.ID);
mockStopJobAction.setup(s => s.label).returns(() => RunJobAction.LABEL);
assert.equal(mockStopJobAction.object.id, RunJobAction.ID);
assert.equal(mockStopJobAction.object.label, RunJobAction.LABEL);
// Run Job Action should make the Job Management service call job action
await mockStopJobAction.object.run(null);
mockJobManagementService.verify(s => s.jobAction(null, null, null), TypeMoq.Times.once());
});
test('Delete Job Action', async () => {
mockDeleteJobAction = TypeMoq.Mock.ofType(DeleteJobAction, TypeMoq.MockBehavior.Strict, DeleteJobAction.ID, DeleteJobAction.LABEL, null, null, mockJobManagementService);
mockDeleteJobAction.setup(s => s.run(TypeMoq.It.isAny())).returns(async () => {
let result = await mockJobManagementService.object.jobAction(null, null, null).then((result) => result.success);
return result;
});
mockDeleteJobAction.setup(s => s.id).returns(() => DeleteJobAction.ID);
mockDeleteJobAction.setup(s => s.label).returns(() => DeleteJobAction.LABEL);
assert.equal(mockDeleteJobAction.object.id, DeleteJobAction.ID);
assert.equal(mockDeleteJobAction.object.label, DeleteJobAction.LABEL);
// Run Job Action should make the Job Management service call job action
await mockDeleteJobAction.object.run(null);
mockJobManagementService.verify(s => s.jobAction(null, null, null), TypeMoq.Times.once());
});
// Step Actions
test('New Step Action', async () => {
mockNewStepAction = TypeMoq.Mock.ofType(NewStepAction, TypeMoq.MockBehavior.Strict, NewJobAction.ID, NewJobAction.LABEL);
let commandServiceCalled = false;
mockNewStepAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => {
commandServiceCalled = true;
return Promise.resolve(commandServiceCalled);
});
mockNewStepAction.setup(s => s.id).returns(() => NewJobAction.ID);
mockNewStepAction.setup(s => s.label).returns(() => NewJobAction.LABEL);
assert.equal(mockNewStepAction.object.id, NewJobAction.ID);
assert.equal(mockNewStepAction.object.label, NewJobAction.LABEL);
// New Step Action should called command service
await mockNewStepAction.object.run(null);
assert(commandServiceCalled);
});
test('Delete Step Action', async () => {
mockDeleteStepAction = TypeMoq.Mock.ofType(DeleteStepAction, TypeMoq.MockBehavior.Strict, DeleteStepAction.ID, DeleteStepAction.LABEL);
let commandServiceCalled = false;
mockDeleteStepAction.setup(s => s.run(TypeMoq.It.isAny())).returns(async () => {
commandServiceCalled = true;
await mockJobManagementService.object.deleteJobStep(null, null).then((result) => result.success);
return commandServiceCalled;
});
mockDeleteStepAction.setup(s => s.id).returns(() => DeleteStepAction.ID);
mockDeleteStepAction.setup(s => s.label).returns(() => DeleteStepAction.LABEL);
assert.equal(mockDeleteStepAction.object.id, DeleteStepAction.ID);
assert.equal(mockDeleteStepAction.object.label, DeleteStepAction.LABEL);
// Delete Step Action should called command service
await mockDeleteStepAction.object.run(null);
assert(commandServiceCalled);
mockJobManagementService.verify(s => s.deleteJobStep(null, null), TypeMoq.Times.once());
});
// Alert Actions
test('New Alert Action', async () => {
mockNewAlertAction = TypeMoq.Mock.ofType(NewJobAction, TypeMoq.MockBehavior.Strict, NewJobAction.ID, NewJobAction.LABEL);
mockNewAlertAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => mockAlertsViewComponent.object.openCreateAlertDialog());
mockNewAlertAction.setup(s => s.id).returns(() => NewJobAction.ID);
mockNewAlertAction.setup(s => s.label).returns(() => NewJobAction.LABEL);
assert.equal(mockNewAlertAction.object.id, NewJobAction.ID);
assert.equal(mockNewAlertAction.object.label, NewJobAction.LABEL);
// New Alert Action from Alerts View should open a dialog
await mockNewAlertAction.object.run(null);
mockAlertsViewComponent.verify(c => c.openCreateAlertDialog(), TypeMoq.Times.once());
});
test('Edit Alert Action', async () => {
mockEditAlertAction = TypeMoq.Mock.ofType(EditAlertAction, TypeMoq.MockBehavior.Strict, EditAlertAction.ID, EditAlertAction.LABEL);
let commandServiceCalled: boolean = false;
mockEditAlertAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => {
commandServiceCalled = true;
return Promise.resolve(commandServiceCalled);
});
mockEditAlertAction.setup(s => s.id).returns(() => EditAlertAction.ID);
mockEditAlertAction.setup(s => s.label).returns(() => EditAlertAction.LABEL);
assert.equal(mockEditAlertAction.object.id, EditAlertAction.ID);
assert.equal(mockEditAlertAction.object.label, EditAlertAction.LABEL);
// Edit Alert Action from Jobs View should open a dialog
await mockEditAlertAction.object.run(null);
assert(commandServiceCalled);
});
test('Delete Alert Action', async () => {
mockDeleteAlertAction = TypeMoq.Mock.ofType(DeleteAlertAction, TypeMoq.MockBehavior.Strict, DeleteAlertAction.ID, DeleteAlertAction.LABEL, null, null, mockJobManagementService);
let commandServiceCalled = false;
mockDeleteAlertAction.setup(s => s.run(TypeMoq.It.isAny())).returns(async () => {
commandServiceCalled = true;
await mockJobManagementService.object.deleteAlert(null, null).then((result) => result.success);
return commandServiceCalled;
});
mockDeleteAlertAction.setup(s => s.id).returns(() => DeleteAlertAction.ID);
mockDeleteAlertAction.setup(s => s.label).returns(() => DeleteAlertAction.LABEL);
assert.equal(mockDeleteAlertAction.object.id, DeleteAlertAction.ID);
assert.equal(mockDeleteAlertAction.object.label, DeleteAlertAction.LABEL);
// Delete Alert Action should call job management service
await mockDeleteAlertAction.object.run(null);
assert(commandServiceCalled);
mockJobManagementService.verify(s => s.deleteAlert(null, null), TypeMoq.Times.once());
});
// Operator Tests
test('New Operator Action', async () => {
mockNewOperatorAction = TypeMoq.Mock.ofType(NewOperatorAction, TypeMoq.MockBehavior.Strict, NewOperatorAction.ID, NewOperatorAction.LABEL);
mockNewOperatorAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => mockOperatorsViewComponent.object.openCreateOperatorDialog());
mockNewOperatorAction.setup(s => s.id).returns(() => NewOperatorAction.ID);
mockNewOperatorAction.setup(s => s.label).returns(() => NewOperatorAction.LABEL);
assert.equal(mockNewOperatorAction.object.id, NewOperatorAction.ID);
assert.equal(mockNewOperatorAction.object.label, NewOperatorAction.LABEL);
// New Operator Action from Operators View should open a dialog
await mockNewOperatorAction.object.run(null);
mockOperatorsViewComponent.verify(c => c.openCreateOperatorDialog(), TypeMoq.Times.once());
});
test('Edit Operator Action', async () => {
mockEditOperatorAction = TypeMoq.Mock.ofType(EditOperatorAction, TypeMoq.MockBehavior.Strict, EditOperatorAction.ID, EditOperatorAction.LABEL);
let commandServiceCalled: boolean = false;
mockEditOperatorAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => {
commandServiceCalled = true;
return Promise.resolve(commandServiceCalled);
});
mockEditOperatorAction.setup(s => s.id).returns(() => EditOperatorAction.ID);
mockEditOperatorAction.setup(s => s.label).returns(() => EditOperatorAction.LABEL);
assert.equal(mockEditOperatorAction.object.id, EditOperatorAction.ID);
assert.equal(mockEditOperatorAction.object.label, EditOperatorAction.LABEL);
// Edit Operator Action from Jobs View should open a dialog
await mockEditOperatorAction.object.run(null);
assert(commandServiceCalled);
});
test('Delete Operator Action', async () => {
mockDeleteOperatorAction = TypeMoq.Mock.ofType(DeleteOperatorAction, TypeMoq.MockBehavior.Strict, DeleteOperatorAction.ID, DeleteOperatorAction.LABEL, null, null, mockJobManagementService);
let commandServiceCalled = false;
mockDeleteOperatorAction.setup(s => s.run(TypeMoq.It.isAny())).returns(async () => {
commandServiceCalled = true;
await mockJobManagementService.object.deleteOperator(null, null).then((result) => result.success);
return commandServiceCalled;
});
mockDeleteOperatorAction.setup(s => s.id).returns(() => DeleteOperatorAction.ID);
mockDeleteOperatorAction.setup(s => s.label).returns(() => DeleteOperatorAction.LABEL);
assert.equal(mockDeleteOperatorAction.object.id, DeleteOperatorAction.ID);
assert.equal(mockDeleteOperatorAction.object.label, DeleteOperatorAction.LABEL);
// Delete Operator Action should call job management service
await mockDeleteOperatorAction.object.run(null);
assert(commandServiceCalled);
mockJobManagementService.verify(s => s.deleteOperator(null, null), TypeMoq.Times.once());
});
// Proxy Actions
test('New Proxy Action', async () => {
mockNewProxyAction = TypeMoq.Mock.ofType(NewProxyAction, TypeMoq.MockBehavior.Strict, NewProxyAction.ID, NewProxyAction.LABEL);
mockNewProxyAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => mockProxiesViewComponent.object.openCreateProxyDialog());
mockNewProxyAction.setup(s => s.id).returns(() => NewProxyAction.ID);
mockNewProxyAction.setup(s => s.label).returns(() => NewProxyAction.LABEL);
assert.equal(mockNewProxyAction.object.id, NewProxyAction.ID);
assert.equal(mockNewProxyAction.object.label, NewProxyAction.LABEL);
// New Proxy Action from Alerts View should open a dialog
await mockNewProxyAction.object.run(null);
mockProxiesViewComponent.verify(c => c.openCreateProxyDialog(), TypeMoq.Times.once());
});
test('Edit Proxy Action', async () => {
mockEditProxyAction = TypeMoq.Mock.ofType(EditProxyAction, TypeMoq.MockBehavior.Strict, EditProxyAction.ID, EditProxyAction.LABEL);
let commandServiceCalled: boolean = false;
mockEditProxyAction.setup(s => s.run(TypeMoq.It.isAny())).returns(() => {
commandServiceCalled = true;
return Promise.resolve(commandServiceCalled);
});
mockEditProxyAction.setup(s => s.id).returns(() => EditProxyAction.ID);
mockEditProxyAction.setup(s => s.label).returns(() => EditProxyAction.LABEL);
assert.equal(mockEditProxyAction.object.id, EditProxyAction.ID);
assert.equal(mockEditProxyAction.object.label, EditProxyAction.LABEL);
// Edit Proxy Action from Proxies View should open a dialog
await mockEditProxyAction.object.run(null);
assert(commandServiceCalled);
});
test('Delete Proxy Action', async () => {
mockDeleteProxyAction = TypeMoq.Mock.ofType(DeleteProxyAction, TypeMoq.MockBehavior.Strict, DeleteProxyAction.ID, DeleteProxyAction.LABEL, null, null, mockJobManagementService);
let commandServiceCalled = false;
mockDeleteProxyAction.setup(s => s.run(TypeMoq.It.isAny())).returns(async () => {
commandServiceCalled = true;
await mockJobManagementService.object.deleteProxy(null, null).then((result) => result.success);
return commandServiceCalled;
});
mockDeleteProxyAction.setup(s => s.id).returns(() => DeleteProxyAction.ID);
mockDeleteProxyAction.setup(s => s.label).returns(() => DeleteProxyAction.LABEL);
assert.equal(mockDeleteProxyAction.object.id, DeleteProxyAction.ID);
assert.equal(mockDeleteProxyAction.object.label, DeleteProxyAction.LABEL);
// Delete Proxy Action should call job management service
await mockDeleteProxyAction.object.run(null);
assert(commandServiceCalled);
mockJobManagementService.verify(s => s.deleteProxy(null, null), TypeMoq.Times.once());
});
});