public async Task ReportJobProgress(DateTimeOffset offsetTime, string message, CancellationToken cancellationToken) { var vstsPlanUrl = this.vstsContext.VstsPlanUri; var authToken = this.vstsContext.AuthToken; var planId = this.vstsContext.PlanId; var projectId = this.vstsContext.ProjectId; var hubName = this.vstsContext.VstsHub.ToString(); var timelineId = this.vstsContext.TimelineId; var eventTime = offsetTime.UtcDateTime; var taskHttpClientWrapper = this.CreateTaskHttpClient(vstsPlanUrl, authToken, this.baseInstrumentation, this.vstsContext.SkipRaisePlanEvents); var vstsBrokerInstrumentation = new VstsBrokerInstrumentation(this.baseInstrumentation, taskHttpClientWrapper, hubName, projectId, planId, this.vstsContext.TaskLogId, this.eventProperties); try { await vstsBrokerInstrumentation.HandleInfoEvent("JobRunning", message, this.eventProperties, cancellationToken, eventTime); } catch (TaskOrchestrationPlanNotFoundException) { // ignore deleted builds } // Find all existing timeline records and set them to in progress state var records = await taskHttpClientWrapper.GetRecordsAsync(projectId, hubName, planId, timelineId, userState : null, cancellationToken : cancellationToken).ConfigureAwait(false); var recordsToUpdate = GetTimelineRecordsToUpdate(records); foreach (var record in recordsToUpdate) { record.State = TimelineRecordState.InProgress; } await taskHttpClientWrapper.UpdateTimelineRecordsAsync(projectId, hubName, planId, timelineId, recordsToUpdate, cancellationToken).ConfigureAwait(false); }
public async Task ReportJobStarted(DateTimeOffset offsetTime, string message, CancellationToken cancellationToken) { var vstsPlanUrl = this.vstsContext.VstsPlanUri; var vstsUrl = this.vstsContext.VstsUri; var authToken = this.vstsContext.AuthToken; var planId = this.vstsContext.PlanId; var projectId = this.vstsContext.ProjectId; var jobId = this.vstsContext.JobId; var hubName = this.vstsContext.VstsHub.ToString(); var eventTime = offsetTime.UtcDateTime; var buildHttpClientWrapper = this.CreateBuildClient(vstsUrl, authToken); var releaseHttpClientWrapper = this.CreateReleaseClient(vstsPlanUrl, authToken); var isSessionValid = await IsSessionValid(this.vstsContext, buildHttpClientWrapper, releaseHttpClientWrapper, cancellationToken).ConfigureAwait(false); if (!isSessionValid) { await this.baseInstrumentation.HandleInfoEvent("SessionAlreadyCancelled", "Skipping ReportJobStarted for cancelled or deleted build/release", this.eventProperties, cancellationToken).ConfigureAwait(false); return; } var taskHttpClientWrapper = this.CreateTaskHttpClient(vstsPlanUrl, authToken, this.baseInstrumentation, this.vstsContext.SkipRaisePlanEvents); var vstsBrokerInstrumentation = new VstsBrokerInstrumentation(this.baseInstrumentation, taskHttpClientWrapper, hubName, projectId, planId, this.vstsContext.TaskLogId, this.eventProperties); var startedEvent = new JobStartedEvent(jobId); await taskHttpClientWrapper.RaisePlanEventAsync(projectId, hubName, planId, startedEvent, cancellationToken).ConfigureAwait(false); await vstsBrokerInstrumentation.HandleInfoEvent("JobStarted", message, this.eventProperties, cancellationToken, eventTime); }
public async Task ReportJobCompleted(DateTimeOffset offsetTime, string message, bool isPassed, CancellationToken cancellationToken) { var vstsPlanUrl = this.vstsContext.VstsPlanUri; var vstsUrl = this.vstsContext.VstsUri; var authToken = this.vstsContext.AuthToken; var planId = this.vstsContext.PlanId; var projectId = this.vstsContext.ProjectId; var jobId = this.vstsContext.JobId; var hubName = this.vstsContext.VstsHub.ToString(); var timelineId = this.vstsContext.TimelineId; var eventTime = offsetTime.UtcDateTime; var buildHttpClientWrapper = this.CreateBuildClient(vstsUrl, authToken); var releaseHttpClientWrapper = this.CreateReleaseClient(vstsPlanUrl, authToken); var isSessionValid = await IsSessionValid(this.vstsContext, buildHttpClientWrapper, releaseHttpClientWrapper, cancellationToken).ConfigureAwait(false); if (!isSessionValid) { await this.baseInstrumentation.HandleInfoEvent("SessionAlreadyCancelled", "Skipping ReportJobStarted for cancelled or deleted build", this.eventProperties, cancellationToken).ConfigureAwait(false); return; } var taskHttpClientWrapper = this.CreateTaskHttpClient(vstsPlanUrl, authToken, this.baseInstrumentation, this.vstsContext.SkipRaisePlanEvents); var vstsBrokerInstrumentation = new VstsBrokerInstrumentation(this.baseInstrumentation, taskHttpClientWrapper, hubName, projectId, planId, this.vstsContext.TaskLogId, this.eventProperties); var completedEvent = new JobCompletedEvent(jobId, isPassed ? TaskResult.Succeeded : TaskResult.Failed); await taskHttpClientWrapper.RaisePlanEventAsync(projectId, hubName, planId, completedEvent, cancellationToken).ConfigureAwait(false); if (isPassed) { await vstsBrokerInstrumentation.HandleInfoEvent("JobCompleted", message, this.eventProperties, cancellationToken, eventTime); } else { await vstsBrokerInstrumentation.HandleErrorEvent("JobFailed", message, this.eventProperties, cancellationToken, eventTime); } // Find all existing timeline records and close them await this.CompleteTimelineRecords(projectId, planId, hubName, timelineId, isPassed?TaskResult.Succeeded : TaskResult.Failed, cancellationToken, taskHttpClientWrapper); }
private async Task ProcessMessage(IServiceBusMessage message, IVstsScheduleHandler <T> handler, CancellationToken cancellationToken, T vstsMessage, IDictionary <string, string> eventProperties) { // create client var projectId = vstsMessage.ProjectId; var planId = vstsMessage.PlanId; var vstsPlanUrl = vstsMessage.VstsPlanUri; var vstsUrl = vstsMessage.VstsUri; var authToken = vstsMessage.AuthToken; var parentTimelineId = vstsMessage.TimelineId; var jobId = vstsMessage.JobId; var hubName = vstsMessage.VstsHub.ToString(); var taskHttpClient = this.CreateTaskClient(vstsPlanUrl, authToken, this.baseInstrumentation, vstsMessage.SkipRaisePlanEvents); // create a timeline if required var timelineName = string.Format("{0}_{1}", this.settings.TimeLineNamePrefix, jobId.ToString("D")); var taskLogId = await this.GetOrCreateTaskLogId(message, cancellationToken, taskHttpClient, projectId, planId, jobId, parentTimelineId, timelineName, hubName).ConfigureAwait(false); eventProperties[VstsMessageConstants.TaskLogIdPropertyName] = taskLogId.ToString(); vstsMessage.TaskLogId = taskLogId; // setup VSTS instrumentation and wrap handler var instrumentation = new VstsBrokerInstrumentation(this.baseInstrumentation, taskHttpClient, hubName, projectId, planId, taskLogId, eventProperties); var instrumentedHandler = new HandlerWithInstrumentation <T>(instrumentation, handler); // process request if (vstsMessage.RequestType == RequestType.Cancel) { // attempt to cancel await instrumentedHandler.Cancel(vstsMessage, cancellationToken).ConfigureAwait(false); } else { // already cancelled? var buildHttpClientWrapper = this.CreateBuildClient(vstsUrl, authToken); var releaseHttpClientWrapper = this.CreateReleaseClient(vstsPlanUrl, authToken); var isSessionValid = await VstsReportingHelper.IsSessionValid(vstsMessage, buildHttpClientWrapper, releaseHttpClientWrapper, cancellationToken).ConfigureAwait(false); if (!isSessionValid) { await this.baseInstrumentation.HandleInfoEvent("SessionAlreadyCancelled", string.Format("Skipping Execute for cancelled or deleted {0}", vstsMessage.VstsHub), eventProperties, cancellationToken).ConfigureAwait(false); return; } // raise assigned event (to signal we got the message) var assignedEvent = new JobAssignedEvent(jobId); await taskHttpClient.RaisePlanEventAsync(projectId, hubName, planId, assignedEvent, cancellationToken).ConfigureAwait(false); // attempt to schedule var scheduleResult = await instrumentedHandler.Execute(vstsMessage, cancellationToken).ConfigureAwait(false); var reportingHelper = this.CreateVstsReportingHelper(vstsMessage, instrumentation, new Dictionary <string, string>()); if (scheduleResult.ScheduleFailed) { // must first call job started, otherwise it cannot be completed await reportingHelper.ReportJobStarted(DateTimeOffset.Now, "Started processing job.", CancellationToken.None).ConfigureAwait(false); await reportingHelper.ReportJobCompleted(DateTimeOffset.Now, string.Format("Failed to schedule job. Message: {0}", scheduleResult.Message), false, CancellationToken.None).ConfigureAwait(false); } else if (vstsMessage.CompleteSychronously) { // raise completed event await reportingHelper.ReportJobCompleted(DateTimeOffset.Now, "Completed processing job.", true, CancellationToken.None).ConfigureAwait(false); } } }