public ProcessDefinitionProcessor( ProcessorEnricherContainer processorEnrichers, IEndpointFactory endpointFactory, IServiceProvider services, ITelemetryLogger telemetry, ILogger <Processor> logger) : base(processorEnrichers, endpointFactory, services, telemetry, logger) { SourceModel = new ProcessorModel(); TargetModel = new ProcessorModel(); }
private async Task LoadLayout(ProcessorModel model, WorkItemTypeModel wit, AzureDevOpsEndpoint endpoint, string processId) { wit.Layout = (await endpoint.GetApiDefinitionAsync <WorkItemLayout>(new object[] { processId, wit.WorkItemType.ReferenceName }, queryForDetails: false)); foreach (var page in wit.Layout.Pages) { var pageKey = $"{wit.WorkItemType.ReferenceName}::{page.Label}"; if (model.WorkItemPages.ContainsKey(pageKey)) { model.WorkItemPages[pageKey] = page; } else { model.WorkItemPages.Add(pageKey, page); } foreach (var section in page.Sections) { foreach (var group in section.Groups) { var groupKey = $"{wit.WorkItemType.ReferenceName}::{page.Label}::{section.Id}::{group.Label}"; if (model.WorkItemGroups.ContainsKey(groupKey)) { model.WorkItemGroups[groupKey] = group; } else { model.WorkItemGroups.Add(groupKey, group); } foreach (var control in group.Controls) { var controlKey = $"{wit.WorkItemType.ReferenceName}::{page.Label}::{section.Id}::{group.Label}::{control.Id}"; if (model.WorkItemControls.ContainsKey(controlKey)) { model.WorkItemControls[controlKey] = control; } else { model.WorkItemControls.Add(controlKey, control); } } } } } }
private async Task BuildModel(ProcessorModel model, AzureDevOpsEndpoint endpoint, bool warnOnMissing) { // Grab all the procs, then iterate over them looking for procs user has configured to be // sync'd. Then grab all Work Item Types for the given process and filter those by the ones user // wants to sync. Log.LogDebug($"Loading model for [{endpoint.Options.Name}]."); var rootFields = (await endpoint.GetApiDefinitionsAsync <WorkItemField>(queryForDetails: false)) .ToDictionary(x => x.ReferenceName, x => x); if (endpoint.Options.Name == Source.Options.Name) { SourceFields = rootFields; } else { TargetFields = rootFields; } var procs = await endpoint.GetApiDefinitionsAsync <ProcessDefinition>(); foreach (var processFilter in _Options.Processes.Keys) { string mappedProcName = processFilter; if (model == TargetModel && _Options.ProcessMaps.ContainsKey(processFilter)) { mappedProcName = _Options.ProcessMaps[processFilter]; } var proc = procs.FirstOrDefault(p => processFilter == "*" || p.Name.Equals(mappedProcName, StringComparison.OrdinalIgnoreCase)); if (proc != null) { //if (!isMapped) mappedProcName = proc.Name; if (!model.ProcessDefinitions.ContainsKey(proc.Id)) { model.ProcessDefinitions.Add(mappedProcName, new ProcessDefinitionModel() { Process = proc, MappedFrom = processFilter, WorkItemTypes = new List <WorkItemTypeModel>() }); } model.ProcessDefinitions[mappedProcName].WorkItemBehaviors = (await endpoint.GetApiDefinitionsAsync <WorkItemBehavior>(new object[] { proc.Id })).ToList(); model.ProcessDefinitions[mappedProcName].WorkItemBehaviors.ForEach(b => { if (!model.WorkItemBehaviors.ContainsKey(b.Id)) { model.WorkItemBehaviors.Add(b.Id, b); } }); #region Build Work Item Types data ... var procWits = (await endpoint.GetApiDefinitionsAsync <WorkItemType>(new object[] { proc.Id }, singleDefinitionQueryString: "$expand=All")); procWits = procWits.Where(x => _Options.Processes[processFilter].Any(a => a == "*" || x.Name.Equals(a, StringComparison.OrdinalIgnoreCase))); if (procWits != null && procWits.Count() > 0) { foreach (var wit in procWits) { if (!model.WorkItemTypes.ContainsKey(wit.Id)) { model.WorkItemTypes.Add(wit.Id, new WorkItemTypeModel() { WorkItemType = wit }); model.ProcessDefinitions[mappedProcName].WorkItemTypes.Add(model.WorkItemTypes[wit.Id]); } else { model.WorkItemTypes[wit.Id] = new WorkItemTypeModel() { WorkItemType = wit }; } #region --- Loading Wit Type Details --- await Task.WhenAll( Task.Run(async() => await LoadLayout(model, model.WorkItemTypes[wit.Id], endpoint, proc.Id)), Task.Run(async() => { model.WorkItemTypes[wit.Id].Fields = (await endpoint.GetApiDefinitionsAsync <WorkItemTypeField>(new object[] { proc.Id, wit.Id }, singleDefinitionQueryString: "$expand=All")).ToList(); model.WorkItemTypes[wit.Id].Fields.ForEach(field => model.WorkItemFields.Add(field.Id, field)); }), Task.Run(async() => { model.WorkItemTypes[wit.Id].States = (await endpoint.GetApiDefinitionsAsync <WorkItemState>(new object[] { proc.Id, wit.Id })).ToList(); model.WorkItemTypes[wit.Id].States.ForEach(state => model.WorkItemStates.Add(state.Name, state)); }), Task.Run(async() => { model.WorkItemTypes[wit.Id].Rules = (await endpoint.GetApiDefinitionsAsync <WorkItemRule>(new object[] { proc.Id, wit.Id })).ToList(); model.WorkItemTypes[wit.Id].Rules.ForEach(rule => model.WorkItemRules.Add(rule.Id, rule)); }), Task.Run(async() => { model.WorkItemTypes[wit.Id].Behaviors = (await endpoint.GetApiDefinitionsAsync <WorkItemTypeBehavior>(new object[] { proc.Id, wit.Id })).ToList(); model.WorkItemTypes[wit.Id].Behaviors.ForEach(rule => { if (!model.WorkItemTypeBehaviors.ContainsKey(rule.Id)) { model.WorkItemTypeBehaviors.Add(rule.Id, rule); } }); }) ); #endregion } } #endregion } else if (warnOnMissing) { Log.LogWarning($"Unable to locate {processFilter} process in {endpoint.Options.Name} organization."); } } }