} // end of ValidateSchemaMapOnCQ /// <summary> /// Validates the Field Map on CQ for a Entity Type /// </summary> /// <param name="entityDef">Handle to Entity Definition</param> /// <param name="fldMaps">Deserialized Field Map data</param> /// <returns>true if successful, false in case of some error</returns> private static void ValidateFieldMapOnCQ(OAdEntityDef entityDef, FieldMapsFieldMap[] fldMaps, string fieldMapFile) { string entityName = CQWrapper.GetEntityDefName(entityDef); object[] cqFields = (object[])CQWrapper.GetFieldDefNames(entityDef); // prepare the list of fields from the current entity type Dictionary <string, bool> cqFieldsList = new Dictionary <string, bool>(TFStringComparer.OrdinalIgnoreCase); foreach (string cqFld in cqFields) { cqFieldsList.Add(cqFld, false); } Display.StartProgressDisplay(UtilityMethods.Format(CQResource.CQ_VALIDATE_FLD_MAP, fieldMapFile)); try { StringBuilder invalidFields = new StringBuilder(); foreach (FieldMapsFieldMap fldMap in fldMaps) { if (fldMap.exclude != null && !TFStringComparer.XmlAttributeValue.Equals(fldMap.exclude, "true") && !CQConstants.CQInternalFields.ContainsKey(fldMap.from)) { // this is to be included in the selected fields for migration if (!cqFieldsList.ContainsKey(fldMap.from)) { if (invalidFields.Length > 0) { invalidFields.Append(", "); } invalidFields.Append(fldMap.from); } } } if (invalidFields.Length > 0) { string errMsg = UtilityMethods.Format(CQResource.CQ_FLD_NOT_EXIST, Path.GetFileName(fieldMapFile), invalidFields.ToString(), entityName); PostMigrationReport.WriteIssue(null, null, RepStatus.Failed, ReportIssueType.Critical, String.Empty, entityName, IssueGroup.Witd, errMsg); throw new ConverterException(errMsg); } } finally { Display.StopProgressDisplay(); Display.NewLine(); } } // end of ValidateFieldMapOnCQ
} // end of MigrateData /// <summary> /// Add the failure to Migration report for the failed work item /// </summary> /// <param name="msgId"></param> /// <param name="id"></param> /// <param name="ex"></param> /// <param name="cqEntityName"></param> /// <param name="currituckWitName"></param> /// <param name="exitOnError"></param> /// <returns></returns> internal static void ReportWorkItemFailure(string msg, string id, string cqEntityName, string currituckWitName, bool exitOnError) { if (!FailedRecords.ContainsKey(id)) { Logger.Write(LogSource.CQ, TraceLevel.Error, msg); PostMigrationReport.WriteIssue(cqEntityName, currituckWitName, ReportStatisticsStatisicsDetails.MigrationStatus.Failed, (exitOnError == true ? ReportIssueType.Critical : ReportIssueType.Error), String.Empty, id, IssueGroup.Wi, msg); Display.DisplayError(msg); FailedRecords.Add(id, String.Empty); } }
} // end of CQEntityRec CTor /// <summary> /// Populate the current record from CQ if its not already in Currituck /// and also process all its references (recursively), Links, History and Attachments /// Else just sets the currituck id for future reference /// </summary> public bool Populate() { bool partiallyMigrated = false; // first check if it exists in the memory cache CQEntity currentEntityRecords = m_cqParams.entityRecords[m_entityName]; CQEntityRec lookupEntity = currentEntityRecords.FindEntityRec(m_entityName, m_dbid); if (lookupEntity != null) { // record already populated.. Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Already populated record '{0}' for Entity '{1}', DBID:{2}", lookupEntity.SourceId, lookupEntity.EntityName, lookupEntity.DBID); return(true); } m_CQEntity = CQWrapper.GetEntityByDbId(m_cqParams.cqSession, m_entityName, m_dbid); // get the source id m_sourceId = CQWrapper.GetEntityDisplayName(m_CQEntity); Logger.Write(LogSource.CQ, TraceLevel.Verbose, UtilityMethods.Format(CQResource.CQ_PROCESSING_REC, m_sourceId)); // check if it exist in currituck using static API VSTSWorkItemHelper wiHelper = (VSTSWorkItemHelper)m_MySchemaMap.vstsHelper; ArrayList checkList = new ArrayList(); checkList.Add(new WorkItemNameValueRelation(CommonConstants.VSTSSrcIdField, m_sourceId)); checkList.Add(new WorkItemNameValueRelation(CommonConstants.VSTSSrcDbField, m_cqParams.uniqueInstId)); wiHelper = (VSTSWorkItemHelper)m_MySchemaMap.vstsHelper; if (wiHelper.IsWIMigrated(checkList) == true) { // need not to load the data from CQ.. // just set the currituck id // not going to update this bug from CQ->Currituck even // if it is updated.. just get out from here as my population is done // with minimal required stuff string warningMsg = UtilityMethods.Format(CQResource.CQ_REC_MIGRATED, m_sourceId); Logger.Write(LogSource.CQ, TraceLevel.Warning, warningMsg); PostMigrationReport.WriteIssue(m_MySchemaMap.entity, m_MySchemaMap.WIT, Stats.MigrationStatus.Skipped, ReportIssueType.Warning, String.Empty, m_sourceId, IssueGroup.Wi, warningMsg); m_WITId = wiHelper.WorkItemId; //compact current object CompactMe(); return(true); } else if (wiHelper.IsCurrentWorkItemValid() == true) { // work item is already there.. partially migrated partiallyMigrated = true; } #if DEBUG CommonConstants.NoOfBugs++; #endif // create the required data structures m_imWorkItem = new InMemoryWorkItem(); string fldName; OAdEntityDef curEntityDef = CQWrapper.GetEntityDef(m_cqParams.cqSession, m_entityName); Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Adding record for Entity {0}, Record {1}", m_entityName, CQWrapper.GetEntityDisplayName(m_CQEntity)); object[] fields = (object[])CQWrapper.GetEntityFieldNames(m_CQEntity); foreach (object fld in fields) { fldName = (string)fld; if (CQConstants.InternalFieldTypes.ContainsKey(fldName)) { // these are internal clearquest fields // we dont want to migrate these Logger.Write(LogSource.CQ, TraceLevel.Info, "Skipping Internal Field '{0}' while migrating data for entity {1}", fldName, m_entityName); continue; } { // process this field only if it exists in the "from" side of Field Map OAdFieldInfo fldInfo = CQWrapper.GetEntityFieldValue(m_CQEntity, fldName); int cqFieldType = CQWrapper.GetFieldType(fldInfo); switch (cqFieldType) { case CQConstants.FIELD_ID: case CQConstants.FIELD_SHORT_STRING: case CQConstants.FIELD_INT: { string fldValue = CQWrapper.GetFieldValue(fldInfo); if (fldValue != null) { m_imWorkItem.InitialView.Add(fldName, fldValue); } } break; case CQConstants.FIELD_MULTILINE_STRING: { string fldValue = CQWrapper.GetFieldValue(fldInfo); if (currentEntityRecords.Entity == null) { // build entity to get the list of allowed/suggested values currentEntityRecords.Entity = CQWrapper.BuildEntity(m_cqParams.cqSession, currentEntityRecords.EntityName); } object[] choices = (object[])CQWrapper.GetFieldChoiceList(currentEntityRecords.Entity, fldName); if (choices != null && choices.Length > 0) { // Multi Line String with List of Allowed/Suggested Values.. replace all '\n' with comma // fix for bug# 429098 if (fldValue != null) { fldValue = fldValue.Replace("\n", ","); } } /* no conversion shall be required.. bug# 20219 - shall be rendered in HTML as it is * // hack for Notes_Log & Description field.. Shall be converted to HTML (bug#429032) * if (fldName.Equals("Notes_Log", StringComparison.OrdinalIgnoreCase) || * fldName.Equals("Description", StringComparison.OrdinalIgnoreCase)) * { * fldValue = VSTSUtil.ConvertTextToHtml(fldValue); * } */ m_imWorkItem.InitialView.Add(fldName, fldValue); } break; case CQConstants.FIELD_DATE_TIME: { string fldValue = CQWrapper.GetFieldValue(fldInfo); if (fldValue != null) { // the time returned from CQ API is the local time.. DateTime fldVal = DateTime.Parse(fldValue, CultureInfo.CurrentCulture); //convert it in UTC DateTime utcTime = CQConverterUtil.ConvertLocalToUTC(fldVal); Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Field [{0}], CQ Time [{1}], UTC Time [{2}]", fldName, fldVal.ToString(), utcTime.ToString()); m_imWorkItem.InitialView.Add(fldName, utcTime); } else { Logger.Write(LogSource.CQ, TraceLevel.Info, "Got null value for field {0}", fldName); } } break; case CQConstants.FIELD_REFERENCE: { // get the current entity def handle OAdEntityDef refEntityDef = CQWrapper.GetFieldReferenceEntityDef(curEntityDef, fldName); string refEntityName = CQWrapper.GetEntityDefName(refEntityDef); // special handling for users.. add the user field value also.. // we dont want to create a link in this case.. // just add the field value pair in IMWorkItem.. and // user map will be applied while saving if (TFStringComparer.WorkItemType.Equals(refEntityName, "users")) { if (CQWrapper.GetFieldValueStatus(fldInfo) == (int)CQConstants.FieldStatus.HAS_VALUE) { // single value required string refFldVal = CQWrapper.GetFieldValue(fldInfo); m_imWorkItem.InitialView.Add(fldName, refFldVal); } } else if (m_cqParams.allowedEntities.ContainsKey(refEntityName)) { int valueStatus = CQWrapper.GetFieldValueStatus(fldInfo); Logger.WriteIf((valueStatus != (int)CQConstants.FieldStatus.HAS_VALUE), LogSource.CQ, TraceLevel.Info, "No Value for Referenced field {0} in Entity {1}", refEntityName, m_entityName); if (valueStatus == (int)CQConstants.FieldStatus.HAS_VALUE) { // single value required string refFldVal = CQWrapper.GetFieldValue(fldInfo); if (String.Equals(refFldVal, SourceId, StringComparison.Ordinal)) { // reference to self.. cannot have a link on to self string warningMsg = UtilityMethods.Format(CQResource.CQ_SELF_REFERENCE, SourceId, EntityName, fldName); Logger.Write(LogSource.CQ, TraceLevel.Warning, warningMsg); PostMigrationReport.WriteIssue(m_MySchemaMap.entity, m_MySchemaMap.WIT, Stats.MigrationStatus.Warning, ReportIssueType.Warning, String.Empty, m_sourceId, IssueGroup.Wi, warningMsg ); } else { m_referencedEntities.Add(new LinkRecord(refEntityName, refFldVal)); } } } } break; case CQConstants.FIELD_REFERENCE_LIST: { // get the current entity def handle OAdEntityDef refEntityDef = CQWrapper.GetFieldReferenceEntityDef(curEntityDef, fldName); string refEntityName = CQWrapper.GetEntityDefName(refEntityDef); // special handling for user list // we dont want to create a link in this case.. // concatenate all the user names separated by comma // NO USER MAP WILL BE APPLIED WHILE SAVING (bug#400276) if (TFStringComparer.WorkItemType.Equals(refEntityName, "users")) { if (CQWrapper.GetFieldValueStatus(fldInfo) == (int)CQConstants.FieldStatus.HAS_VALUE) { object[] refFldValues = CQWrapper.GetFieldValueAsList(fldInfo); StringBuilder userList = new StringBuilder(); for (int valueIndex = 0; valueIndex < refFldValues.Length; valueIndex++) { object refFldObj = refFldValues[valueIndex]; if (valueIndex > 0) { userList.Append(","); } userList.Append((string)refFldObj); } m_imWorkItem.InitialView.Add(fldName, userList.ToString()); } } else if (m_cqParams.allowedEntities.ContainsKey(refEntityName)) { int valueStatus = CQWrapper.GetFieldValueStatus(fldInfo); Logger.WriteIf((valueStatus != (int)CQConstants.FieldStatus.HAS_VALUE), LogSource.CQ, TraceLevel.Info, "No Value for Referenced field {0} in Entity {1}", fldName, m_entityName); if (valueStatus == (int)CQConstants.FieldStatus.HAS_VALUE) { // value list expected object[] refFldValues = CQWrapper.GetFieldValueAsList(fldInfo); foreach (object refFldObj in refFldValues) { string refFldVal = (string)refFldObj; if (String.Equals(refFldVal, SourceId, StringComparison.Ordinal)) { // reference to self.. cannot have a link on to self string warningMsg = UtilityMethods.Format(CQResource.CQ_SELF_REFERENCE, SourceId, EntityName, fldName); Logger.Write(LogSource.CQ, TraceLevel.Warning, warningMsg); PostMigrationReport.WriteIssue(m_MySchemaMap.entity, m_MySchemaMap.WIT, Stats.MigrationStatus.Warning, ReportIssueType.Warning, String.Empty, m_sourceId, IssueGroup.Wi, warningMsg); } else { m_referencedEntities.Add(new LinkRecord(refEntityName, refFldVal)); } } } } } break; case CQConstants.FIELD_ATTACHMENT_LIST: case CQConstants.FIELD_STATE: case CQConstants.FIELD_JOURNAL: case CQConstants.FIELD_DBID: case CQConstants.FIELD_STATETYPE: case CQConstants.FIELD_RECORDTYPE: Logger.Write(LogSource.CQ, TraceLevel.Info, "Skipping the Field migration for Internal Field Type '{0}'", cqFieldType); // not migrating these fields as they are CQ internal fields continue; default: Logger.Write(LogSource.CQ, TraceLevel.Info, "Skipping the Field migration for Unkknown Field Type '{0}'", cqFieldType); break; } } } // end of foreachfields // add the source id and db separately m_imWorkItem.InitialView.Add(CommonConstants.VSTSSrcIdField, m_sourceId); m_imWorkItem.InitialView.Add(CommonConstants.VSTSSrcDbField, m_cqParams.uniqueInstId); // use vstshelper to migrate the data wiHelper = (VSTSWorkItemHelper)m_MySchemaMap.vstsHelper; wiHelper.IsWIMigrated(checkList); // get attachments in the imworkitem ProcessAttachments(); // history processing will use same imWorkItem for first history info // and create other history indexes int migratedHistory = 0; if (wiHelper.IsCurrentWorkItemValid()) { migratedHistory = wiHelper.GetCurrentWorkItemHistoryCount(); if (migratedHistory > 0) { // We are going for incremental migration. And as we stuff first history item of a CQBug // into InitialView itself, actual no. of migrated history is one more than the value of // the "Migration Status" field. So increment by one. ++migratedHistory; } } ArrayList historyItems = ProcessHistory(m_imWorkItem.InitialView, migratedHistory); Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Dumping initial view for {0}", m_sourceId); foreach (object key in m_imWorkItem.InitialView.Keys) { Logger.Write(LogSource.CQ, TraceLevel.Verbose, "{0} - {1}", key, m_imWorkItem.InitialView[key]); } bool initialViewStatus = true; try { if (!partiallyMigrated) { // if some history items or links are left to be migrated.. leave the bug as opened.. if (historyItems.Count > 0 || m_referencedEntities.Count > 0) { Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Creating initial view of {0} .. {1} Histories, {2} Links pending", SourceId, historyItems.Count, m_referencedEntities.Count); // create the record and keep it open for history editing initialViewStatus = wiHelper.CreateInitialViewOfWorkItem(m_sourceId, m_imWorkItem, false); } else { Logger.Write(LogSource.CQ, TraceLevel.Verbose, "Creating initial view of {0}", SourceId); // create all the entries in the record and set the status to done initialViewStatus = wiHelper.CreateInitialViewOfWorkItem(m_sourceId, m_imWorkItem, true); } } } catch (Exception ex) { // creation of work item failed string errMsg = UtilityMethods.Format(CQResource.CQ_WI_CREATION_FAILED, SourceId, ex.Message); CQConverter.ReportWorkItemFailure(errMsg, SourceId, m_MySchemaMap.entity, m_MySchemaMap.WIT, m_cqParams.exitOnError); if (m_cqParams.exitOnError == true) { throw new ConverterException(errMsg); } else { // continue with another work item // need to skip this work item.. m_WITId = -1; CompactMe(); return(false); } } finally { } // get back currituck id and store in this m_WITId = wiHelper.WorkItemId; // store the handle of work item to restore the state of work item helper back to // working work item which may get changed because of processing links recursively object workItem = wiHelper.GetCurrentWorkItem(); // before processing history, clean out attachments.. only if its already migrated if (wiHelper.GetCurrentWorkItemAttachmentsCount() == m_imWorkItem.Attachments.Count) { m_imWorkItem.Attachments.Clear(); } // add all the links now so that they go as part of history bool refRecordStatus = true; foreach (LinkRecord linkRec in m_referencedEntities) { if (AddReferenceRecord(linkRec) == false) { refRecordStatus = false; // once false always false } } // process duplicate records if (ProcessDuplicates(m_cqParams) == false) { refRecordStatus = false; } bool writeHistoryPassed = true; wiHelper.SetCurrentWorkItem(workItem); if (historyItems.Count > 0 || m_imWorkItem.Links.Count > 0 || m_imWorkItem.Attachments.Count > 0) { m_imWorkItem.HistoryItems = historyItems; try { writeHistoryPassed = wiHelper.WriteHistoryItems(m_sourceId, m_imWorkItem, refRecordStatus && initialViewStatus); if (!writeHistoryPassed) { // Bug#59861: In the case of the partially migrated bug, // converter says all bugs migrated successfully in // summary, but in error section it says one bug failed // due to attachment size issue. This issue has already // been written to the report. Just need to update the // statistics info. PostMigrationReport.WriteIssue(m_MySchemaMap.entity, m_MySchemaMap.WIT, Stats.MigrationStatus.Failed, ReportIssueType.Info, null, m_sourceId, IssueGroup.Wi, null); } // set the bug migration status to done only if there were no // problems with initial view and any of the references if ((!writeHistoryPassed || !refRecordStatus || !initialViewStatus) && m_cqParams.exitOnError) { // stop processing more records CompactMe(); return(false); } } catch (Exception ex) { // creation of history failed string errMsg = UtilityMethods.Format(CQResource.CQ_WI_MIG_FAILED, SourceId, ex.Message); CQConverter.ReportWorkItemFailure(errMsg, SourceId, m_MySchemaMap.entity, m_MySchemaMap.WIT, m_cqParams.exitOnError); if (m_cqParams.exitOnError == true) { throw new ConverterException(errMsg); } else { // continue with another work item.. reporting this failure CompactMe(); return(false); } } // end of catch finally { } } // end of history items processing // add to pass count ConverterMain.MigrationReport.Statistics.NumberOfItems++; // add to per work item type section if (writeHistoryPassed) { PostMigrationReport.WriteIssue(m_MySchemaMap.entity, m_MySchemaMap.WIT, Stats.MigrationStatus.Passed, ReportIssueType.Info, null, m_sourceId, IssueGroup.Wi, null); } //compact current object CompactMe(); return(true); } // end of Populate()
/// <summary> /// This method validates that the given work item type /// contains WITD/WORKITEMTYPE node and "name" attribute /// matches the entityNamematches /// </summary> /// <param name="entityName">Entity Name</param> /// <param name="witdFileName">WITD file name</param> internal static void ValidateWorkItemType( string entityName, string witdFileName, string schemaMapFile) { // verify if the xml file exist and read permission is there UtilityMethods.ValidateFile(witdFileName, schemaMapFile); // open the xml file and look for WorkItemType node XmlDocument witdDoc; try { witdDoc = UtilityMethods.LoadFileAsXmlDocument(witdFileName); } catch (XmlException xmlEx) { // some error in loading file.. malformed xml // no WORKITEMTYPE element found.. invalid xml string errMsg = UtilityMethods.Format( VSTSResource.VstsInvalidXmlFile, witdFileName, schemaMapFile, xmlEx.Message, xmlEx.LineNumber, xmlEx.LinePosition); PostMigrationReport.WriteIssue(null, null, ReportStatisticsStatisicsDetails.MigrationStatus.Failed, ReportIssueType.Critical, String.Empty, entityName, IssueGroup.Config, errMsg); Logger.Write(LogSource.WorkItemTracking, TraceLevel.Error, errMsg); throw new ConverterException(errMsg); } XmlNamespaceManager nsm = new XmlNamespaceManager(witdDoc.NameTable); nsm.AddNamespace("CURR", Common.CommonConstants.WITDTypesNamespace); string tagWitdWithNS = "//CURR:WITD"; string tagWitdWithoutNS = "/WITD"; string tagWitWithNS = "//CURR:WORKITEMTYPE"; string tagWitWithoutNS = "WORKITEMTYPE"; // try with the namespace prefix XmlNode witdNode = witdDoc.SelectSingleNode(tagWitdWithNS, nsm); if (witdNode == null) { // no node found with this namespace definition.. try without namespace witdNode = witdDoc.SelectSingleNode(tagWitdWithoutNS, nsm); } if (witdNode == null) { string errMsg = UtilityMethods.Format( VSTSResource.VstsNoWitd, witdFileName, schemaMapFile); PostMigrationReport.WriteIssue(null, null, ReportStatisticsStatisicsDetails.MigrationStatus.Failed, ReportIssueType.Critical, String.Empty, entityName, IssueGroup.Config, errMsg); Logger.Write(LogSource.WorkItemTracking, TraceLevel.Error, errMsg); throw new ConverterException(errMsg); } XmlNode witNode = witdNode.SelectSingleNode(tagWitWithNS, nsm); if (witNode == null) { witNode = witdNode.SelectSingleNode(tagWitWithoutNS, nsm); } if (witNode == null) { // no WORKITEMTYPE element found.. invalid xml string errMsg = UtilityMethods.Format( VSTSResource.VstsNoWorkItemType, witdFileName, schemaMapFile); PostMigrationReport.WriteIssue(null, null, ReportStatisticsStatisicsDetails.MigrationStatus.Failed, ReportIssueType.Critical, String.Empty, entityName, IssueGroup.Config, errMsg); Logger.Write(LogSource.WorkItemTracking, TraceLevel.Error, errMsg); throw new ConverterException(errMsg); } else { // look for name attribute XmlAttribute nameAttrib = witNode.Attributes["name"]; if (nameAttrib == null) { // no "name" attribute set string errMsg = UtilityMethods.Format( VSTSResource.VstsNoNameAttribute, witdFileName, schemaMapFile); PostMigrationReport.WriteIssue(null, null, ReportStatisticsStatisicsDetails.MigrationStatus.Failed, ReportIssueType.Critical, String.Empty, entityName, IssueGroup.Config, errMsg); Logger.Write(LogSource.WorkItemTracking, TraceLevel.Error, errMsg); throw new ConverterException(errMsg); } if (!TFStringComparer.XmlAttributeValue.Equals(entityName, nameAttrib.Value)) { // mismatch in target entity string errMsg = UtilityMethods.Format( VSTSResource.VstsWitMismatch, witdFileName, entityName, schemaMapFile); PostMigrationReport.WriteIssue(null, null, ReportStatisticsStatisicsDetails.MigrationStatus.Failed, ReportIssueType.Critical, String.Empty, entityName, IssueGroup.Config, errMsg); Logger.Write(LogSource.WorkItemTracking, TraceLevel.Error, errMsg); throw new ConverterException(errMsg); } } }
} // end of ValidateFieldMapOnCQ /// <summary> /// Execute the Query and migrate the data /// </summary> /// <param name="baseEntityName">Base Entity Name</param> private void MigrateData(string baseEntityName, string baseEntityWitName) { Session cqSession = m_cqConnection.GetUserSession(); OAdQuerydef qryDef = m_cqConnection.QueryDefinition; // edit the query and add dbid field // dbid is suppose to be unique within a Entity CQWrapper.BuildField(qryDef, "dbid"); // prepare result set OAdResultset result = CQWrapper.BuildResultSet(cqSession, qryDef); // process records for base entity CQEntity baseEntityRecords = m_cqParams.entityRecords[baseEntityName]; // enable record count before execute so that no of records can be fetched CQWrapper.EnableRecordCount(result); // execute the query CQWrapper.ExecuteResultSet(result); int columnCount = CQWrapper.GetResultSetColumnCount(result); // lookup for dbid column bool dbidExist = false; int dbidColumnIndex = 0; for (int colIter = 1; colIter <= columnCount; colIter++) { if (string.Equals(CQWrapper.GetColumnLabel(result, colIter), "dbid", StringComparison.OrdinalIgnoreCase)) { dbidExist = true; dbidColumnIndex = colIter; break; } } if (!dbidExist) { // neither query contain dbid nor can be edited to include a new column string errMsg = UtilityMethods.Format(CQResource.CQ_NO_DBID_IN_QUERY, m_cqConnection.QueryName, m_convParams.ConfigFile); PostMigrationReport.WriteIssue(null, null, RepStatus.Failed, ReportIssueType.Critical, String.Empty, baseEntityName, IssueGroup.Config, errMsg); Logger.Write(LogSource.CQ, TraceLevel.Error, errMsg); throw new ConverterException(errMsg); } // start the progress thread for updating the progress m_progressThread = new Thread(new ThreadStart(CQConverter.UpdateProgress)); m_progressThread.Name = "Progress"; try { // get the work item helper handle TotalRecords = CQWrapper.GetRecordCount(result); m_progressThread.Start(); while (CQWrapper.ResultSetMoveNext(result) == CQConstants.SUCCESS) { string dbid = (string)CQWrapper.GetColumnValue(result, dbidColumnIndex); // create a CQEntity for that CQEntityRec record = new CQEntityRec(int.Parse(dbid), baseEntityName, m_cqParams); try { // populate and migrate the record and all referenced records RecordsProcessed++; baseEntityRecords.AddRecord(record); if (record.Populate() == false && m_cqParams.exitOnError == true) { return; // stop processing more records } } catch (ConverterException conEx) { // log the error and continue with next item string errMsg = UtilityMethods.Format(CQResource.CQ_WI_READ_FAILED, dbid, conEx.Message); ReportWorkItemFailure(errMsg, dbid, baseEntityName, baseEntityWitName, m_cqParams.exitOnError); if (m_cqParams.exitOnError == true) { // throw the error back .. should not continue with the current record throw; } } } } finally { // terminate the progress thread m_progressThread.Abort(); Thread.Sleep(5000); // allow the display thread to stop } } // end of MigrateData
} // end of FindAllowedEntitiesToMigrate /// <summary> /// Validate all the Entity Types on Clear Quest /// Followed by the respective Field Mappings /// </summary> /// <returns>true if successful, false in case of some error</returns> private void ValidateSchemaMapOnCQ() { Session cqSession = m_cqConnection.GetUserSession(); object[] cqEntities = (object[])CQWrapper.GetSubmitEntityDefNames(cqSession); Display.NewLine(); foreach (SchemaMapping schMap in m_convParams.SchemaMaps) { string infoMsg = UtilityMethods.Format(CQResource.SchemaValidation, schMap.WITDFile); Logger.Write(LogSource.CQ, TraceLevel.Verbose, infoMsg); bool entityFoundInCQ = false; foreach (object obj in cqEntities) { if (schMap.entity.Equals(obj.ToString(), StringComparison.OrdinalIgnoreCase)) { entityFoundInCQ = true; break; } } if (!entityFoundInCQ) { try { Display.StartProgressDisplay(infoMsg); string errMsg = UtilityMethods.Format(CQResource.CQ_ENTITY_NOT_EXIST, CurConResource.Analysis, schMap.entity, Path.GetFileName(m_convParams.SchemaMapFile)); PostMigrationReport.WriteIssue(null, null, RepStatus.Failed, ReportIssueType.Critical, String.Empty, schMap.entity, IssueGroup.Witd, errMsg); throw new ConverterException(errMsg); } finally { Display.StopProgressDisplay(); } } else { OAdEntityDef currEntityDef = CQWrapper.GetEntityDef(cqSession, schMap.entity); // can validate the fields at CQ also, for this entity string fieldMapFile = schMap.fieldMapFile; if (fieldMapFile != null) { UtilityMethods.ValidateFile(fieldMapFile, schMap.schemaMapFile); FieldMaps fldMaps = WITFieldMappings.CreateFromFile(fieldMapFile); ValidateFieldMapOnCQ(currEntityDef, fldMaps.FieldMap, fieldMapFile); // add the predefined/internal field maps FieldMapsFieldMap[] internalFldMaps = GetInternalFieldMaps(fldMaps); fldMaps.FieldMap.CopyTo(internalFldMaps, 0); fldMaps.FieldMap = internalFldMaps; // add the loaded field map in Schema Field Map for future use m_schemaFieldMap.Add(schMap.entity, fldMaps); } } } // end of foreach SchemaMappings } // end of ValidateSchemaMapOnCQ
private void FindAllowedEntitiesToMigrate(string baseEntityName, Session cqSession) { string[] refEntities = CQConverterUtil.GetReferencedEntityDefNames (cqSession, baseEntityName, m_convParams.ConfigFile); // check against the entity defs provided in schema map xml m_cqParams.allowedEntities = new Dictionary <string, bool>(TFStringComparer.OrdinalIgnoreCase); foreach (SchemaMapping map in m_cqParams.schemaMaps) { m_cqParams.allowedEntities.Add(map.entity, false); } bool baseEntityFound = false; foreach (string entity in m_cqParams.allowedEntities.Keys) { if (baseEntityName.Equals(entity, StringComparison.OrdinalIgnoreCase)) { baseEntityFound = true; break; } } if (!baseEntityFound) { // base entity has to be migrated string errMsg = UtilityMethods.Format(CQResource.CQ_BASE_ENTITY_REQ, CurConResource.Analysis, baseEntityName, Path.GetFileName(m_convParams.SchemaMapFile)); PostMigrationReport.WriteIssue(null, null, RepStatus.Failed, ReportIssueType.Critical, String.Empty, baseEntityName, IssueGroup.Witd, errMsg); Logger.Write(LogSource.CQ, TraceLevel.Error, errMsg); throw new ConverterException(errMsg); } // for entries other than base entity // generate warning if not being selected for migration foreach (string entity in refEntities) { if (!m_cqParams.allowedEntities.ContainsKey(entity)) { string warningMsg = UtilityMethods.Format(CQResource.CQ_DROP_ENTITY, entity, m_convParams.SchemaMapFile); Logger.Write(LogSource.CQ, TraceLevel.Warning, warningMsg); PostMigrationReport.WriteIssue(null, null, RepStatus.Warning, ReportIssueType.Warning, String.Empty, entity, IssueGroup.Witd, warningMsg); m_cqParams.allowedEntities.Remove(entity); } } // remove the entries from allowed entities which // are not referened (dir/indir) from base entity // foreach (string // set the allowed entities in allowedEntities object } // end of FindAllowedEntitiesToMigrate