コード例 #1
0
        private async void EndPage()
        {
            if (_pageWriter != null)
            {
                _pageWriter.Flush();
                _pageData.Flush();
                //The StreamWriter object calls Dispose() on the provided Stream object when StreamWriter.Dispose is called.
                _pageWriter.Dispose();
                _pageWriter = null;
                _pageData   = null;
                var taskLog = await planHelper.CreateTaskLog(new TaskLog(string.Format(@"logs\{0:D}", jobId)), default(CancellationToken)).ConfigureAwait(false);

                // Upload the contents
                using (FileStream fs = File.Open(_dataFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    await planHelper.AppendLogContentAsync(taskLog.Id, fs, default(CancellationToken)).ConfigureAwait(false);
                }

                // Create a new record and only set the Log field
                var attachmentUpdataRecord = new TimelineRecord {
                    Id = jobId, Log = taskLog
                };
                await planHelper.UpdateTimelineRecordsAsync(timelineId, attachmentUpdataRecord, default(CancellationToken)).ConfigureAwait(false);
            }
        }
コード例 #2
0
        public void AddFailure(TimelineRecord record, string classification)
        {
            var scope   = GetScope(record);
            var failure = new Failure(scope, classification);

            failures.Add(failure);
        }
コード例 #3
0
        public TimelineBuilder AddRecord(string previousAttemptTimelineId)
        {
            int nextId = 1;

            if (records.Any())
            {
                nextId += records.Max(r => int.Parse(r.Id));
            }

            TimelineRecord record = new TimelineRecord()
            {
                Id     = nextId.ToString(),
                Issues = Array.Empty <TimelineIssue>()
            };

            if (string.IsNullOrEmpty(previousAttemptTimelineId))
            {
                record.PreviousAttempts = Array.Empty <TimelineAttempt>();
            }
            else
            {
                record.PreviousAttempts = new[] {
                    new TimelineAttempt()
                    {
                        TimelineId = previousAttemptTimelineId
                    }
                };
            }

            records.Add(record);

            return(this);
        }
コード例 #4
0
        private async Task CreateTaskTimelineRecordIfRequired(CancellationToken cancellationToken)
        {
            if (taskMessage.TaskInstanceId.Equals(Guid.Empty))
            {
                var timelineRecordId = Guid.NewGuid();
                var timelineRecord   = new TimelineRecord
                {
                    Id         = timelineRecordId,
                    RecordType = "task",
                    Name       = taskMessage.TaskInstanceName,
                    Order      = 1,
                    StartTime  = DateTime.UtcNow,
                    State      = TimelineRecordState.Pending,
                    ParentId   = taskMessage.JobId,
                };
                var taskClient = GetTaskClient(taskMessage.PlanUri, taskMessage.AuthToken);
                await taskClient.UpdateTimelineRecordsAsync(
                    taskMessage.ProjectId,
                    taskMessage.HubName,
                    taskMessage.PlanId,
                    taskMessage.TimelineId,
                    new List <TimelineRecord> {
                    timelineRecord
                },
                    cancellationToken);

                this.taskMessage.TaskInstanceId = timelineRecordId;
            }
        }
コード例 #5
0
        // log an error issue to job level timeline record
        private async Task LogWorkerProcessUnhandledException(Pipelines.AgentJobRequestMessage message, string errorMessage)
        {
            try
            {
                var systemConnection = message.Resources.Endpoints.SingleOrDefault(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection));
                ArgUtil.NotNull(systemConnection, nameof(systemConnection));

                var            jobServer           = HostContext.GetService <IJobServer>();
                VssCredentials jobServerCredential = VssUtil.GetVssCredential(systemConnection);
                VssConnection  jobConnection       = VssUtil.CreateConnection(systemConnection.Url, jobServerCredential);

                /* Below is the legacy 'OnPremises' code that is currently unused by the runner
                 * ToDo: re-implement code as appropriate once GHES support is added.
                 * // Make sure SystemConnection Url match Config Url base for OnPremises server
                 * if (!message.Variables.ContainsKey(Constants.Variables.System.ServerType) ||
                 *  string.Equals(message.Variables[Constants.Variables.System.ServerType]?.Value, "OnPremises", StringComparison.OrdinalIgnoreCase))
                 * {
                 *  try
                 *  {
                 *      Uri result = null;
                 *      Uri configUri = new Uri(_runnerSetting.ServerUrl);
                 *      if (Uri.TryCreate(new Uri(configUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped)), jobServerUrl.PathAndQuery, out result))
                 *      {
                 *          //replace the schema and host portion of messageUri with the host from the
                 *          //server URI (which was set at config time)
                 *          jobServerUrl = result;
                 *      }
                 *  }
                 *  catch (InvalidOperationException ex)
                 *  {
                 *      //cannot parse the Uri - not a fatal error
                 *      Trace.Error(ex);
                 *  }
                 *  catch (UriFormatException ex)
                 *  {
                 *      //cannot parse the Uri - not a fatal error
                 *      Trace.Error(ex);
                 *  }
                 * } */

                await jobServer.ConnectAsync(jobConnection);

                var timeline = await jobServer.GetTimelineAsync(message.Plan.ScopeIdentifier, message.Plan.PlanType, message.Plan.PlanId, message.Timeline.Id, CancellationToken.None);

                ArgUtil.NotNull(timeline, nameof(timeline));
                TimelineRecord jobRecord = timeline.Records.FirstOrDefault(x => x.Id == message.JobId && x.RecordType == "Job");
                ArgUtil.NotNull(jobRecord, nameof(jobRecord));
                jobRecord.ErrorCount++;
                jobRecord.Issues.Add(new Issue()
                {
                    Type = IssueType.Error, Message = errorMessage
                });
                await jobServer.UpdateTimelineRecordsAsync(message.Plan.ScopeIdentifier, message.Plan.PlanType, message.Plan.PlanId, message.Timeline.Id, new TimelineRecord[] { jobRecord }, CancellationToken.None);
            }
            catch (Exception ex)
            {
                Trace.Error("Fail to report unhandled exception from Runner.Worker process");
                Trace.Error(ex);
            }
        }
コード例 #6
0
 public async Task UpdateTimelineRecordsAsync(Guid timelineId, TimelineRecord attachmentUpdataRecord, CancellationToken cancellationToken)
 {
     await taskClient.UpdateTimelineRecordsAsync(this.projectId, this.planType, this.planId, timelineId,
                                                 new List <TimelineRecord> {
         attachmentUpdataRecord
     }, cancellationToken);
 }
コード例 #7
0
        /// <summary>
        /// Converts a <see cref="TimelineRecord"/> to an <see cref="AzureDevOpsTimelineRecord"/>.
        /// </summary>
        /// <param name="timelineRecord">Timeline record to convert.</param>
        /// <returns>Converted timeline record.</returns>
        public static AzureDevOpsTimelineRecord ToAzureDevOpsTimelineRecord(this TimelineRecord timelineRecord)
        {
            timelineRecord.NotNull(nameof(timelineRecord));

            return
                (new AzureDevOpsTimelineRecord
            {
                Attempt = timelineRecord.Attempt,
                ChangeId = timelineRecord.ChangeId,
                CurrentOperation = timelineRecord.CurrentOperation,
                ErrorCount = timelineRecord.ErrorCount,
                FinishTime = timelineRecord.FinishTime,
                Id = timelineRecord.Id,
                LastModified = timelineRecord.LastModified,
                Name = timelineRecord.Name,
                Order = timelineRecord.Order,
                ParentId = timelineRecord.ParentId,
                PercentComplete = timelineRecord.PercentComplete,
                RecordType = timelineRecord.RecordType,
                Result = timelineRecord.Result?.ToAzureDevOpsTaskResult(),
                ResultCode = timelineRecord.ResultCode,
                StartTime = timelineRecord.StartTime,
                State = timelineRecord.State?.ToAzureDevOpsTimelineRecordState(),
                WarningCount = timelineRecord.WarningCount,
                WorkerName = timelineRecord.WorkerName,
            });
        }
コード例 #8
0
        private async Task EndPage()
        {
            if (pageWriter != null)
            {
                pageWriter.Flush();
                pageData.Flush();
                pageWriter.Dispose();
                pageWriter = null;
                pageData   = null;
                var log     = new TaskLog(string.Format(@"logs\{0:D}", taskProperties.TaskInstanceId));
                var taskLog = await taskClient.CreateLogAsync(log).ConfigureAwait(false);

                // Upload the contents
                using (var fs = File.Open(dataFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    await taskClient.AppendLogContentAsync(taskLog.Id, fs).ConfigureAwait(false);
                }

                // Create a new record and only set the Log field
                var attachmentUpdataRecord = new TimelineRecord {
                    Id = taskProperties.TaskInstanceId, Log = taskLog
                };
                await taskClient.UpdateTimelineRecordsAsync(attachmentUpdataRecord, default(CancellationToken)).ConfigureAwait(false);
            }
        }
コード例 #9
0
        private string GetScope(TimelineRecord record)
        {
            var timelineStack = new Stack <TimelineRecord>();

            var current = record;

            while (true)
            {
                timelineStack.Push(current);

                var parent = Timeline.Records.Where(r => r.Id == current.ParentId).SingleOrDefault();
                if (parent == null)
                {
                    break;
                }
                else
                {
                    current = parent;
                }
            }

            var scopeBuilder = new StringBuilder();

            timelineStack.ForEach(r => scopeBuilder.Append($"/{r.RecordType}:{r.Name}"));

            var scope = scopeBuilder.ToString();

            return(scope);
        }
コード例 #10
0
    public void RecordSpeech(string jsonString)
    {
        SpeechHistory  history     = JsonUtility.FromJson <SpeechHistory>(jsonString);
        TextRecord     textRecord  = new TextRecord(history.durationSec);
        VoiceRecord    voiceRecord = new VoiceRecord(history.durationSec, history.fileID);
        TimelineRecord timeline    = timelineRecords.Find(t => t.timeSec == history.timeSec);

        if (timeline == null)
        {
            timeline         = new TimelineRecord();
            timeline.timeSec = history.timeSec;
            timeline.text    = textRecord;
            timeline.voice   = voiceRecord;
            timelineRecords.Add(timeline);
            return;
        }

        if (timeline.text == null)
        {
            timeline.text = textRecord;
        }

        if (timeline.voice == null)
        {
            timeline.voice = voiceRecord;
        }
        else
        {
            Utilities.MergeValues(timeline.voice, voiceRecord);
        }
    }
コード例 #11
0
    public void RecordGraphicSwitching(string showGraphicId, string hideGraphicId)
    {
        if (!isRecording)
        {
            return;
        }

        List <GraphicRecord> graphicRecords = new List <GraphicRecord>();

        if (showGraphicId != null)
        {
            GraphicRecord record = new GraphicRecord(showGraphicId, "show");
            graphicRecords.Add(record);
        }

        if (hideGraphicId != null)
        {
            GraphicRecord record = new GraphicRecord(hideGraphicId, "hide");
            graphicRecords.Add(record);
        }

        TimelineRecord timeline = timelineRecords.Find(t => t.timeSec == CurrentTimeSec());

        if (timeline == null)
        {
            timeline         = new TimelineRecord();
            timeline.timeSec = CurrentTimeSec();
            timelineRecords.Add(timeline);
        }
        ;
        timeline.graphic = graphicRecords;
    }
コード例 #12
0
 public SearchBuildLogsResult(BuildResultInfo buildInfo, string jobName, TimelineRecord record, BuildLogReference buildLogReference, string line)
 {
     BuildInfo         = buildInfo;
     JobName           = jobName;
     Record            = record;
     BuildLogReference = buildLogReference;
     Line = line;
 }
コード例 #13
0
 public TimelineRecordItem(
     TimelineRecord record,
     TimelineTree tree)
 {
     Debug.Assert(tree.TryGetNode(record.Id, out _));
     Record = record;
     Tree   = tree;
 }
コード例 #14
0
 public SearchTimelineResult(
     Build build,
     TimelineRecord timelineRecord,
     string line)
 {
     Build          = build;
     TimelineRecord = timelineRecord;
     Line           = line;
 }
コード例 #15
0
        private async Task <int> GetOrCreateTaskLogId(IServiceBusMessage message, CancellationToken cancellationToken, ITaskClient taskClient, Guid projectId, Guid planId, Guid jobId, Guid parentTimelineId, string timelineName, string hubName)
        {
            // attempt to get from message
            var logIdObject = message.GetProperty(VstsMessageConstants.TaskLogIdPropertyName);
            var taskLogId   = 0;
            var gotLogId    = logIdObject != null && int.TryParse(logIdObject.ToString(), out taskLogId);

            if (gotLogId)
            {
                return(taskLogId);
            }

            // attempt to find existing
            var records = await taskClient.GetRecordsAsync(projectId, hubName, planId, parentTimelineId, userState : null, cancellationToken : cancellationToken).ConfigureAwait(false);

            foreach (var record in records)
            {
                if (string.Equals(record.Name, timelineName, StringComparison.OrdinalIgnoreCase))
                {
                    return(record.Log.Id);
                }
            }

            // Create a new timeline
            var subTimelineId = Guid.NewGuid();

            // create a log file
            var logsSubtimelineId = string.Format(@"logs\{0:D}", subTimelineId);
            var taskLog           = await taskClient.CreateLogAsync(projectId, hubName, planId, new TaskLog(logsSubtimelineId), userState : null, cancellationToken : cancellationToken).ConfigureAwait(false);

            // create a sub-timeline
            var timelineRecord = new TimelineRecord
            {
                Id              = subTimelineId,
                Name            = timelineName,
                StartTime       = DateTime.UtcNow,
                State           = TimelineRecordState.InProgress,
                RecordType      = "task", // Record type can be job or task, as we will be dealing only with task here
                WorkerName      = this.settings.WorkerName,
                Order           = 1,      // The job timeline record must be at order 1
                Log             = taskLog,
                ParentId        = jobId,
                PercentComplete = 0,
                ErrorCount      = 0,
                WarningCount    = 0
            };

            await taskClient.UpdateTimelineRecordsAsync(projectId, hubName, planId, parentTimelineId, new List <TimelineRecord> {
                timelineRecord
            }, cancellationToken).ConfigureAwait(false);

            // save the taskLogId on the message
            taskLogId = taskLog.Id;

            return(taskLogId);
        }
コード例 #16
0
        public Job(TimelineRecord record, int depth)
        {
            Depth = depth;

            Id       = record.Id;
            Name     = record.Name;
            Duration = record.Duration;
            Order    = record.Order;
            Result   = record.Result;
            LogId    = record.Log?.Id;
        }
コード例 #17
0
        public void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord)
        {
            ArgUtil.NotEmpty(timelineId, nameof(timelineId));
            ArgUtil.NotNull(timelineRecord, nameof(timelineRecord));
            ArgUtil.NotEmpty(timelineRecord.Id, nameof(timelineRecord.Id));

            _timelineUpdateQueue.TryAdd(timelineId, new ConcurrentQueue <TimelineRecord>());

            Trace.Verbose("Enqueue timeline {0} update queue: {1}", timelineId, timelineRecord.Id);
            _timelineUpdateQueue[timelineId].Enqueue(timelineRecord.Clone());
        }
コード例 #18
0
        public bool TryGetParent(TimelineRecord record, [NotNullWhen(true)] out TimelineRecord?parent)
        {
            if (IdToNodeMap.TryGetValue(record.Id, out var node) &&
                node.ParentNode is object)
            {
                parent = node.ParentNode.TimelineRecord;
                return(true);
            }

            parent = null;
            return(false);
        }
コード例 #19
0
        private async Task UploadFile(UploadFileInfo file)
        {
            bool uploadSucceed = false;

            try
            {
                if (String.Equals(file.Type, CoreAttachmentType.Log, StringComparison.OrdinalIgnoreCase))
                {
                    // Create the log
                    var taskLog = await _jobServer.CreateLogAsync(_scopeIdentifier, _hubName, _planId, new TaskLog(String.Format(@"logs\{0:D}", file.TimelineRecordId)), default(CancellationToken));

                    // Upload the contents
                    using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        var logUploaded = await _jobServer.AppendLogContentAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, fs, default(CancellationToken));
                    }

                    // Create a new record and only set the Log field
                    var attachmentUpdataRecord = new TimelineRecord()
                    {
                        Id = file.TimelineRecordId, Log = taskLog
                    };
                    QueueTimelineRecordUpdate(file.TimelineId, attachmentUpdataRecord);
                }
                else
                {
                    // Create attachment
                    using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        var result = await _jobServer.CreateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, fs, default(CancellationToken));
                    }
                }

                uploadSucceed = true;
            }
            finally
            {
                if (uploadSucceed && file.DeleteSource)
                {
                    try
                    {
                        File.Delete(file.Path);
                    }
                    catch (Exception ex)
                    {
                        Trace.Info("Catch exception during delete success uploaded file.");
                        Trace.Error(ex);
                    }
                }
            }
        }
コード例 #20
0
        protected IList <string> GetTimelineLogLines(TimelineRecord record)
        {
            var jobService = GetMockedService <FakeJobServer>();
            var lines      = jobService.LogLines.GetValueOrDefault(record.Log.Id).ToList();

            if (lines.Count <= 0)
            {
                lines = new List <string>();
                // Fall back to blobstore
                foreach (var blobId in jobService.IdToBlobMapping.GetValueOrDefault(record.Log.Id))
                {
                    lines.AddRange(jobService.UploadedLogBlobs.GetValueOrDefault(blobId));
                }
            }
            return(lines);
        }
コード例 #21
0
    public void RecordFacialExpression(string expressionName)
    {
        float currentTime = CurrentTimeSec();

        TimelineRecord timeline = timelineRecords.Find(t => t.timeSec == currentTime);

        if (timeline == null)
        {
            timeline         = new TimelineRecord();
            timeline.timeSec = currentTime;
            timelineRecords.Add(timeline);
        }
        ;

        SpecialActionRecord action = new SpecialActionRecord(null, expressionName);

        timeline.spAction = action;
    }
コード例 #22
0
ファイル: RunTestsUtil.cs プロジェクト: sharwell/devops-util
        private async Task <JobTestTime> TryGetJobTestTime(TimelineRecord record, TimelineRecord parentRecord)
        {
            using var stream = new MemoryStream();
            await DevOpsServer.DownloadFileAsync(record.Log.Url, stream);

            stream.Position = 0;

            var      totalTimeRegex    = new Regex(@"Test execution time: ([\d.:]+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            var      assemblyTimeRegex = new Regex(@" ([\w.]+\.dll[\d.]*)\s+PASSED ([\d.:]+)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
            var      jobName           = parentRecord.Name;
            var      assemblies        = new List <AssemblyTestTime>();
            TimeSpan?jobDuration       = null;

            using var reader = new StreamReader(stream);
            do
            {
                var line = await reader.ReadLineAsync();

                if (line is null)
                {
                    break;
                }

                var assemblyTimeMatch = assemblyTimeRegex.Match(line);
                if (assemblyTimeMatch.Success)
                {
                    var duration = TimeSpan.Parse(assemblyTimeMatch.Groups[2].Value);
                    assemblies.Add(new AssemblyTestTime(assemblyTimeMatch.Groups[1].Value, duration));
                    continue;
                }

                var totalTimeMatch = totalTimeRegex.Match(line);
                if (totalTimeMatch.Success)
                {
                    jobDuration = TimeSpan.Parse(totalTimeMatch.Groups[1].Value);
                    break;
                }
            } while (true);

            return(jobDuration is object
                   ?new JobTestTime(jobName, jobDuration.Value, assemblies)
                       : null);
        }
コード例 #23
0
        public void UpdateDetailTimelineRecord(TimelineRecord record)
        {
            ArgUtil.NotNull(record, nameof(record));

            if (record.RecordType == ExecutionContextType.Job)
            {
                throw new ArgumentOutOfRangeException(nameof(record));
            }

            if (_detailTimelineId == Guid.Empty)
            {
                // create detail timeline
                _detailTimelineId = Guid.NewGuid();
                _record.Details   = new Timeline(_detailTimelineId);

                _jobServerQueue.QueueTimelineRecordUpdate(_mainTimelineId, _record);
            }

            TimelineRecord existRecord;

            if (_detailRecords.TryGetValue(record.Id, out existRecord))
            {
                existRecord.Name             = record.Name ?? existRecord.Name;
                existRecord.RecordType       = record.RecordType ?? existRecord.RecordType;
                existRecord.Order            = record.Order ?? existRecord.Order;
                existRecord.ParentId         = record.ParentId ?? existRecord.ParentId;
                existRecord.StartTime        = record.StartTime ?? existRecord.StartTime;
                existRecord.FinishTime       = record.FinishTime ?? existRecord.FinishTime;
                existRecord.PercentComplete  = record.PercentComplete ?? existRecord.PercentComplete;
                existRecord.CurrentOperation = record.CurrentOperation ?? existRecord.CurrentOperation;
                existRecord.Result           = record.Result ?? existRecord.Result;
                existRecord.ResultCode       = record.ResultCode ?? existRecord.ResultCode;
                existRecord.State            = record.State ?? existRecord.State;

                _jobServerQueue.QueueTimelineRecordUpdate(_detailTimelineId, existRecord);
            }
            else
            {
                _detailRecords[record.Id] = record;
                _jobServerQueue.QueueTimelineRecordUpdate(_detailTimelineId, record);
            }
        }
コード例 #24
0
        public GateHelper(string taskInstanceId, string hubName, string jobId, string planId, string timelineId, string projectId, string vstsUrl, string authToken)
        {
            // create guuids
            this.JobGuid          = new Guid(jobId);
            this.PlanGuid         = new Guid(planId);
            this.TimelineGuid     = new Guid(timelineId);
            this.ProjectGuid      = new Guid(projectId);
            this.TaskInstanceGuid = new Guid(taskInstanceId);

            // save token and vsts url
            this.VstsUrl   = vstsUrl;
            this.AuthToken = authToken;
            this.HubName   = hubName;

            // create connection to vsts
            try
            {
                this.Connection = new VssConnection(new Uri(this.VstsUrl), new VssBasicCredential("", authToken));
            }
            catch (Exception e)
            {
                System.Console.WriteLine("ok");
            }

            // get task client
            try
            {
                this.TaskClient = this.Connection.GetClient <TaskHttpClient>();
            }
            catch (Exception e)
            {
                System.Console.WriteLine("ok");
            }
            // get the plan
            this.Plan = this.TaskClient.GetPlanAsync(this.ProjectGuid, this.HubName, this.PlanGuid).SyncResult();

            // get httpTaskTimeLineRecord
            var timeLineRecords = this.TaskClient.GetRecordsAsync(this.ProjectGuid, this.HubName, this.PlanGuid, this.TimelineGuid).SyncResult();

            this.TimelineRecord = timeLineRecords.Where(record => record.ParentId != null)
                                  .First();
        }
コード例 #25
0
        private async Task CreateTaskTimelineRecordIfRequired(TaskClient taskClient, CancellationToken cancellationToken)
        {
            if (taskProperties.TaskInstanceId.Equals(Guid.Empty))
            {
                taskProperties.TaskInstanceId = Guid.NewGuid();
            }

            var timelineRecord = new TimelineRecord
            {
                Id         = taskProperties.TaskInstanceId,
                RecordType = "task",
                Name       = taskProperties.TaskInstanceName,
                Order      = 1,
                StartTime  = DateTime.UtcNow,
                State      = TimelineRecordState.Pending,
                ParentId   = taskProperties.JobId,
            };

            // this is an upsert call
            await taskClient.UpdateTimelineRecordsAsync(timelineRecord, cancellationToken).ConfigureAwait(false);
        }
コード例 #26
0
        private void MergeTimelineRecords(TimelineRecord timelineRecord, TimelineRecord rec)
        {
            timelineRecord.CurrentOperation = rec.CurrentOperation ?? timelineRecord.CurrentOperation;
            timelineRecord.Details          = rec.Details ?? timelineRecord.Details;
            timelineRecord.FinishTime       = rec.FinishTime ?? timelineRecord.FinishTime;
            timelineRecord.Log             = rec.Log ?? timelineRecord.Log;
            timelineRecord.Name            = rec.Name ?? timelineRecord.Name;
            timelineRecord.RefName         = rec.RefName ?? timelineRecord.RefName;
            timelineRecord.PercentComplete = rec.PercentComplete ?? timelineRecord.PercentComplete;
            timelineRecord.RecordType      = rec.RecordType ?? timelineRecord.RecordType;
            timelineRecord.Result          = rec.Result ?? timelineRecord.Result;
            timelineRecord.ResultCode      = rec.ResultCode ?? timelineRecord.ResultCode;
            timelineRecord.StartTime       = rec.StartTime ?? timelineRecord.StartTime;
            timelineRecord.State           = rec.State ?? timelineRecord.State;
            timelineRecord.WorkerName      = rec.WorkerName ?? timelineRecord.WorkerName;

            if (rec.ErrorCount != null && rec.ErrorCount > 0)
            {
                timelineRecord.ErrorCount = rec.ErrorCount;
            }

            if (rec.WarningCount != null && rec.WarningCount > 0)
            {
                timelineRecord.WarningCount = rec.WarningCount;
            }

            if (rec.Issues.Count > 0)
            {
                timelineRecord.Issues.Clear();
                timelineRecord.Issues.AddRange(rec.Issues.Select(i => i.Clone()));
            }

            if (rec.Variables.Count > 0)
            {
                foreach (var variable in rec.Variables)
                {
                    timelineRecord.Variables[variable.Key] = variable.Value.Clone();
                }
            }
        }
        public async Task CreateTaskTimelineRecordIfRequired(TaskClient taskClient, CancellationToken cancellationToken)
        {
            if (taskProperties.TaskInstanceId.Equals(Guid.Empty))
            {
                taskProperties.TaskInstanceId = Guid.NewGuid();
            }

            var timelineRecord = new TimelineRecord
            {
                Id         = taskProperties.TaskInstanceId,
                RecordType = "task",
                StartTime  = DateTime.UtcNow,
                ParentId   = taskProperties.JobId,
            };

            if (!string.IsNullOrWhiteSpace(taskProperties.TaskInstanceName))
            {
                timelineRecord.Name = taskProperties.TaskInstanceName;
            }

            // this is an upsert call
            await taskClient.UpdateTimelineRecordAsync(timelineRecord, cancellationToken).ConfigureAwait(false);
        }
コード例 #28
0
        private void timelineLV_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (sender == null)
            {
                return;
            }

            ListView lv = sender as ListView;

            if (lv == null)
            {
                return;
            }

            TimelineRecord tr = lv.SelectedItem as TimelineRecord;

            if (tr != null && !String.IsNullOrWhiteSpace(tr.LogUrl) && tr.ParentId != null)
            {
                Frame.Navigate(typeof(LogPage), new StringKeyValuePair {
                    key = tr.Name, value = tr.LogUrl
                });
            }
        }
コード例 #29
0
        private async Task UploadFile(UploadFileInfo file)
        {
            bool uploadSucceed = false;

            try
            {
                if (String.Equals(file.Type, CoreAttachmentType.Log, StringComparison.OrdinalIgnoreCase))
                {
                    // Create the log
                    var taskLog = await _jobServer.CreateLogAsync(_scopeIdentifier, _hubName, _planId, new TaskLog(String.Format(@"logs\{0:D}", file.TimelineRecordId)), default(CancellationToken));

                    using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                    {
                        if (_writeToBlobStoreLogs)
                        {
                            try
                            {
                                var blobBlockId = await _jobServer.UploadLogToBlobStore(fs, _hubName, _planId, taskLog.Id);

                                int lineCount = File.ReadLines(file.Path).Count();

                                // Notify TFS
                                await _jobServer.AssociateLogAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, blobBlockId, lineCount, default(CancellationToken));
                            }
                            catch
                            {
                                // Fall back to FCS
                                fs.Position = 0;
                                await _jobServer.AppendLogContentAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, fs, default(CancellationToken));
                            }
                        }
                        else
                        {
                            await _jobServer.AppendLogContentAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, fs, default(CancellationToken));
                        }
                    }

                    // Create a new record and only set the Log field
                    var attachmentUpdataRecord = new TimelineRecord()
                    {
                        Id = file.TimelineRecordId, Log = taskLog
                    };
                    QueueTimelineRecordUpdate(file.TimelineId, attachmentUpdataRecord);
                }
                else
                {
                    if (_writeToBlobStoreAttachments)
                    {
                        try
                        {
                            var(dedupId, length) = await _jobServer.UploadAttachmentToBlobStore(_debugMode, file.Path, _planId, _jobTimelineRecordId, default(CancellationToken));

                            // Notify TFS
                            await _jobServer.AssosciateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, dedupId, (long)length, default(CancellationToken));
                        }
                        catch
                        {
                            // Fall back to file-based FCS
                            using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                            {
                                var result = await _jobServer.CreateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, fs, default(CancellationToken));
                            }
                        }
                    }
                    else
                    {
                        // Create attachment
                        using (FileStream fs = File.Open(file.Path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        {
                            var result = await _jobServer.CreateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, fs, default(CancellationToken));
                        }
                    }
                }

                uploadSucceed = true;
            }
            finally
            {
                if (uploadSucceed && file.DeleteSource)
                {
                    try
                    {
                        File.Delete(file.Path);
                    }
                    catch (Exception ex)
                    {
                        Trace.Info("Catch exception during delete success uploaded file.");
                        Trace.Error(ex);
                    }
                }
            }
        }
コード例 #30
0
        private async Task UploadFile(UploadFileInfo file)
        {
            bool uploadSucceed = false;
            try
            {
                if (String.Equals(file.Type, CoreAttachmentType.Log, StringComparison.OrdinalIgnoreCase))
                {
                    // Create the log
                    var taskLog = await _jobServer.CreateLogAsync(_scopeIdentifier, _hubName, _planId, new TaskLog(String.Format(@"logs\{0:D}", file.TimelineRecordId)), default(CancellationToken));

                    // Upload the contents
                    using (FileStream fs = File.OpenRead(file.Path))
                    {
                        var logUploaded = await _jobServer.AppendLogContentAsync(_scopeIdentifier, _hubName, _planId, taskLog.Id, fs, default(CancellationToken));
                    }

                    // Create a new record and only set the Log field
                    var attachmentUpdataRecord = new TimelineRecord() { Id = file.TimelineRecordId, Log = taskLog };
                    QueueTimelineRecordUpdate(file.TimelineId, attachmentUpdataRecord);
                }
                else
                {
                    // Create attachment
                    using (FileStream fs = File.OpenRead(file.Path))
                    {
                        var result = await _jobServer.CreateAttachmentAsync(_scopeIdentifier, _hubName, _planId, file.TimelineId, file.TimelineRecordId, file.Type, file.Name, fs, default(CancellationToken));
                    }
                }

                uploadSucceed = true;
            }
            finally
            {
                if (uploadSucceed && file.DeleteSource)
                {
                    try
                    {
                        File.Delete(file.Path);
                    }
                    catch (Exception ex)
                    {
                        Trace.Info("Catch exception during delete success uploaded file.");
                        Trace.Error(ex);
                    }
                }
            }
        }
コード例 #31
0
        public void QueueTimelineRecordUpdate(Guid timelineId, TimelineRecord timelineRecord)
        {
            ArgUtil.NotEmpty(timelineId, nameof(timelineId));
            ArgUtil.NotNull(timelineRecord, nameof(timelineRecord));
            ArgUtil.NotEmpty(timelineRecord.Id, nameof(timelineRecord.Id));

            _timelineUpdateQueue.TryAdd(timelineId, new ConcurrentQueue<TimelineRecord>());

            Trace.Verbose("Enqueue timeline {0} update queue: {1}", timelineId, timelineRecord.Id);
            _timelineUpdateQueue[timelineId].Enqueue(timelineRecord.Clone());
        }
コード例 #32
0
 public async Task UpdateTimelineRecordsAsync(TimelineRecord timelineRecord, CancellationToken cancellationToken)
 {
     await taskClient.UpdateTimelineRecordsAsync(this.taskProperties.ProjectId, this.taskProperties.HubName, this.taskProperties.PlanId, this.taskProperties.TimelineId, new List <TimelineRecord> {
         timelineRecord
     }, cancellationToken).ConfigureAwait(false);
 }
コード例 #33
0
        public void UpdateDetailTimelineRecord(TimelineRecord record)
        {
            ArgUtil.NotNull(record, nameof(record));

            if (record.RecordType == ExecutionContextType.Job)
            {
                throw new ArgumentOutOfRangeException(nameof(record));
            }

            if (_detailTimelineId == Guid.Empty)
            {
                // create detail timeline
                _detailTimelineId = Guid.NewGuid();
                _record.Details = new Timeline(_detailTimelineId);

                _jobServerQueue.QueueTimelineRecordUpdate(_mainTimelineId, _record);
            }

            TimelineRecord existRecord;
            if (_detailRecords.TryGetValue(record.Id, out existRecord))
            {
                existRecord.Name = record.Name ?? existRecord.Name;
                existRecord.RecordType = record.RecordType ?? existRecord.RecordType;
                existRecord.Order = record.Order ?? existRecord.Order;
                existRecord.ParentId = record.ParentId ?? existRecord.ParentId;
                existRecord.StartTime = record.StartTime ?? existRecord.StartTime;
                existRecord.FinishTime = record.FinishTime ?? existRecord.FinishTime;
                existRecord.PercentComplete = record.PercentComplete ?? existRecord.PercentComplete;
                existRecord.CurrentOperation = record.CurrentOperation ?? existRecord.CurrentOperation;
                existRecord.Result = record.Result ?? existRecord.Result;
                existRecord.ResultCode = record.ResultCode ?? existRecord.ResultCode;
                existRecord.State = record.State ?? existRecord.State;

                _jobServerQueue.QueueTimelineRecordUpdate(_detailTimelineId, existRecord);
            }
            else
            {
                _detailRecords[record.Id] = record;
                _jobServerQueue.QueueTimelineRecordUpdate(_detailTimelineId, record);
            }
        }
コード例 #34
0
        private void ProcessTaskDetailCommand(IExecutionContext context, Dictionary<string, string> eventProperties, string data)
        {
            TimelineRecord record = new TimelineRecord();

            String timelineRecord;
            if (!eventProperties.TryGetValue(TaskDetailEventProperties.TimelineRecordId, out timelineRecord) ||
                string.IsNullOrEmpty(timelineRecord) ||
                new Guid(timelineRecord).Equals(Guid.Empty))
            {
                throw new Exception(StringUtil.Loc("MissingTimelineRecordId"));
            }
            else
            {
                record.Id = new Guid(timelineRecord);
            }

            string parentTimlineRecord;
            if (eventProperties.TryGetValue(TaskDetailEventProperties.ParentTimelineRecordId, out parentTimlineRecord))
            {
                record.ParentId = new Guid(parentTimlineRecord);
            }

            String name;
            if (eventProperties.TryGetValue(TaskDetailEventProperties.Name, out name))
            {
                record.Name = name;
            }

            String recordType;
            if (eventProperties.TryGetValue(TaskDetailEventProperties.Type, out recordType))
            {
                record.RecordType = recordType;
            }

            String order;
            if (eventProperties.TryGetValue(TaskDetailEventProperties.Order, out order))
            {
                int orderInt = 0;
                if (int.TryParse(order, out orderInt))
                {
                    record.Order = orderInt;
                }
            }

            String percentCompleteValue;
            if (eventProperties.TryGetValue(TaskDetailEventProperties.Progress, out percentCompleteValue))
            {
                Int32 progress;
                if (Int32.TryParse(percentCompleteValue, out progress))
                {
                    record.PercentComplete = (Int32)Math.Min(Math.Max(progress, 0), 100);
                }
            }

            if (!String.IsNullOrEmpty(data))
            {
                record.CurrentOperation = data;
            }

            string result;
            if (eventProperties.TryGetValue(TaskDetailEventProperties.Result, out result))
            {
                record.Result = EnumUtil.TryParse<TaskResult>(result) ?? TaskResult.Succeeded;
            }

            String startTime;
            if (eventProperties.TryGetValue(TaskDetailEventProperties.StartTime, out startTime))
            {
                record.StartTime = ParseDateTime(startTime, DateTime.UtcNow);
            }

            String finishtime;
            if (eventProperties.TryGetValue(TaskDetailEventProperties.FinishTime, out finishtime))
            {
                record.FinishTime = ParseDateTime(finishtime, DateTime.UtcNow);
            }

            String state;
            if (eventProperties.TryGetValue(TaskDetailEventProperties.State, out state))
            {
                record.State = ParseTimelineRecordState(state, TimelineRecordState.Pending);
            }


            TimelineRecord trackingRecord;
            // in front validation as much as possible.
            // timeline record is happened in back end queue, user will not receive result of the timeline record updates.
            // front validation will provide user better understanding when things went wrong.
            if (_timelineRecordsTracker.TryGetValue(record.Id, out trackingRecord))
            {
                // we already created this timeline record
                // make sure parentid does not changed.
                if (record.ParentId != null &&
                    record.ParentId != trackingRecord.ParentId)
                {
                    throw new Exception(StringUtil.Loc("CannotChangeParentTimelineRecord"));
                }
                else if (record.ParentId == null)
                {
                    record.ParentId = trackingRecord.ParentId;
                }

                // populate default value for empty field.
                if (record.State == TimelineRecordState.Completed)
                {
                    if (record.PercentComplete == null)
                    {
                        record.PercentComplete = 100;
                    }

                    if (record.FinishTime == null)
                    {
                        record.FinishTime = DateTime.UtcNow;
                    }
                }
            }
            else
            {
                // we haven't created this timeline record
                // make sure we have name/type and parent record has created.
                if (string.IsNullOrEmpty(record.Name))
                {
                    throw new Exception(StringUtil.Loc("NameRequiredForTimelineRecord"));
                }

                if (string.IsNullOrEmpty(record.RecordType))
                {
                    throw new Exception(StringUtil.Loc("TypeRequiredForTimelineRecord"));
                }

                if (record.ParentId != null && record.ParentId != Guid.Empty)
                {
                    if (!_timelineRecordsTracker.ContainsKey(record.ParentId.Value))
                    {
                        throw new Exception(StringUtil.Loc("ParentTimelineNotCreated"));
                    }
                }

                // populate default value for empty field.
                if (record.StartTime == null)
                {
                    record.StartTime = DateTime.UtcNow;
                }

                if (record.State == null)
                {
                    record.State = TimelineRecordState.InProgress;
                }
            }

            context.UpdateDetailTimelineRecord(record);

            _timelineRecordsTracker[record.Id] = record;
        }
コード例 #35
0
ファイル: Timeline.cs プロジェクト: impworks/xna.geek.engine
        public int AddAbsolute(float time, Action action, string comment = null)
		{
			var record = new TimelineRecord
			{
			    Time = time,
				Action = action,
				Comment = comment,
				RecordId = _MaxRecordId++
			};

			if (_Current == null || _Current.Time > time)
				_Current = record;

			for (var idx = 0; idx < _KeyFrames.Count; idx++)
			{
				var curr = _KeyFrames[idx];
				if (curr.Time > time)
				{
					_KeyFrames.Insert(idx, record);
					return record.RecordId;
				}
			}

			// the current item is the last
			_KeyFrames.Add(record);
			return record.RecordId;
		}
コード例 #36
0
ファイル: Timeline.cs プロジェクト: impworks/xna.geek.engine
		private void shiftCurrent()
		{
			var nextIndex = _KeyFrames.IndexOf(_Current) + 1;
			if (nextIndex < _KeyFrames.Count)
			{
				_Current = _KeyFrames[nextIndex];

			    if (nextIndex > SKIPPED_EVENT_THRESHOLD && !IsLooped)
			        clearSkipped();
			}
			else
			{
				if (IsLooped)
				{
					CurrentTime = 0;
					_Current = _KeyFrames[0];
				}
				else
				{
					_Current = null;
				}
			}
		}