private JsonPatchOperation GetAddHyperlinkWithCommentOperation(IList <WorkItem> targetWorkItems, WorkItemMigrationState state, int sourceId, int targetId, WorkItem sourceWorkItem, ISet <string> enabledPhaseStatuses) { IList <WorkItemRelation> targetRelations = targetWorkItems.First(a => a.Id == targetId).Relations; foreach (WorkItemRelation targetRelation in targetRelations) { if (RelationHelpers.IsRelationHyperlinkToSourceWorkItem(context, targetRelation, sourceId)) { string hyperlink = context.WorkItemIdsUris[sourceId]; // only store the enabled phase statuses RevAndPhaseStatus newRevAndPhaseStatus = new RevAndPhaseStatus(); newRevAndPhaseStatus.Rev = sourceWorkItem.Rev.Value; newRevAndPhaseStatus.PhaseStatus = enabledPhaseStatuses; state.RevAndPhaseStatus = newRevAndPhaseStatus; // get the key even if its letter case is different but it matches otherwise string idKeyFromFields = targetRelation.Attributes.GetKeyIgnoringCase(Constants.RelationAttributeId); object attributeId = targetRelation.Attributes[idKeyFromFields]; JsonPatchOperation addHyperlinkWithCommentOperation = MigrationHelpers.GetHyperlinkAddOperation(hyperlink, newRevAndPhaseStatus.GetCommentRepresentation(), attributeId); return(addHyperlinkWithCommentOperation); } } throw new Exception($"Could not find hyperlink to source work item on target work item with id: {targetId}. Expected source work item id: {sourceId}"); }
private IDictionary <int, WorkItemRelation> GetTargetIdToHyperlinkToSourceRelationMapping(IList <WorkItem> targetWorkItems, IDictionary <int, WorkItemMigrationState> targetToWorkItemMigrationState) { Dictionary <int, WorkItemRelation> result = new Dictionary <int, WorkItemRelation>(); foreach (WorkItem targetWorkItem in targetWorkItems) { if (targetWorkItem.Relations == null) { throw new ValidationException($"Target work item with id: {targetWorkItem.Id} does not have any relations."); } foreach (WorkItemRelation relation in targetWorkItem.Relations) { //check for hyperlink to the source - used for incremental updates int sourceId = targetToWorkItemMigrationState[targetWorkItem.Id.Value].SourceId; int targetId = targetWorkItem.Id.Value; if (RelationHelpers.IsRelationHyperlinkToSourceWorkItem(ValidationContext, relation, sourceId)) { result.Add(targetId, relation); break; } } } return(result); }
private async Task VerifyRelationTypesExistsOnTarget(IValidationContext context) { var sourceRelationTypes = await WorkItemTrackingHelpers.GetRelationTypesAsync(context.SourceClient.WorkItemTrackingHttpClient); var targetRelationTypes = await WorkItemTrackingHelpers.GetRelationTypesAsync(context.TargetClient.WorkItemTrackingHttpClient); foreach (var relationType in sourceRelationTypes) { //retrieve relations which are of type workitemlink defined by attribute kvp {"usage", "workitemlink"} //exclude remote link types because they need to be converted into hyperlinks if (IsWorkItemLinkType(relationType)) { if (RelationHelpers.IsRemoteLinkType(relationType)) { context.RemoteLinkRelationTypes.Add(relationType.ReferenceName); } else { if (TargetHasRelationType(relationType, targetRelationTypes)) { context.ValidatedWorkItemLinkRelationTypes.Add(relationType.ReferenceName); } else { Logger.LogWarning(LogDestination.File, $"Target: Relation type {relationType.ReferenceName} does not exist"); } } } } }
private RevAndPhaseStatus GetRevAndPhaseStatus(WorkItem targetWorkItem, int sourceWorkItemId) { if (targetWorkItem.Relations != null) { foreach (WorkItemRelation relation in targetWorkItem.Relations) { if (RelationHelpers.IsRelationHyperlinkToSourceWorkItem(context, relation, sourceWorkItemId)) { // get the key even if its letter case is different but it matches otherwise string keyFromFields = relation.Attributes.GetKeyIgnoringCase(Constants.RelationAttributeComment); string relationRevAndPhaseStatusComment = relation.Attributes[keyFromFields].ToString(); RevAndPhaseStatus revAndPhaseStatus = new RevAndPhaseStatus(relationRevAndPhaseStatusComment); return(revAndPhaseStatus); } } } throw new Exception($"Could not find comment in relation hyperlink to source work item on target work item with id: {targetWorkItem.Id.Value}. Expected source work item id: {sourceWorkItemId}"); }
public async Task <IEnumerable <JsonPatchOperation> > Process(IMigrationContext migrationContext, IBatchMigrationContext batchContext, WorkItem sourceWorkItem, WorkItem targetWorkItem) { IList <JsonPatchOperation> jsonPatchOperations = new List <JsonPatchOperation>(); IEnumerable <WorkItemRelation> sourceRemoteLinks = sourceWorkItem.Relations?.Where(r => RelationHelpers.IsRemoteLinkType(migrationContext, r.Rel)); if (sourceRemoteLinks != null && sourceRemoteLinks.Any()) { foreach (WorkItemRelation sourceRemoteLink in sourceRemoteLinks) { string url = ConvertRemoteLinkToHyperlink(sourceRemoteLink.Url); WorkItemRelation targetRemoteLinkHyperlinkRelation = GetHyperlinkIfExistsOnTarget(targetWorkItem, url); if (targetRemoteLinkHyperlinkRelation != null) // is on target { JsonPatchOperation remoteLinkHyperlinkAddOperation = MigrationHelpers.GetRelationAddOperation(targetRemoteLinkHyperlinkRelation); jsonPatchOperations.Add(remoteLinkHyperlinkAddOperation); } else // is not on target { string comment = string.Empty; if (sourceRemoteLink.Attributes.ContainsKey(Constants.RelationAttributeComment)) { comment = $"{sourceRemoteLink.Attributes[Constants.RelationAttributeComment]}"; } WorkItemRelation newRemoteLinkHyperlinkRelation = new WorkItemRelation(); newRemoteLinkHyperlinkRelation.Rel = Constants.Hyperlink; newRemoteLinkHyperlinkRelation.Url = url; newRemoteLinkHyperlinkRelation.Attributes = new Dictionary <string, object>(); newRemoteLinkHyperlinkRelation.Attributes[Constants.RelationAttributeComment] = comment; JsonPatchOperation remoteLinkHyperlinkAddOperation = MigrationHelpers.GetRelationAddOperation(newRemoteLinkHyperlinkRelation); jsonPatchOperations.Add(remoteLinkHyperlinkAddOperation); } } } return(jsonPatchOperations); }