// Return an EnterpriseChangeRequest with mapped values needed for the state transiton // If there is a fail with mapping some values, this will be captured in event log. // TODO: This could likely be described in a xml mapping file for configuration public static EnterpriseChangeRequest mapFromWorkitem( Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem, Uri about, String action) { EnterpriseChangeRequest newEcr = new EnterpriseChangeRequest(); newEcr.SetAbout(about); // Create a mapped ECR based on suggested action switch (action) { case ACTION_CREATE: newEcr.SetTitle(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_TITLE, workItem)); newEcr.SetDescription(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_DESCRIPTION, workItem)); newEcr.SetCurrentMho(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CURRENT_MHO, workItem)); newEcr.SetCustomer(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CUSTOMER, workItem)); newEcr.SetProduct(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_PRODUCT, workItem)); newEcr.SetProductRevision(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_PRODUCT_REVISION, workItem)); newEcr.SetNodeProduct(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_NODE_PRODUCT, workItem)); newEcr.SetNodeProductRevision(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_NODE_PRODUCT_REVISION, workItem)); // Note: The field firstTechnicalContact also is needed for TR creation. This we retrieve from // the user in the create notification, and put in the REST call header as required by MHWeb. // Formally we have mapping specified in ERICSSON_DEFECT_CREATOR_SIGNUM, but not used. // Add the connected Bug as related link Uri relatedBug = new Uri(HandlerSettings.GetUriForBug(workItem.Id.ToString())); String label = workItem.Id.ToString() + ": " + workItem.Title; OSLC4Net.Core.Model.Link link = new OSLC4Net.Core.Model.Link(relatedBug, label); newEcr.AddRelatedChangeRequest(link); break; case ACTION_REGISTER_ROUTE: newEcr.SetAction(ACTION_REGISTER_ROUTE); newEcr.SetImpactOnISP(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_IMPACT_ON_ISP, workItem)); newEcr.SetPriority(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_PRIORITY, workItem)); newEcr.SetDiddet(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_DIDDET, workItem)); newEcr.SetActivity(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_ACTIVITY, workItem)); newEcr.SetFirstTechContactInfo(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_FIRST_TECHNICAL_CONTACT_INFO, workItem)); newEcr.SetCountry(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_COUNTRY, workItem)); newEcr.SetSite(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_SITE, workItem)); break; case ACTION_ASSIGN: newEcr.SetAction(ACTION_ASSIGN); newEcr.SetOwner(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_OWNER, workItem)); break; case ACTION_PROPOSE: newEcr.SetAction(ACTION_PROPOSE); newEcr.SetDiddet(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_DIDDET, workItem)); newEcr.SetActivity(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_ACTIVITY, workItem)); newEcr.SetFirstTechContactInfo(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_FIRST_TECHNICAL_CONTACT_INFO, workItem)); newEcr.SetExpectedImpactOnISP(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_EXPECTED_IMPACT_ON_ISP, workItem)); newEcr.SetAnswer(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_ANSWER, workItem)); newEcr.SetFaultCode(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_FAULTCODE, workItem)); newEcr.SetAnswerCode(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_ANSWER_CODE, workItem)); // Corrected Product info is mandatory for some answerCodes and optional for others. Here // we pass in all cases and let the bug.xml handle mandatoryness and mhweb complain if not // present. newEcr.SetCorrectedProduct( AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CORRECTED_PRODUCT, workItem)); newEcr.SetCorrectedProductRevision( AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CORRECTED_PRODUCT_REVISION, workItem)); newEcr.SetCorrectedNodeProduct( AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CORRECTED_NODE_PRODUCT, workItem)); newEcr.SetCorrectedNodeProductRevision( AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CORRECTED_NODE_PRODUCT_REVISION, workItem)); break; case ACTION_APPROVE: newEcr.SetAction(ACTION_APPROVE); break; case ACTION_VERIFY: newEcr.SetAction(ACTION_VERIFY); newEcr.SetCorrectedNodeProduct( AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CORRECTED_NODE_PRODUCT, workItem)); newEcr.SetCorrectedNodeProductRevision( AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CORRECTED_NODE_PRODUCT_REVISION, workItem)); break; case ACTION_ANSWER: newEcr.SetAction(ACTION_ANSWER); newEcr.SetCorrectedNodeProduct( AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CORRECTED_NODE_PRODUCT, workItem)); newEcr.SetCorrectedNodeProductRevision( AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_CORRECTED_NODE_PRODUCT_REVISION, workItem)); break; case ACTION_ACCEPT: newEcr.SetAction(ACTION_ACCEPT); break; case ACTION_REJECT: newEcr.SetAction(ACTION_REJECT); newEcr.SetNotebook(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_NOTEBOOK, workItem)); break; case ACTION_DUPLICATE: newEcr.SetAction(ACTION_DUPLICATE); newEcr.SetPrimaryTR(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_PRIMARYTR, workItem)); break; case ACTION_UNDUPLICATE: newEcr.SetAction(ACTION_UNDUPLICATE); break; case ACTION_CHANGE_PRODUCT: newEcr.SetAction(ACTION_CHANGE_PRODUCT); newEcr.SetProduct(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_PRODUCT, workItem)); newEcr.SetProductRevision(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_PRODUCT_REVISION, workItem)); newEcr.SetNodeProduct(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_NODE_PRODUCT, workItem)); newEcr.SetNodeProductRevision(AttributesMapper.GetTfsValueForEcrKey(TFSMapper.ECM_NODE_PRODUCT_REVISION, workItem)); break; case ACTION_REACTIVATE: newEcr.SetAction(ACTION_REACTIVATE); break; case ACTION_FINISH: newEcr.SetAction(ACTION_FINISH); break; case ACTION_DISCONNECT: newEcr.SetAction(ACTION_DISCONNECT); break; } return(newEcr); }
// Update the connected TR. private void updateTR( Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem, WorkItemChangedEvent notification, String user, Uri about, ref Status status) { String oldState, newState, action; ECRMapper.getStatusChange(notification, workItem, out oldState, out newState, out action); if (action != null) { if (action.Equals(ECRMapper.ACTION_IGNORE)) { // Ignore all changes return; } if (action.Equals(ECRMapper.ACTION_DUPLICATE)) { // UC 9.4: Duplicate - Find Bug with duplicate id, get attached TR and send action duplicate // Update needs to be done before setting the Bug as Duplicate as the TR can't change after. updateTRFields(workItem, notification, user, about, ref status); EnterpriseChangeRequest ecr = ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_DUPLICATE); if (ecr.GetPrimaryTR() == null || ecr.GetPrimaryTR().Length == 0) { // Failed to find a Bug with a connected TR. Log error and return. String msg = String.Format( "Failed to find duplicate to Bug: {0}, or duplicate Bug had not TR Link set", workItem.Title); HandlerSettings.LogMessage(msg, HandlerSettings.LoggingLevel.ERROR); status.ErrorMessage = msg; return; } callUpdateTR(ecr, user, null, ref status); if (!status.OK) { // Log issue, but continue if e.g. a state change HandlerSettings.LogMessage( String.Format("Failed to set TR as duplicate based on Bug: {0}", workItem.Title), HandlerSettings.LoggingLevel.WARN); } // After setting Bug/TR as Duplicated, no futher changes should be propagated. return; } if (action.Equals(ECRMapper.ACTION_UNDUPLICATE)) { // UC 9.4: Unduplicate - Move TR back to Registered by sending action unduplicate EnterpriseChangeRequest ecr = ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_UNDUPLICATE); callUpdateTR(ecr, user, null, ref status); if (!status.OK) { // Log issue, but continue if e.g. a state change HandlerSettings.LogMessage( String.Format("Failed to unduplicate TR based on Bug ", workItem.Title), HandlerSettings.LoggingLevel.WARN); } // Update needs to be done after "Unduplicating" the Bug as the TR can't change before. updateTRFields(workItem, notification, user, about, ref status); // Return before handling a possible state change as states can be out of sync // (normal case) when Bug has been Duplicate. Bug then Resolved / Closed, and // TR in an Active state. User needs to set TR state to Active. return; } else if (action.Equals(ECRMapper.ACTION_CHANGE_PRODUCT)) { // UC 10.2: Update of the release - propagate info to TR EnterpriseChangeRequest ecr = ECRMapper.mapFromWorkitem(workItem, about, ECRMapper.ACTION_CHANGE_PRODUCT); bool noProduct = ecr.GetProduct().Length == 0; if (noProduct) { // No product found, so value is for internal release - add message in notebook ecr.SetNotebook("The referenced design item was moved to a product internal to Design"); } callUpdateTR(ecr, user, null, ref status); if (!status.OK) { // Log issue, but continue if e.g. a state change HandlerSettings.LogMessage( String.Format("Failed to change product on TR based on Bug ", workItem.Title), HandlerSettings.LoggingLevel.WARN); } } } updateTRFields(workItem, notification, user, about, ref status); if (newState != null) { // Handle state change updateTRState(workItem, oldState, newState, user, about, ref status);; } }