mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -05:00
Add Agent Job and Job Step request handlers (#635)
* Stage changes * Fix update job request handler * WIP * Additional agent handler updates * Setup agent job step create test * Fix Step update handler
This commit is contained in:
@@ -49,13 +49,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
protected override bool DoPreProcessExecution(RunType runType, out ExecutionMode executionResult)
|
||||
{
|
||||
base.DoPreProcessExecution(runType, out executionResult);
|
||||
this.data.ApplyChanges(creating: true);
|
||||
if (!IsScripting(runType))
|
||||
{
|
||||
this.DataContainer.SqlDialogSubject = this.data.Job;
|
||||
}
|
||||
|
||||
if (this.configAction == ConfigAction.Drop)
|
||||
{
|
||||
if (this.data.Job != null)
|
||||
{
|
||||
this.data.Job.DropIfExists();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.data.ApplyChanges(creating: this.configAction == ConfigAction.Create);
|
||||
if (!IsScripting(runType))
|
||||
{
|
||||
this.DataContainer.SqlDialogSubject = this.data.Job;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ using Microsoft.SqlServer.Management.Smo.Agent;
|
||||
using Microsoft.SqlServer.Management.Diagnostics;
|
||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||
using SMO = Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Smo.Agent;
|
||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
using SMO = Microsoft.SqlServer.Management.Smo;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
@@ -1139,9 +1140,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
else
|
||||
{
|
||||
// just lookup the original object
|
||||
STParameters parameters = new STParameters(this.context.Document);
|
||||
string urn = string.Empty;
|
||||
job = this.context.Server.GetSmoObject(this.urn) as Job;
|
||||
job = this.Job;
|
||||
}
|
||||
|
||||
if (!this.IsReadOnly)
|
||||
|
||||
@@ -15,8 +15,10 @@ using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Smo.Agent;
|
||||
using Microsoft.SqlServer.Management.Diagnostics;
|
||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
using SMO = Microsoft.SqlServer.Management.Smo;
|
||||
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
{
|
||||
internal class JobSchedulesData
|
||||
|
||||
@@ -17,6 +17,7 @@ using System.Text;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Smo.Agent;
|
||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@ using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Smo.Agent;
|
||||
using SMO = Microsoft.SqlServer.Management.Smo;
|
||||
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
{
|
||||
internal class JobStepData
|
||||
@@ -45,26 +44,32 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
/// Original name of this step
|
||||
/// </summary>
|
||||
string originalName;
|
||||
|
||||
/// <summary>
|
||||
/// Current name
|
||||
/// </summary>
|
||||
string currentName;
|
||||
|
||||
/// <summary>
|
||||
/// Current step id
|
||||
/// </summary>
|
||||
int id;
|
||||
|
||||
/// <summary>
|
||||
/// Original step id
|
||||
/// </summary>
|
||||
int originalId;
|
||||
|
||||
/// <summary>
|
||||
/// Subsystem that will execute this step
|
||||
/// </summary>
|
||||
AgentSubSystem subSystem;
|
||||
|
||||
/// <summary>
|
||||
/// action to take if the step fails
|
||||
/// </summary>
|
||||
StepCompletionAction failureAction;
|
||||
|
||||
/// <summary>
|
||||
/// Action to take if the step succeeds
|
||||
/// </summary>
|
||||
@@ -175,6 +180,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
return jobStep;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Server version
|
||||
/// </summary>
|
||||
@@ -185,6 +191,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
return this.parent.Version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// indicates whether the job exists on the server
|
||||
/// </summary>
|
||||
@@ -237,7 +244,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
#endregion
|
||||
|
||||
#region Properties for Job Step
|
||||
public String Name
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -248,7 +255,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
this.currentName = value.Trim();
|
||||
}
|
||||
}
|
||||
public String Command
|
||||
|
||||
public string Command
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -274,7 +282,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
this.commandExecutionSuccessCode = value;
|
||||
}
|
||||
}
|
||||
public String DatabaseName
|
||||
public string DatabaseName
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -287,7 +295,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
this.databaseName = value;
|
||||
}
|
||||
}
|
||||
public String DatabaseUserName
|
||||
public string DatabaseUserName
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -300,7 +308,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
this.databaseUserName = value;
|
||||
}
|
||||
}
|
||||
public String Server
|
||||
public string Server
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -706,7 +714,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
this.successStep = null;
|
||||
this.successStepId = -1;
|
||||
this.priority = OSRunPriority.Normal;
|
||||
this.outputFileName = String.Empty;
|
||||
this.outputFileName = string.Empty;
|
||||
this.appendToLogFile = false;
|
||||
this.appendToStepHist = false;
|
||||
this.writeLogToTable = false;
|
||||
@@ -1027,15 +1035,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
this.failStep = step;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Smo.Agent;
|
||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
{
|
||||
|
||||
@@ -4,168 +4,88 @@
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Diagnostics;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Smo.Agent;
|
||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for JobSteps.
|
||||
/// JobStepsActions
|
||||
/// </summary>
|
||||
internal class JobStepsActions : ManagementActionBase
|
||||
{
|
||||
private bool validated = true;
|
||||
private JobStepData data;
|
||||
private JobData jobData;
|
||||
|
||||
private JobData data;
|
||||
|
||||
public JobStepsActions(CDataContainer dataContainer, JobData data)
|
||||
public JobStepsActions(
|
||||
CDataContainer dataContainer,
|
||||
JobData jobData,
|
||||
AgentJobStepInfo stepInfo,
|
||||
ConfigAction configAction)
|
||||
{
|
||||
this.DataContainer = dataContainer;
|
||||
this.data = data;
|
||||
this.jobData = jobData;
|
||||
|
||||
if (configAction == ConfigAction.Update)
|
||||
{
|
||||
JobStep jobStep = GetJobStep(this.jobData, stepInfo.StepName);
|
||||
this.data = new JobStepData(jobStep, jobData.JobSteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.data = new JobStepData(jobData.JobSteps);
|
||||
}
|
||||
|
||||
// load properties from AgentJobStepInfo
|
||||
this.data.ID = stepInfo.Id;
|
||||
this.data.Name = stepInfo.StepName;
|
||||
this.data.Command = stepInfo.Script;
|
||||
}
|
||||
|
||||
#region ISupportValidation
|
||||
/// <summary>
|
||||
/// Validate the Job step data.
|
||||
/// This is limited to two checks
|
||||
/// 1. See if all steps are reachable
|
||||
/// 2. If we are editing rather than creating check to see if the last steps completion
|
||||
/// action will change from GoToNext to QuitWithSuccess.
|
||||
/// </summary>
|
||||
/// <returns>true if the checks passed, or the user has ok the warning</returns>
|
||||
public bool Validate()
|
||||
protected override bool DoPreProcessExecution(RunType runType, out ExecutionMode executionResult)
|
||||
{
|
||||
// Only validate once after the user has made changes. Validate() is called when the
|
||||
// user navigates away from the JobSteps page, and if they navigate back and then out
|
||||
// again they'd be prompted twice. This annoys our users.
|
||||
if (this.validated)
|
||||
base.DoPreProcessExecution(runType, out executionResult);
|
||||
|
||||
// Make sure the job step name is not blank.
|
||||
if (this.data.Name == null || this.data.Name.Length == 0)
|
||||
{
|
||||
return true;
|
||||
throw new Exception(SR.JobStepNameCannotBeBlank);
|
||||
}
|
||||
|
||||
bool valid = true;
|
||||
// Get the unreachable steps
|
||||
List<JobStepData> unreachableSteps = this.data.JobSteps.FindUnreachableJobSteps();
|
||||
// see if the last step success completion action will change
|
||||
bool lastStepWillChange = this.data.JobSteps.CheckIfLastStepCompletionActionWillChange();
|
||||
|
||||
// warning message
|
||||
StringBuilder warningMessage = new StringBuilder();
|
||||
|
||||
// if there are unreachable steps, add the warning and each problematic step
|
||||
if (unreachableSteps.Count > 0)
|
||||
// Check to make sure that the user has not entered a job step name that already exists.
|
||||
for (int stepIndex = 0; stepIndex < this.data.Parent.Steps.Count; ++stepIndex)
|
||||
{
|
||||
warningMessage.AppendLine("JobSR.UnreachableStepHeader");
|
||||
foreach (JobStepData jobStep in unreachableSteps)
|
||||
// don't compare if the id's are the same.
|
||||
if (data.ID != ((JobStepData)this.data.Parent.Steps[stepIndex]).ID && data.Name == ((JobStepData)this.data.Parent.Steps[stepIndex]).Name)
|
||||
{
|
||||
warningMessage.AppendLine("JobSR.UnreachableStepFormat(jobStep.ID, jobStep.Name)");
|
||||
// Throw an error if the job step name already exists
|
||||
throw new Exception(SR.JobStepNameAlreadyExists(this.data.Name));
|
||||
}
|
||||
warningMessage.AppendLine(string.Empty);
|
||||
}
|
||||
|
||||
// add a warning if the last step will change
|
||||
if (lastStepWillChange)
|
||||
{
|
||||
warningMessage.AppendLine("JobSR.LastStepSuccessWillChange");
|
||||
warningMessage.AppendLine(string.Empty);
|
||||
if (runType == RunType.RunNow)
|
||||
{
|
||||
this.data.ApplyChanges(this.jobData.Job);
|
||||
}
|
||||
|
||||
// if anything was wrong tell the user and see if they are ok with it
|
||||
if (warningMessage.Length > 0)
|
||||
{
|
||||
warningMessage.Append("JobSR.AreYouSure");
|
||||
}
|
||||
|
||||
this.validated = valid;
|
||||
return valid;
|
||||
// regular execution always takes place
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
// private void PopulateGrid(JobStepsData steps)
|
||||
// {
|
||||
// for (int i = 0; i < steps.Steps.Count; i++)
|
||||
// {
|
||||
// JobStepData step = steps.Steps[i] as JobStepData;
|
||||
// if (step != null)
|
||||
// {
|
||||
// // add rows to the grid
|
||||
// GridCellCollection row = new GridCellCollection();
|
||||
// GridCell cell;
|
||||
|
||||
// // id
|
||||
// cell = new GridCell(step.ID.ToString(CultureInfo.InvariantCulture));
|
||||
// row.Add(cell);
|
||||
// // step name
|
||||
// cell = new GridCell(step.Name);
|
||||
// row.Add(cell);
|
||||
// // subsystem
|
||||
// cell = new GridCell(JobStepSubSystems.LookupFriendlyName(step.SubSystem));
|
||||
// row.Add(cell);
|
||||
// // on success
|
||||
// cell = new GridCell(GetFriendlyNameForAction(step.SuccessAction, step.SuccessStep));
|
||||
// row.Add(cell);
|
||||
// // on failure
|
||||
// cell = new GridCell(GetFriendlyNameForAction(step.FailureAction, step.FailStep));
|
||||
// row.Add(cell);
|
||||
|
||||
// this.jobStepList.AddRow(row);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
/// <summary>
|
||||
/// Convert an action and it's target step to a localizable user friendly name
|
||||
/// </summary>
|
||||
/// <param name="action"></param>
|
||||
/// <param name="targetStep"></param>
|
||||
/// <returns></returns>
|
||||
// private static string GetFriendlyNameForAction(StepCompletionAction action, JobStepData targetStep)
|
||||
// {
|
||||
// String friendlyName = String.Empty;
|
||||
// // switch (action)
|
||||
// // {
|
||||
// // case StepCompletionAction.GoToNextStep:
|
||||
// // friendlyName = JobSR.GotoNextStep;
|
||||
// // break;
|
||||
// // case StepCompletionAction.QuitWithFailure:
|
||||
// // friendlyName = JobSR.QuitWithFailure;
|
||||
// // break;
|
||||
// // case StepCompletionAction.QuitWithSuccess:
|
||||
// // friendlyName = JobSR.QuitWithSuccess;
|
||||
// // break;
|
||||
// // case StepCompletionAction.GoToStep:
|
||||
// // STrace.Assert(targetStep != null, "Action type is goto step, but the target step is null");
|
||||
// // if (targetStep != null)
|
||||
// // {
|
||||
// // friendlyName = JobSR.GotoStep(targetStep.ID, targetStep.Name);
|
||||
// // }
|
||||
// // break;
|
||||
// // default:
|
||||
// // STrace.Assert(false, "Unknown jobstep completion action");
|
||||
// // break;
|
||||
// // }
|
||||
// return friendlyName;
|
||||
// }
|
||||
|
||||
|
||||
public void CreateJobStep()
|
||||
private JobStep GetJobStep(JobData jobData, string stepName)
|
||||
{
|
||||
//JobStepData data = new JobStepData(this.data.JobSteps);
|
||||
JobStepData data = this.data.JobSteps.Steps[0] as JobStepData;
|
||||
JobStepPropertySheet jsProp = new JobStepPropertySheet(this.DataContainer, data);
|
||||
|
||||
jsProp.Init();
|
||||
jsProp.Create();
|
||||
JobStep jobStep = null;
|
||||
if (jobData.Job != null)
|
||||
{
|
||||
const string UrnFormatStr = "Server[@Name='{0}']/JobServer[@Name='{0}']/Job[@Name='{1}']/Step[@Name='{2}']";
|
||||
string serverName = this.DataContainer.Server.Name.ToUpper();
|
||||
string urn = string.Format(UrnFormatStr, serverName, jobData.Job.Name, stepName);
|
||||
jobStep = jobData.Job.Parent.Parent.GetSmoObject(urn) as JobStep;
|
||||
}
|
||||
return jobStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Smo.Agent;
|
||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
using SMO = Microsoft.SqlServer.Management.Smo;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||
|
||||
@@ -9,18 +9,14 @@ using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using Microsoft.SqlServer.Management.Smo.Agent;
|
||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
|
||||
namespace Microsoft.SqlServer.Management.SqlManagerUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for JobsRefrencingScheduleForm.
|
||||
/// </summary>
|
||||
#if DEBUG || EXPOSE_MANAGED_INTERNALS
|
||||
public
|
||||
#else
|
||||
internal
|
||||
#endif
|
||||
class JobsReferencingScheduleForm
|
||||
public class JobsReferencingScheduleForm
|
||||
{
|
||||
#region UI Variables
|
||||
|
||||
|
||||
Reference in New Issue
Block a user