From 6f69f7e303dc732fe47ad2e62e9bae54344e8654 Mon Sep 17 00:00:00 2001 From: Aditya Bist Date: Thu, 4 Oct 2018 13:52:08 -0700 Subject: [PATCH] Agent: Edit Job backend (#700) * added stepInfo for editing jobs/steps * added schedules to history requests * added alerts and schedules to history * formatting * code review comments * removed smo import --- .../Agent/AgentService.cs | 19 ++- .../Agent/Common/AgentUtilities.cs | 124 +++++++++++++++--- .../Agent/Contracts/AgentJobHistoryInfo.cs | 28 ++-- .../Agent/Contracts/AgentScheduleInfo.cs | 1 + yarn.lock | 4 + 5 files changed, 147 insertions(+), 29 deletions(-) create mode 100644 yarn.lock diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/AgentService.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/AgentService.cs index 4d2fe264..45920e82 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/AgentService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/AgentService.cs @@ -186,6 +186,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent out connInfo); if (connInfo != null) { + ConnectionServiceInstance.TryFindConnection(parameters.OwnerUri, out connInfo); + CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true); + var jobs = dataContainer.Server.JobServer.Jobs; Tuple tuple = CreateSqlConnection(connInfo, parameters.JobId); SqlConnectionInfo sqlConnInfo = tuple.Item1; DataTable dt = tuple.Item2; @@ -202,7 +205,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent var tlog = t as ILogSource; tlog.Initialize(); var logEntries = t.LogEntries; - jobHistories = AgentUtilities.ConvertToAgentJobHistoryInfo(logEntries, job); + + // Send Steps, Alerts and Schedules with job history in background + JobStepCollection steps = jobs[jobName].JobSteps; + JobScheduleCollection schedules = jobs[jobName].JobSchedules; + List alerts = new List(); + foreach (Alert alert in dataContainer.Server.JobServer.Alerts) + { + if (alert.JobID == jobId && alert.JobName == jobName) + { + alerts.Add(alert); + } + } + jobHistories = AgentUtilities.ConvertToAgentJobHistoryInfo(logEntries, job, steps, schedules, alerts); tlog.CloseReader(); } result.Jobs = jobHistories.ToArray(); @@ -739,6 +754,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent 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; @@ -756,6 +772,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent 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; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Common/AgentUtilities.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Common/AgentUtilities.cs index e1b3ed5f..528942d4 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Common/AgentUtilities.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Common/AgentUtilities.cs @@ -57,24 +57,93 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent }; } - public static AgentJobStep ConvertToAgentJobStep(ILogEntry logEntry, DataRow jobRow) + internal static AgentJobStep ConvertToAgentJobStepInfo(JobStep step, LogSourceJobHistory.LogEntryJobHistory logEntry, string jobId) { - var entry = logEntry as LogSourceJobHistory.LogEntryJobHistory; - string stepId = entry.StepID; - string stepName = entry.StepName; - string message = entry.Message; - DateTime runDate = logEntry.PointInTime; - int runStatus = logEntry.Severity == SeverityClass.Success ? 1 : 0; - AgentJobStep step = new AgentJobStep(); - step.StepId = stepId; - step.StepName = stepName; - step.Message = message; - step.RunDate = runDate; - step.RunStatus = runStatus; - return step; + AgentJobStepInfo stepInfo = new AgentJobStepInfo(); + stepInfo.JobId = jobId; + stepInfo.JobName = logEntry.JobName; + stepInfo.StepName = step.Name; + stepInfo.SubSystem = step.SubSystem.ToString(); + stepInfo.Id = step.ID; + stepInfo.FailureAction = step.OnFailAction.ToString(); + stepInfo.SuccessAction = step.OnSuccessAction.ToString(); + stepInfo.FailStepId = step.OnFailStep; + stepInfo.SuccessStepId = step.OnSuccessStep; + stepInfo.Command = step.Command; + stepInfo.CommandExecutionSuccessCode = step.CommandExecutionSuccessCode; + stepInfo.DatabaseName = step.DatabaseName; + stepInfo.DatabaseUserName = step.DatabaseUserName; + stepInfo.Server = step.Server; + stepInfo.OutputFileName = step.OutputFileName; + stepInfo.RetryAttempts = step.RetryAttempts; + stepInfo.RetryInterval = step.RetryInterval; + stepInfo.ProxyName = step.ProxyName; + AgentJobStep jobStep = new AgentJobStep(); + jobStep.stepId = logEntry.StepID; + jobStep.stepName = logEntry.StepName; + jobStep.stepDetails = stepInfo; + jobStep.message = logEntry.Message; + jobStep.runDate = step.LastRunDate.ToString(); + jobStep.runStatus = (Contracts.CompletionResult) step.LastRunOutcome; + return jobStep; } - public static List ConvertToAgentJobHistoryInfo(List logEntries, DataRow jobRow) + internal static AgentScheduleInfo ConvertToAgentScheduleInfo(JobSchedule schedule) + { + AgentScheduleInfo scheduleInfo = new AgentScheduleInfo(); + scheduleInfo.Id = schedule.ID; + scheduleInfo.Name = schedule.Name; + scheduleInfo.JobName = " "; + scheduleInfo.IsEnabled = schedule.IsEnabled; + scheduleInfo.FrequencyTypes = (Contracts.FrequencyTypes) schedule.FrequencyTypes; + scheduleInfo.FrequencySubDayTypes = (Contracts.FrequencySubDayTypes) schedule.FrequencySubDayTypes; + scheduleInfo.FrequencySubDayInterval = schedule.FrequencySubDayInterval; + scheduleInfo.FrequencyRelativeIntervals = (Contracts.FrequencyRelativeIntervals) schedule.FrequencyRelativeIntervals; + scheduleInfo.FrequencyRecurrenceFactor = schedule.FrequencyRecurrenceFactor; + scheduleInfo.FrequencyInterval = schedule.FrequencyInterval; + scheduleInfo.DateCreated = schedule.DateCreated; + scheduleInfo.ActiveStartTimeOfDay = schedule.ActiveStartTimeOfDay; + scheduleInfo.ActiveStartDate = schedule.ActiveStartDate; + scheduleInfo.ActiveEndTimeOfDay = schedule.ActiveEndTimeOfDay; + scheduleInfo.ActiveEndDate = schedule.ActiveEndDate; + scheduleInfo.JobCount = schedule.JobCount; + scheduleInfo.ScheduleUid = schedule.ScheduleUid; + var scheduleData = new JobScheduleData(schedule); + scheduleInfo.Description = scheduleData.Description; + return scheduleInfo; + } + + internal static AgentAlertInfo ConvertToAgentAlertInfo(Alert alert) + { + AgentAlertInfo alertInfo = new AgentAlertInfo(); + alertInfo.Id = alert.ID; + alertInfo.Name = alert.Name; + alertInfo.DelayBetweenResponses = alert.DelayBetweenResponses; + alertInfo.EventDescriptionKeyword = alert.EventDescriptionKeyword; + alertInfo.EventSource = alert.EventSource; + alertInfo.HasNotification = alert.HasNotification; + alertInfo.IncludeEventDescription = (Contracts.NotifyMethods) alert.IncludeEventDescription; + alertInfo.IsEnabled = alert.IsEnabled; + alertInfo.JobId = alert.JobID.ToString(); + alertInfo.JobName = alert.JobName; + alertInfo.LastOccurrenceDate = alert.LastOccurrenceDate.ToString(); + alertInfo.LastResponseDate = alert.LastResponseDate.ToString(); + alertInfo.MessageId = alert.MessageID; + alertInfo.NotificationMessage = alert.NotificationMessage; + alertInfo.OccurrenceCount = alert.OccurrenceCount; + alertInfo.PerformanceCondition = alert.PerformanceCondition; + alertInfo.Severity = alert.Severity; + alertInfo.DatabaseName = alert.DatabaseName; + alertInfo.CountResetDate = alert.CountResetDate.ToString(); + alertInfo.CategoryName = alert.CategoryName; + alertInfo.AlertType = (Contracts.AlertType) alert.AlertType; + alertInfo.WmiEventNamespace = alert.WmiEventNamespace; + alertInfo.WmiEventQuery = alert.WmiEventQuery; + return alertInfo; + } + + public static List ConvertToAgentJobHistoryInfo(List logEntries, + DataRow jobRow, JobStepCollection steps, JobScheduleCollection schedules, List alerts) { List jobs = new List(); // get all the values for a job history @@ -102,14 +171,29 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent // Add steps to the job if any var jobSteps = new List(); - if (entry.CanLoadSubEntries) + foreach (JobStep step in steps) { - foreach (ILogEntry step in entry.SubEntries) - { - jobSteps.Add(AgentUtilities.ConvertToAgentJobStep(step, jobRow)); - } + var jobId = jobRow[UrnJobId].ToString(); + jobSteps.Add(AgentUtilities.ConvertToAgentJobStepInfo(step, logEntry, jobId)); } + jobHistoryInfo.Steps = jobSteps.ToArray(); + + // Add schedules to the job if any + var jobSchedules = new List(); + foreach (JobSchedule schedule in schedules) + { + jobSchedules.Add(AgentUtilities.ConvertToAgentScheduleInfo(schedule)); + } + jobHistoryInfo.Schedules = jobSchedules.ToArray(); + + // Add alerts to the job if any + var jobAlerts = new List(); + foreach (Alert alert in alerts) + { + jobAlerts.Add(AgentUtilities.ConvertToAgentAlertInfo(alert)); + } + jobHistoryInfo.Alerts = jobAlerts.ToArray(); jobs.Add(jobHistoryInfo); } return jobs; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentJobHistoryInfo.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentJobHistoryInfo.cs index 549ca9a6..b6f39cb1 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentJobHistoryInfo.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentJobHistoryInfo.cs @@ -34,16 +34,28 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts public string RetriesAttempted { get; set; } public string Server { get; set; } public AgentJobStep[] Steps { get; set; } + public AgentScheduleInfo[] Schedules { get; set; } + public AgentAlertInfo[] Alerts { get; set; } } - public class AgentJobStep + public enum CompletionResult { - public string StepId { get; set; } - public string StepName { get; set; } - public string Message { get; set; } - public DateTime RunDate { get; set; } - public int RunStatus { get; set; } - + Failed = 0, + Succeeded = 1, + Retry = 2, + Cancelled = 3, + InProgress = 4, + Unknown = 5 } - + + public class AgentJobStep + { + public string jobId; + public string stepId; + public string stepName; + public string message; + public string runDate; + public CompletionResult runStatus; + public AgentJobStepInfo stepDetails; + } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentScheduleInfo.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentScheduleInfo.cs index 6dabd2fa..c3751f5f 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentScheduleInfo.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentScheduleInfo.cs @@ -64,5 +64,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts public int JobCount { get; set; } public DateTime ActiveEndDate { get; set; } public Guid ScheduleUid { get; set; } + public string Description { get; set; } } } diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..fb57ccd1 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + +