using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Runtime.Serialization; using GitHub.DistributedTask.ObjectTemplating.Tokens; using GitHub.DistributedTask.Pipelines.ContextData; using GitHub.DistributedTask.WebApi; using GitHub.Services.WebApi; using Newtonsoft.Json; namespace GitHub.DistributedTask.Pipelines { [DataContract] [EditorBrowsable(EditorBrowsableState.Never)] public sealed class AgentJobRequestMessage { [JsonConstructor] internal AgentJobRequestMessage() { } /// /// Job request message sent to the runner /// /// Hierarchy of environment variables to overlay, last wins. public AgentJobRequestMessage( TaskOrchestrationPlanReference plan, TimelineReference timeline, Guid jobId, String jobDisplayName, String jobName, TemplateToken jobContainer, TemplateToken jobServiceContainers, IList environmentVariables, IDictionary variables, IList maskHints, JobResources jobResources, DictionaryContextData contextData, WorkspaceOptions workspaceOptions, IEnumerable steps, IEnumerable scopes, IList fileTable, TemplateToken jobOutputs, IList defaults) { this.MessageType = JobRequestMessageTypes.PipelineAgentJobRequest; this.Plan = plan; this.JobId = jobId; this.JobDisplayName = jobDisplayName; this.JobName = jobName; this.JobContainer = jobContainer; this.JobServiceContainers = jobServiceContainers; this.Timeline = timeline; this.Resources = jobResources; this.Workspace = workspaceOptions; this.JobOutputs = jobOutputs; m_variables = new Dictionary(variables, StringComparer.OrdinalIgnoreCase); m_maskHints = new List(maskHints); m_steps = new List(steps); if (scopes != null) { m_scopes = new List(scopes); } if (environmentVariables?.Count > 0) { m_environmentVariables = new List(environmentVariables); } if (defaults?.Count > 0) { m_defaults = new List(defaults); } this.ContextData = new Dictionary(StringComparer.OrdinalIgnoreCase); if (contextData?.Count > 0) { foreach (var pair in contextData) { this.ContextData[pair.Key] = pair.Value; } } if (fileTable?.Count > 0) { m_fileTable = new List(fileTable); } } [DataMember] public String MessageType { get; private set; } [DataMember] public TaskOrchestrationPlanReference Plan { get; private set; } [DataMember] public TimelineReference Timeline { get; private set; } [DataMember] public Guid JobId { get; private set; } [DataMember] public String JobDisplayName { get; private set; } [DataMember] public String JobName { get; private set; } [DataMember(EmitDefaultValue = false)] public TemplateToken JobContainer { get; private set; } [DataMember(EmitDefaultValue = false)] public TemplateToken JobServiceContainers { get; private set; } [DataMember(EmitDefaultValue = false)] public TemplateToken JobOutputs { get; private set; } [DataMember] public Int64 RequestId { get; internal set; } [DataMember] public DateTime LockedUntil { get; internal set; } [DataMember] public JobResources Resources { get; private set; } [DataMember(EmitDefaultValue = false)] [EditorBrowsable(EditorBrowsableState.Never)] public IDictionary ContextData { get; private set; } [DataMember(EmitDefaultValue = false)] public WorkspaceOptions Workspace { get; private set; } /// /// Gets the collection of mask hints /// public List MaskHints { get { if (m_maskHints == null) { m_maskHints = new List(); } return m_maskHints; } } /// /// Gets the hierarchy of environment variables to overlay, last wins. /// public IList EnvironmentVariables { get { if (m_environmentVariables == null) { m_environmentVariables = new List(); } return m_environmentVariables; } } /// /// Gets the hierarchy of defaults to overlay, last wins. /// public IList Defaults { get { if (m_defaults == null) { m_defaults = new List(); } return m_defaults; } } /// /// Gets the collection of variables associated with the current context. /// public IDictionary Variables { get { if (m_variables == null) { m_variables = new Dictionary(StringComparer.OrdinalIgnoreCase); } return m_variables; } } public IList Steps { get { if (m_steps == null) { m_steps = new List(); } return m_steps; } } public IList Scopes { get { if (m_scopes == null) { m_scopes = new List(); } return m_scopes; } } /// /// Gets the table of files used when parsing the pipeline (e.g. yaml files) /// public IList FileTable { get { if (m_fileTable == null) { m_fileTable = new List(); } return m_fileTable; } } public TaskAgentMessage GetAgentMessage() { var body = JsonUtility.ToString(this); return new TaskAgentMessage { Body = body, MessageType = JobRequestMessageTypes.PipelineAgentJobRequest }; } [OnSerializing] private void OnSerializing(StreamingContext context) { if (m_environmentVariables?.Count == 0) { m_environmentVariables = null; } if (m_defaults?.Count == 0) { m_defaults = null; } if (m_fileTable?.Count == 0) { m_fileTable = null; } if (m_maskHints?.Count == 0) { m_maskHints = null; } else if (m_maskHints != null) { m_maskHints = new List(this.m_maskHints.Distinct()); } if (m_scopes?.Count == 0) { m_scopes = null; } if (m_variables?.Count == 0) { m_variables = null; } } [DataMember(Name = "EnvironmentVariables", EmitDefaultValue = false)] private List m_environmentVariables; [DataMember(Name = "Defaults", EmitDefaultValue = false)] private List m_defaults; [DataMember(Name = "FileTable", EmitDefaultValue = false)] private List m_fileTable; [DataMember(Name = "Mask", EmitDefaultValue = false)] private List m_maskHints; [DataMember(Name = "Steps", EmitDefaultValue = false)] private List m_steps; [DataMember(Name = "Scopes", EmitDefaultValue = false)] private List m_scopes; [DataMember(Name = "Variables", EmitDefaultValue = false)] private IDictionary m_variables; } }