public async static Task <List <WorkItemRelationType> > GetRelationTypesAsync(WorkItemTrackingHttpClient client) { return(await RetryHelper.RetryAsync(async() => { return await client.GetRelationTypesAsync(); }, 5)); }
private static WorkItemLinkTypeCollection GetLinks(WorkItemTrackingHttpClient workItemStore) { var types = workItemStore.GetRelationTypesAsync().GetAwaiter().GetResult(); var d = new Dictionary <string, IList <WorkItemRelationType> >(StringComparer.OrdinalIgnoreCase); var d2 = new Dictionary <string, WorkItemLinkType>(StringComparer.OrdinalIgnoreCase); foreach (var type in types.Where(p => (string)p.Attributes["usage"] == "workItemLink")) { var m = ImmutableLinkTypeNameRegex.Match(type.ReferenceName); var linkRef = m.Groups["LinkTypeReferenceName"].Value; if (string.IsNullOrWhiteSpace(linkRef)) { linkRef = type.ReferenceName; } if (!d.ContainsKey(linkRef)) { d[linkRef] = new List <WorkItemRelationType>(); } d[linkRef].Add(type); if (!d2.ContainsKey(linkRef)) { d2[linkRef] = new WorkItemLinkType(linkRef); } } foreach (var kvp in d2) { var type = kvp.Value; var ends = d[kvp.Key]; type.IsDirectional = ends.All(p => (bool)p.Attributes["directional"]); type.IsActive = ends.All(p => (bool)p.Attributes["enabled"]); var forwardEnd = ends.Count == 1 && !type.IsDirectional ? ends[0] : ends.SingleOrDefault(p => p.ReferenceName.EndsWith("Forward")); if (!forwardEnd.ReferenceName.EndsWith("Forward")) { forwardEnd.ReferenceName += "-Forward"; } type.SetForwardEnd(new WorkItemLinkTypeEnd(forwardEnd) { IsForwardLink = true, LinkType = type }); type.SetReverseEnd( type.IsDirectional ? new WorkItemLinkTypeEnd( ends.SingleOrDefault(p => p.ReferenceName.EndsWith("Reverse"))) { LinkType = type } : type.ForwardEnd); // The REST API does not return the ID of the link type. For well-known system links, we can populate the ID value if (CoreLinkTypeReferenceNames.All.Contains(type.ReferenceName, StringComparer.OrdinalIgnoreCase)) { int forwardId = 0, reverseId = 0; if (CoreLinkTypeReferenceNames.Hierarchy.Equals(type.ReferenceName, StringComparison.OrdinalIgnoreCase)) { // The forward should be Child, but the ID used in CoreLinkTypes is -2, should be 2 forwardId = CoreLinkTypes.Child; reverseId = CoreLinkTypes.Parent; } else if (CoreLinkTypeReferenceNames.Related.Equals(type.ReferenceName, StringComparison.OrdinalIgnoreCase)) { forwardId = reverseId = CoreLinkTypes.Related; } else if (CoreLinkTypeReferenceNames.Dependency.Equals(type.ReferenceName, StringComparison.OrdinalIgnoreCase)) { forwardId = CoreLinkTypes.Successor; reverseId = CoreLinkTypes.Predecessor; } ((WorkItemLinkTypeEnd)type.ForwardEnd).Id = -forwardId; ((WorkItemLinkTypeEnd)type.ReverseEnd).Id = -reverseId; } } return(new WorkItemLinkTypeCollection(d2.Values.OfType <IWorkItemLinkType>().ToList())); }