mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
1537 lines
63 KiB
C#
1537 lines
63 KiB
C#
//
|
|
// 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 System.Collections.Generic;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using System.Xml;
|
|
using Microsoft.SqlServer.Management.Common;
|
|
using Microsoft.SqlServer.Management.Smo;
|
|
using Microsoft.SqlServer.Management.Smo.Agent;
|
|
using Microsoft.SqlTools.Hosting.Protocol;
|
|
using Microsoft.SqlTools.ServiceLayer.Agent.Contracts;
|
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
|
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
|
using Microsoft.SqlTools.ServiceLayer.Management;
|
|
using Microsoft.SqlTools.ServiceLayer.Utility;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.Agent
|
|
{
|
|
/// <summary>
|
|
/// Main class for Agent Service functionality
|
|
/// </summary>
|
|
public class AgentService
|
|
{
|
|
private ConnectionService connectionService = null;
|
|
private static readonly Lazy<AgentService> instance = new Lazy<AgentService>(() => new AgentService());
|
|
|
|
/// <summary>
|
|
/// Construct a new AgentService instance with default parameters
|
|
/// </summary>
|
|
public AgentService()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the singleton instance object
|
|
/// </summary>
|
|
public static AgentService Instance
|
|
{
|
|
get { return instance.Value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Internal for testing purposes only
|
|
/// </summary>
|
|
internal ConnectionService ConnectionServiceInstance
|
|
{
|
|
get
|
|
{
|
|
if (connectionService == null)
|
|
{
|
|
connectionService = ConnectionService.Instance;
|
|
}
|
|
return connectionService;
|
|
}
|
|
|
|
set
|
|
{
|
|
connectionService = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Service host object for sending/receiving requests/events.
|
|
/// Internal for testing purposes.
|
|
/// </summary>
|
|
internal IProtocolEndpoint ServiceHost
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the service instance
|
|
/// </summary>
|
|
public void InitializeService(ServiceHost serviceHost)
|
|
{
|
|
this.ServiceHost = serviceHost;
|
|
|
|
// Jobs request handlers
|
|
this.ServiceHost.SetRequestHandler(AgentJobsRequest.Type, HandleAgentJobsRequest);
|
|
this.ServiceHost.SetRequestHandler(AgentJobHistoryRequest.Type, HandleJobHistoryRequest);
|
|
this.ServiceHost.SetRequestHandler(AgentJobActionRequest.Type, HandleJobActionRequest);
|
|
|
|
this.ServiceHost.SetRequestHandler(CreateAgentJobRequest.Type, HandleCreateAgentJobRequest);
|
|
this.ServiceHost.SetRequestHandler(UpdateAgentJobRequest.Type, HandleUpdateAgentJobRequest);
|
|
this.ServiceHost.SetRequestHandler(DeleteAgentJobRequest.Type, HandleDeleteAgentJobRequest);
|
|
|
|
this.ServiceHost.SetRequestHandler(AgentJobDefaultsRequest.Type, HandleAgentJobDefaultsRequest);
|
|
|
|
// Job Steps request handlers
|
|
this.ServiceHost.SetRequestHandler(CreateAgentJobStepRequest.Type, HandleCreateAgentJobStepRequest);
|
|
this.ServiceHost.SetRequestHandler(UpdateAgentJobStepRequest.Type, HandleUpdateAgentJobStepRequest);
|
|
this.ServiceHost.SetRequestHandler(DeleteAgentJobStepRequest.Type, HandleDeleteAgentJobStepRequest);
|
|
|
|
// Alerts request handlers
|
|
this.ServiceHost.SetRequestHandler(AgentAlertsRequest.Type, HandleAgentAlertsRequest);
|
|
this.ServiceHost.SetRequestHandler(CreateAgentAlertRequest.Type, HandleCreateAgentAlertRequest);
|
|
this.ServiceHost.SetRequestHandler(UpdateAgentAlertRequest.Type, HandleUpdateAgentAlertRequest);
|
|
this.ServiceHost.SetRequestHandler(DeleteAgentAlertRequest.Type, HandleDeleteAgentAlertRequest);
|
|
|
|
// Operators request handlers
|
|
this.ServiceHost.SetRequestHandler(AgentOperatorsRequest.Type, HandleAgentOperatorsRequest);
|
|
this.ServiceHost.SetRequestHandler(CreateAgentOperatorRequest.Type, HandleCreateAgentOperatorRequest);
|
|
this.ServiceHost.SetRequestHandler(UpdateAgentOperatorRequest.Type, HandleUpdateAgentOperatorRequest);
|
|
this.ServiceHost.SetRequestHandler(DeleteAgentOperatorRequest.Type, HandleDeleteAgentOperatorRequest);
|
|
|
|
// Proxy Accounts request handlers
|
|
this.ServiceHost.SetRequestHandler(AgentProxiesRequest.Type, HandleAgentProxiesRequest);
|
|
this.ServiceHost.SetRequestHandler(CreateAgentProxyRequest.Type, HandleCreateAgentProxyRequest);
|
|
this.ServiceHost.SetRequestHandler(UpdateAgentProxyRequest.Type, HandleUpdateAgentProxyRequest);
|
|
this.ServiceHost.SetRequestHandler(DeleteAgentProxyRequest.Type, HandleDeleteAgentProxyRequest);
|
|
|
|
// Schedule request handlers
|
|
this.ServiceHost.SetRequestHandler(AgentSchedulesRequest.Type, HandleAgentSchedulesRequest);
|
|
this.ServiceHost.SetRequestHandler(CreateAgentScheduleRequest.Type, HandleCreateAgentScheduleRequest);
|
|
this.ServiceHost.SetRequestHandler(UpdateAgentScheduleRequest.Type, HandleUpdateAgentScheduleRequest);
|
|
this.ServiceHost.SetRequestHandler(DeleteAgentScheduleRequest.Type, HandleDeleteAgentScheduleRequest);
|
|
|
|
// Notebook request handlers
|
|
this.ServiceHost.SetRequestHandler(AgentNotebooksRequest.Type, HandleAgentNotebooksRequest);
|
|
this.ServiceHost.SetRequestHandler(AgentNotebookHistoryRequest.Type, HandleAgentNotebookHistoryRequest);
|
|
this.ServiceHost.SetRequestHandler(AgentNotebookMaterializedRequest.Type, HandleAgentNotebookMaterializedRequest);
|
|
this.ServiceHost.SetRequestHandler(AgentNotebookTemplateRequest.Type, HandleAgentNotebookTemplateRequest);
|
|
this.ServiceHost.SetRequestHandler(CreateAgentNotebookRequest.Type, HandleCreateAgentNotebookRequest);
|
|
this.ServiceHost.SetRequestHandler(DeleteAgentNotebookRequest.Type, HandleDeleteAgentNotebooksRequest);
|
|
this.ServiceHost.SetRequestHandler(UpdateAgentNotebookRequest.Type, HandleUpdateAgentNotebookRequest);
|
|
this.ServiceHost.SetRequestHandler(UpdateAgentNotebookRunPinRequest.Type, HandleUpdateAgentNotebookRunPinRequest);
|
|
this.ServiceHost.SetRequestHandler(UpdateAgentNotebookRunNameRequest.Type, HandleUpdateAgentNotebookRunNameRequest);
|
|
this.ServiceHost.SetRequestHandler(DeleteNotebookMaterializedRequest.Type, HandleDeleteNotebookMaterializedRequest);
|
|
|
|
serviceHost.RegisterShutdownTask((_, _) =>
|
|
{
|
|
DeleteAgentNotebooksTempFiles();
|
|
return Task.FromResult(0);
|
|
});
|
|
|
|
}
|
|
|
|
#region "Jobs Handlers"
|
|
|
|
/// <summary>
|
|
/// Handle request to get Agent job activities
|
|
/// </summary>
|
|
internal async Task HandleAgentJobsRequest(AgentJobsParams parameters, RequestContext<AgentJobsResult> requestContext)
|
|
{
|
|
try
|
|
{
|
|
var result = new AgentJobsResult();
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
|
|
if (connInfo != null)
|
|
{
|
|
var serverConnection = ConnectionService.OpenServerConnection(connInfo);
|
|
var fetcher = new JobFetcher(serverConnection);
|
|
var filter = new JobActivityFilter();
|
|
var jobs = fetcher.FetchJobs(filter);
|
|
var agentJobs = new List<AgentJobInfo>();
|
|
if (jobs != null)
|
|
{
|
|
foreach (var job in jobs.Values)
|
|
{
|
|
agentJobs.Add(AgentUtilities.ConvertToAgentJobInfo(job));
|
|
}
|
|
}
|
|
result.Success = true;
|
|
result.Jobs = agentJobs.ToArray();
|
|
serverConnection.SqlConnectionObject.Close();
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
await requestContext.SendError(e);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle request to get Agent Job history
|
|
/// </summary>
|
|
internal async Task HandleJobHistoryRequest(AgentJobHistoryParams parameters, RequestContext<AgentJobHistoryResult> requestContext)
|
|
{
|
|
try
|
|
{
|
|
var result = new AgentJobHistoryResult();
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
if (connInfo != null)
|
|
{
|
|
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
var jobServer = dataContainer.Server.JobServer;
|
|
var jobs = jobServer.Jobs;
|
|
Tuple<SqlConnectionInfo, DataTable, ServerConnection> tuple = CreateSqlConnection(connInfo, parameters.JobId);
|
|
SqlConnectionInfo sqlConnInfo = tuple.Item1;
|
|
DataTable dt = tuple.Item2;
|
|
ServerConnection connection = tuple.Item3;
|
|
|
|
// Send Steps, Alerts and Schedules with job history in background
|
|
// Add steps to the job if any
|
|
JobStepCollection steps = jobs[parameters.JobName].JobSteps;
|
|
var jobSteps = new List<AgentJobStepInfo>();
|
|
foreach (JobStep step in steps)
|
|
{
|
|
jobSteps.Add(AgentUtilities.ConvertToAgentJobStepInfo(step, parameters.JobId, parameters.JobName));
|
|
}
|
|
result.Steps = jobSteps.ToArray();
|
|
|
|
// Add schedules to the job if any
|
|
JobScheduleCollection schedules = jobs[parameters.JobName].JobSchedules;
|
|
var jobSchedules = new List<AgentScheduleInfo>();
|
|
foreach (JobSchedule schedule in schedules)
|
|
{
|
|
jobSchedules.Add(AgentUtilities.ConvertToAgentScheduleInfo(schedule));
|
|
}
|
|
result.Schedules = jobSchedules.ToArray();
|
|
|
|
// Alerts
|
|
AlertCollection alerts = jobServer.Alerts;
|
|
var jobAlerts = new List<Alert>();
|
|
foreach (Alert alert in alerts)
|
|
{
|
|
if (alert.JobName == parameters.JobName)
|
|
{
|
|
jobAlerts.Add(alert);
|
|
}
|
|
}
|
|
result.Alerts = AgentUtilities.ConvertToAgentAlertInfo(jobAlerts);
|
|
|
|
// Add histories
|
|
int count = dt.Rows.Count;
|
|
List<AgentJobHistoryInfo> jobHistories = new List<AgentJobHistoryInfo>();
|
|
if (count > 0)
|
|
{
|
|
var job = dt.Rows[0];
|
|
Guid jobId = (Guid)job[AgentUtilities.UrnJobId];
|
|
int runStatus = Convert.ToInt32(job[AgentUtilities.UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture);
|
|
var t = new LogSourceJobHistory(parameters.JobName, sqlConnInfo, null, runStatus, jobId, null);
|
|
var tlog = t as ILogSource;
|
|
tlog.Initialize();
|
|
var logEntries = t.LogEntries;
|
|
|
|
// Finally add the job histories
|
|
jobHistories = AgentUtilities.ConvertToAgentJobHistoryInfo(logEntries, job, steps);
|
|
result.Histories = jobHistories.ToArray();
|
|
result.Success = true;
|
|
tlog.CloseReader();
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
await requestContext.SendError(e);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle request to Run a Job
|
|
/// </summary>
|
|
internal async Task HandleJobActionRequest(AgentJobActionParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
var result = new ResultStatus();
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
if (connInfo != null)
|
|
{
|
|
var serverConnection = ConnectionService.OpenServerConnection(connInfo);
|
|
var jobHelper = new JobHelper(serverConnection);
|
|
jobHelper.JobName = parameters.JobName;
|
|
switch (parameters.Action)
|
|
{
|
|
case "run":
|
|
jobHelper.Start();
|
|
break;
|
|
case "stop":
|
|
jobHelper.Stop();
|
|
break;
|
|
case "delete":
|
|
jobHelper.Delete();
|
|
break;
|
|
case "enable":
|
|
jobHelper.Enable(true);
|
|
break;
|
|
case "disable":
|
|
jobHelper.Enable(false);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
result.Success = true;
|
|
await requestContext.SendResult(result);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.Message;
|
|
Exception exception = e.InnerException;
|
|
while (exception != null)
|
|
{
|
|
result.ErrorMessage += Environment.NewLine + "\t" + exception.Message;
|
|
exception = exception.InnerException;
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
}
|
|
|
|
internal async Task HandleCreateAgentJobRequest(CreateAgentJobParams parameters, RequestContext<CreateAgentJobResult> requestContext)
|
|
{
|
|
var result = await ConfigureAgentJob(
|
|
parameters.OwnerUri,
|
|
parameters.Job.Name,
|
|
parameters.Job,
|
|
ConfigAction.Create,
|
|
ManagementUtils.asRunType(parameters.TaskExecutionMode));
|
|
|
|
await requestContext.SendResult(new CreateAgentJobResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
internal async Task HandleUpdateAgentJobRequest(UpdateAgentJobParams parameters, RequestContext<UpdateAgentJobResult> requestContext)
|
|
{
|
|
var result = await ConfigureAgentJob(
|
|
parameters.OwnerUri,
|
|
parameters.OriginalJobName,
|
|
parameters.Job,
|
|
ConfigAction.Update,
|
|
ManagementUtils.asRunType(parameters.TaskExecutionMode));
|
|
|
|
await requestContext.SendResult(new UpdateAgentJobResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
internal async Task HandleDeleteAgentJobRequest(DeleteAgentJobParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
var result = await ConfigureAgentJob(
|
|
parameters.OwnerUri,
|
|
parameters.Job.Name,
|
|
parameters.Job,
|
|
ConfigAction.Drop,
|
|
ManagementUtils.asRunType(parameters.TaskExecutionMode));
|
|
|
|
await requestContext.SendResult(new ResultStatus()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
internal async Task HandleCreateAgentJobStepRequest(CreateAgentJobStepParams parameters, RequestContext<CreateAgentJobStepResult> requestContext)
|
|
{
|
|
Tuple<bool, string> result = await ConfigureAgentJobStep(
|
|
parameters.OwnerUri,
|
|
parameters.Step,
|
|
ConfigAction.Create,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new CreateAgentJobStepResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
internal async Task HandleUpdateAgentJobStepRequest(UpdateAgentJobStepParams parameters, RequestContext<UpdateAgentJobStepResult> requestContext)
|
|
{
|
|
Tuple<bool, string> result = await ConfigureAgentJobStep(
|
|
parameters.OwnerUri,
|
|
parameters.Step,
|
|
ConfigAction.Update,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new UpdateAgentJobStepResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
internal async Task HandleDeleteAgentJobStepRequest(DeleteAgentJobStepParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
Tuple<bool, string> result = await ConfigureAgentJobStep(
|
|
parameters.OwnerUri,
|
|
parameters.Step,
|
|
ConfigAction.Drop,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new ResultStatus()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
internal async Task HandleAgentJobDefaultsRequest(AgentJobDefaultsParams parameters, RequestContext<AgentJobDefaultsResult> requestContext)
|
|
{
|
|
var result = new AgentJobDefaultsResult();
|
|
try
|
|
{
|
|
JobData jobData;
|
|
CDataContainer dataContainer;
|
|
CreateJobData(parameters.OwnerUri, "default", out dataContainer, out jobData);
|
|
|
|
// current connection user name for
|
|
result.Owner = dataContainer.ServerConnection.TrueLogin;
|
|
|
|
var categories = jobData.Categories;
|
|
result.Categories = new AgentJobCategory[categories.Length];
|
|
for (int i = 0; i < categories.Length; ++i)
|
|
{
|
|
result.Categories[i] = new AgentJobCategory
|
|
{
|
|
Id = categories[i].SmoCategory.ID,
|
|
Name = categories[i].SmoCategory.Name
|
|
};
|
|
}
|
|
|
|
result.Success = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = ex.ToString();
|
|
}
|
|
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
#endregion // "Jobs Handlers"
|
|
|
|
#region "Alert Handlers"
|
|
|
|
/// <summary>
|
|
/// Handle request to get the alerts list
|
|
/// </summary>
|
|
internal async Task HandleAgentAlertsRequest(AgentAlertsParams parameters, RequestContext<AgentAlertsResult> requestContext)
|
|
{
|
|
var result = new AgentAlertsResult();
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(parameters.OwnerUri, out connInfo);
|
|
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
|
|
int alertsCount = dataContainer.Server.JobServer.Alerts.Count;
|
|
var alerts = new AgentAlertInfo[alertsCount];
|
|
for (int i = 0; i < alertsCount; ++i)
|
|
{
|
|
var alert = dataContainer.Server.JobServer.Alerts[i];
|
|
alerts[i] = new AgentAlertInfo
|
|
{
|
|
Id = alert.ID,
|
|
Name = alert.Name,
|
|
DelayBetweenResponses = alert.DelayBetweenResponses,
|
|
EventDescriptionKeyword = alert.EventDescriptionKeyword,
|
|
EventSource = alert.EventSource,
|
|
HasNotification = alert.HasNotification,
|
|
IncludeEventDescription = (Contracts.NotifyMethods)alert.IncludeEventDescription,
|
|
IsEnabled = alert.IsEnabled,
|
|
JobId = alert.JobID.ToString(),
|
|
JobName = alert.JobName,
|
|
LastOccurrenceDate = alert.LastOccurrenceDate.ToString(),
|
|
LastResponseDate = alert.LastResponseDate.ToString(),
|
|
MessageId = alert.MessageID,
|
|
NotificationMessage = alert.NotificationMessage,
|
|
OccurrenceCount = alert.OccurrenceCount,
|
|
PerformanceCondition = alert.PerformanceCondition,
|
|
Severity = alert.Severity,
|
|
DatabaseName = alert.DatabaseName,
|
|
CountResetDate = alert.CountResetDate.ToString(),
|
|
CategoryName = alert.CategoryName,
|
|
AlertType = (Contracts.AlertType)alert.AlertType,
|
|
WmiEventNamespace = alert.WmiEventNamespace,
|
|
WmiEventQuery = alert.WmiEventQuery
|
|
};
|
|
}
|
|
|
|
result.Alerts = alerts;
|
|
result.Success = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = ex.ToString();
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle request to create an alert
|
|
/// </summary>
|
|
internal async Task HandleCreateAgentAlertRequest(CreateAgentAlertParams parameters, RequestContext<CreateAgentAlertResult> requestContext)
|
|
{
|
|
var result = await ConfigureAgentAlert(
|
|
parameters.OwnerUri,
|
|
parameters.Alert.Name,
|
|
parameters.Alert,
|
|
ConfigAction.Create,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new CreateAgentAlertResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle request to update an alert
|
|
/// </summary>
|
|
internal async Task HandleUpdateAgentAlertRequest(UpdateAgentAlertParams parameters, RequestContext<UpdateAgentAlertResult> requestContext)
|
|
{
|
|
var result = await ConfigureAgentAlert(
|
|
parameters.OwnerUri,
|
|
parameters.OriginalAlertName,
|
|
parameters.Alert,
|
|
ConfigAction.Update,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new UpdateAgentAlertResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle request to delete an alert
|
|
/// </summary>
|
|
internal async Task HandleDeleteAgentAlertRequest(DeleteAgentAlertParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
var result = await ConfigureAgentAlert(
|
|
parameters.OwnerUri,
|
|
parameters.Alert.Name,
|
|
parameters.Alert,
|
|
ConfigAction.Drop,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new ResultStatus()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
#endregion // "Alert Handlers"
|
|
|
|
#region "Operator Handlers"
|
|
|
|
internal async Task HandleAgentOperatorsRequest(AgentOperatorsParams parameters, RequestContext<AgentOperatorsResult> requestContext)
|
|
{
|
|
var result = new AgentOperatorsResult();
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(parameters.OwnerUri, out connInfo);
|
|
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
|
|
int operatorCount = dataContainer.Server.JobServer.Operators.Count;
|
|
var operators = new AgentOperatorInfo[operatorCount];
|
|
for (int i = 0; i < operatorCount; ++i)
|
|
{
|
|
var item = dataContainer.Server.JobServer.Operators[i];
|
|
operators[i] = new AgentOperatorInfo
|
|
{
|
|
Name = item.Name,
|
|
Id = item.ID,
|
|
EmailAddress = item.EmailAddress,
|
|
Enabled = item.Enabled,
|
|
LastEmailDate = item.LastEmailDate.ToString(),
|
|
LastNetSendDate = item.LastNetSendDate.ToString(),
|
|
LastPagerDate = item.LastPagerDate.ToString(),
|
|
PagerAddress = item.PagerAddress,
|
|
CategoryName = item.CategoryName,
|
|
PagerDays = (Contracts.WeekDays)item.PagerDays,
|
|
SaturdayPagerEndTime = item.SaturdayPagerEndTime.ToString(),
|
|
SaturdayPagerStartTime = item.SaturdayPagerEndTime.ToString(),
|
|
SundayPagerEndTime = item.SundayPagerEndTime.ToString(),
|
|
SundayPagerStartTime = item.SundayPagerStartTime.ToString(),
|
|
NetSendAddress = item.NetSendAddress,
|
|
WeekdayPagerStartTime = item.WeekdayPagerStartTime.ToString(),
|
|
WeekdayPagerEndTime = item.WeekdayPagerEndTime.ToString()
|
|
};
|
|
}
|
|
|
|
result.Operators = operators;
|
|
result.Success = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = ex.ToString();
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleCreateAgentOperatorRequest(
|
|
CreateAgentOperatorParams parameters,
|
|
RequestContext<AgentOperatorResult> requestContext)
|
|
{
|
|
var result = await ConfigureAgentOperator(
|
|
parameters.OwnerUri,
|
|
parameters.Operator,
|
|
ConfigAction.Create,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new AgentOperatorResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2,
|
|
Operator = parameters.Operator
|
|
});
|
|
}
|
|
|
|
internal async Task HandleUpdateAgentOperatorRequest(
|
|
UpdateAgentOperatorParams parameters,
|
|
RequestContext<AgentOperatorResult> requestContext)
|
|
{
|
|
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<ResultStatus> requestContext)
|
|
{
|
|
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"
|
|
|
|
|
|
#region "Proxy Handlers"
|
|
|
|
internal async Task HandleAgentProxiesRequest(AgentProxiesParams parameters, RequestContext<AgentProxiesResult> requestContext)
|
|
{
|
|
var result = new AgentProxiesResult();
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(parameters.OwnerUri, out connInfo);
|
|
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
|
|
int proxyCount = dataContainer.Server.JobServer.ProxyAccounts.Count;
|
|
var proxies = new AgentProxyInfo[proxyCount];
|
|
for (int i = 0; i < proxyCount; ++i)
|
|
{
|
|
var proxy = dataContainer.Server.JobServer.ProxyAccounts[i];
|
|
proxies[i] = new AgentProxyInfo
|
|
{
|
|
Id = proxy.ID,
|
|
AccountName = proxy.Name,
|
|
Description = proxy.Description,
|
|
CredentialName = proxy.CredentialName,
|
|
CredentialIdentity = proxy.CredentialIdentity,
|
|
CredentialId = proxy.CredentialID,
|
|
IsEnabled = proxy.IsEnabled
|
|
};
|
|
}
|
|
result.Proxies = proxies;
|
|
result.Success = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = ex.ToString();
|
|
}
|
|
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleCreateAgentProxyRequest(CreateAgentProxyParams parameters, RequestContext<AgentProxyResult> requestContext)
|
|
{
|
|
var result = await ConfigureAgentProxy(
|
|
parameters.OwnerUri,
|
|
parameters.Proxy.AccountName,
|
|
parameters.Proxy,
|
|
ConfigAction.Create,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new AgentProxyResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2,
|
|
Proxy = parameters.Proxy
|
|
});
|
|
}
|
|
|
|
internal async Task HandleUpdateAgentProxyRequest(UpdateAgentProxyParams parameters, RequestContext<AgentProxyResult> requestContext)
|
|
{
|
|
var result = await ConfigureAgentProxy(
|
|
parameters.OwnerUri,
|
|
parameters.Proxy.AccountName,
|
|
parameters.Proxy,
|
|
ConfigAction.Update,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new AgentProxyResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2,
|
|
Proxy = parameters.Proxy
|
|
});
|
|
}
|
|
|
|
internal async Task HandleDeleteAgentProxyRequest(DeleteAgentProxyParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
var result = await ConfigureAgentProxy(
|
|
parameters.OwnerUri,
|
|
parameters.Proxy.AccountName,
|
|
parameters.Proxy,
|
|
ConfigAction.Drop,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new ResultStatus()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
#endregion // "Proxy Handlers"
|
|
|
|
#region "Schedule Handlers"
|
|
|
|
internal async Task HandleAgentSchedulesRequest(AgentSchedulesParams parameters, RequestContext<AgentSchedulesResult> requestContext)
|
|
{
|
|
var result = new AgentSchedulesResult();
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(parameters.OwnerUri, out connInfo);
|
|
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
|
|
int scheduleCount = dataContainer.Server.JobServer.SharedSchedules.Count;
|
|
var schedules = new AgentScheduleInfo[scheduleCount];
|
|
for (int i = 0; i < scheduleCount; ++i)
|
|
{
|
|
var schedule = dataContainer.Server.JobServer.SharedSchedules[i];
|
|
var scheduleData = new JobScheduleData(schedule);
|
|
schedules[i] = new AgentScheduleInfo();
|
|
schedules[i].Id = schedule.ID;
|
|
schedules[i].Name = schedule.Name;
|
|
schedules[i].IsEnabled = schedule.IsEnabled;
|
|
schedules[i].FrequencyTypes = (Contracts.FrequencyTypes)schedule.FrequencyTypes;
|
|
schedules[i].FrequencySubDayTypes = (Contracts.FrequencySubDayTypes)schedule.FrequencySubDayTypes;
|
|
schedules[i].FrequencySubDayInterval = schedule.FrequencySubDayInterval;
|
|
schedules[i].FrequencyRelativeIntervals = (Contracts.FrequencyRelativeIntervals)schedule.FrequencyRelativeIntervals;
|
|
schedules[i].FrequencyRecurrenceFactor = schedule.FrequencyRecurrenceFactor;
|
|
schedules[i].FrequencyInterval = schedule.FrequencyInterval;
|
|
schedules[i].DateCreated = schedule.DateCreated;
|
|
schedules[i].ActiveStartTimeOfDay = schedule.ActiveStartTimeOfDay;
|
|
schedules[i].ActiveStartDate = schedule.ActiveStartDate;
|
|
schedules[i].ActiveEndTimeOfDay = schedule.ActiveEndTimeOfDay;
|
|
schedules[i].JobCount = schedule.JobCount;
|
|
schedules[i].ActiveEndDate = schedule.ActiveEndDate;
|
|
schedules[i].ScheduleUid = schedule.ScheduleUid;
|
|
schedules[i].Description = scheduleData.Description;
|
|
}
|
|
result.Schedules = schedules;
|
|
result.Success = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = ex.ToString();
|
|
}
|
|
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleCreateAgentScheduleRequest(CreateAgentScheduleParams parameters, RequestContext<AgentScheduleResult> requestContext)
|
|
{
|
|
var result = await ConfigureAgentSchedule(
|
|
parameters.OwnerUri,
|
|
parameters.Schedule,
|
|
ConfigAction.Create,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new AgentScheduleResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2,
|
|
Schedule = parameters.Schedule
|
|
});
|
|
}
|
|
|
|
internal async Task HandleUpdateAgentScheduleRequest(UpdateAgentScheduleParams parameters, RequestContext<AgentScheduleResult> requestContext)
|
|
{
|
|
var result = await ConfigureAgentSchedule(
|
|
parameters.OwnerUri,
|
|
parameters.Schedule,
|
|
ConfigAction.Update,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new AgentScheduleResult()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2,
|
|
Schedule = parameters.Schedule
|
|
});
|
|
}
|
|
|
|
internal async Task HandleDeleteAgentScheduleRequest(DeleteAgentScheduleParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
var result = await ConfigureAgentSchedule(
|
|
parameters.OwnerUri,
|
|
parameters.Schedule,
|
|
ConfigAction.Drop,
|
|
RunType.RunNow);
|
|
|
|
await requestContext.SendResult(new ResultStatus()
|
|
{
|
|
Success = result.Item1,
|
|
ErrorMessage = result.Item2
|
|
});
|
|
}
|
|
|
|
#endregion // "Schedule Handlers"
|
|
|
|
#region "Helpers"
|
|
|
|
internal void ExecuteAction(ManagementActionBase action, RunType runType)
|
|
{
|
|
var executionHandler = new ExecutonHandler(action);
|
|
executionHandler.RunNow(runType, this);
|
|
if (executionHandler.ExecutionResult == ExecutionMode.Failure)
|
|
{
|
|
if (executionHandler.ExecutionFailureException != null)
|
|
{
|
|
throw executionHandler.ExecutionFailureException;
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Failed to execute action");
|
|
}
|
|
}
|
|
}
|
|
|
|
internal async Task<Tuple<bool, string>> ConfigureAgentJob(
|
|
string ownerUri,
|
|
string originalJobName,
|
|
AgentJobInfo jobInfo,
|
|
ConfigAction configAction,
|
|
RunType runType)
|
|
{
|
|
try
|
|
{
|
|
JobData jobData;
|
|
CDataContainer dataContainer;
|
|
CreateJobData(ownerUri, originalJobName, out dataContainer, out jobData, configAction, jobInfo);
|
|
|
|
using (JobActions actions = new JobActions(dataContainer, jobData, configAction))
|
|
{
|
|
ExecuteAction(actions, runType);
|
|
}
|
|
|
|
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo);
|
|
if (connInfo != null)
|
|
{
|
|
dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
}
|
|
|
|
// Execute step actions if they exist
|
|
if (configAction != ConfigAction.Drop && jobInfo.JobSteps != null && jobInfo.JobSteps.Length > 0)
|
|
{
|
|
foreach (AgentJobStepInfo step in jobInfo.JobSteps)
|
|
{
|
|
configAction = ConfigAction.Create;
|
|
foreach (JobStep jobStep in dataContainer.Server.JobServer.Jobs[originalJobName].JobSteps)
|
|
{
|
|
// any changes made to step other than name or ordering
|
|
if ((step.StepName == jobStep.Name && step.Id == jobStep.ID) ||
|
|
// if the step name was changed
|
|
(step.StepName != jobStep.Name && step.Id == jobStep.ID) ||
|
|
// if the step ordering was changed
|
|
(step.StepName == jobStep.Name && step.Id != jobStep.ID))
|
|
{
|
|
configAction = ConfigAction.Update;
|
|
break;
|
|
}
|
|
}
|
|
await ConfigureAgentJobStep(ownerUri, step, configAction, runType, jobData, dataContainer);
|
|
}
|
|
}
|
|
|
|
// Execute schedule actions if they exist
|
|
if (jobInfo.JobSchedules != null && jobInfo.JobSchedules.Length > 0)
|
|
{
|
|
foreach (AgentScheduleInfo schedule in jobInfo.JobSchedules)
|
|
{
|
|
await ConfigureAgentSchedule(ownerUri, schedule, configAction, runType, jobData, dataContainer);
|
|
}
|
|
}
|
|
|
|
// Execute alert actions if they exist
|
|
if (jobInfo.Alerts != null && jobInfo.Alerts.Length > 0)
|
|
{
|
|
foreach (AgentAlertInfo alert in jobInfo.Alerts)
|
|
{
|
|
alert.JobId = jobData.Job.JobID.ToString();
|
|
await ConfigureAgentAlert(ownerUri, alert.Name, alert, configAction, runType, jobData, dataContainer);
|
|
}
|
|
}
|
|
|
|
return new Tuple<bool, string>(true, string.Empty);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return new Tuple<bool, string>(false, ex.ToString());
|
|
}
|
|
}
|
|
|
|
internal Task<Tuple<bool, string>> ConfigureAgentJobStep(
|
|
string ownerUri,
|
|
AgentJobStepInfo stepInfo,
|
|
ConfigAction configAction,
|
|
RunType runType,
|
|
JobData jobData = null,
|
|
CDataContainer dataContainer = null)
|
|
{
|
|
return Task.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrWhiteSpace(stepInfo.JobName))
|
|
{
|
|
return new Tuple<bool, string>(false, "JobName cannot be null");
|
|
}
|
|
|
|
if (jobData == null)
|
|
{
|
|
CreateJobData(ownerUri, stepInfo.JobName, out dataContainer, out jobData);
|
|
}
|
|
|
|
using (var actions = new JobStepsActions(dataContainer, jobData, stepInfo, configAction))
|
|
{
|
|
ExecuteAction(actions, runType);
|
|
}
|
|
|
|
return new Tuple<bool, string>(true, string.Empty);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// log exception here
|
|
return new Tuple<bool, string>(false, ex.ToString());
|
|
}
|
|
});
|
|
}
|
|
|
|
internal Task<Tuple<bool, string>> ConfigureAgentAlert(
|
|
string ownerUri,
|
|
string alertName,
|
|
AgentAlertInfo alert,
|
|
ConfigAction configAction,
|
|
RunType runType,
|
|
JobData jobData = null,
|
|
CDataContainer dataContainer = null)
|
|
{
|
|
return Task<Tuple<bool, string>>.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
// If the alert is being created outside of a job
|
|
if (string.IsNullOrWhiteSpace(alert.JobName))
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo);
|
|
dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
}
|
|
else
|
|
{
|
|
if (jobData == null)
|
|
{
|
|
// If the alert is being created inside a job
|
|
CreateJobData(ownerUri, alert.JobName, out dataContainer, out jobData);
|
|
}
|
|
}
|
|
STParameters param = new STParameters(dataContainer.Document);
|
|
param.SetParam("alert", alertName);
|
|
if (alert != null)
|
|
{
|
|
using (AgentAlertActions actions = new AgentAlertActions(dataContainer, alertName, alert, configAction, jobData))
|
|
{
|
|
ExecuteAction(actions, runType);
|
|
}
|
|
}
|
|
|
|
return new Tuple<bool, string>(true, string.Empty);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return new Tuple<bool, string>(false, ex.ToString());
|
|
}
|
|
});
|
|
}
|
|
|
|
internal Task<Tuple<bool, string>> ConfigureAgentOperator(
|
|
string ownerUri,
|
|
AgentOperatorInfo operatorInfo,
|
|
ConfigAction configAction,
|
|
RunType runType)
|
|
{
|
|
return Task.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 actions = new AgentOperatorActions(dataContainer, operatorInfo, configAction))
|
|
{
|
|
ExecuteAction(actions, runType);
|
|
}
|
|
|
|
return new Tuple<bool, string>(true, string.Empty);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return new Tuple<bool, string>(false, ex.ToString());
|
|
}
|
|
});
|
|
}
|
|
|
|
internal Task<Tuple<bool, string>> ConfigureAgentProxy(
|
|
string ownerUri,
|
|
string accountName,
|
|
AgentProxyInfo proxy,
|
|
ConfigAction configAction,
|
|
RunType runType)
|
|
{
|
|
return Task.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo);
|
|
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
STParameters param = new STParameters(dataContainer.Document);
|
|
param.SetParam("proxyaccount", accountName);
|
|
|
|
using (AgentProxyAccountActions actions = new AgentProxyAccountActions(dataContainer, proxy, configAction))
|
|
{
|
|
ExecuteAction(actions, runType);
|
|
}
|
|
|
|
return new Tuple<bool, string>(true, string.Empty);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return new Tuple<bool, string>(false, ex.ToString());
|
|
}
|
|
});
|
|
}
|
|
|
|
internal Task<Tuple<bool, string>> ConfigureAgentSchedule(
|
|
string ownerUri,
|
|
AgentScheduleInfo schedule,
|
|
ConfigAction configAction,
|
|
RunType runType,
|
|
JobData jobData = null,
|
|
CDataContainer dataContainer = null)
|
|
{
|
|
return Task.Run(() =>
|
|
{
|
|
try
|
|
{
|
|
if (jobData == null)
|
|
{
|
|
CreateJobData(ownerUri, schedule.JobName, out dataContainer, out jobData);
|
|
}
|
|
|
|
const string UrnFormatStr = "Server/JobServer[@Name='{0}']/Job[@Name='{1}']/Schedule[@Name='{2}']";
|
|
string serverName = dataContainer.Server.Name.ToUpper();
|
|
string scheduleUrn = string.Format(UrnFormatStr, serverName, jobData.Job.Name, schedule.Name);
|
|
|
|
STParameters param = new STParameters(dataContainer.Document);
|
|
param.SetParam("urn", scheduleUrn);
|
|
|
|
using (JobSchedulesActions actions = new JobSchedulesActions(dataContainer, jobData, schedule, configAction))
|
|
{
|
|
ExecuteAction(actions, runType);
|
|
}
|
|
|
|
return new Tuple<bool, string>(true, string.Empty);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return new Tuple<bool, string>(false, ex.ToString());
|
|
}
|
|
});
|
|
}
|
|
|
|
private void CreateJobData(
|
|
string ownerUri,
|
|
string jobName,
|
|
out CDataContainer dataContainer,
|
|
out JobData jobData,
|
|
ConfigAction configAction = ConfigAction.Create,
|
|
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);
|
|
string originalName = jobInfo != null && !string.Equals(jobName, jobInfo.Name) ? jobName : string.Empty;
|
|
param.SetParam("job", configAction == ConfigAction.Update ? jobName : string.Empty);
|
|
param.SetParam("jobid", string.Empty);
|
|
|
|
jobData = new JobData(dataContainer, jobInfo, configAction);
|
|
}
|
|
|
|
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/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 serverConnection = ConnectionService.OpenServerConnection(connInfo);
|
|
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 HandleAgentNotebooksRequest(AgentNotebooksParams parameters, RequestContext<AgentNotebooksResult> requestContext)
|
|
{
|
|
var result = new AgentNotebooksResult();
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
result.Success = true;
|
|
result.Notebooks = AgentNotebookHelper.GetAgentNotebooks(connInfo).Result;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleAgentNotebookHistoryRequest(
|
|
AgentNotebookHistoryParams parameters, RequestContext<AgentNotebookHistoryResult> requestContext)
|
|
{
|
|
var result = new AgentNotebookHistoryResult();
|
|
try
|
|
{
|
|
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
|
|
result = await GetAgentNotebookHistories(
|
|
connInfo,
|
|
parameters.JobId,
|
|
parameters.JobName,
|
|
parameters.TargetDatabase
|
|
);
|
|
|
|
result.Success = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleAgentNotebookMaterializedRequest(AgentNotebookMaterializedParams parameters, RequestContext<AgentNotebookMaterializedResult> requestContext)
|
|
{
|
|
var result = new AgentNotebookMaterializedResult();
|
|
try
|
|
{
|
|
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
result.NotebookMaterialized = AgentNotebookHelper.GetMaterializedNotebook(connInfo, parameters.NotebookMaterializedId, parameters.TargetDatabase).Result;
|
|
result.Success = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleAgentNotebookTemplateRequest(AgentNotebookTemplateParams parameters, RequestContext<AgentNotebookTemplateResult> requestContext)
|
|
{
|
|
var result = new AgentNotebookTemplateResult();
|
|
try
|
|
{
|
|
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
result.NotebookTemplate = await AgentNotebookHelper.GetTemplateNotebook(connInfo, parameters.JobId, parameters.TargetDatabase);
|
|
result.Success = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleCreateAgentNotebookRequest(CreateAgentNotebookParams parameters, RequestContext<CreateAgentNotebookResult> requestContext)
|
|
{
|
|
var result = new CreateAgentNotebookResult();
|
|
try
|
|
{
|
|
// storing result
|
|
result.Success = true;
|
|
await AgentNotebookHelper.CreateNotebook(
|
|
this,
|
|
parameters.OwnerUri,
|
|
parameters.Notebook,
|
|
parameters.TemplateFilePath,
|
|
ManagementUtils.asRunType(parameters.TaskExecutionMode)
|
|
);
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleDeleteAgentNotebooksRequest(DeleteAgentNotebookParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
var result = new ResultStatus();
|
|
try
|
|
{
|
|
// Calling delete notebook helper function
|
|
await AgentNotebookHelper.DeleteNotebook(
|
|
this,
|
|
parameters.OwnerUri,
|
|
parameters.Notebook,
|
|
ManagementUtils.asRunType(parameters.TaskExecutionMode)
|
|
);
|
|
result.Success = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleUpdateAgentNotebookRequest(UpdateAgentNotebookParams parameters, RequestContext<UpdateAgentNotebookResult> requestContext)
|
|
{
|
|
var result = new UpdateAgentNotebookResult();
|
|
try
|
|
{
|
|
// Calling update helper function
|
|
await AgentNotebookHelper.UpdateNotebook(
|
|
this,
|
|
parameters.OwnerUri,
|
|
parameters.OriginalNotebookName,
|
|
parameters.Notebook,
|
|
parameters.TemplateFilePath,
|
|
ManagementUtils.asRunType(parameters.TaskExecutionMode));
|
|
result.Success = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleUpdateAgentNotebookRunNameRequest(UpdateAgentNotebookRunNameParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
var result = new ResultStatus();
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
// Calling update helper function
|
|
await AgentNotebookHelper.UpdateMaterializedNotebookName(
|
|
connInfo,
|
|
parameters.agentNotebookHistory,
|
|
parameters.TargetDatabase,
|
|
parameters.MaterializedNotebookName);
|
|
result.Success = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleUpdateAgentNotebookRunPinRequest(UpdateAgentNotebookRunPinParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
var result = new ResultStatus();
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
// Calling update helper function
|
|
await AgentNotebookHelper.UpdateMaterializedNotebookPin(
|
|
connInfo,
|
|
parameters.agentNotebookHistory,
|
|
parameters.TargetDatabase,
|
|
parameters.MaterializedNotebookPin);
|
|
result.Success = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
internal async Task HandleDeleteNotebookMaterializedRequest(DeleteMaterializedNotebookParams parameters, RequestContext<ResultStatus> requestContext)
|
|
{
|
|
var result = new ResultStatus();
|
|
try
|
|
{
|
|
ConnectionInfo connInfo;
|
|
ConnectionServiceInstance.TryFindConnection(
|
|
parameters.OwnerUri,
|
|
out connInfo);
|
|
// Calling update helper function
|
|
await AgentNotebookHelper.DeleteMaterializedNotebook(
|
|
connInfo,
|
|
parameters.agentNotebookHistory,
|
|
parameters.TargetDatabase);
|
|
result.Success = true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = e.ToString();
|
|
|
|
}
|
|
await requestContext.SendResult(result);
|
|
}
|
|
|
|
public async Task<AgentNotebookHistoryResult> GetAgentNotebookHistories
|
|
(
|
|
ConnectionInfo connInfo,
|
|
string jobId,
|
|
string jobName,
|
|
string targetDatabase
|
|
)
|
|
{
|
|
AgentNotebookHistoryResult result = new AgentNotebookHistoryResult();
|
|
// fetching Job information
|
|
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true);
|
|
var jobServer = dataContainer.Server.JobServer;
|
|
var jobs = jobServer.Jobs;
|
|
Tuple<SqlConnectionInfo, DataTable, ServerConnection> tuple = CreateSqlConnection(connInfo, jobId);
|
|
SqlConnectionInfo sqlConnInfo = tuple.Item1;
|
|
DataTable dt = tuple.Item2;
|
|
|
|
// add steps to the job if any
|
|
JobStepCollection steps = jobs[jobName].JobSteps;
|
|
var jobSteps = new List<AgentJobStepInfo>();
|
|
foreach (JobStep step in steps)
|
|
{
|
|
jobSteps.Add(AgentUtilities.ConvertToAgentJobStepInfo(step, jobId, jobName));
|
|
}
|
|
result.Steps = jobSteps.ToArray();
|
|
|
|
// add schedules to the job if any
|
|
JobScheduleCollection schedules = jobs[jobName].JobSchedules;
|
|
var jobSchedules = new List<AgentScheduleInfo>();
|
|
foreach (JobSchedule schedule in schedules)
|
|
{
|
|
jobSchedules.Add(AgentUtilities.ConvertToAgentScheduleInfo(schedule));
|
|
}
|
|
result.Schedules = jobSchedules.ToArray();
|
|
|
|
// add histories
|
|
int count = dt.Rows.Count;
|
|
List<AgentNotebookHistoryInfo> notebookHistories = new List<AgentNotebookHistoryInfo>();
|
|
if (count > 0)
|
|
{
|
|
var job = dt.Rows[0];
|
|
Guid tempjobId = (Guid)job[AgentUtilities.UrnJobId];
|
|
int runStatus = Convert.ToInt32(job[AgentUtilities.UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture);
|
|
var t = new LogSourceJobHistory(jobName, sqlConnInfo, null, runStatus, tempjobId, null);
|
|
var tlog = t as ILogSource;
|
|
tlog.Initialize();
|
|
var logEntries = t.LogEntries;
|
|
var jobHistories = AgentUtilities.ConvertToAgentNotebookHistoryInfo(logEntries, job, steps);
|
|
// fetching notebook part of histories
|
|
Dictionary<string, DataRow> notebookHistoriesDict = new Dictionary<string, DataRow>();
|
|
DataTable materializedNotebookTable = await AgentNotebookHelper.GetAgentNotebookHistories(connInfo, jobId, targetDatabase);
|
|
foreach (DataRow materializedNotebookRow in materializedNotebookTable.Rows)
|
|
{
|
|
notebookHistoriesDict.Add(materializedNotebookRow["job_runtime"].ToString(), materializedNotebookRow);
|
|
}
|
|
|
|
// adding notebook information to job histories
|
|
foreach (var jobHistory in jobHistories)
|
|
{
|
|
string jobRuntime = jobHistory.RunDate.ToString("yyyyMMddHHmmss");
|
|
AgentNotebookHistoryInfo notebookHistory = jobHistory;
|
|
if (notebookHistoriesDict.ContainsKey(jobRuntime))
|
|
{
|
|
notebookHistory.MaterializedNotebookId = (int)notebookHistoriesDict[jobRuntime]["materialized_id"];
|
|
notebookHistory.MaterializedNotebookErrorInfo = notebookHistoriesDict[jobRuntime]["notebook_error"] as string;
|
|
notebookHistory.MaterializedNotebookName = notebookHistoriesDict[jobRuntime]["notebook_name"] as string;
|
|
notebookHistory.MaterializedNotebookPin = (bool)notebookHistoriesDict[jobRuntime]["pin"];
|
|
notebookHistory.MaterializedNotebookDeleted = (bool)notebookHistoriesDict[jobRuntime]["is_deleted"];
|
|
}
|
|
if (notebookHistory.MaterializedNotebookDeleted)
|
|
{
|
|
continue;
|
|
}
|
|
notebookHistories.Add(notebookHistory);
|
|
|
|
}
|
|
result.Histories = notebookHistories.ToArray();
|
|
tlog.CloseReader();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#endregion // "Helpers"
|
|
|
|
internal void DeleteAgentNotebooksTempFiles()
|
|
{
|
|
if (FileUtilities.SafeDirectoryExists(FileUtilities.AgentNotebookTempFolder))
|
|
{
|
|
FileUtilities.SafeDirectoryDelete(FileUtilities.AgentNotebookTempFolder, true);
|
|
}
|
|
}
|
|
}
|
|
}
|