_AssignedToNameToEncodedPAT
_LastDateForcedUpdatedBy
_LastDateDeleteForcedUpdatedBy
This commit is contained in:
2023-10-08 15:37:36 -07:00
parent 7d8f409ff3
commit 61334d690b
8 changed files with 293 additions and 17 deletions

View File

@ -14,6 +14,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
@ -27,11 +28,39 @@ public class ProcessData : IProcessData
List<object> Shared.Properties.IProcessData.Details => _Details;
public ProcessData(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection, HttpClient httpClient, string basePage, string api, string query, WorkItemTrackingHttpClient workItemTrackingHttpClient, string project, ReadOnlyDictionary<string, string> assignedToNameToUser, ReadOnlyDictionary<string, string> requestorNameToUser, string json)
public ProcessData(IFileRead fileRead,
Logistics logistics,
List<FileInfo> fileInfoCollection,
HttpClient httpClient,
string basePage,
string api,
string query,
WorkItemTrackingHttpClient workItemTrackingHttpClient,
string project,
ReadOnlyDictionary<string, string> assignedToNameToEncodedPAT,
ReadOnlyDictionary<string, string> assignedToNameToUser,
ReadOnlyDictionary<string, string> requestorNameToUser,
string json,
bool forceUpdatedBy,
bool forceDeleteUpdatedBy)
{
fileInfoCollection.Clear();
_Details = new List<object>();
Parse(fileRead, logistics, fileInfoCollection, httpClient, basePage, api, query, workItemTrackingHttpClient, project, assignedToNameToUser, requestorNameToUser, json);
Parse(fileRead,
logistics,
fileInfoCollection,
httpClient,
basePage,
api,
query,
workItemTrackingHttpClient,
project,
assignedToNameToEncodedPAT,
assignedToNameToUser,
requestorNameToUser,
json,
forceUpdatedBy,
forceDeleteUpdatedBy);
}
string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors)
@ -92,7 +121,7 @@ public class ProcessData : IProcessData
return result.ToString();
}
private static Value[] GetWorkItems(HttpClient httpClient, string basePage, string api, string ids)
private static Value[] GetWorkItems(IFileRead fileRead, HttpClient httpClient, string basePage, string api, string ids)
{
Value[]? results;
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, $"/workitems?ids={ids}"));
@ -106,6 +135,8 @@ public class ProcessData : IProcessData
JsonElement? jsonElement = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
if (jsonElement is null || jsonElement.Value.ValueKind != JsonValueKind.Object)
throw new NullReferenceException(nameof(jsonElement));
if (!fileRead.IsEAFHosted)
File.WriteAllText("../../example.json", jsonElement.Value.EnumerateObject().Last().Value.ToString());
results = JsonSerializer.Deserialize<Value[]>(jsonElement.Value.EnumerateObject().Last().Value);
if (results is null || !results.Any())
throw new NullReferenceException(nameof(results));
@ -158,12 +189,23 @@ public class ProcessData : IProcessData
return result;
}
private static int GetPriority(FIBacklogMesa fiBacklogMesa)
{
int result;
if (!int.TryParse(fiBacklogMesa.Priority.Substring(0, 1), out int priority) || priority == 0 || priority > 3)
result = 4;
else
result = priority;
return result;
}
private static string? GetMappedState(FIBacklogMesa fiBacklogMesa) =>
fiBacklogMesa.Status == "CMP" ? "Closed" : fiBacklogMesa.Status == "UAT" ? "Resolved" : fiBacklogMesa.Status == "In process" ? "Active" : null;
private static void SetSyncTag(WorkItemTrackingHttpClient workItemTrackingHttpClient, ReadOnlyDictionary<string, string> requestorNameToUser, Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa, ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
string key;
int priority;
bool isBugFix;
string? state;
List<string> tags;
@ -193,6 +235,11 @@ public class ProcessData : IProcessData
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if (!string.IsNullOrEmpty(fiBacklogMesa.Definition) && valueWithReq.Value.Fields.SystemDescription != fiBacklogMesa.Definition.Replace("&", "&amp;").Replace("\"", "&quot;"))
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
foreach (string tag in tags)
{
if (compareTags.Contains(tag))
@ -212,11 +259,7 @@ public class ProcessData : IProcessData
}
if (!isBugFix)
{
if (!int.TryParse(fiBacklogMesa.Priority.Substring(0, 1), out int priority))
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
priority = GetPriority(fiBacklogMesa);
if (valueWithReq.Value.Fields.MicrosoftVSTSCommonPriority != priority)
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
@ -247,12 +290,134 @@ public class ProcessData : IProcessData
}
}
private static ReadOnlyDictionary<string, List<int>> GetForceUpdatedByCollection(ReadOnlyDictionary<string, string> assignedToNameToEncodedPAT, ReadOnlyDictionary<string, string> assignedToNameToUser, Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa, ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
Dictionary<string, List<int>> results = new();
string key;
List<int>? reqCollection;
FIBacklogMesa? fiBacklogMesa;
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
key = $"{valueWithReq.Req} - ";
if (!keyToFIBacklogMesa.TryGetValue(key, out fiBacklogMesa))
continue;
if (string.IsNullOrEmpty(fiBacklogMesa.AssignedTo))
continue;
if (!assignedToNameToUser.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToUser))
continue;
if (!valueWithReq.Value.Fields.SystemChangedBy.UniqueName.Equals(assignedToUser, StringComparison.CurrentCultureIgnoreCase))
{
if (!assignedToNameToEncodedPAT.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToEncodedPAT) || assignedToEncodedPAT.Length < 15)
continue;
if (!results.TryGetValue(assignedToEncodedPAT, out reqCollection))
{
results.Add(assignedToEncodedPAT, new());
if (!results.TryGetValue(assignedToEncodedPAT, out reqCollection))
throw new NotSupportedException();
}
reqCollection.Add(valueWithReq.Value.Id);
}
}
return new(results);
}
private static ReadOnlyDictionary<string, List<int[]>> GetForceUpdatedByCollectionDelete(string forceUpdatedByComment, ReadOnlyDictionary<string, string> assignedToNameToEncodedPAT, ReadOnlyDictionary<string, string> assignedToNameToUser, Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa, ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
Dictionary<string, List<int[]>> results = new();
string key;
List<int[]>? reqCollection;
FIBacklogMesa? fiBacklogMesa;
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
key = $"{valueWithReq.Req} - ";
if (!keyToFIBacklogMesa.TryGetValue(key, out fiBacklogMesa))
continue;
if (string.IsNullOrEmpty(fiBacklogMesa.AssignedTo))
continue;
if (!assignedToNameToUser.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToUser))
continue;
if (valueWithReq.Value.Fields.SystemHistory == forceUpdatedByComment)
{
if (!assignedToNameToEncodedPAT.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToEncodedPAT) || assignedToEncodedPAT.Length < 15)
continue;
if (!results.TryGetValue(assignedToEncodedPAT, out reqCollection))
{
results.Add(assignedToEncodedPAT, new());
if (!results.TryGetValue(assignedToEncodedPAT, out reqCollection))
throw new NotSupportedException();
}
reqCollection.Add(new int[] { valueWithReq.Value.Id, valueWithReq.Value.CommentVersionRef.CommentId });
}
}
return new(results);
}
private static void Post(HttpClient httpClient, string basePage, string api, string query, HttpContent httpContent)
{
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.PostAsync(string.Concat(basePage, api, query), httpContent);
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<string> stringTask = httpResponseMessageTask.Result.Content.ReadAsStringAsync();
stringTask.Wait();
}
private static void ForceUpdatedBy(HttpClient httpClient, string basePage, string project, string api, string forceUpdatedByComment, ReadOnlyDictionary<string, List<int>> updateCollection)
{
string stringPayload;
HttpContent httpContent;
HttpClient keyHttpClient;
AuthenticationHeaderValue authenticationHeaderValue;
foreach (KeyValuePair<string, List<int>> keyValuePair in updateCollection)
{
keyHttpClient = new() { BaseAddress = httpClient.BaseAddress };
authenticationHeaderValue = keyHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", keyValuePair.Key);
if (authenticationHeaderValue.Parameter != keyValuePair.Key)
throw new NotSupportedException();
foreach (int id in keyValuePair.Value)
{
stringPayload = JsonSerializer.Serialize(new { text = forceUpdatedByComment });
httpContent = new StringContent($"{stringPayload}", Encoding.UTF8, "application/json");
Post(keyHttpClient, $"{basePage}/{project}", api, $"/workitems/{id}/comments?api-version=5.1-preview.3", httpContent);
}
}
}
private static void Delete(HttpClient httpClient, string basePage, string api, string query)
{
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.DeleteAsync(string.Concat(basePage, api, query));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<string> stringTask = httpResponseMessageTask.Result.Content.ReadAsStringAsync();
stringTask.Wait();
}
private static void ForceUpdatedByDelete(HttpClient httpClient, string basePage, string project, string api, ReadOnlyDictionary<string, List<int[]>> deleteCollection)
{
HttpClient keyHttpClient;
AuthenticationHeaderValue authenticationHeaderValue;
foreach (KeyValuePair<string, List<int[]>> keyValuePair in deleteCollection)
{
keyHttpClient = new() { BaseAddress = httpClient.BaseAddress };
authenticationHeaderValue = keyHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", keyValuePair.Key);
if (authenticationHeaderValue.Parameter != keyValuePair.Key)
throw new NotSupportedException();
foreach (int[] idCollection in keyValuePair.Value)
{
if (idCollection.Length != 2)
throw new NotSupportedException();
Delete(keyHttpClient, $"{basePage}/{project}", api, $"/workitems/{idCollection[0]}/comments/{idCollection[1]}?api-version=7.0-preview.3");
}
}
}
private static string GetDescription(FIBacklogMesa fiBacklogMesa, DateTime dateTime) =>
$"Req:{fiBacklogMesa.Req}; Submitted:{(dateTime == DateTime.MinValue ? fiBacklogMesa.Submitted : dateTime.ToString("d-MMM-yy"))}; Requestor:{fiBacklogMesa.Requestor}; AssignedTo:{fiBacklogMesa.AssignedTo}; SecondResource:{fiBacklogMesa.SecondResource}; Systems:{fiBacklogMesa.SystemS}; ";
private static void Update(HttpClient httpClient, string basePage, string api, string query, HttpContent httpContent)
{
#if CORE
#if Windows
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.PatchAsync(string.Concat(basePage, api, query), httpContent);
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
@ -398,6 +563,7 @@ public class ProcessData : IProcessData
JsonPatchDocument result = new();
if (userStoryWorkItemTask?.Result.Id is null)
throw new NotSupportedException();
int priority = GetPriority(fiBacklogMesa);
string title = $"{fiBacklogMesa.Req} - {fiBacklogMesa.Subject}";
if (title.Length > 128)
title = title.Substring(0, 127);
@ -409,13 +575,12 @@ public class ProcessData : IProcessData
tags.RemoveAt(tags.Count - 1);
}
AddPatch(result, "/fields/System.IterationPath", project);
AddPatch(result, "/fields/Microsoft.VSTS.Common.Priority", priority);
if (!string.IsNullOrEmpty(fiBacklogMesa.Definition))
AddPatch(result, "/fields/System.Description", fiBacklogMesa.Definition);
string? state = GetMappedState(fiBacklogMesa);
if (!string.IsNullOrEmpty(state))
AddPatch(result, "/fields/System.State", state);
if (int.TryParse(fiBacklogMesa.Priority.Substring(0, 1), out int priority) && priority != 0)
AddPatch(result, "/fields/Microsoft.VSTS.Common.Priority", priority);
if (!string.IsNullOrEmpty(fiBacklogMesa.EstEffortDays) && int.TryParse(fiBacklogMesa.EstEffortDays, out int estEffortDays) && estEffortDays != 0)
AddPatch(result, "/fields/Microsoft.VSTS.Scheduling.Effort", estEffortDays);
DateTime? dateTime = GetCommitDate(fiBacklogMesa);
@ -518,7 +683,21 @@ public class ProcessData : IProcessData
}
}
private void Parse(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection, HttpClient httpClient, string basePage, string api, string query, WorkItemTrackingHttpClient workItemTrackingHttpClient, string project, ReadOnlyDictionary<string, string> assignedToNameToUser, ReadOnlyDictionary<string, string> requestorNameToUser, string json)
private void Parse(IFileRead fileRead,
Logistics logistics,
List<FileInfo> fileInfoCollection,
HttpClient httpClient,
string basePage,
string api,
string query,
WorkItemTrackingHttpClient workItemTrackingHttpClient,
string project,
ReadOnlyDictionary<string, string> assignedToNameToEncodedPAT,
ReadOnlyDictionary<string, string> assignedToNameToUser,
ReadOnlyDictionary<string, string> requestorNameToUser,
string json,
bool forceUpdatedBy,
bool forceDeleteUpdatedBy)
{
if (fileRead is null)
throw new NullReferenceException();
@ -527,6 +706,7 @@ public class ProcessData : IProcessData
if (fileInfoCollection is null)
throw new NullReferenceException();
int counter = 0;
string forceUpdatedByComment = "Force updated by";
string? directory = Path.GetDirectoryName(fileRead.ReportFullPath) ?? throw new Exception();
string[] checkFiles = Directory.GetFiles(directory, "*.csv", SearchOption.TopDirectoryOnly);
if (checkFiles.Any())
@ -535,10 +715,19 @@ public class ProcessData : IProcessData
{
string ids = GetIds(httpClient, basePage, api, query);
Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa = GetFIBacklogMesaCollection(json);
Value[] workItems = string.IsNullOrEmpty(ids) ? Array.Empty<Value>() : GetWorkItems(httpClient, basePage, api, ids);
Value[] workItems = string.IsNullOrEmpty(ids) ? Array.Empty<Value>() : GetWorkItems(fileRead, httpClient, basePage, api, ids);
int count = keyToFIBacklogMesa.Count;
ReadOnlyCollection<ValueWithReq> valueWithReqCollection = GetValueWithReqCollection(workItems);
SetSyncTag(workItemTrackingHttpClient, requestorNameToUser, keyToFIBacklogMesa, valueWithReqCollection);
ReadOnlyDictionary<string, List<int>> updateCollection = GetForceUpdatedByCollection(assignedToNameToEncodedPAT, assignedToNameToUser, keyToFIBacklogMesa, valueWithReqCollection);
if (updateCollection.Count > 0 && forceUpdatedBy)
ForceUpdatedBy(httpClient, basePage, project, api, forceUpdatedByComment, updateCollection);
if (forceDeleteUpdatedBy)
{
ReadOnlyDictionary<string, List<int[]>> deleteCollection = GetForceUpdatedByCollectionDelete(forceUpdatedByComment, assignedToNameToEncodedPAT, assignedToNameToUser, keyToFIBacklogMesa, valueWithReqCollection);
if (deleteCollection.Count > 0 && forceDeleteUpdatedBy)
ForceUpdatedByDelete(httpClient, basePage, project, api, deleteCollection);
}
ReadOnlyCollection<ValueWithReq> extra = RemoveFrom(keyToFIBacklogMesa, valueWithReqCollection);
if (count != extra.Count)
{ }