TFS Integration Platform – Aggregated Fields: Question & Answer 17

In response to current proof of concept (POC) exercises using the TFS Integration Platform, the need for aggregated WIT fields was highlighted.

Huh? What is an aggregated field?

In terms of the TFS Integration Platform and the WIT Adapters, the aggregated field is simply a combination of more than one field from the source in one target field. 

Terry made the following sample configuration file available, which highlights the new feature <AggregatedFields></AggregatedFields> quite nicely:

   1: <Session SessionUniqueId="882d715f-214a-4901-aefb-a309ed4a8bd2"
   2:                FriendlyName="Work Item Tracking session"
   3:                LeftMigrationSourceUniqueId="BB2BD2C6-92B5-4817-AB51-A087B6532F0D"
   4:                RightMigrationSourceUniqueId="f4741818-F14C-458f-bb20-4bbac20f95c3"
   5:                SessionType="WorkItemTracking">
   6:         <Filters>
   7:           <!-- Filter Pairs will be constructed at run time. Any existing filters will be ingored. -->
   8:         </Filters>
  10:         <CustomSettings>
  11:           <SettingXml>
  12:             <WITSessionCustomSetting>
  13:               <WorkItemTypes>
  14:                 <WorkItemType LeftWorkItemTypeName="Defect" RightWorkItemTypeName="Defect" fieldMap="Defect2DefectFieldMap" />
  15:               </WorkItemTypes>
  16:               <FieldMaps>
  17:                 <FieldMap name="Defect2DefectFieldMap">
  18:                   <MappedFields>
  20:                     <!-- left to right, i.e. CQ to TFS -->
  21:                     <MappedField LeftName="State" RightName="System.State" MapFromSide="Left" valueMap=""/>
  22:                     <!--<MappedField LeftName="Headline" RightName="System.Title" MapFromSide="Left" valueMap=""/>-->
  23:                     <MappedField LeftName="Description" RightName="System.Description" MapFromSide="Left" valueMap=""/>
  24:                     <MappedField LeftName="Priority" RightName="Microsoft.TeamFoundation.Converters.Priority_String" MapFromSide="Left" valueMap=""/>
  25:                     <MappedField LeftName="Severity" RightName="Microsoft.VSTS.Common.Severity" MapFromSide="Left" valueMap=""/>
  26:                     <!--<MappedField LeftName="Submitter" RightName="Microsoft.TeamFoundation.Converters.Submitter" MapFromSide="Left" valueMap="UserMap"/>-->
  27:                     <!--<MappedField LeftName="Submit_Date" RightName="System.CreatedDate" MapFromSide="Left" valueMap=""/>-->
  28:                     <MappedField LeftName="Owner" RightName="System.AssignedTo" MapFromSide="Left" valueMap="UserMap"/>
  29:                     <MappedField LeftName="Keywords" RightName="Microsoft.TeamFoundation.Converters.Keywords" MapFromSide="Left" valueMap=""/>
  30:                     <MappedField LeftName="Symptoms" RightName="Microsoft.TeamFoundation.Converters.Symptoms" MapFromSide="Left" valueMap=""/>
  31:                     <MappedField LeftName="Notes_Log" RightName="Microsoft.TeamFoundation.Converters.Notes_Log" MapFromSide="Left" valueMap=""/>
  32:                     <MappedField LeftName="Resolution" RightName="Microsoft.TeamFoundation.Converters.Resolution" MapFromSide="Left" valueMap=""/>
  33:                     <MappedField LeftName="ucm_vob_object" RightName="Microsoft.TeamFoundation.Converters.ucm_vob_object" MapFromSide="Left" valueMap=""/>
  34:                     <MappedField LeftName="ucm_stream_object" RightName="Microsoft.TeamFoundation.Converters.ucm_stream_object" MapFromSide="Left" valueMap=""/>
  35:                     <MappedField LeftName="ucm_stream" RightName="Microsoft.TeamFoundation.Converters.ucm_stream" MapFromSide="Left" valueMap=""/>
  36:                     <MappedField LeftName="ucm_view" RightName="Microsoft.TeamFoundation.Converters.ucm_view" MapFromSide="Left" valueMap=""/>
  37:                     <!-- NOTE THAT CQ history fields records a line of change description. All such history fields in a record type are mapped to System.Description -->
  38:                     <MappedField LeftName="history" RightName="System.History" MapFromSide="Left" valueMap=""/>
  40:                     <!-- right to left, i.e. TFS to CQ -->
  41:                     <MappedField LeftName="State" RightName="System.State" MapFromSide="Right" valueMap=""/>
  42:                     <MappedField LeftName="Headline" RightName="System.Title" MapFromSide="Right" valueMap=""/>
  43:                     <MappedField LeftName="Description" RightName="System.Description" MapFromSide="Right" valueMap=""/>
  44:                     <MappedField LeftName="Priority" RightName="Microsoft.TeamFoundation.Converters.Priority_String" MapFromSide="Right" valueMap=""/>
  45:                     <MappedField LeftName="Severity" RightName="Microsoft.VSTS.Common.Severity" MapFromSide="Right" valueMap=""/>
  46:                     <MappedField LeftName="Owner" RightName="System.AssignedTo" MapFromSide="Right" valueMap="UserMap"/>
  47:                     <MappedField LeftName="Keywords" RightName="Microsoft.TeamFoundation.Converters.Keywords" MapFromSide="Right" valueMap=""/>
  48:                     <MappedField LeftName="Symptoms" RightName="Microsoft.TeamFoundation.Converters.Symptoms" MapFromSide="Right" valueMap=""/>
  49:                     <MappedField LeftName="Notes_Log" RightName="Microsoft.TeamFoundation.Converters.Notes_Log" MapFromSide="Right" valueMap=""/>
  50:                     <MappedField LeftName="Resolution" RightName="Microsoft.TeamFoundation.Converters.Resolution" MapFromSide="Right" valueMap=""/>
  51:                     <MappedField LeftName="ucm_vob_object" RightName="Microsoft.TeamFoundation.Converters.ucm_vob_object" MapFromSide="Right" valueMap=""/>
  52:                     <MappedField LeftName="ucm_stream_object" RightName="Microsoft.TeamFoundation.Converters.ucm_stream_object" MapFromSide="Right" valueMap=""/>
  53:                     <MappedField LeftName="ucm_stream" RightName="Microsoft.TeamFoundation.Converters.ucm_stream" MapFromSide="Right" valueMap=""/>
  54:                     <MappedField LeftName="ucm_view" RightName="Microsoft.TeamFoundation.Converters.ucm_view" MapFromSide="Right" valueMap=""/>
  55:                     <!-- NOTE THAT CQ history fields records a line of change description. All such history fields in a record type are mapped to System.Description -->
  56:                     <MappedField LeftName="history" RightName="System.History" MapFromSide="Right" valueMap=""/>
  58:                   </MappedFields>
  60:               <AggregatedFields>
  61:                 <FieldsAggregationGroup MapFromSide="Left" TargetFieldName="System.Title" Format="[combine '{0}' with '{1}']">
  62:                   <SourceField Index="0" SourceFieldName="State" valueMap=""/>
  63:                   <SourceField Index="1" SourceFieldName="Severity" valueMap=""/>
  64:                 </FieldsAggregationGroup>
  65:               </AggregatedFields>
  67:                 </FieldMap>
  68:               </FieldMaps>
  69:               <ValueMaps>
  70:                 <ValueMap name="UserMap">
  71:                   <Value LeftValue="demo" RightValue="Demo User" />
  72:                 </ValueMap>
  73:               </ValueMaps>
  74:             </WITSessionCustomSetting>
  75:           </SettingXml>
  76:         </CustomSettings>

The magic happens in lines 60 to 65, where we combine the State and Severity fields from the source in the  target title.


Other changes introduced as part of this feature

  1. At the Work Item type mapping level we now have to be explicit:
    • In the past an absence of WIT mapping meant that we map from source A to target A. This implicit mapping is now obsolete!
    • Today we have to define WIT mapping explicitly, such as:

    • To simulate the old map everything from source to target implicitly, we can define:

             <WorkItemType LeftWorkItemTypeName="*" RightWorkItemTypeName="*" fieldMap="@@ALL@@" />

      Note that both “*” and “@@ALL@@” are wildcard characters.

  2. At the Field Mapping level the “ExcludedFields” is now obsolete.
    • Only explicitly mapped fields will now be migrated

What’s next in the series of questions & answers? You decide … please  continue to send us your questions.

Acronyms Used

| POC – Proof of Concepts | WIT – Work Item Type |

Comments (4)

  1. kapinnow says:

    I tried to use the <AggregatedFields> inside the <WorkItemType> scheme but it does not seems to fit there (which was somehow expected from your writing. However, I want to use some form of aggregations in order to display a combination of fields at one place in a work item while editing the individual fields at another place. How would that be possible?

  2. I recommend that you refer to the "TFS_Integration_Platform-Configuration" document that ships as part of the product for the configuration information on this feature. If you have prroblems, please raise a thread on…/threads and share your configfuration file for analysis.

  3. wendellp says:

    What if we want to disaggreagate a field during migration, from Version to Major Version, Minor Version and Revision for example?  Thanks Willy.

  4. The reverse of aggregation is not implemented in the TFS Integration Tools and at this stage there are no plans for this feature. You could consider to either customise the relevant adapter using code from…/changesets or to develop a custom Add-in, the latter probably being the preference.

Skip to main content