azure-devops-migration-tools icon indicating copy to clipboard operation
azure-devops-migration-tools copied to clipboard

[Bug]: TfsWorkItemEmbededLinkTool does not use TfsUserMappingTool data

Open JDAVF opened this issue 6 months ago • 0 comments

Version

  • [x] I confirm that I am using the latest version

Source Version

Azure DevOps Server 2022

Target Version

Azure DevOps Service

Relevant configuration

userMapping.json:
{
  "Tester": "Test"
}

Relevant log output

[21:52:19 INF] [16.1.0] EmbededImagesRepairEnricher: Fixing HTML field attachments for work item 321 from https://devops/tfs/Proj to https://dev.azure.com/Proj/ 
[21:52:19 INF] [16.1.0] TfsWorkItemEmbededLinkTool: Fixing embedded mention links on target work item 321 from https://devops/tfs/Proj to https://dev.azure.com/Proj/ 
[21:52:19 DBG] [16.1.0] TfsWorkItemEmbededLinkTool: User identity Tester mention traced on field History on target work item 321. 
[21:52:23 INF] [16.1.0] TfsWorkItemEmbededLinkTool: [SKIP] Matching user identity Tester mention was not found on field History on target work item 321. So left it as it is. 

For normal work items fields, it works just fine:
[21:52:19 DBG] [16.1.0] TfsUserMappingTool::MapUserIdentityField [ReferenceName|System.AssignedTo] 
[21:52:19 DBG] [16.1.0] TfsUserMappingTool::MapUserIdentityField::Map:[Tester][new|Test] 
[21:52:19 DBG] [16.1.0] PopulateWorkItem:FieldUpdate: System.AssignedTo | Source:Test Target:Test

What happened?

Users in mention are not properly replaced with the same logic as the usermappings, but just fetches exactly the same user by Displayname. See src/MigrationTools.Clients.TfsObjectModel/Tools/TfsWorkItemEmbededLinkTool.cs

` _targetTeamFoundationIdentitiesLazyCache = new Lazy<List<TeamFoundationIdentity>>(() => { try { TfsTeamService teamService = processor.Target.GetService<TfsTeamService>(); TfsConnection connection = (TfsConnection)processor.Target.InternalCollection;

                var identityService = processor.Target.GetService<IIdentityManagementService>();
                var tfi = identityService.ReadIdentity(IdentitySearchFactor.General, "Project Collection Valid Users", MembershipQuery.Expanded, ReadIdentityOptions.None);
                return identityService.ReadIdentities(tfi.Members, MembershipQuery.None, ReadIdentityOptions.None).ToList();
            }
            catch (Exception ex)
            {
                Log.LogError(ex, "{LogTypeName}: Unable load list of identities from target collection.", LogTypeName);
                Telemetry.TrackException(ex, null);
                return new List<TeamFoundationIdentity>();
            }
        });`

This is fetching all users (once, due to Lazy), but this is already been done (if enabled) by TfsUserMappingTool: private List<IdentityItemData> GetUsersListFromServer(IGroupSecurityService gss) { Identity allIdentities = gss.ReadIdentity(SearchFactor.AccountName, "Project Collection Valid Users", QueryMembership.Expanded);

Debug in Visual Studio

  • [x] Visual Studio Debug

JDAVF avatar Jun 29 '25 06:06 JDAVF