/// <summary> /// Check if the work item is already migrated /// This function also sets the context for the current work item /// </summary> /// <param name="hid">List of criteria to match</param> /// <returns>true if migrated</returns> public bool IsWIMigrated(ArrayList checkList) { try { // Add project name and work item type names to the check list! checkList.Add(new WorkItemNameValueRelation("System.WorkItemType", m_witName)); checkList.Add(new WorkItemNameValueRelation("System.AreaPath", m_vstsConnection.projectName, WorkItemNameValueRelation.RelationShipType.UNDER)); m_currentWorkItem = VSTSUtil.FindWorkItem(m_vstsConnection, checkList); if (m_currentWorkItem != null) { object statusObj = m_currentWorkItem["Migration Status"]; if (statusObj != null) { Debug.Assert(statusObj is string); if (String.Equals(statusObj as string, "Done", StringComparison.Ordinal)) { return(true); } } } } finally { } return(false); }
public VSTSConnection(XmlNode configuration) { string bisUri = configuration.SelectSingleNode("URI").InnerText.Trim(); string projectName = configuration.SelectSingleNode("ProjectName").InnerText.Trim(); Initialize(bisUri, projectName); // Ensure that the current user is part of Service Accounts VSTSUtil.IsCurrentUserInServiceAccount(bisUri); }
/// <summary> /// Another wrapper around find work item /// </summary> /// <param name="checkList"></param> /// <returns></returns> public WorkItem FindWorkItem(ArrayList checkList) { // Add project name and work item type names to the check list! checkList.Add(new WorkItemNameValueRelation("System.WorkItemType", m_witName)); checkList.Add(new WorkItemNameValueRelation("System.AreaPath", m_vstsConnection.projectName, WorkItemNameValueRelation.RelationShipType.UNDER)); WorkItem tempWi = VSTSUtil.FindWorkItem(m_vstsConnection, checkList); return(tempWi); }
/// <summary> /// Get the Currituck field name from the Field Map /// </summary> /// <param name="from">Source field name</param> /// <param name="fvalue">Field value if changed because of some value map</param> /// <returns>Currituck Field Name</returns> private string GetMappedFieldName(string fName, ref object fValue) { string toval = string.Empty; FieldMapsFieldMap nmap = (FieldMapsFieldMap)m_fieldMappings[fName]; if (nmap != null) { FieldMapsFieldMapValueMaps fvmaps = null; toval = nmap.to; // check if there are value mappings for this field! if (nmap.ValueMaps != null) { fvmaps = nmap.ValueMaps; if (fvmaps.refer != null && !TFStringComparer.XmlAttributeValue.Equals(fvmaps.refer, "UserMap")) { fvmaps = (FieldMapsFieldMapValueMaps)m_valueMappings[nmap.ValueMaps.refer]; } if (TFStringComparer.XmlAttributeValue.Equals(fvmaps.refer, "UserMap")) { string currUser = fValue.ToString(); string toUser = currUser; if (m_userMappings != null && m_userMappings.UserMap != null) { foreach (UserMappingsUserMap userMap in m_userMappings.UserMap) { if (TFStringComparer.UserName.Equals(userMap.From, currUser)) { toUser = userMap.To; break; } } } if (m_vstsConnection.store.UserDisplayMode == UserDisplayMode.AccountName) { // for alias mode, no resolution is ever required fValue = toUser; } else { // resolve the user for Display Name mode if (VSTSUtil.ResolvedUsers.Contains(toUser)) { fValue = VSTSUtil.ResolvedUsers[toUser]; } else { Identity userIdentity = VSTSUtil.ResolveUser(m_vstsConnection, toUser); if (userIdentity == null) { CommonConstants.UnresolvedUsers.Append(string.Concat(toUser, ", ")); VSTSUtil.ResolvedUsers.Add(toUser, toUser); fValue = toUser; } else { VSTSUtil.ResolvedUsers.Add(toUser, userIdentity.DisplayName); fValue = userIdentity.DisplayName; } } } } else if (fvmaps.ValueMap != null) { int score = 0; ValueMap bestMatch = null; string fldVal = fValue.ToString(); foreach (ValueMap fvmap in fvmaps.ValueMap) { if (fldVal.StartsWith(fvmap.from, StringComparison.OrdinalIgnoreCase)) { // found one candidate if (fvmap.from.Length > score) { score = fvmap.from.Length; bestMatch = fvmap; } } } if (score > 0) { fValue = String.Concat(bestMatch.to, fValue.ToString().Substring(bestMatch.from.Length)); } } } // If it is Area Path, calculate the Area ID and update that field if (TFStringComparer.WorkItemFieldFriendlyName.Equals(nmap.to, VSTSConstants.AreaPathField) || TFStringComparer.WorkItemFieldFriendlyName.Equals(nmap.to, VSTSConstants.IterationPathField)) { Node.TreeType type = Node.TreeType.Area; if (TFStringComparer.WorkItemFieldFriendlyName.Equals(nmap.to, VSTSConstants.AreaPathField)) { toval = VSTSConstants.AreaIdField; type = Node.TreeType.Area; } else { toval = VSTSConstants.IterationIdField; type = Node.TreeType.Iteration; } Node tmpNode = null; string fValueStr = fValue.ToString().Trim(); if (fValueStr.Length != 0) { tmpNode = VSTSUtil.FindNodeInSubTree(m_vstsConnection, fValueStr, type); } if (tmpNode != null) { if (type == Node.TreeType.Area) { // update the current work item structure with this area id m_vstsWorkItem.areaId = tmpNode.Id; } fValue = tmpNode.Id; } else { if (fvmaps != null && fvmaps.defaultValue != null && fvmaps.defaultValue.Trim().Length > 0) { string defaultValueStr = fvmaps.defaultValue.Trim(); tmpNode = VSTSUtil.FindNodeInSubTree(m_vstsConnection, defaultValueStr, type); if (tmpNode != null) { Logger.Write(LogSource.WorkItemTracking, TraceLevel.Warning, UtilityMethods.Format( "Using: '{0}' instead of: '{1}' for: '{2}'", defaultValueStr, fValueStr, nmap.to)); ConverterMain.MigrationReport.WriteIssue("MigrationCheck", ReportIssueType.Info, UtilityMethods.Format( VSTSResource.UsingDefaultValue, defaultValueStr, fValueStr, nmap.to)); fValue = tmpNode.Id; } else { string errMsg = UtilityMethods.Format( VSTSResource.InvalidDefaultValueMap, m_sourceWorkItemId, nmap.to, fValueStr, m_fieldMapFile); throw new ConverterException(errMsg); } } else { string errMsg = UtilityMethods.Format( VSTSResource.NullDefaultValueMap, m_sourceWorkItemId, nmap.to, fValueStr, m_fieldMapFile); throw new ConverterException(errMsg); } } } } return(toval); }
/// <summary> /// Add/Update the web service package with the given field and value /// </summary> /// <param name="webServiceHelper">Web Service package</param> /// <param name="fName">Field Name</param> /// <param name="fValue">Field Value</param> internal void UpdateWorkItemField(WSHelper webServiceHelper, string fName, object fValue) { if (fValue == null || fValue.ToString().Trim().Length == 0) { fValue = String.Empty; } // apply field map and value map string toFldName = GetMappedFieldName(fName, ref fValue); if (string.IsNullOrEmpty(toFldName)) { Logger.Write(LogSource.WorkItemTracking, TraceLevel.Info, "No field map for work item [{0}], field [{1}].. Dropping", m_sourceWorkItemId, fName); return; } Field fld = m_wi.Fields[toFldName]; if (fld != null) { if (VSTSConstants.SkipFields.ContainsKey(fld.ReferenceName)) { Logger.Write(LogSource.WorkItemTracking, TraceLevel.Info, "Field {0} is being skipped as it cannot be modified using web service", fName); return; } switch (fld.FieldDefinition.FieldType) { // html type fields case CurClient.FieldType.Html: case CurClient.FieldType.History: // apply html formatting on this // and add to InsertText webServiceHelper.AddDescriptiveField(fld.ReferenceName, VSTSUtil.ConvertTextToHtml(fValue.ToString()), true); break; case CurClient.FieldType.PlainText: // add to InsertText webServiceHelper.AddDescriptiveField(fld.ReferenceName, fValue.ToString(), false); break; case CurClient.FieldType.DateTime: DateTime value; string dateValue = String.Empty; if (fValue is DateTime) { value = (DateTime)fValue; dateValue = CommonConstants.ConvertDateToString(value); } else { if (!String.IsNullOrEmpty(fValue.ToString())) { Logger.Write(LogSource.WorkItemTracking, TraceLevel.Warning, "Value of field {0} is not of type DateTime", fld.Name, fValue.ToString()); if (DateTime.TryParse(fValue.ToString(), out value) == true) { dateValue = CommonConstants.ConvertDateToString(value); } } } webServiceHelper.AddColumn(fld.ReferenceName, dateValue); break; case CurClient.FieldType.String: string fStrVal = fValue.ToString(); string fTruncatedValue = fStrVal; if (fStrVal.Length > VSTSConstants.MaxStringFieldLength) { // put the original value in history field webServiceHelper.AddDescriptiveField(VSTSConstants.HistoryFieldRefName, String.Concat(toFldName, ": ", fStrVal), true); // Fix for 58661 CQConverter: The truncation of string fields should // be reported in the migration report. string warnMsg = string.Format(VSTSResource.WarningFieldTruncated, toFldName, fStrVal, fTruncatedValue); ConverterMain.MigrationReport.WriteIssue(String.Empty, warnMsg, m_sourceWorkItemId.ToString(CultureInfo.InvariantCulture), string.Empty, IssueGroup.Wi.ToString(), ReportIssueType.Warning, null); // truncate the field value fTruncatedValue = fStrVal.Substring(0, VSTSConstants.MaxStringFieldLength); Logger.Write(LogSource.WorkItemTracking, TraceLevel.Warning, "Truncating field '{0}' value , From [{1}] to [{2}]", toFldName, fStrVal, fTruncatedValue); } webServiceHelper.AddColumn(fld.ReferenceName, fTruncatedValue); break; default: webServiceHelper.AddColumn(fld.ReferenceName, fValue.ToString()); break; } } }