Skip to content

Commit 4c98820

Browse files
committed
Export all users
1 parent 9135fee commit 4c98820

File tree

5 files changed

+83
-32
lines changed

5 files changed

+83
-32
lines changed

src/MigrationTools.Clients.TfsObjectModel/Processors/TfsExportUsersForMappingProcessor.cs

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4+
using System.IO;
45
using System.Linq;
56
using Microsoft.Extensions.Logging;
67
using Microsoft.Extensions.Options;
@@ -42,30 +43,26 @@ protected override void InternalExecute()
4243
{
4344
Stopwatch stopwatch = Stopwatch.StartNew();
4445

45-
if (string.IsNullOrEmpty(CommonTools.UserMapping.Options.UserMappingFile))
46-
{
47-
Log.LogError("UserMappingFile is not set");
48-
throw new ArgumentNullException("UserMappingFile must be set on the TfsUserMappingToolOptions in CommonEnrichersConfig.");
49-
}
46+
CheckOptions();
5047

51-
List<IdentityMapData> usersToMap = new List<IdentityMapData>();
48+
IdentityMapResult data;
5249
if (Options.OnlyListUsersInWorkItems)
5350
{
5451
Log.LogInformation("OnlyListUsersInWorkItems is true, only users in work items will be listed");
5552
List<WorkItemData> sourceWorkItems = Source.WorkItems.GetWorkItems(Options.WIQLQuery);
5653
Log.LogInformation("Processed {0} work items from Source", sourceWorkItems.Count);
5754

58-
usersToMap = CommonTools.UserMapping.GetUsersInSourceMappedToTargetForWorkItems(this, sourceWorkItems);
59-
Log.LogInformation("Found {usersToMap} total mapped", usersToMap.Count);
55+
data = CommonTools.UserMapping.GetUsersInSourceMappedToTargetForWorkItems(this, sourceWorkItems);
56+
Log.LogInformation("Found {usersToMap} total mapped", data.IdentityMap.Count);
6057
}
6158
else
6259
{
6360
Log.LogInformation("OnlyListUsersInWorkItems is false, all users will be listed");
64-
usersToMap = CommonTools.UserMapping.GetUsersInSourceMappedToTarget(this);
65-
Log.LogInformation("Found {usersToMap} total mapped", usersToMap.Count);
61+
data = CommonTools.UserMapping.GetUsersInSourceMappedToTarget(this);
62+
Log.LogInformation("Found {usersToMap} total mapped", data.IdentityMap.Count);
6663
}
6764

68-
usersToMap = usersToMap.Where(x => x.Source.DisplayName != x.Target?.DisplayName).ToList();
65+
List<IdentityMapData> usersToMap = data.IdentityMap.Where(x => x.Source.DisplayName != x.Target?.DisplayName).ToList();
6966
Log.LogInformation("Filtered to {usersToMap} total viable mappings", usersToMap.Count);
7067
Dictionary<string, string> usermappings = [];
7168
foreach (IdentityMapData userMapping in usersToMap)
@@ -74,11 +71,40 @@ protected override void InternalExecute()
7471
// it would throw with duplicate key. This way we just overwrite the value – last item in source wins.
7572
usermappings[userMapping.Source.DisplayName] = userMapping.Target?.DisplayName;
7673
}
77-
System.IO.File.WriteAllText(CommonTools.UserMapping.Options.UserMappingFile, JsonConvert.SerializeObject(usermappings, Formatting.Indented));
78-
Log.LogInformation("Writen to: {LocalExportJsonFile}", CommonTools.UserMapping.Options.UserMappingFile);
74+
File.WriteAllText(CommonTools.UserMapping.Options.UserMappingFile, JsonConvert.SerializeObject(usermappings, Formatting.Indented));
75+
Log.LogInformation("User mappings writen to: {LocalExportJsonFile}", CommonTools.UserMapping.Options.UserMappingFile);
76+
if (Options.ExportAllUsers)
77+
{
78+
ExportAllUsers(data);
79+
}
7980

8081
stopwatch.Stop();
8182
Log.LogInformation("DONE in {Elapsed} seconds", stopwatch.Elapsed);
8283
}
84+
85+
private void ExportAllUsers(IdentityMapResult data)
86+
{
87+
var allUsers = new
88+
{
89+
data.SourceUsers,
90+
data.TargetUsers
91+
};
92+
File.WriteAllText(Options.UserExportFile, JsonConvert.SerializeObject(allUsers, Formatting.Indented));
93+
Log.LogInformation("All user writen to: {exportFile}", Options.UserExportFile);
94+
}
95+
96+
private void CheckOptions()
97+
{
98+
if (string.IsNullOrEmpty(CommonTools.UserMapping.Options.UserMappingFile))
99+
{
100+
Log.LogError("UserMappingFile is not set");
101+
throw new ArgumentNullException("UserMappingFile must be set on the TfsUserMappingToolOptions in CommonTools.");
102+
}
103+
if (Options.ExportAllUsers && string.IsNullOrEmpty(Options.UserExportFile))
104+
{
105+
Log.LogError($"Flag ExportAllUsers is set but export file UserExportFile is not set.");
106+
throw new ArgumentNullException("UserExportFile must be set on the TfsExportUsersForMappingProcessorOptions in Processors.");
107+
}
108+
}
83109
}
84110
}

src/MigrationTools.Clients.TfsObjectModel/Processors/TfsExportUsersForMappingProcessorOptions.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using System.Collections.Generic;
2-
using MigrationTools._EngineV1.Configuration;
3-
using MigrationTools.Enrichers;
4-
using MigrationTools.Processors.Infrastructure;
1+
using MigrationTools.Processors.Infrastructure;
52

63
namespace MigrationTools.Processors
74
{
@@ -16,5 +13,17 @@ public class TfsExportUsersForMappingProcessorOptions : ProcessorOptions
1613
/// <default>true</default>
1714
public bool OnlyListUsersInWorkItems { get; set; } = true;
1815

16+
/// <summary>
17+
/// Set to <see langword="true"/>, if you want to export all users in source and target server.
18+
/// The lists of user can be useful, if you need tu manually edit mapping file.
19+
/// Users will be exported to file set in <see cref="UserExportFile"/>.
20+
/// </summary>
21+
public bool ExportAllUsers { get; set; }
22+
23+
/// <summary>
24+
/// Path to export file where all source and target servers' users will be exported.
25+
/// Users are exported only if <see cref="ExportAllUsers"/> is set to <see langword="true"/>.
26+
/// </summary>
27+
public string UserExportFile { get; set; }
1928
}
2029
}

src/MigrationTools.Clients.TfsObjectModel/Processors/TfsWorkItemMigrationProcessor.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -227,15 +227,15 @@ protected override void InternalExecute()
227227

228228
private void ValidateAllUsersExistOrAreMapped(List<WorkItemData> sourceWorkItems)
229229
{
230-
231230
contextLog.Information("Validating::Check that all users in the source exist in the target or are mapped!");
232-
List<IdentityMapData> usersToMap = new List<IdentityMapData>();
233-
usersToMap = CommonTools.UserMapping.GetUsersInSourceMappedToTargetForWorkItems(this, sourceWorkItems);
234-
if (usersToMap != null && usersToMap?.Count > 0)
231+
IdentityMapResult usersToMap = CommonTools.UserMapping.GetUsersInSourceMappedToTargetForWorkItems(this, sourceWorkItems);
232+
if (usersToMap.IdentityMap != null && usersToMap.IdentityMap.Count > 0)
235233
{
236-
Log.LogWarning("Validating Failed! There are {usersToMap} users that exist in the source that do not exist in the target. This will not cause any errors, but may result in disconnected users that could have been mapped. Use the ExportUsersForMapping processor to create a list of mappable users. Then Import using ", usersToMap.Count);
234+
Log.LogWarning("Validating Failed! There are {usersToMap} users that exist in the source that do not exist "
235+
+ "in the target. This will not cause any errors, but may result in disconnected users that could have "
236+
+ "been mapped. Use the ExportUsersForMapping processor to create a list of mappable users.",
237+
usersToMap.IdentityMap.Count);
237238
}
238-
239239
}
240240

241241
//private void ValidateAllNodesExistOrAreMapped(List<WorkItemData> sourceWorkItems)

src/MigrationTools.Clients.TfsObjectModel/Tools/TfsUserMappingTool.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Linq;
44
using Microsoft.Extensions.Logging;
@@ -121,11 +121,12 @@ private List<IdentityItemData> GetUsersListFromServer(IGroupSecurityService gss)
121121
Log.LogWarning("TfsUserMappingTool::GetUsersListFromServer::[user:{user}] Failed With {Exception}", sid, ex.Message);
122122
}
123123
}
124+
foundUsers.Sort((x, y) => x.AccountName.CompareTo(y.AccountName));
124125
Log.LogInformation("TfsUserMappingTool::GetUsersListFromServer {count} user identities are applicable for mapping", foundUsers.Count);
125126
return foundUsers;
126127
}
127128

128-
public List<IdentityMapData> GetUsersInSourceMappedToTarget(TfsProcessor processor)
129+
public IdentityMapResult GetUsersInSourceMappedToTarget(TfsProcessor processor)
129130
{
130131
Log.LogDebug("TfsUserMappingTool::GetUsersInSourceMappedToTarget");
131132
if (Options.Enabled)
@@ -162,25 +163,31 @@ public List<IdentityMapData> GetUsersInSourceMappedToTarget(TfsProcessor process
162163
targetUser ??= targetUsers.SingleOrDefault(x => x.DisplayName == sourceUser.DisplayName);
163164
identityMap.Add(new IdentityMapData { Source = sourceUser, Target = targetUser });
164165
}
165-
return identityMap;
166+
return new()
167+
{
168+
IdentityMap = identityMap,
169+
SourceUsers = sourceUsers,
170+
TargetUsers = targetUsers
171+
};
166172
}
167173
else
168174
{
169175
Log.LogWarning("TfsUserMappingTool is disabled in settings. You may have users in the source that are not mapped to the target. ");
170-
return [];
176+
return new();
171177
}
172178
}
173179

174-
public List<IdentityMapData> GetUsersInSourceMappedToTargetForWorkItems(TfsProcessor processor, List<WorkItemData> sourceWorkItems)
180+
public IdentityMapResult GetUsersInSourceMappedToTargetForWorkItems(TfsProcessor processor, List<WorkItemData> sourceWorkItems)
175181
{
176182
if (Options.Enabled)
177183
{
178184
Dictionary<string, string> result = new Dictionary<string, string>();
179185
HashSet<string> workItemUsers = GetUsersFromWorkItems(sourceWorkItems, Options.IdentityFieldsToCheck);
180186
Log.LogDebug($"TfsUserMappingTool::GetUsersInSourceMappedToTargetForWorkItems [workItemUsers|{workItemUsers.Count}]");
181-
List<IdentityMapData> mappedUsers = GetUsersInSourceMappedToTarget(processor);
182-
Log.LogDebug($"TfsUserMappingTool::GetUsersInSourceMappedToTargetForWorkItems [mappedUsers|{mappedUsers.Count}]");
183-
return mappedUsers.Where(x => workItemUsers.Contains(x.Source.DisplayName)).ToList();
187+
IdentityMapResult mappedUsers = GetUsersInSourceMappedToTarget(processor);
188+
Log.LogDebug($"TfsUserMappingTool::GetUsersInSourceMappedToTargetForWorkItems [mappedUsers|{mappedUsers.IdentityMap.Count}]");
189+
mappedUsers.IdentityMap = mappedUsers.IdentityMap.Where(x => workItemUsers.Contains(x.Source.DisplayName)).ToList();
190+
return mappedUsers;
184191
}
185192
else
186193
{

src/MigrationTools/DataContracts/IdentityItemData.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace MigrationTools.DataContracts
1+
using System.Collections.Generic;
2+
3+
namespace MigrationTools.DataContracts
24
{
35
public class IdentityItemData
46
{
@@ -14,4 +16,11 @@ public class IdentityMapData
1416
public IdentityItemData Source { get; set; }
1517
public IdentityItemData Target { get; set; }
1618
}
19+
20+
public class IdentityMapResult
21+
{
22+
public List<IdentityMapData> IdentityMap { get; set; } = [];
23+
public List<IdentityItemData> SourceUsers { get; set; } = [];
24+
public List<IdentityItemData> TargetUsers { get; set; } = [];
25+
}
1726
}

0 commit comments

Comments
 (0)