mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -05:00
Drop job step and Create\Update alert handlers (#636)
* Add Delete Job Step implementation * Update create\update agent alert handlers to use execution handler * Cleanup create/update/delete operator request handlers
This commit is contained in:
@@ -7,8 +7,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Microsoft.SqlServer.Management.Common;
|
using Microsoft.SqlServer.Management.Common;
|
||||||
@@ -21,7 +19,6 @@ using Microsoft.SqlTools.ServiceLayer.Connection;
|
|||||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||||
using Microsoft.SqlTools.Utility;
|
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||||
{
|
{
|
||||||
@@ -266,18 +263,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tuple<SqlConnectionInfo, DataTable, ServerConnection> CreateSqlConnection(ConnectionInfo connInfo, String jobId)
|
|
||||||
{
|
|
||||||
var sqlConnection = ConnectionService.OpenSqlConnection(connInfo);
|
|
||||||
var serverConnection = new ServerConnection(sqlConnection);
|
|
||||||
var server = new Server(serverConnection);
|
|
||||||
var filter = new JobHistoryFilter();
|
|
||||||
filter.JobID = new Guid(jobId);
|
|
||||||
var dt = server.JobServer.EnumJobHistory(filter);
|
|
||||||
var sqlConnInfo = new SqlConnectionInfo(serverConnection, SqlServer.Management.Common.ConnectionType.SqlConnection);
|
|
||||||
return new Tuple<SqlConnectionInfo, DataTable, ServerConnection>(sqlConnInfo, dt, serverConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task HandleCreateAgentJobRequest(CreateAgentJobParams parameters, RequestContext<CreateAgentJobResult> requestContext)
|
internal async Task HandleCreateAgentJobRequest(CreateAgentJobParams parameters, RequestContext<CreateAgentJobResult> requestContext)
|
||||||
{
|
{
|
||||||
var result = await ConfigureAgentJob(
|
var result = await ConfigureAgentJob(
|
||||||
@@ -366,135 +351,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
Success = result.Item1,
|
Success = result.Item1,
|
||||||
ErrorMessage = result.Item2
|
ErrorMessage = result.Item2
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<Tuple<bool, string>> ConfigureAgentJob(
|
|
||||||
string ownerUri,
|
|
||||||
AgentJobInfo jobInfo,
|
|
||||||
ConfigAction configAction,
|
|
||||||
RunType runType)
|
|
||||||
{
|
|
||||||
return await Task<Tuple<bool, string>>.Run(() =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ConnectionInfo connInfo;
|
|
||||||
ConnectionServiceInstance.TryFindConnection(
|
|
||||||
ownerUri,
|
|
||||||
out connInfo);
|
|
||||||
|
|
||||||
CDataContainer dataContainer = CDataContainer.CreateDataContainer(
|
|
||||||
connInfo,
|
|
||||||
databaseExists: true);
|
|
||||||
|
|
||||||
XmlDocument jobDoc = CreateJobXmlDocument(
|
|
||||||
dataContainer.Server.Name.ToUpper(),
|
|
||||||
jobInfo.Name);
|
|
||||||
|
|
||||||
dataContainer.Init(jobDoc.InnerXml);
|
|
||||||
|
|
||||||
STParameters param = new STParameters(dataContainer.Document);
|
|
||||||
param.SetParam("job", string.Empty);
|
|
||||||
param.SetParam("jobid", string.Empty);
|
|
||||||
|
|
||||||
var jobData = new JobData(dataContainer, jobInfo);
|
|
||||||
using (JobActions jobActions = new JobActions(dataContainer, jobData, configAction))
|
|
||||||
{
|
|
||||||
var executionHandler = new ExecutonHandler(jobActions);
|
|
||||||
executionHandler.RunNow(runType, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Tuple<bool, string>(true, string.Empty);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return new Tuple<bool, string>(false, ex.ToString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task<Tuple<bool, string>> ConfigureAgentJobStep(
|
|
||||||
string ownerUri,
|
|
||||||
AgentJobStepInfo stepInfo,
|
|
||||||
ConfigAction configAction,
|
|
||||||
RunType runType)
|
|
||||||
{
|
|
||||||
return await Task<Tuple<bool, string>>.Run(() =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(stepInfo.JobName))
|
|
||||||
{
|
|
||||||
return new Tuple<bool, string>(false, "JobId cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
ConnectionInfo connInfo;
|
|
||||||
ConnectionServiceInstance.TryFindConnection(
|
|
||||||
ownerUri,
|
|
||||||
out connInfo);
|
|
||||||
|
|
||||||
CDataContainer dataContainer = CDataContainer.CreateDataContainer(
|
|
||||||
connInfo,
|
|
||||||
databaseExists: true);
|
|
||||||
|
|
||||||
XmlDocument jobDoc = CreateJobXmlDocument(
|
|
||||||
dataContainer.Server.Name.ToUpper(),
|
|
||||||
stepInfo.JobName);
|
|
||||||
|
|
||||||
dataContainer.Init(jobDoc.InnerXml);
|
|
||||||
|
|
||||||
STParameters param = new STParameters(dataContainer.Document);
|
|
||||||
param.SetParam("job", string.Empty);
|
|
||||||
param.SetParam("jobid", string.Empty);
|
|
||||||
|
|
||||||
var jobData = new JobData(dataContainer);
|
|
||||||
using (var jobStep = new JobStepsActions(dataContainer, jobData, stepInfo, configAction))
|
|
||||||
{
|
|
||||||
var executionHandler = new ExecutonHandler(jobStep);
|
|
||||||
executionHandler.RunNow(runType, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Tuple<bool, string>(true, string.Empty);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
// log exception here
|
|
||||||
return new Tuple<bool, string>(false, ex.ToString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public XmlDocument CreateJobXmlDocument(string svrName, string jobName)
|
|
||||||
{
|
|
||||||
// XML element strings
|
|
||||||
const string XmlFormDescElementName = "formdescription";
|
|
||||||
const string XmlParamsElementName = "params";
|
|
||||||
const string XmlJobElementName = "job";
|
|
||||||
const string XmlUrnElementName = "urn";
|
|
||||||
const string UrnFormatStr = "Server[@Name='{0}']/JobServer[@Name='{0}']/Job[@Name='{1}']";
|
|
||||||
|
|
||||||
// Write out XML.
|
|
||||||
StringWriter textWriter = new StringWriter();
|
|
||||||
XmlTextWriter xmlWriter = new XmlTextWriter(textWriter);
|
|
||||||
|
|
||||||
xmlWriter.WriteStartElement(XmlFormDescElementName);
|
|
||||||
xmlWriter.WriteStartElement(XmlParamsElementName);
|
|
||||||
|
|
||||||
xmlWriter.WriteElementString(XmlJobElementName, jobName);
|
|
||||||
xmlWriter.WriteElementString(XmlUrnElementName, string.Format(UrnFormatStr, svrName, jobName));
|
|
||||||
|
|
||||||
xmlWriter.WriteEndElement();
|
|
||||||
xmlWriter.WriteEndElement();
|
|
||||||
|
|
||||||
xmlWriter.Close();
|
|
||||||
|
|
||||||
// Create an XML document.
|
|
||||||
XmlDocument doc = new XmlDocument();
|
|
||||||
XmlTextReader rdr = new XmlTextReader(new System.IO.StringReader(textWriter.ToString()));
|
|
||||||
rdr.MoveToContent();
|
|
||||||
doc.LoadXml(rdr.ReadOuterXml());
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion // "Jobs Handlers"
|
#endregion // "Jobs Handlers"
|
||||||
|
|
||||||
@@ -511,9 +368,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
result.Alerts = new List<AgentAlertInfo>().ToArray();
|
result.Alerts = new List<AgentAlertInfo>().ToArray();
|
||||||
|
|
||||||
ConnectionInfo connInfo;
|
ConnectionInfo connInfo;
|
||||||
ConnectionServiceInstance.TryFindConnection(
|
ConnectionServiceInstance.TryFindConnection(parameters.OwnerUri, out connInfo);
|
||||||
parameters.OwnerUri,
|
|
||||||
out connInfo);
|
|
||||||
|
|
||||||
if (connInfo != null)
|
if (connInfo != null)
|
||||||
{
|
{
|
||||||
@@ -525,29 +380,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateAgentAlertInfo(AgentAlertInfo alert)
|
|
||||||
{
|
|
||||||
return alert != null
|
|
||||||
&& !string.IsNullOrWhiteSpace(alert.JobName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle request to create an alert
|
/// Handle request to create an alert
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal async Task HandleCreateAgentAlertRequest(CreateAgentAlertParams parameters, RequestContext<CreateAgentAlertResult> requestContext)
|
internal async Task HandleCreateAgentAlertRequest(CreateAgentAlertParams parameters, RequestContext<CreateAgentAlertResult> requestContext)
|
||||||
{
|
{
|
||||||
await Task.Run(async () =>
|
var result = await ConfigureAgentAlert(
|
||||||
|
parameters.OwnerUri,
|
||||||
|
parameters.Alert,
|
||||||
|
ConfigAction.Create,
|
||||||
|
RunType.RunNow);
|
||||||
|
|
||||||
|
await requestContext.SendResult(new CreateAgentAlertResult()
|
||||||
{
|
{
|
||||||
var result = new CreateAgentAlertResult();
|
Success = result.Item1,
|
||||||
ConnectionInfo connInfo;
|
ErrorMessage = result.Item2
|
||||||
ConnectionServiceInstance.TryFindConnection(
|
});
|
||||||
parameters.OwnerUri,
|
|
||||||
out connInfo);
|
|
||||||
|
|
||||||
CreateOrUpdateAgentAlert(connInfo, parameters.Alert);
|
|
||||||
|
|
||||||
await requestContext.SendResult(result);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -555,71 +403,34 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal async Task HandleUpdateAgentAlertRequest(UpdateAgentAlertParams parameters, RequestContext<UpdateAgentAlertResult> requestContext)
|
internal async Task HandleUpdateAgentAlertRequest(UpdateAgentAlertParams parameters, RequestContext<UpdateAgentAlertResult> requestContext)
|
||||||
{
|
{
|
||||||
await Task.Run(async () =>
|
var result = await ConfigureAgentAlert(
|
||||||
|
parameters.OwnerUri,
|
||||||
|
parameters.Alert,
|
||||||
|
ConfigAction.Update,
|
||||||
|
RunType.RunNow);
|
||||||
|
|
||||||
|
await requestContext.SendResult(new UpdateAgentAlertResult()
|
||||||
{
|
{
|
||||||
var result = new UpdateAgentAlertResult();
|
Success = result.Item1,
|
||||||
ConnectionInfo connInfo;
|
ErrorMessage = result.Item2
|
||||||
ConnectionServiceInstance.TryFindConnection(
|
|
||||||
parameters.OwnerUri,
|
|
||||||
out connInfo);
|
|
||||||
|
|
||||||
CreateOrUpdateAgentAlert(connInfo, parameters.Alert);
|
|
||||||
|
|
||||||
await requestContext.SendResult(result);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateOrUpdateAgentAlert(ConnectionInfo connInfo, AgentAlertInfo alert)
|
|
||||||
{
|
|
||||||
if (connInfo != null && ValidateAgentAlertInfo(alert))
|
|
||||||
{
|
|
||||||
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
||||||
STParameters param = new STParameters(dataContainer.Document);
|
|
||||||
param.SetParam("alert", alert.JobName);
|
|
||||||
|
|
||||||
using (AgentAlertActions agentAlert = new AgentAlertActions(dataContainer, alert))
|
|
||||||
{
|
|
||||||
agentAlert.CreateOrUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle request to delete an alert
|
/// Handle request to delete an alert
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal async Task HandleDeleteAgentAlertRequest(DeleteAgentAlertParams parameters, RequestContext<ResultStatus> requestContext)
|
internal async Task HandleDeleteAgentAlertRequest(DeleteAgentAlertParams parameters, RequestContext<ResultStatus> requestContext)
|
||||||
{
|
{
|
||||||
await Task.Run(async () =>
|
var result = await ConfigureAgentAlert(
|
||||||
|
parameters.OwnerUri,
|
||||||
|
parameters.Alert,
|
||||||
|
ConfigAction.Drop,
|
||||||
|
RunType.RunNow);
|
||||||
|
|
||||||
|
await requestContext.SendResult(new ResultStatus()
|
||||||
{
|
{
|
||||||
var result = new ResultStatus();
|
Success = result.Item1,
|
||||||
try
|
ErrorMessage = result.Item2
|
||||||
{
|
|
||||||
ConnectionInfo connInfo;
|
|
||||||
ConnectionServiceInstance.TryFindConnection(
|
|
||||||
parameters.OwnerUri,
|
|
||||||
out connInfo);
|
|
||||||
|
|
||||||
AgentAlertInfo alert = parameters.Alert;
|
|
||||||
if (connInfo != null && ValidateAgentAlertInfo(alert))
|
|
||||||
{
|
|
||||||
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
||||||
STParameters param = new STParameters(dataContainer.Document);
|
|
||||||
param.SetParam("alert", alert.JobName);
|
|
||||||
|
|
||||||
using (AgentAlertActions agentAlert = new AgentAlertActions(dataContainer, alert))
|
|
||||||
{
|
|
||||||
agentAlert.Drop();
|
|
||||||
result.Success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
result.Success = false;
|
|
||||||
result.ErrorMessage = ex.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
await requestContext.SendResult(result);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,41 +441,60 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
internal async Task HandleAgentOperatorsRequest(AgentOperatorsParams parameters, RequestContext<AgentOperatorsResult> requestContext)
|
internal async Task HandleAgentOperatorsRequest(AgentOperatorsParams parameters, RequestContext<AgentOperatorsResult> requestContext)
|
||||||
{
|
{
|
||||||
await requestContext.SendResult(null);
|
await requestContext.SendResult(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task HandleCreateAgentOperatorRequest(CreateAgentOperatorParams parameters, RequestContext<CreateAgentOperatorResult> requestContext)
|
internal async Task HandleCreateAgentOperatorRequest(
|
||||||
|
CreateAgentOperatorParams parameters,
|
||||||
|
RequestContext<AgentOperatorResult> requestContext)
|
||||||
{
|
{
|
||||||
await Task.Run(async () =>
|
var result = await ConfigureAgentOperator(
|
||||||
|
parameters.OwnerUri,
|
||||||
|
parameters.Operator,
|
||||||
|
ConfigAction.Create,
|
||||||
|
RunType.RunNow);
|
||||||
|
|
||||||
|
await requestContext.SendResult(new AgentOperatorResult()
|
||||||
{
|
{
|
||||||
var result = new CreateAgentOperatorResult();
|
Success = result.Item1,
|
||||||
ConnectionInfo connInfo;
|
ErrorMessage = result.Item2,
|
||||||
ConnectionServiceInstance.TryFindConnection(
|
Operator = parameters.Operator
|
||||||
parameters.OwnerUri,
|
|
||||||
out connInfo);
|
|
||||||
|
|
||||||
AgentOperatorInfo operatorInfo = parameters.Operator;
|
|
||||||
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
||||||
STParameters param = new STParameters(dataContainer.Document);
|
|
||||||
param.SetParam("operator", operatorInfo.Name);
|
|
||||||
|
|
||||||
using (AgentOperator agentOperator = new AgentOperator(dataContainer, operatorInfo))
|
|
||||||
{
|
|
||||||
agentOperator.CreateOrUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
await requestContext.SendResult(result);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task HandleUpdateAgentOperatorRequest(UpdateAgentOperatorParams parameters, RequestContext<UpdateAgentOperatorResult> requestContext)
|
internal async Task HandleUpdateAgentOperatorRequest(
|
||||||
|
UpdateAgentOperatorParams parameters,
|
||||||
|
RequestContext<AgentOperatorResult> requestContext)
|
||||||
{
|
{
|
||||||
await requestContext.SendResult(null);
|
var result = await ConfigureAgentOperator(
|
||||||
|
parameters.OwnerUri,
|
||||||
|
parameters.Operator,
|
||||||
|
ConfigAction.Update,
|
||||||
|
RunType.RunNow);
|
||||||
|
|
||||||
|
await requestContext.SendResult(new AgentOperatorResult()
|
||||||
|
{
|
||||||
|
Success = result.Item1,
|
||||||
|
ErrorMessage = result.Item2,
|
||||||
|
Operator = parameters.Operator
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task HandleDeleteAgentOperatorRequest(DeleteAgentOperatorParams parameters, RequestContext<DeleteAgentOperatorResult> requestContext)
|
internal async Task HandleDeleteAgentOperatorRequest(
|
||||||
|
DeleteAgentOperatorParams parameters,
|
||||||
|
RequestContext<ResultStatus> requestContext)
|
||||||
{
|
{
|
||||||
await requestContext.SendResult(null);
|
var result = await ConfigureAgentOperator(
|
||||||
}
|
parameters.OwnerUri,
|
||||||
|
parameters.Operator,
|
||||||
|
ConfigAction.Drop,
|
||||||
|
RunType.RunNow);
|
||||||
|
|
||||||
|
await requestContext.SendResult(new ResultStatus()
|
||||||
|
{
|
||||||
|
Success = result.Item1,
|
||||||
|
ErrorMessage = result.Item2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#endregion // "Operator Handlers"
|
#endregion // "Operator Handlers"
|
||||||
|
|
||||||
@@ -718,6 +548,140 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion // "Proxy Handlers"
|
||||||
|
|
||||||
|
|
||||||
|
#region "Helpers"
|
||||||
|
|
||||||
|
internal async Task<Tuple<bool, string>> ConfigureAgentJob(
|
||||||
|
string ownerUri,
|
||||||
|
AgentJobInfo jobInfo,
|
||||||
|
ConfigAction configAction,
|
||||||
|
RunType runType)
|
||||||
|
{
|
||||||
|
return await Task<Tuple<bool, string>>.Run(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JobData jobData;
|
||||||
|
CDataContainer dataContainer;
|
||||||
|
CreateJobData(ownerUri, jobInfo.Name, out dataContainer, out jobData, jobInfo);
|
||||||
|
|
||||||
|
using (JobActions jobActions = new JobActions(dataContainer, jobData, configAction))
|
||||||
|
{
|
||||||
|
var executionHandler = new ExecutonHandler(jobActions);
|
||||||
|
executionHandler.RunNow(runType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Tuple<bool, string>(true, string.Empty);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new Tuple<bool, string>(false, ex.ToString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<Tuple<bool, string>> ConfigureAgentJobStep(
|
||||||
|
string ownerUri,
|
||||||
|
AgentJobStepInfo stepInfo,
|
||||||
|
ConfigAction configAction,
|
||||||
|
RunType runType)
|
||||||
|
{
|
||||||
|
return await Task<Tuple<bool, string>>.Run(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(stepInfo.JobName))
|
||||||
|
{
|
||||||
|
return new Tuple<bool, string>(false, "JobId cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
JobData jobData;
|
||||||
|
CDataContainer dataContainer;
|
||||||
|
CreateJobData(ownerUri, stepInfo.JobName, out dataContainer, out jobData);
|
||||||
|
|
||||||
|
using (var jobStep = new JobStepsActions(dataContainer, jobData, stepInfo, configAction))
|
||||||
|
{
|
||||||
|
var executionHandler = new ExecutonHandler(jobStep);
|
||||||
|
executionHandler.RunNow(runType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Tuple<bool, string>(true, string.Empty);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// log exception here
|
||||||
|
return new Tuple<bool, string>(false, ex.ToString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<Tuple<bool, string>> ConfigureAgentAlert(
|
||||||
|
string ownerUri,
|
||||||
|
AgentAlertInfo alert,
|
||||||
|
ConfigAction configAction,
|
||||||
|
RunType runType)
|
||||||
|
{
|
||||||
|
return await Task<Tuple<bool, string>>.Run(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ConnectionInfo connInfo;
|
||||||
|
ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo);
|
||||||
|
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
||||||
|
STParameters param = new STParameters(dataContainer.Document);
|
||||||
|
param.SetParam("alert", alert.JobName);
|
||||||
|
|
||||||
|
if (alert != null && !string.IsNullOrWhiteSpace(alert.JobName))
|
||||||
|
{
|
||||||
|
using (AgentAlertActions agentAlert = new AgentAlertActions(dataContainer, alert, configAction))
|
||||||
|
{
|
||||||
|
var executionHandler = new ExecutonHandler(agentAlert);
|
||||||
|
executionHandler.RunNow(runType, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Tuple<bool, string>(true, string.Empty);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new Tuple<bool, string>(false, ex.ToString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
internal async Task<Tuple<bool, string>> ConfigureAgentOperator(
|
||||||
|
string ownerUri,
|
||||||
|
AgentOperatorInfo operatorInfo,
|
||||||
|
ConfigAction configAction,
|
||||||
|
RunType runType)
|
||||||
|
{
|
||||||
|
return await Task<Tuple<bool, string>>.Run(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ConnectionInfo connInfo;
|
||||||
|
ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo);
|
||||||
|
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
||||||
|
STParameters param = new STParameters(dataContainer.Document);
|
||||||
|
param.SetParam("operator", operatorInfo.Name);
|
||||||
|
|
||||||
|
using (AgentOperatorActions agentOperator = new AgentOperatorActions(dataContainer, operatorInfo, configAction))
|
||||||
|
{
|
||||||
|
var executionHandler = new ExecutonHandler(agentOperator);
|
||||||
|
executionHandler.RunNow(runType, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Tuple<bool, string>(true, string.Empty);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return new Tuple<bool, string>(false, ex.ToString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
internal async Task<bool> ConfigureAgentProxy(
|
internal async Task<bool> ConfigureAgentProxy(
|
||||||
string ownerUri,
|
string ownerUri,
|
||||||
string accountName,
|
string accountName,
|
||||||
@@ -763,8 +727,73 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateJobData(
|
||||||
|
string ownerUri,
|
||||||
|
string jobName,
|
||||||
|
out CDataContainer dataContainer,
|
||||||
|
out JobData jobData,
|
||||||
|
AgentJobInfo jobInfo = null)
|
||||||
|
{
|
||||||
|
ConnectionInfo connInfo;
|
||||||
|
ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo);
|
||||||
|
dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
||||||
|
|
||||||
|
XmlDocument jobDoc = CreateJobXmlDocument(dataContainer.Server.Name.ToUpper(), jobName);
|
||||||
|
dataContainer.Init(jobDoc.InnerXml);
|
||||||
|
|
||||||
|
STParameters param = new STParameters(dataContainer.Document);
|
||||||
|
param.SetParam("job", string.Empty);
|
||||||
|
param.SetParam("jobid", string.Empty);
|
||||||
|
|
||||||
|
jobData = new JobData(dataContainer, jobInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion // "Proxy Handlers"
|
public static XmlDocument CreateJobXmlDocument(string svrName, string jobName)
|
||||||
|
{
|
||||||
|
// XML element strings
|
||||||
|
const string XmlFormDescElementName = "formdescription";
|
||||||
|
const string XmlParamsElementName = "params";
|
||||||
|
const string XmlJobElementName = "job";
|
||||||
|
const string XmlUrnElementName = "urn";
|
||||||
|
const string UrnFormatStr = "Server[@Name='{0}']/JobServer[@Name='{0}']/Job[@Name='{1}']";
|
||||||
|
|
||||||
|
// Write out XML.
|
||||||
|
StringWriter textWriter = new StringWriter();
|
||||||
|
XmlTextWriter xmlWriter = new XmlTextWriter(textWriter);
|
||||||
|
|
||||||
|
xmlWriter.WriteStartElement(XmlFormDescElementName);
|
||||||
|
xmlWriter.WriteStartElement(XmlParamsElementName);
|
||||||
|
|
||||||
|
xmlWriter.WriteElementString(XmlJobElementName, jobName);
|
||||||
|
xmlWriter.WriteElementString(XmlUrnElementName, string.Format(UrnFormatStr, svrName, jobName));
|
||||||
|
|
||||||
|
xmlWriter.WriteEndElement();
|
||||||
|
xmlWriter.WriteEndElement();
|
||||||
|
|
||||||
|
xmlWriter.Close();
|
||||||
|
|
||||||
|
// Create an XML document.
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
XmlTextReader rdr = new XmlTextReader(new System.IO.StringReader(textWriter.ToString()));
|
||||||
|
rdr.MoveToContent();
|
||||||
|
doc.LoadXml(rdr.ReadOuterXml());
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Tuple<SqlConnectionInfo, DataTable, ServerConnection> CreateSqlConnection(ConnectionInfo connInfo, String jobId)
|
||||||
|
{
|
||||||
|
var sqlConnection = ConnectionService.OpenSqlConnection(connInfo);
|
||||||
|
var serverConnection = new ServerConnection(sqlConnection);
|
||||||
|
var server = new Server(serverConnection);
|
||||||
|
var filter = new JobHistoryFilter();
|
||||||
|
filter.JobID = new Guid(jobId);
|
||||||
|
var dt = server.JobServer.EnumJobHistory(filter);
|
||||||
|
var sqlConnInfo = new SqlConnectionInfo(serverConnection, SqlServer.Management.Common.ConnectionType.SqlConnection);
|
||||||
|
return new Tuple<SqlConnectionInfo, DataTable, ServerConnection>(sqlConnInfo, dt, serverConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion // "Helpers"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts
|
|||||||
RequestType<AgentOperatorsParams, AgentOperatorsResult>.Create("agent/operators");
|
RequestType<AgentOperatorsParams, AgentOperatorsResult>.Create("agent/operators");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SQL Agent Operator result
|
||||||
|
/// </summary>
|
||||||
|
public class AgentOperatorResult : ResultStatus
|
||||||
|
{
|
||||||
|
public AgentOperatorInfo Operator { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQL Agent create Operator params
|
/// SQL Agent create Operator params
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -48,13 +56,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts
|
|||||||
public AgentOperatorInfo Operator { get; set; }
|
public AgentOperatorInfo Operator { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SQL Agent create Operator result
|
|
||||||
/// </summary>
|
|
||||||
public class CreateAgentOperatorResult : ResultStatus
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQL Agent create Operator request type
|
/// SQL Agent create Operator request type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -64,38 +65,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts
|
|||||||
/// Request definition
|
/// Request definition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly
|
public static readonly
|
||||||
RequestType<CreateAgentOperatorParams, CreateAgentOperatorResult> Type =
|
RequestType<CreateAgentOperatorParams, AgentOperatorResult> Type =
|
||||||
RequestType<CreateAgentOperatorParams, CreateAgentOperatorResult>.Create("agent/createoperator");
|
RequestType<CreateAgentOperatorParams, AgentOperatorResult>.Create("agent/createoperator");
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SQL Agent delete Operator params
|
|
||||||
/// </summary>
|
|
||||||
public class DeleteAgentOperatorParams : GeneralRequestDetails
|
|
||||||
{
|
|
||||||
public string OwnerUri { get; set; }
|
|
||||||
|
|
||||||
public AgentOperatorInfo Operator { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SQL Agent delete Operator result
|
|
||||||
/// </summary>
|
|
||||||
public class DeleteAgentOperatorResult : ResultStatus
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SQL Agent delete Operator request type
|
|
||||||
/// </summary>
|
|
||||||
public class DeleteAgentOperatorRequest
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Request definition
|
|
||||||
/// </summary>
|
|
||||||
public static readonly
|
|
||||||
RequestType<DeleteAgentOperatorParams, DeleteAgentOperatorResult> Type =
|
|
||||||
RequestType<DeleteAgentOperatorParams, DeleteAgentOperatorResult>.Create("agent/deleteoperator");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -108,13 +79,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts
|
|||||||
public AgentOperatorInfo Operator { get; set; }
|
public AgentOperatorInfo Operator { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SQL Agent update Operator result
|
|
||||||
/// </summary>
|
|
||||||
public class UpdateAgentOperatorResult : ResultStatus
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SQL Agent update Operator request type
|
/// SQL Agent update Operator request type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -124,7 +88,30 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts
|
|||||||
/// Request definition
|
/// Request definition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly
|
public static readonly
|
||||||
RequestType<UpdateAgentOperatorParams, UpdateAgentOperatorResult> Type =
|
RequestType<UpdateAgentOperatorParams, AgentOperatorResult> Type =
|
||||||
RequestType<UpdateAgentOperatorParams, UpdateAgentOperatorResult>.Create("agent/updateoperator");
|
RequestType<UpdateAgentOperatorParams, AgentOperatorResult>.Create("agent/updateoperator");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SQL Agent delete Operator params
|
||||||
|
/// </summary>
|
||||||
|
public class DeleteAgentOperatorParams : GeneralRequestDetails
|
||||||
|
{
|
||||||
|
public string OwnerUri { get; set; }
|
||||||
|
|
||||||
|
public AgentOperatorInfo Operator { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SQL Agent delete Operator request type
|
||||||
|
/// </summary>
|
||||||
|
public class DeleteAgentOperatorRequest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Request definition
|
||||||
|
/// </summary>
|
||||||
|
public static readonly
|
||||||
|
RequestType<DeleteAgentOperatorParams, ResultStatus> Type =
|
||||||
|
RequestType<DeleteAgentOperatorParams, ResultStatus>.Create("agent/deleteoperator");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Data;
|
|
||||||
using Microsoft.SqlServer.Management.Common;
|
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.SqlServer.Management.Smo.Agent;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
|
||||||
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||||
|
|
||||||
@@ -27,14 +21,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private AgentAlertInfo alertInfo = null;
|
private AgentAlertInfo alertInfo = null;
|
||||||
|
|
||||||
|
private ConfigAction configAction;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default constructor that will be used to create dialog
|
/// Default constructor that will be used to create dialog
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataContainer"></param>
|
/// <param name="dataContainer"></param>
|
||||||
public AgentAlertActions(CDataContainer dataContainer, AgentAlertInfo alertInfo)
|
public AgentAlertActions(CDataContainer dataContainer, AgentAlertInfo alertInfo, ConfigAction configAction)
|
||||||
{
|
{
|
||||||
this.alertInfo = alertInfo;
|
this.alertInfo = alertInfo;
|
||||||
this.DataContainer = dataContainer;
|
this.DataContainer = dataContainer;
|
||||||
|
this.configAction = configAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetAlertName(CDataContainer container)
|
private static string GetAlertName(CDataContainer container)
|
||||||
@@ -44,7 +41,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
parameters.SetDocument(container.Document);
|
parameters.SetDocument(container.Document);
|
||||||
if (parameters.GetParam("alert", ref alertName) == false || string.IsNullOrWhiteSpace(alertName))
|
if (parameters.GetParam("alert", ref alertName) == false || string.IsNullOrWhiteSpace(alertName))
|
||||||
{
|
{
|
||||||
throw new Exception("SRError.AlertNameCannotBeBlank");
|
throw new Exception(SR.AlertNameCannotBeBlank);
|
||||||
}
|
}
|
||||||
return alertName.Trim();
|
return alertName.Trim();
|
||||||
}
|
}
|
||||||
@@ -59,8 +56,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
protected override bool DoPreProcessExecution(RunType runType, out ExecutionMode executionResult)
|
protected override bool DoPreProcessExecution(RunType runType, out ExecutionMode executionResult)
|
||||||
{
|
{
|
||||||
base.DoPreProcessExecution(runType, out executionResult);
|
base.DoPreProcessExecution(runType, out executionResult);
|
||||||
return false;
|
if (this.configAction == ConfigAction.Drop)
|
||||||
}
|
{
|
||||||
|
Drop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CreateOrUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// regular execution always takes place
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Drop()
|
public bool Drop()
|
||||||
{
|
{
|
||||||
@@ -136,11 +143,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
ApplicationException applicationException;
|
ApplicationException applicationException;
|
||||||
if (createNewAlert)
|
if (createNewAlert)
|
||||||
{
|
{
|
||||||
applicationException = new ApplicationException("AgentAlertSR.CannotCreateNewAlert", e);
|
applicationException = new ApplicationException(SR.CannotCreateNewAlert, e);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
applicationException = new ApplicationException("AgentAlertSR.CannotAlterAlert", e);
|
applicationException = new ApplicationException(SR.CannotAlterAlert, e);
|
||||||
}
|
}
|
||||||
throw applicationException;
|
throw applicationException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||||
|
|
||||||
|
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Agent Operators management class
|
||||||
|
/// </summary>
|
||||||
|
internal class AgentOperatorActions : ManagementActionBase
|
||||||
|
{
|
||||||
|
private AgentOperatorInfo operatorInfo;
|
||||||
|
private AgentOperatorsData operatorsData = null;
|
||||||
|
private ConfigAction configAction;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor
|
||||||
|
/// </summary>
|
||||||
|
public AgentOperatorActions(
|
||||||
|
CDataContainer dataContainer,
|
||||||
|
AgentOperatorInfo operatorInfo,
|
||||||
|
ConfigAction configAction)
|
||||||
|
{
|
||||||
|
if (dataContainer == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("dataContainer");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operatorInfo == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("operatorInfo");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.operatorInfo = operatorInfo;
|
||||||
|
this.DataContainer = dataContainer;
|
||||||
|
this.configAction = configAction;
|
||||||
|
|
||||||
|
STParameters parameters = new STParameters();
|
||||||
|
parameters.SetDocument(dataContainer.Document);
|
||||||
|
|
||||||
|
string agentOperatorName = null;
|
||||||
|
if (parameters.GetParam("operator", ref agentOperatorName))
|
||||||
|
{
|
||||||
|
this.operatorsData = new AgentOperatorsData(
|
||||||
|
dataContainer,
|
||||||
|
agentOperatorName,
|
||||||
|
createMode: configAction == ConfigAction.Create);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("agentOperatorName");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if(disposing)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
// <summary>
|
||||||
|
/// called by PreProcessExecution to enable derived classes to take over execution
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="runType"></param>
|
||||||
|
/// <param name="executionResult"></param>
|
||||||
|
/// <returns>
|
||||||
|
/// true if regular execution should take place, false if everything,
|
||||||
|
/// has been done by this function
|
||||||
|
/// </returns>
|
||||||
|
protected override bool DoPreProcessExecution(RunType runType, out ExecutionMode executionResult)
|
||||||
|
{
|
||||||
|
base.DoPreProcessExecution(runType, out executionResult);
|
||||||
|
|
||||||
|
if (this.configAction == ConfigAction.Drop)
|
||||||
|
{
|
||||||
|
var currentOperator = this.operatorsData.Operator;
|
||||||
|
if (currentOperator != null)
|
||||||
|
{
|
||||||
|
currentOperator.DropIfExists();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.operatorsData.ApplyChanges(this.operatorInfo);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,158 +4,15 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.SqlServer.Management.Common;
|
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.SqlServer.Management.Smo.Agent;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Admin;
|
|
||||||
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Agent Operators management class
|
|
||||||
/// </summary>
|
|
||||||
internal class AgentOperator : ManagementActionBase
|
|
||||||
{
|
|
||||||
private AgentOperatorInfo operatorInfo;
|
|
||||||
|
|
||||||
AgentOperatorsData operatorsData = null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor
|
|
||||||
/// </summary>
|
|
||||||
public AgentOperator(CDataContainer dataContainer, AgentOperatorInfo operatorInfo)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (dataContainer == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("dataContainer");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operatorInfo == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("operatorInfo");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.operatorInfo = operatorInfo;
|
|
||||||
this.DataContainer = dataContainer;
|
|
||||||
|
|
||||||
STParameters parameters = new STParameters();
|
|
||||||
parameters.SetDocument(dataContainer.Document);
|
|
||||||
|
|
||||||
string agentOperatorName = null;
|
|
||||||
if (parameters.GetParam("operator", ref agentOperatorName))
|
|
||||||
{
|
|
||||||
this.operatorsData = new AgentOperatorsData(dataContainer, agentOperatorName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("agentOperatorName");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
throw new ApplicationException("AgentOperatorsSR.FailedToCreateInitializeAgentOperatorDialog", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clean up any resources being used.
|
|
||||||
/// </summary>
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if(disposing)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CreateOrUpdate()
|
|
||||||
{
|
|
||||||
this.operatorsData.ApplyChanges(this.operatorInfo);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region internal structures
|
|
||||||
/// <summary>
|
|
||||||
/// Provides data to be consumed in the job notification grid
|
|
||||||
/// </summary>
|
|
||||||
internal struct AgentJobNotificationHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// constructor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">job name</param>
|
|
||||||
/// <param name="notifyEmail"></param>
|
|
||||||
/// <param name="notifyPager"></param>
|
|
||||||
public AgentJobNotificationHelper(string name, CompletionAction notifyEmail, CompletionAction notifyPager)
|
|
||||||
{
|
|
||||||
this.Name = name;
|
|
||||||
this.NotifyEmail = notifyEmail;
|
|
||||||
this.NotifyPager = notifyPager;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Name of the job
|
|
||||||
/// </summary>
|
|
||||||
public string Name;
|
|
||||||
/// <summary>
|
|
||||||
/// job email notification action
|
|
||||||
/// </summary>
|
|
||||||
public CompletionAction NotifyEmail;
|
|
||||||
/// <summary>
|
|
||||||
/// job pager notification action
|
|
||||||
/// </summary>
|
|
||||||
public CompletionAction NotifyPager;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Provides data to be consumed in the alert notification grid
|
|
||||||
/// </summary>
|
|
||||||
internal struct AgentAlertNotificationHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// constructor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="name">Name of the alert</param>
|
|
||||||
/// <param name="notifyEmail"></param>
|
|
||||||
/// <param name="notifyPager"></param>
|
|
||||||
/// <param name="alert">Alert object</param>
|
|
||||||
public AgentAlertNotificationHelper(string name, bool notifyEmail, bool notifyPager, Alert alert)
|
|
||||||
{
|
|
||||||
this.Name = name;
|
|
||||||
this.NotifyEmail = notifyEmail;
|
|
||||||
this.NotifyPager = notifyPager;
|
|
||||||
this.Alert = alert;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Alert name
|
|
||||||
/// </summary>
|
|
||||||
public string Name;
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates whether the alert will notify the operator through email
|
|
||||||
/// </summary>
|
|
||||||
public bool NotifyEmail;
|
|
||||||
/// <summary>
|
|
||||||
/// Indicates whether the alert will notify the operator through pager
|
|
||||||
/// </summary>
|
|
||||||
public bool NotifyPager;
|
|
||||||
/// <summary>
|
|
||||||
/// Alert object. optimisation to stop us having to lookup the alert object when needed
|
|
||||||
/// </summary>
|
|
||||||
public Alert Alert;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Proxy class for the AgentOperators dialog and property pages.
|
/// Proxy class for the AgentOperators dialog and property pages.
|
||||||
/// Performs lazy instantiation of groups of data based around the operators dialog property pages
|
/// Performs lazy instantiation of groups of data based around the operators dialog property pages
|
||||||
@@ -170,7 +27,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Original operator name. Empty if we are creating a new operator
|
/// Original operator name. Empty if we are creating a new operator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string originalOperatorName = String.Empty;
|
string originalOperatorName = string.Empty;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates whether we are creating an operator or not
|
/// Indicates whether we are creating an operator or not
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -209,6 +66,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// will be null if the alert notifications have not been initialised
|
/// will be null if the alert notifications have not been initialised
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IList<AgentAlertNotificationHelper> alertNotifications;
|
IList<AgentAlertNotificationHelper> alertNotifications;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// will be null if the job notifications have not been initialised
|
/// will be null if the job notifications have not been initialised
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -222,6 +80,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region properties
|
#region properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// the current Operator SMO object
|
||||||
|
/// </summary>
|
||||||
|
public Operator Operator
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
JobServer jobServer = GetJobServer();
|
||||||
|
return jobServer.Operators[this.originalOperatorName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// indicates if the data is in create mode
|
/// indicates if the data is in create mode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -232,6 +103,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
return this.createMode;
|
return this.createMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// name of the object
|
/// name of the object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -248,6 +120,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
name = value;
|
name = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates if the dataobject is readonly
|
/// Indicates if the dataobject is readonly
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -275,6 +148,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
enabled = value;
|
enabled = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// email address of this operator
|
/// email address of this operator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -291,6 +165,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.emailAddress = value;
|
this.emailAddress = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// pager address of this operator
|
/// pager address of this operator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -324,6 +199,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.pagerDays = value;
|
this.pagerDays = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Weekday start time for this operator to be active
|
/// Weekday start time for this operator to be active
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -340,6 +216,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.weekdayStartTime = value;
|
this.weekdayStartTime = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Weekday end time for this operator to be active
|
/// Weekday end time for this operator to be active
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -356,6 +233,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.weekdayEndTime = value;
|
this.weekdayEndTime = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saturday start time for this operator to be active
|
/// Saturday start time for this operator to be active
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -372,6 +250,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.saturdayStartTime = value;
|
this.saturdayStartTime = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saturday end time for this operator to be active
|
/// Saturday end time for this operator to be active
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -388,6 +267,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.saturdayEndTime = value;
|
this.saturdayEndTime = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sunday start time for this operator to be active
|
/// Sunday start time for this operator to be active
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -404,6 +284,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.sundayStartTime = value;
|
this.sundayStartTime = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saturday end time for this operator to be active
|
/// Saturday end time for this operator to be active
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -438,6 +319,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.alertNotifications = value;
|
this.alertNotifications = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Jobs that notify this operator. This has to be set through the jobs dialog and is read only
|
/// Jobs that notify this operator. This has to be set through the jobs dialog and is read only
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -463,6 +345,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
return this.lastEmailDate;
|
return this.lastEmailDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Date this operator was last paged
|
/// Date this operator was last paged
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -480,7 +363,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
public AgentOperatorsData(CDataContainer dataContainer, string operatorName)
|
public AgentOperatorsData(CDataContainer dataContainer, string operatorName, bool createMode)
|
||||||
{
|
{
|
||||||
if (dataContainer == null)
|
if (dataContainer == null)
|
||||||
{
|
{
|
||||||
@@ -497,7 +380,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.originalOperatorName = operatorName;
|
this.originalOperatorName = operatorName;
|
||||||
this.name = operatorName;
|
this.name = operatorName;
|
||||||
|
|
||||||
this.createMode = operatorName.Length == 0;
|
this.createMode = createMode;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -541,6 +424,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.generalInitialized = true;
|
this.generalInitialized = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load the data for the jobs that notify this operator. Can be called multiple times and will
|
/// Load the data for the jobs that notify this operator. Can be called multiple times and will
|
||||||
/// only load the data initially, or after a reset.
|
/// only load the data initially, or after a reset.
|
||||||
@@ -577,6 +461,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load alerts that notify this operator
|
/// Load alerts that notify this operator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -824,9 +709,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void LoadGeneralDefaults()
|
private void LoadGeneralDefaults()
|
||||||
{
|
{
|
||||||
name = String.Empty;
|
name = string.Empty;
|
||||||
this.emailAddress = String.Empty;
|
this.emailAddress = string.Empty;
|
||||||
this.pagerAddress = String.Empty;
|
this.pagerAddress = string.Empty;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
pagerDays = 0;
|
pagerDays = 0;
|
||||||
|
|
||||||
@@ -835,6 +720,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
|
|
||||||
this.generalInitialized = true;
|
this.generalInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set job notification defaults. This is just an empty list
|
/// Set job notification defaults. This is just an empty list
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -842,6 +728,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
this.jobNotifications = new List<AgentJobNotificationHelper>();
|
this.jobNotifications = new List<AgentJobNotificationHelper>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// set the alert notification defaults. This list will contain all of the alerts
|
/// set the alert notification defaults. This list will contain all of the alerts
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -858,6 +745,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.alertNotifications.Add(alertNotification);
|
this.alertNotifications.Add(alertNotification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// load defaults for the history page
|
/// load defaults for the history page
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -878,9 +766,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
private JobServer GetJobServer()
|
private JobServer GetJobServer()
|
||||||
{
|
{
|
||||||
JobServer jobServer = this.dataContainer.Server.JobServer;
|
JobServer jobServer = this.dataContainer.Server.JobServer;
|
||||||
if(jobServer == null)
|
if (jobServer == null)
|
||||||
{
|
{
|
||||||
throw new ApplicationException("AgentOperatorsSR.JobServerIsNotAvailable");
|
throw new ApplicationException(SR.JobServerIsNotAvailable);
|
||||||
}
|
}
|
||||||
return jobServer;
|
return jobServer;
|
||||||
}
|
}
|
||||||
@@ -894,7 +782,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
private Operator GetCurrentOperator()
|
private Operator GetCurrentOperator()
|
||||||
{
|
{
|
||||||
JobServer jobServer = GetJobServer();
|
JobServer jobServer = GetJobServer();
|
||||||
|
|
||||||
Operator currentOperator = jobServer.Operators[this.originalOperatorName];
|
Operator currentOperator = jobServer.Operators[this.originalOperatorName];
|
||||||
this.createMode = (currentOperator == null);
|
this.createMode = (currentOperator == null);
|
||||||
if (this.createMode)
|
if (this.createMode)
|
||||||
@@ -913,6 +800,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
return new TimeSpan(dateTime.Hour, dateTime.Minute, dateTime.Second);
|
return new TimeSpan(dateTime.Hour, dateTime.Minute, dateTime.Second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -944,4 +832,81 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region internal structures
|
||||||
|
/// <summary>
|
||||||
|
/// Provides data to be consumed in the job notification grid
|
||||||
|
/// </summary>
|
||||||
|
internal struct AgentJobNotificationHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">job name</param>
|
||||||
|
/// <param name="notifyEmail"></param>
|
||||||
|
/// <param name="notifyPager"></param>
|
||||||
|
public AgentJobNotificationHelper(string name, CompletionAction notifyEmail, CompletionAction notifyPager)
|
||||||
|
{
|
||||||
|
this.Name = name;
|
||||||
|
this.NotifyEmail = notifyEmail;
|
||||||
|
this.NotifyPager = notifyPager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the job
|
||||||
|
/// </summary>
|
||||||
|
public string Name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// job email notification action
|
||||||
|
/// </summary>
|
||||||
|
public CompletionAction NotifyEmail;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// job pager notification action
|
||||||
|
/// </summary>
|
||||||
|
public CompletionAction NotifyPager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides data to be consumed in the alert notification grid
|
||||||
|
/// </summary>
|
||||||
|
internal struct AgentAlertNotificationHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// constructor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Name of the alert</param>
|
||||||
|
/// <param name="notifyEmail"></param>
|
||||||
|
/// <param name="notifyPager"></param>
|
||||||
|
/// <param name="alert">Alert object</param>
|
||||||
|
public AgentAlertNotificationHelper(string name, bool notifyEmail, bool notifyPager, Alert alert)
|
||||||
|
{
|
||||||
|
this.Name = name;
|
||||||
|
this.NotifyEmail = notifyEmail;
|
||||||
|
this.NotifyPager = notifyPager;
|
||||||
|
this.Alert = alert;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Alert name
|
||||||
|
/// </summary>
|
||||||
|
public string Name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether the alert will notify the operator through email
|
||||||
|
/// </summary>
|
||||||
|
public bool NotifyEmail;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates whether the alert will notify the operator through pager
|
||||||
|
/// </summary>
|
||||||
|
public bool NotifyPager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Alert object. optimisation to stop us having to lookup the alert object when needed
|
||||||
|
/// </summary>
|
||||||
|
public Alert Alert;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
private ILogEntry m_currentEntry = null;
|
private ILogEntry m_currentEntry = null;
|
||||||
private int m_index = 0;
|
private int m_index = 0;
|
||||||
private bool m_isClosed = false;
|
private bool m_isClosed = false;
|
||||||
private TypedColumnCollection columnTypes;
|
|
||||||
private IServiceProvider serviceProvider = null;
|
private IServiceProvider serviceProvider = null;
|
||||||
|
|
||||||
private static string historyTableDeclaration = "declare @tmp_sp_help_jobhistory table";
|
private static string historyTableDeclaration = "declare @tmp_sp_help_jobhistory table";
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
private JobStepData data;
|
private JobStepData data;
|
||||||
private JobData jobData;
|
private JobData jobData;
|
||||||
|
private ConfigAction configAction;
|
||||||
|
|
||||||
public JobStepsActions(
|
public JobStepsActions(
|
||||||
CDataContainer dataContainer,
|
CDataContainer dataContainer,
|
||||||
@@ -26,17 +27,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
AgentJobStepInfo stepInfo,
|
AgentJobStepInfo stepInfo,
|
||||||
ConfigAction configAction)
|
ConfigAction configAction)
|
||||||
{
|
{
|
||||||
|
this.configAction = configAction;
|
||||||
this.DataContainer = dataContainer;
|
this.DataContainer = dataContainer;
|
||||||
this.jobData = jobData;
|
this.jobData = jobData;
|
||||||
|
|
||||||
if (configAction == ConfigAction.Update)
|
if (configAction == ConfigAction.Create)
|
||||||
{
|
{
|
||||||
JobStep jobStep = GetJobStep(this.jobData, stepInfo.StepName);
|
this.data = new JobStepData(jobData.JobSteps);
|
||||||
this.data = new JobStepData(jobStep, jobData.JobSteps);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.data = new JobStepData(jobData.JobSteps);
|
JobStep jobStep = GetJobStep(this.jobData, stepInfo.StepName);
|
||||||
|
this.data = new JobStepData(jobStep, jobData.JobSteps);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load properties from AgentJobStepInfo
|
// load properties from AgentJobStepInfo
|
||||||
@@ -48,27 +50,36 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
protected override bool DoPreProcessExecution(RunType runType, out ExecutionMode executionResult)
|
protected override bool DoPreProcessExecution(RunType runType, out ExecutionMode executionResult)
|
||||||
{
|
{
|
||||||
base.DoPreProcessExecution(runType, out executionResult);
|
base.DoPreProcessExecution(runType, out executionResult);
|
||||||
|
if (this.configAction == ConfigAction.Drop)
|
||||||
// Make sure the job step name is not blank.
|
|
||||||
if (this.data.Name == null || this.data.Name.Length == 0)
|
|
||||||
{
|
{
|
||||||
throw new Exception(SR.JobStepNameCannotBeBlank);
|
if (this.data.JobStep != null)
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
// Throw an error if the job step name already exists
|
this.data.JobStep.DropIfExists();
|
||||||
throw new Exception(SR.JobStepNameAlreadyExists(this.data.Name));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Make sure the job step name is not blank.
|
||||||
|
if (this.data.Name == null || this.data.Name.Length == 0)
|
||||||
|
{
|
||||||
|
throw new Exception(SR.JobStepNameCannotBeBlank);
|
||||||
|
}
|
||||||
|
|
||||||
if (runType == RunType.RunNow)
|
// 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)
|
||||||
this.data.ApplyChanges(this.jobData.Job);
|
{
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
// Throw an error if the job step name already exists
|
||||||
|
throw new Exception(SR.JobStepNameAlreadyExists(this.data.Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runType == RunType.RunNow)
|
||||||
|
{
|
||||||
|
this.data.ApplyChanges(this.jobData.Job);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// regular execution always takes place
|
// regular execution always takes place
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using System;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@@ -16,6 +15,7 @@ using Microsoft.SqlServer.Management.Diagnostics;
|
|||||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||||
using Microsoft.SqlServer.Management.Smo;
|
using Microsoft.SqlServer.Management.Smo;
|
||||||
using Microsoft.SqlServer.Management.Smo.Agent;
|
using Microsoft.SqlServer.Management.Smo.Agent;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
||||||
{
|
{
|
||||||
@@ -30,16 +30,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region private struct members
|
#region private struct members
|
||||||
private String name;
|
private string name;
|
||||||
private String description;
|
private string description;
|
||||||
private System.Int32 id;
|
private int id;
|
||||||
private System.Int32 activeEndDate;
|
private int activeEndDate;
|
||||||
private System.Int32 activeEndTimeOfDay;
|
private int activeEndTimeOfDay;
|
||||||
private System.Int32 activeStartDate;
|
private int activeStartDate;
|
||||||
private System.Int32 activeStartTimeOfDay;
|
private int activeStartTimeOfDay;
|
||||||
private System.Int32 frequencyInterval;
|
private int frequencyInterval;
|
||||||
private System.Int32 frequencyRecurrenceFactor;
|
private int frequencyRecurrenceFactor;
|
||||||
private System.Int32 frequencySubDayInterval;
|
private int frequencySubDayInterval;
|
||||||
private FrequencyTypes frequencyTypes;
|
private FrequencyTypes frequencyTypes;
|
||||||
private FrequencySubDayTypes frequencySubDayTypes;
|
private FrequencySubDayTypes frequencySubDayTypes;
|
||||||
private FrequencyRelativeIntervals frequencyRelativeIntervals;
|
private FrequencyRelativeIntervals frequencyRelativeIntervals;
|
||||||
@@ -289,7 +289,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
if (this.FrequencyInterval == 0)
|
if (this.FrequencyInterval == 0)
|
||||||
{
|
{
|
||||||
return String.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder daysOfWeek = new StringBuilder();
|
StringBuilder daysOfWeek = new StringBuilder();
|
||||||
@@ -347,7 +347,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
string format = String.Empty;
|
string format = string.Empty;
|
||||||
|
|
||||||
switch (this.FrequencyTypes)
|
switch (this.FrequencyTypes)
|
||||||
{
|
{
|
||||||
@@ -508,43 +508,43 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public properties
|
#region public properties
|
||||||
public System.Int32 ActiveEndDate
|
public int ActiveEndDate
|
||||||
{
|
{
|
||||||
get { return activeEndDate; }
|
get { return activeEndDate; }
|
||||||
set { activeEndDate = value; }
|
set { activeEndDate = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Int32 ActiveEndTimeOfDay
|
public int ActiveEndTimeOfDay
|
||||||
{
|
{
|
||||||
get { return activeEndTimeOfDay; }
|
get { return activeEndTimeOfDay; }
|
||||||
set { activeEndTimeOfDay = value; }
|
set { activeEndTimeOfDay = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Int32 ActiveStartDate
|
public int ActiveStartDate
|
||||||
{
|
{
|
||||||
get { return activeStartDate; }
|
get { return activeStartDate; }
|
||||||
set { activeStartDate = value; }
|
set { activeStartDate = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Int32 ActiveStartTimeOfDay
|
public int ActiveStartTimeOfDay
|
||||||
{
|
{
|
||||||
get { return activeStartTimeOfDay; }
|
get { return activeStartTimeOfDay; }
|
||||||
set { activeStartTimeOfDay = value; }
|
set { activeStartTimeOfDay = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Int32 FrequencyInterval
|
public int FrequencyInterval
|
||||||
{
|
{
|
||||||
get { return frequencyInterval; }
|
get { return frequencyInterval; }
|
||||||
set { frequencyInterval = value; }
|
set { frequencyInterval = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Int32 FrequencyRecurrenceFactor
|
public int FrequencyRecurrenceFactor
|
||||||
{
|
{
|
||||||
get { return frequencyRecurrenceFactor; }
|
get { return frequencyRecurrenceFactor; }
|
||||||
set { frequencyRecurrenceFactor = value; }
|
set { frequencyRecurrenceFactor = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Int32 FrequencySubDayInterval
|
public int FrequencySubDayInterval
|
||||||
{
|
{
|
||||||
get { return frequencySubDayInterval; }
|
get { return frequencySubDayInterval; }
|
||||||
set { frequencySubDayInterval = value; }
|
set { frequencySubDayInterval = value; }
|
||||||
@@ -592,7 +592,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Int32 ID
|
public int ID
|
||||||
{
|
{
|
||||||
get { return id; }
|
get { return id; }
|
||||||
set { id = value; }
|
set { id = value; }
|
||||||
@@ -1147,16 +1147,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
|
|
||||||
if (jobSchedules != null && version.Major < 9)
|
if (jobSchedules != null && version.Major < 9)
|
||||||
{
|
{
|
||||||
///Check to see if a duplicate job schedule name has been entered. This condition is permissable
|
// Check to see if a duplicate job schedule name has been entered. This condition is permissable
|
||||||
///in SQL 9, but not in previous versions.
|
// in SQL 9, but not in previous versions.
|
||||||
for (int index = 0; index < jobSchedules.Count; index++)
|
for (int index = 0; index < jobSchedules.Count; index++)
|
||||||
{
|
{
|
||||||
//If the schedule name matches an existing job, throw an error and ask user to enter another
|
// If the schedule name matches an existing job, throw an error and ask user to enter another
|
||||||
//name.
|
// name.
|
||||||
if (((JobScheduleData)jobSchedules[index]).Name == this.Name &&
|
if (((JobScheduleData)jobSchedules[index]).Name == this.Name &&
|
||||||
this.currentName != this.originalName)
|
this.currentName != this.originalName)
|
||||||
{
|
{
|
||||||
sbError.Append("SRError.ScheduleNameAlreadyExists(this.Name)" + "\n");
|
sbError.Append(SR.ScheduleNameAlreadyExists(this.Name) + "\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1165,40 +1165,39 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
// weekly schdule - ensure that the start date is less than the end date
|
// weekly schdule - ensure that the start date is less than the end date
|
||||||
if (this.ActiveStartDate > this.ActiveEndDate)
|
if (this.ActiveStartDate > this.ActiveEndDate)
|
||||||
{
|
{
|
||||||
sbError.Append("SRError.StartDateGreaterThanEndDate" + "\n");
|
sbError.Append(SR.StartDateGreaterThanEndDate + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//One Time events validations
|
// One Time events validations
|
||||||
if (this.FrequencyTypes == FrequencyTypes.OneTime)
|
if (this.FrequencyTypes == FrequencyTypes.OneTime)
|
||||||
{
|
{
|
||||||
//Check to make sure that the start time is greater than the baseline
|
// Check to make sure that the start time is greater than the baseline
|
||||||
//date of 01/01/1990
|
// date of 01/01/1990
|
||||||
if (this.ActiveStartDate < minStartDate)
|
if (this.ActiveStartDate < minStartDate)
|
||||||
{
|
{
|
||||||
sbError.Append("SRError.InvalidStartDate" + "\n");
|
sbError.Append(SR.InvalidStartDate + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Recurring schdule. Start time must be less than the end time.
|
// Recurring schdule. Start time must be less than the end time.
|
||||||
if (this.FrequencyTypes != FrequencyTypes.OneTime &&
|
if (this.FrequencyTypes != FrequencyTypes.OneTime &&
|
||||||
this.FrequencyTypes != FrequencyTypes.OnIdle)
|
this.FrequencyTypes != FrequencyTypes.OnIdle)
|
||||||
{
|
{
|
||||||
//Check to make sure that the start time is greater than the baseline
|
// Check to make sure that the start time is greater than the baseline
|
||||||
//date of 01/01/1990
|
// date of 01/01/1990
|
||||||
if (this.ActiveStartDate < minStartDate)
|
if (this.ActiveStartDate < minStartDate)
|
||||||
{
|
{
|
||||||
sbError.Append("SRError.InvalidStartDate" + "\n");
|
sbError.Append(SR.InvalidStartDate + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Check to ensure that the StartTime != to the EndTime
|
// Check to ensure that the StartTime != to the EndTime
|
||||||
if (this.ActiveStartTime == this.ActiveEndTime)
|
if (this.ActiveStartTime == this.ActiveEndTime)
|
||||||
{
|
{
|
||||||
sbError.Append("SRError.EndTimeEqualToStartTime" + "\n");
|
sbError.Append(SR.EndTimeEqualToStartTime + "\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// weekly schedule - at least one day should be selected
|
// weekly schedule - at least one day should be selected
|
||||||
@@ -1206,12 +1205,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
if (this.FrequencyInterval == 0)
|
if (this.FrequencyInterval == 0)
|
||||||
{
|
{
|
||||||
sbError.Append("SRError.InvalidWeeklySchedule" + "\n");
|
sbError.Append(SR.InvalidWeeklySchedule + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// $FUTURE add extra checks in future - e.g. 147675 - starttime/endtime startdate/enddate and thier format
|
|
||||||
|
|
||||||
// return error
|
// return error
|
||||||
if (sbError.ToString().Length > 0)
|
if (sbError.ToString().Length > 0)
|
||||||
{
|
{
|
||||||
@@ -1243,6 +1240,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.alreadyCreated = false;
|
this.alreadyCreated = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provide context to create a new schedule.
|
/// Provide context to create a new schedule.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1259,6 +1257,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
{
|
{
|
||||||
this.source = schedule;
|
this.source = schedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return this.GetSimpleJobDescription();
|
return this.GetSimpleJobDescription();
|
||||||
@@ -1322,6 +1321,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
this.alreadyCreated = false;
|
this.alreadyCreated = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// set defaults assuming no parent.
|
/// set defaults assuming no parent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1362,14 +1362,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
|
|
||||||
#region static constants
|
#region static constants
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum date supported by SSMS.
|
/// Maximum date supported
|
||||||
/// This is the same as the culture max date because SQl Agent range is larger than all cultures' ranges.
|
/// This is the same as the culture max date because SQL Agent range is larger than all cultures' ranges.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static DateTime MaxAgentDateValue
|
public static DateTime MaxAgentDateValue
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return DateTime.Now; // Utils.GetMaxCultureDateTime().Date;
|
return Utils.GetMaxCultureDateTime().Date;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#if false
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
@@ -182,3 +183,4 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#if false
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
@@ -605,11 +606,4 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#if false
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
@@ -466,3 +467,4 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#if false
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
@@ -155,3 +156,4 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#if false
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
@@ -250,10 +251,4 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#if false
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
@@ -108,3 +109,4 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#if false
|
||||||
//
|
//
|
||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
@@ -28,17 +29,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class SqlServerAgentPropertiesJobSystem : ManagementActionBase
|
internal class SqlServerAgentPropertiesJobSystem : ManagementActionBase
|
||||||
{
|
{
|
||||||
#region Private members
|
|
||||||
|
|
||||||
private int shutDownWaitTime;
|
|
||||||
private bool sysAdminOnly;
|
|
||||||
private string domainUser = string.Empty;
|
|
||||||
private string userName = string.Empty;
|
|
||||||
private string passwdMask = new string('*', 16);
|
|
||||||
private SecureString securePasswd = new SecureString();
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Implementation
|
#region Implementation
|
||||||
|
|
||||||
private void ApplyChanges()
|
private void ApplyChanges()
|
||||||
@@ -148,11 +138,4 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -4349,6 +4349,78 @@ namespace Microsoft.SqlTools.ServiceLayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string AlertNameCannotBeBlank
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.AlertNameCannotBeBlank);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string CannotCreateNewAlert
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.CannotCreateNewAlert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string CannotAlterAlert
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.CannotAlterAlert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string InvalidScheduleTitle
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.InvalidScheduleTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string InvalidWeeklySchedule
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.InvalidWeeklySchedule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string StartDateGreaterThanEndDate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.StartDateGreaterThanEndDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string StartTimeGreaterThanEndTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.StartTimeGreaterThanEndTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string EndTimeEqualToStartTime
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.EndTimeEqualToStartTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string InvalidStartDate
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.InvalidStartDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static string ConnectionServiceListDbErrorNotConnected(string uri)
|
public static string ConnectionServiceListDbErrorNotConnected(string uri)
|
||||||
{
|
{
|
||||||
return Keys.GetString(Keys.ConnectionServiceListDbErrorNotConnected, uri);
|
return Keys.GetString(Keys.ConnectionServiceListDbErrorNotConnected, uri);
|
||||||
@@ -4594,6 +4666,11 @@ namespace Microsoft.SqlTools.ServiceLayer
|
|||||||
return Keys.GetString(Keys.JobStepNameAlreadyExists, jobName);
|
return Keys.GetString(Keys.JobStepNameAlreadyExists, jobName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string ScheduleNameAlreadyExists(string scheduleName)
|
||||||
|
{
|
||||||
|
return Keys.GetString(Keys.ScheduleNameAlreadyExists, scheduleName);
|
||||||
|
}
|
||||||
|
|
||||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
public class Keys
|
public class Keys
|
||||||
{
|
{
|
||||||
@@ -6369,6 +6446,36 @@ namespace Microsoft.SqlTools.ServiceLayer
|
|||||||
public const string JobStepNameAlreadyExists = "JobStepNameAlreadyExists";
|
public const string JobStepNameAlreadyExists = "JobStepNameAlreadyExists";
|
||||||
|
|
||||||
|
|
||||||
|
public const string AlertNameCannotBeBlank = "AlertNameCannotBeBlank";
|
||||||
|
|
||||||
|
|
||||||
|
public const string CannotCreateNewAlert = "CannotCreateNewAlert";
|
||||||
|
|
||||||
|
|
||||||
|
public const string CannotAlterAlert = "CannotAlterAlert";
|
||||||
|
|
||||||
|
|
||||||
|
public const string InvalidScheduleTitle = "InvalidScheduleTitle";
|
||||||
|
|
||||||
|
|
||||||
|
public const string InvalidWeeklySchedule = "InvalidWeeklySchedule";
|
||||||
|
|
||||||
|
|
||||||
|
public const string StartDateGreaterThanEndDate = "StartDateGreaterThanEndDate";
|
||||||
|
|
||||||
|
|
||||||
|
public const string StartTimeGreaterThanEndTime = "StartTimeGreaterThanEndTime";
|
||||||
|
|
||||||
|
|
||||||
|
public const string EndTimeEqualToStartTime = "EndTimeEqualToStartTime";
|
||||||
|
|
||||||
|
|
||||||
|
public const string InvalidStartDate = "InvalidStartDate";
|
||||||
|
|
||||||
|
|
||||||
|
public const string ScheduleNameAlreadyExists = "ScheduleNameAlreadyExists";
|
||||||
|
|
||||||
|
|
||||||
private Keys()
|
private Keys()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|||||||
@@ -2522,4 +2522,45 @@
|
|||||||
<comment>.
|
<comment>.
|
||||||
Parameters: 0 - jobName (string) </comment>
|
Parameters: 0 - jobName (string) </comment>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="AlertNameCannotBeBlank" xml:space="preserve">
|
||||||
|
<value>The name of the alert cannot be blank.</value>
|
||||||
|
<comment></comment>
|
||||||
|
</data>
|
||||||
|
<data name="CannotCreateNewAlert" xml:space="preserve">
|
||||||
|
<value>Cannot create new alert.</value>
|
||||||
|
<comment></comment>
|
||||||
|
</data>
|
||||||
|
<data name="CannotAlterAlert" xml:space="preserve">
|
||||||
|
<value>Cannot alter alert.</value>
|
||||||
|
<comment></comment>
|
||||||
|
</data>
|
||||||
|
<data name="InvalidScheduleTitle" xml:space="preserve">
|
||||||
|
<value>Invalid Schedule</value>
|
||||||
|
<comment> Schedule error message</comment>
|
||||||
|
</data>
|
||||||
|
<data name="InvalidWeeklySchedule" xml:space="preserve">
|
||||||
|
<value>Select at least one day to be part of this weekly schedule.</value>
|
||||||
|
<comment></comment>
|
||||||
|
</data>
|
||||||
|
<data name="StartDateGreaterThanEndDate" xml:space="preserve">
|
||||||
|
<value>The job schedule starting date cannot be greater than the ending date.</value>
|
||||||
|
<comment></comment>
|
||||||
|
</data>
|
||||||
|
<data name="StartTimeGreaterThanEndTime" xml:space="preserve">
|
||||||
|
<value>The job schedule starting time cannot be after the ending time.</value>
|
||||||
|
<comment></comment>
|
||||||
|
</data>
|
||||||
|
<data name="EndTimeEqualToStartTime" xml:space="preserve">
|
||||||
|
<value>The job schedule ending time must be after the starting time.</value>
|
||||||
|
<comment></comment>
|
||||||
|
</data>
|
||||||
|
<data name="InvalidStartDate" xml:space="preserve">
|
||||||
|
<value>Start date must be on or after January 1, 1990.</value>
|
||||||
|
<comment></comment>
|
||||||
|
</data>
|
||||||
|
<data name="ScheduleNameAlreadyExists" xml:space="preserve">
|
||||||
|
<value>There is already a schedule named '{0}' for this job. You must specify a different name.</value>
|
||||||
|
<comment>.
|
||||||
|
Parameters: 0 - scheduleName (string) </comment>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -888,18 +888,6 @@ InvalidPathError = Cannot access the specified path on the server: {0}
|
|||||||
# Profiler
|
# Profiler
|
||||||
ProfilerConnectionNotFound = Connection not found
|
ProfilerConnectionNotFound = Connection not found
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# SQL Agent
|
# SQL Agent
|
||||||
EnableAlertsTitle(String serverName) = Enable Alerts - {0}
|
EnableAlertsTitle(String serverName) = Enable Alerts - {0}
|
||||||
@@ -1016,8 +1004,6 @@ CannotCreateInitializeHistoryPage = Cannot create/initialize History page.
|
|||||||
; Exception throw when dialog cannot refresh operator
|
; Exception throw when dialog cannot refresh operator
|
||||||
CannotResetOperator = Cannot reset operator.
|
CannotResetOperator = Cannot reset operator.
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
; Name of label on notifications page
|
; Name of label on notifications page
|
||||||
AlertList = Alert list:
|
AlertList = Alert list:
|
||||||
; Name of label on notifications page
|
; Name of label on notifications page
|
||||||
@@ -1043,7 +1029,6 @@ CannotModifyAlerts = Cannot modify alerts.
|
|||||||
; Exception thrown when we cannot create script that modify alerts
|
; Exception thrown when we cannot create script that modify alerts
|
||||||
CannotCreateScriptForModifyAlerts = Cannot create script for modify alerts.
|
CannotCreateScriptForModifyAlerts = Cannot create script for modify alerts.
|
||||||
|
|
||||||
|
|
||||||
;job categories
|
;job categories
|
||||||
CategoryLocal = [Uncategorized (Local)]
|
CategoryLocal = [Uncategorized (Local)]
|
||||||
CategoryFromMsx = Jobs from MSX
|
CategoryFromMsx = Jobs from MSX
|
||||||
@@ -1069,4 +1054,16 @@ CategoryDataCollector = Data Collector
|
|||||||
|
|
||||||
JobAlreadyExists(string jobName) = A job named '{0}' already exists. Enter a unique name for the job.
|
JobAlreadyExists(string jobName) = A job named '{0}' already exists. Enter a unique name for the job.
|
||||||
JobStepNameCannotBeBlank = The name of the job step cannot be blank.
|
JobStepNameCannotBeBlank = The name of the job step cannot be blank.
|
||||||
JobStepNameAlreadyExists(string jobName) = There is already a step named '{0}' for this job. You must specify a different name.
|
JobStepNameAlreadyExists(string jobName) = There is already a step named '{0}' for this job. You must specify a different name.
|
||||||
|
AlertNameCannotBeBlank = The name of the alert cannot be blank.
|
||||||
|
CannotCreateNewAlert = Cannot create new alert.
|
||||||
|
CannotAlterAlert = Cannot alter alert.
|
||||||
|
|
||||||
|
; Schedule error message
|
||||||
|
InvalidScheduleTitle = Invalid Schedule
|
||||||
|
InvalidWeeklySchedule = Select at least one day to be part of this weekly schedule.
|
||||||
|
StartDateGreaterThanEndDate = The job schedule starting date cannot be greater than the ending date.
|
||||||
|
StartTimeGreaterThanEndTime = The job schedule starting time cannot be after the ending time.
|
||||||
|
EndTimeEqualToStartTime = The job schedule ending time must be after the starting time.
|
||||||
|
InvalidStartDate = Start date must be on or after January 1, 1990.
|
||||||
|
ScheduleNameAlreadyExists(string scheduleName)=There is already a schedule named '{0}' for this job. You must specify a different name.
|
||||||
@@ -2995,6 +2995,57 @@
|
|||||||
<note>.
|
<note>.
|
||||||
Parameters: 0 - jobName (string) </note>
|
Parameters: 0 - jobName (string) </note>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="AlertNameCannotBeBlank">
|
||||||
|
<source>The name of the alert cannot be blank.</source>
|
||||||
|
<target state="new">The name of the alert cannot be blank.</target>
|
||||||
|
<note></note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="CannotCreateNewAlert">
|
||||||
|
<source>Cannot create new alert.</source>
|
||||||
|
<target state="new">Cannot create new alert.</target>
|
||||||
|
<note></note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="CannotAlterAlert">
|
||||||
|
<source>Cannot alter alert.</source>
|
||||||
|
<target state="new">Cannot alter alert.</target>
|
||||||
|
<note></note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="InvalidScheduleTitle">
|
||||||
|
<source>Invalid Schedule</source>
|
||||||
|
<target state="new">Invalid Schedule</target>
|
||||||
|
<note> Schedule error message</note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="InvalidWeeklySchedule">
|
||||||
|
<source>Select at least one day to be part of this weekly schedule.</source>
|
||||||
|
<target state="new">Select at least one day to be part of this weekly schedule.</target>
|
||||||
|
<note></note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="StartDateGreaterThanEndDate">
|
||||||
|
<source>The job schedule starting date cannot be greater than the ending date.</source>
|
||||||
|
<target state="new">The job schedule starting date cannot be greater than the ending date.</target>
|
||||||
|
<note></note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="StartTimeGreaterThanEndTime">
|
||||||
|
<source>The job schedule starting time cannot be after the ending time.</source>
|
||||||
|
<target state="new">The job schedule starting time cannot be after the ending time.</target>
|
||||||
|
<note></note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="EndTimeEqualToStartTime">
|
||||||
|
<source>The job schedule ending time must be after the starting time.</source>
|
||||||
|
<target state="new">The job schedule ending time must be after the starting time.</target>
|
||||||
|
<note></note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="InvalidStartDate">
|
||||||
|
<source>Start date must be on or after January 1, 1990.</source>
|
||||||
|
<target state="new">Start date must be on or after January 1, 1990.</target>
|
||||||
|
<note></note>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="ScheduleNameAlreadyExists">
|
||||||
|
<source>There is already a schedule named '{0}' for this job. You must specify a different name.</source>
|
||||||
|
<target state="new">There is already a schedule named '{0}' for this job. You must specify a different name.</target>
|
||||||
|
<note>.
|
||||||
|
Parameters: 0 - scheduleName (string) </note>
|
||||||
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
@@ -261,6 +261,21 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
|||||||
{
|
{
|
||||||
return "[" + s.Replace("]", "]]") + "]";
|
return "[" + s.Replace("]", "]]") + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Some calendars, such as the UmAlQuraCalendar, support an upper date range that is earlier than MaxValue.
|
||||||
|
/// In these cases, trying to access MaxValue in variable assignments or formatting and parsing operations can throw
|
||||||
|
/// an ArgumentOutOfRangeException. Rather than retrieving the value of DateTime.MaxValue, you can retrieve the value
|
||||||
|
/// of the specified culture's latest valid date value from the
|
||||||
|
/// System.Globalization.CultureInfo.DateTimeFormat.Calendar.MaxSupportedDateTime property.
|
||||||
|
/// http://msdn.microsoft.com/en-us/library/system.datetime.maxvalue(v=VS.90).aspx
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static DateTime GetMaxCultureDateTime()
|
||||||
|
{
|
||||||
|
CultureInfo currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
|
||||||
|
return currentCulture.DateTimeFormat.Calendar.MaxSupportedDateTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -3,21 +3,11 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data.SqlClient;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlServer.Management.Smo;
|
|
||||||
using Microsoft.SqlServer.Management.XEvent;
|
|
||||||
using Microsoft.SqlTools.Hosting.Protocol;
|
using Microsoft.SqlTools.Hosting.Protocol;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Agent;
|
using Microsoft.SqlTools.ServiceLayer.Agent;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
|
||||||
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Profiler;
|
|
||||||
using Microsoft.SqlTools.ServiceLayer.Profiler.Contracts;
|
|
||||||
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||||
using Moq;
|
using Moq;
|
||||||
@@ -53,43 +43,44 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Verify the default "create agent alert" request handler with valid parameters
|
/// Verify the default "create agent alert" request handler with valid parameters
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// TODO: Fix flaky test. See https://github.com/Microsoft/sqltoolsservice/issues/630
|
[Fact]
|
||||||
// [Fact]
|
|
||||||
public async Task TestHandleCreateAgentAlertsRequest()
|
public async Task TestHandleCreateAgentAlertsRequest()
|
||||||
{
|
{
|
||||||
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||||
{
|
{
|
||||||
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
|
// setup
|
||||||
|
var createContext = new Mock<RequestContext<CreateAgentAlertResult>>();
|
||||||
|
var deleteContext = new Mock<RequestContext<ResultStatus>>();
|
||||||
|
|
||||||
var requestParams = new CreateAgentAlertParams
|
var service = new AgentService();
|
||||||
|
var alert = new AgentAlertInfo()
|
||||||
{
|
{
|
||||||
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
JobName = "test_update_job",
|
||||||
Alert = new AgentAlertInfo()
|
AlertType = AlertType.SqlServerEvent,
|
||||||
{
|
Severity = 1
|
||||||
JobName = "Test Job Name"
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var requestContext = new Mock<RequestContext<CreateAgentAlertResult>>();
|
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
|
||||||
|
await service.HandleDeleteAgentAlertRequest(new DeleteAgentAlertParams()
|
||||||
|
{
|
||||||
|
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
||||||
|
Alert = alert
|
||||||
|
}, deleteContext.Object);
|
||||||
|
|
||||||
AgentService service = new AgentService();
|
// test
|
||||||
await service.HandleCreateAgentAlertRequest(requestParams, requestContext.Object);
|
await service.HandleCreateAgentAlertRequest(new CreateAgentAlertParams
|
||||||
|
{
|
||||||
|
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
||||||
|
Alert = alert
|
||||||
|
}, createContext.Object);
|
||||||
|
createContext.VerifyAll();
|
||||||
|
|
||||||
// var agentAlerts = await AgentTestUtils.GetAgentAlerts(connectionResult.ConnectionInfo.OwnerUri);
|
// cleanup
|
||||||
// if (agentAlerts != null && agentAlerts.Length > 0)
|
await service.HandleDeleteAgentAlertRequest(new DeleteAgentAlertParams()
|
||||||
// {
|
{
|
||||||
// foreach (var agentAlert in agentAlerts)
|
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
||||||
// {
|
Alert = alert
|
||||||
// if (agentAlert.JobName.Equals(alert.JobName))
|
}, deleteContext.Object);
|
||||||
// {
|
|
||||||
// await service.HandleDeleteAgentAlertRequest(new DeleteAgentAlertParams()
|
|
||||||
// {
|
|
||||||
// OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
|
||||||
// Alert = alert
|
|
||||||
// }, deleteContext.Object);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +92,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent
|
|||||||
{
|
{
|
||||||
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||||
{
|
{
|
||||||
|
// setup
|
||||||
var createContext = new Mock<RequestContext<CreateAgentAlertResult>>();
|
var createContext = new Mock<RequestContext<CreateAgentAlertResult>>();
|
||||||
var updateContext = new Mock<RequestContext<UpdateAgentAlertResult>>();
|
var updateContext = new Mock<RequestContext<UpdateAgentAlertResult>>();
|
||||||
var deleteContext = new Mock<RequestContext<ResultStatus>>();
|
var deleteContext = new Mock<RequestContext<ResultStatus>>();
|
||||||
@@ -126,21 +118,21 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent
|
|||||||
Alert = alert
|
Alert = alert
|
||||||
}, createContext.Object);
|
}, createContext.Object);
|
||||||
|
|
||||||
|
// test
|
||||||
|
alert.Severity = 2;
|
||||||
await service.HandleUpdateAgentAlertRequest(new UpdateAgentAlertParams()
|
await service.HandleUpdateAgentAlertRequest(new UpdateAgentAlertParams()
|
||||||
{
|
{
|
||||||
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
||||||
Alert = alert
|
Alert = alert
|
||||||
}, updateContext.Object);
|
}, updateContext.Object);
|
||||||
|
updateContext.VerifyAll();
|
||||||
|
|
||||||
|
// cleanup
|
||||||
await service.HandleDeleteAgentAlertRequest(new DeleteAgentAlertParams()
|
await service.HandleDeleteAgentAlertRequest(new DeleteAgentAlertParams()
|
||||||
{
|
{
|
||||||
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
||||||
Alert = alert
|
Alert = alert
|
||||||
}, deleteContext.Object);
|
}, deleteContext.Object);
|
||||||
|
|
||||||
createContext.VerifyAll();
|
|
||||||
updateContext.VerifyAll();
|
|
||||||
deleteContext.VerifyAll();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,8 +64,33 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent
|
|||||||
await AgentTestUtils.UpdateAgentJobStep(service, connectionResult, stepInfo);
|
await AgentTestUtils.UpdateAgentJobStep(service, connectionResult, stepInfo);
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
await AgentTestUtils.DeleteAgentJob(service, connectionResult, job, verify: false);
|
await AgentTestUtils.DeleteAgentJob(service, connectionResult, job, verify: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// TestHandleDeleteAgentJobRequest
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public async Task TestHandleDeleteAgentJobStepRequest()
|
||||||
|
{
|
||||||
|
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||||
|
{
|
||||||
|
// setup
|
||||||
|
var service = new AgentService();
|
||||||
|
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
|
||||||
|
var job = AgentTestUtils.GetTestJobInfo();
|
||||||
|
await AgentTestUtils.DeleteAgentJob(service, connectionResult, job, verify: false);
|
||||||
|
await AgentTestUtils.CreateAgentJob(service, connectionResult, job);
|
||||||
|
var stepInfo = AgentTestUtils.GetTestJobStepInfo(connectionResult, job);
|
||||||
|
await AgentTestUtils.CreateAgentJobStep(service, connectionResult, stepInfo);
|
||||||
|
|
||||||
|
// test
|
||||||
|
await AgentTestUtils.DeleteAgentJobStep(service, connectionResult, stepInfo);
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
await AgentTestUtils.DeleteAgentJob(service, connectionResult, job, verify: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,34 +16,69 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent
|
|||||||
{
|
{
|
||||||
public class AgentOperatorTests
|
public class AgentOperatorTests
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Verify the default "create agent alert" request handler with valid parameters
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public async Task TestHandleCreateAgentOperatorRequest()
|
||||||
|
{
|
||||||
|
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||||
|
{
|
||||||
|
// setup
|
||||||
|
var service = new AgentService();
|
||||||
|
var operatorInfo = AgentTestUtils.GetTestOperatorInfo();
|
||||||
|
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
|
||||||
|
await AgentTestUtils.DeleteAgentOperator(service, connectionResult, operatorInfo);
|
||||||
|
|
||||||
|
// test
|
||||||
|
await AgentTestUtils.CreateAgentOperator(service, connectionResult, operatorInfo);
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
await AgentTestUtils.DeleteAgentOperator(service, connectionResult, operatorInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Verify the default "update agent alert" request handler with valid parameters
|
/// TestHandleUpdateAgentOperatorRequest
|
||||||
/// </summary>
|
/// </summary>
|
||||||
//[Fact]
|
[Fact]
|
||||||
public async Task TestHandleUpdateAgentOperatorRequest()
|
public async Task TestHandleUpdateAgentOperatorRequest()
|
||||||
{
|
{
|
||||||
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||||
{
|
{
|
||||||
var createContext = new Mock<RequestContext<CreateAgentOperatorResult>>();
|
// setup
|
||||||
|
|
||||||
var service = new AgentService();
|
var service = new AgentService();
|
||||||
var operatorInfo = new AgentOperatorInfo()
|
var operatorInfo = AgentTestUtils.GetTestOperatorInfo();
|
||||||
{
|
|
||||||
Id = 10,
|
|
||||||
Name = "Joe DBA",
|
|
||||||
EmailAddress = "test@aol.com"
|
|
||||||
};
|
|
||||||
|
|
||||||
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
|
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
|
||||||
|
await AgentTestUtils.DeleteAgentOperator(service, connectionResult, operatorInfo);
|
||||||
|
await AgentTestUtils.CreateAgentOperator(service, connectionResult, operatorInfo);
|
||||||
|
|
||||||
await service.HandleCreateAgentOperatorRequest(new CreateAgentOperatorParams
|
// test
|
||||||
{
|
operatorInfo.EmailAddress = "updated@email.com";
|
||||||
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
await AgentTestUtils.UpdateAgentOperator(service, connectionResult, operatorInfo);
|
||||||
Operator = operatorInfo
|
|
||||||
}, createContext.Object);
|
|
||||||
|
|
||||||
createContext.VerifyAll();
|
// cleanup
|
||||||
|
await AgentTestUtils.DeleteAgentOperator(service, connectionResult, operatorInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// TestHandleDeleteAgentOperatorRequest
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public async Task TestHandleDeleteAgentOperatorRequest()
|
||||||
|
{
|
||||||
|
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||||
|
{
|
||||||
|
// setup
|
||||||
|
var service = new AgentService();
|
||||||
|
var operatorInfo = AgentTestUtils.GetTestOperatorInfo();
|
||||||
|
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
|
||||||
|
await AgentTestUtils.DeleteAgentOperator(service, connectionResult, operatorInfo);
|
||||||
|
await AgentTestUtils.CreateAgentOperator(service, connectionResult, operatorInfo);
|
||||||
|
|
||||||
|
// test
|
||||||
|
await AgentTestUtils.DeleteAgentOperator(service, connectionResult, operatorInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,16 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static AgentOperatorInfo GetTestOperatorInfo()
|
||||||
|
{
|
||||||
|
return new AgentOperatorInfo()
|
||||||
|
{
|
||||||
|
Id = 10,
|
||||||
|
Name = "Joe DBA",
|
||||||
|
EmailAddress = "test@aol.com"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
internal static async Task CreateAgentJob(
|
internal static async Task CreateAgentJob(
|
||||||
AgentService service,
|
AgentService service,
|
||||||
TestConnectionResult connectionResult,
|
TestConnectionResult connectionResult,
|
||||||
@@ -135,6 +145,62 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent
|
|||||||
context.VerifyAll();
|
context.VerifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static async Task DeleteAgentJobStep(
|
||||||
|
AgentService service,
|
||||||
|
TestConnectionResult connectionResult,
|
||||||
|
AgentJobStepInfo stepInfo)
|
||||||
|
{
|
||||||
|
var context = new Mock<RequestContext<ResultStatus>>();
|
||||||
|
await service.HandleDeleteAgentJobStepRequest(new DeleteAgentJobStepParams
|
||||||
|
{
|
||||||
|
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
||||||
|
Step = stepInfo
|
||||||
|
}, context.Object);
|
||||||
|
context.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static async Task CreateAgentOperator(
|
||||||
|
AgentService service,
|
||||||
|
TestConnectionResult connectionResult,
|
||||||
|
AgentOperatorInfo operatorInfo)
|
||||||
|
{
|
||||||
|
var context = new Mock<RequestContext<AgentOperatorResult>>();
|
||||||
|
await service.HandleCreateAgentOperatorRequest(new CreateAgentOperatorParams
|
||||||
|
{
|
||||||
|
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
||||||
|
Operator = operatorInfo
|
||||||
|
}, context.Object);
|
||||||
|
context.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static async Task UpdateAgentOperator(
|
||||||
|
AgentService service,
|
||||||
|
TestConnectionResult connectionResult,
|
||||||
|
AgentOperatorInfo operatorInfo)
|
||||||
|
{
|
||||||
|
var context = new Mock<RequestContext<AgentOperatorResult>>();
|
||||||
|
await service.HandleUpdateAgentOperatorRequest(new UpdateAgentOperatorParams
|
||||||
|
{
|
||||||
|
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
||||||
|
Operator = operatorInfo
|
||||||
|
}, context.Object);
|
||||||
|
context.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static async Task DeleteAgentOperator(
|
||||||
|
AgentService service,
|
||||||
|
TestConnectionResult connectionResult,
|
||||||
|
AgentOperatorInfo operatorInfo)
|
||||||
|
{
|
||||||
|
var context = new Mock<RequestContext<ResultStatus>>();
|
||||||
|
await service.HandleDeleteAgentOperatorRequest(new DeleteAgentOperatorParams
|
||||||
|
{
|
||||||
|
OwnerUri = connectionResult.ConnectionInfo.OwnerUri,
|
||||||
|
Operator = operatorInfo
|
||||||
|
}, context.Object);
|
||||||
|
context.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
internal static async Task<AgentAlertInfo[]> GetAgentAlerts(string connectionUri)
|
internal static async Task<AgentAlertInfo[]> GetAgentAlerts(string connectionUri)
|
||||||
{
|
{
|
||||||
var requestParams = new AgentAlertsParams()
|
var requestParams = new AgentAlertsParams()
|
||||||
|
|||||||
Reference in New Issue
Block a user