Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Great Bug Bash of 2024 07! #2203

Merged
merged 9 commits into from
Jul 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Net;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.TeamFoundation;
using Microsoft.TeamFoundation.Client;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
Expand Down Expand Up @@ -155,6 +156,13 @@ private TfsTeamProjectCollection GetDependantTfsCollection(NetworkCredential cre
Log.Information("Access granted to {CollectionUrl} for {Name} ({Account})", TfsConfig.Collection, y.AuthorizedIdentity.DisplayName, y.AuthorizedIdentity.UniqueName);
_Telemetry.TrackDependency(new DependencyTelemetry("TfsObjectModel", TfsConfig.Collection.ToString(), "GetWorkItem", null, startTime, timer.Elapsed, "200", true));
}
catch (TeamFoundationServerUnauthorizedException ex)
{
timer.Stop();
_Telemetry.TrackDependency(new DependencyTelemetry("TfsObjectModel", TfsConfig.Collection.ToString(), "GetWorkItem", null, startTime, timer.Elapsed, "401", false));
Log.Error(ex, "Unable to configure store: Check persmissions and credentials for {AuthenticationMode}!", _config.AuthenticationMode);
Environment.Exit(-1);
}
catch (Exception ex)
{
timer.Stop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public override WorkItemData GetWorkItem(int id)
}
var startTime = DateTime.UtcNow;
var timer = System.Diagnostics.Stopwatch.StartNew();
WorkItem y;
WorkItem y = null ;
try
{
Log.Debug("TfsWorkItemMigrationClient::GetWorkItem({id})", id);
Expand All @@ -167,13 +167,15 @@ public override WorkItemData GetWorkItem(int id)
{
Telemetry.TrackException(ex,
new Dictionary<string, string> {
{ "CollectionUrl", MigrationClient.Config.AsTeamProjectConfig().Collection.ToString() }
{ "CollectionUrl", MigrationClient.Config.AsTeamProjectConfig().Collection.ToString() },
{ "Project", MigrationClient.Config.AsTeamProjectConfig().Project.ToString() },
{ "WorkItem", id.ToString() }
},
new Dictionary<string, double> {
{ "Time",timer.ElapsedMilliseconds }
});
Log.Error(ex, "Unable to GetWorkItem with id[{id}]", id);
throw;
Environment.Exit(-1);
} finally
{
timer.Stop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ private IList<WorkItem> GetWorkItemsFromQuery(TfsWorkItemMigrationClient wiClien
timer.Stop();
Telemetry.TrackDependency(new DependencyTelemetry("TfsObjectModel", MigrationClient.Config.AsTeamProjectConfig().Collection.ToString(), "GetWorkItemsFromQuery", null, startTime, timer.Elapsed, "200", true));
}
catch (ValidationException ex)
{
timer.Stop();
Telemetry.TrackDependency(new DependencyTelemetry("TfsObjectModel", MigrationClient.Config.AsTeamProjectConfig().Collection.ToString(), "GetWorkItemsFromQuery", null, startTime, timer.Elapsed, "500", false));
Log.Error(ex, " Error running query");
Environment.Exit(-1);
}
catch (Exception ex)
{
timer.Stop();
Expand Down
37 changes: 29 additions & 8 deletions src/MigrationTools/Services/TelemetryClientAdapter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Security.Principal;
using System.Text.RegularExpressions;
using Elmah.Io.Client;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
Expand All @@ -9,17 +12,17 @@
{
public class TelemetryClientAdapter : ITelemetryLogger
{
private TelemetryClient _telemetryClient;

Check warning on line 15 in src/MigrationTools/Services/TelemetryClientAdapter.cs

View workflow job for this annotation

GitHub Actions / Build, Test, Sonar Cloud Analysis, & Package

Make '_telemetryClient' 'readonly'. (https://rules.sonarsource.com/csharp/RSPEC-2933)
private static IElmahioAPI elmahIoClient;

public TelemetryClientAdapter(TelemetryClient telemetryClient)
{
telemetryClient.InstrumentationKey = "2d666f84-b3fb-4dcf-9aad-65de038d2772";

Check warning on line 20 in src/MigrationTools/Services/TelemetryClientAdapter.cs

View workflow job for this annotation

GitHub Actions / Build, Test, Sonar Cloud Analysis, & Package

'TelemetryClient.InstrumentationKey.set' is obsolete: 'InstrumentationKey based global ingestion is being deprecated. Recommended to set TelemetryConfiguration.ConnectionString. See https://github.com/microsoft/ApplicationInsights-dotnet/issues/2560 for more details.'
telemetryClient.Context.Session.Id = Guid.NewGuid().ToString();
telemetryClient.Context.Device.OperatingSystem = Environment.OSVersion.ToString();
if (!(System.Reflection.Assembly.GetEntryAssembly() is null))
{
telemetryClient.Context.Component.Version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString();
telemetryClient.Context.Component.Version = GetRunningVersion().versionString;
}
_telemetryClient = telemetryClient;

Expand All @@ -28,7 +31,7 @@
Timeout = TimeSpan.FromSeconds(30),
UserAgent = "Azure-DevOps-Migration-Tools",
});
elmahIoClient.Messages.OnMessage += (sender, args) => args.Message.Version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString();
elmahIoClient.Messages.OnMessage += (sender, args) => args.Message.Version = GetRunningVersion().versionString;

}

Expand Down Expand Up @@ -84,18 +87,27 @@
Application = "Azure-DevOps-Migration-Tools",
ServerVariables = new List<Item>
{
new Item("User-Agent", $"X-ELMAHIO-APPLICATION; OS={Environment.OSVersion.Platform}; OSVERSION={Environment.OSVersion.Version}; ENGINE=Azure-DevOps-Migration-Tools"),
new Item("User-Agent", $"X-ELMAHIO-APPLICATION; OS={Environment.OSVersion.Platform}; OSVERSION={Environment.OSVersion.Version}; ENGINEVERSION={GetRunningVersion().versionString}; ENGINE=Azure-DevOps-Migration-Tools"),
}
};
foreach (var property in properties)
createMessage.Data.Add(new Item("SessionId", SessionId));
createMessage.Data.Add(new Item("Version", GetRunningVersion().versionString));

if (properties != null)
{
createMessage.Data.Add(new Item(property.Key, property.Value));
foreach (var property in properties)
{
createMessage.Data.Add(new Item(property.Key, property.Value));
}

}
foreach (var measurement in measurements)
if (measurements != null)
{
createMessage.Data.Add(new Item(measurement.Key, measurement.Value.ToString()));
foreach (var measurement in measurements)
{
createMessage.Data.Add(new Item(measurement.Key, measurement.Value.ToString()));
}
}

var result = elmahIoClient.Messages.CreateAndNotify(new Guid("24086b6d-4f58-47f4-8ac7-68d8bc05ca9e"), createMessage);
Console.WriteLine($"Error logged to Elmah.io");
}
Expand All @@ -104,5 +116,14 @@
{
_telemetryClient.TrackRequest(name, startTime, duration, responseCode, success);
}

public static (Version version, string PreReleaseLabel, string versionString) GetRunningVersion()
{
FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly()?.Location);
var matches = Regex.Matches(myFileVersionInfo.ProductVersion, @"^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<build>0|[1-9]\d*)(?:-((?<label>:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?<fullEnd>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$");

Check warning on line 123 in src/MigrationTools/Services/TelemetryClientAdapter.cs

View workflow job for this annotation

GitHub Actions / Build, Test, Sonar Cloud Analysis, & Package

Pass a timeout to limit the execution time. (https://rules.sonarsource.com/csharp/RSPEC-6444)
Version version = new Version(myFileVersionInfo.FileVersion);
string textVersion = version.Major + "." + version.Minor + "." + version.Build + "-" + matches[0].Groups[1].Value;
return (version, matches[0].Groups[1].Value, textVersion);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using MigrationTools.DataContracts.Pipelines;
using MigrationTools.Enrichers;
using VstsSyncMigrator.Engine.ComponentContext;
using Environment = System.Environment;

namespace VstsSyncMigrator.Engine
{
Expand Down Expand Up @@ -633,6 +634,11 @@ private ITestPlan FindTestPlan(string planName, int sourcePlanId)
//Get Target ReflectedWorkItemId
var targetWI = Engine.Target.WorkItems.GetWorkItem(testPlan.Id.ToString());
Log.LogDebug("TestPlansAndSuitesMigrationContext::FindTestPlan::TargetWorkItem[{workItemId]", targetWI.Id);
if (!targetWI.Fields.ContainsKey(Engine.Target.Config.AsTeamProjectConfig().ReflectedWorkItemIDFieldName))
{
Log.LogError("TestPlansAndSuitesMigrationContext::FindTestPlan::TargetWorkItem[{workItemId} does not have ReflectedWorkItemId field {ReflectedWorkItemIDFieldName}", targetWI.Id, Engine.Target.Config.AsTeamProjectConfig().ReflectedWorkItemIDFieldName);
Environment.Exit(-1);
}
string workItemReflectedId = (string)targetWI.Fields[Engine.Target.Config.AsTeamProjectConfig().ReflectedWorkItemIDFieldName].Value;
Log.LogDebug("TestPlansAndSuitesMigrationContext::FindTestPlan::TargetWorkItem[{workItemId] [{ReflectedWorkItemId]", targetWI.Id, workItemReflectedId);
//Compaire
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,14 +304,16 @@ private void ValidateAllNodesExistOrAreMapped(List<WorkItemData> sourceWorkItems
contextLog.Information("Validating::Check that all Area & Iteration paths from Source have a valid mapping on Target");
if (!_nodeStructureEnricher.Options.Enabled && Engine.Target.Config.AsTeamProjectConfig().Project != Engine.Source.Config.AsTeamProjectConfig().Project)
{
throw new ConfigException("Source and Target projects have different names, but NodeStructureEnricher is not enabled. Cant continue... please enable nodeStructureEnricher in the config and restart.");
Log.LogError("Source and Target projects have different names, but NodeStructureEnricher is not enabled. Cant continue... please enable nodeStructureEnricher in the config and restart.");
Environment.Exit(-1);
}
if ( _nodeStructureEnricher.Options.Enabled)
{
List<NodeStructureItem> nodeStructureMissingItems = _nodeStructureEnricher.GetMissingRevisionNodes(sourceWorkItems);
if (_nodeStructureEnricher.ValidateTargetNodesExist(nodeStructureMissingItems))
{
throw new Exception("Missing Iterations in Target preventing progress, check log for list. To continue you MUST configure IterationMaps or AreaMaps that matches the missing paths..");
Log.LogError("Missing Iterations in Target preventing progress, check log for list. To continue you MUST configure IterationMaps or AreaMaps that matches the missing paths..");
Environment.Exit(-1);
}
} else
{
Expand All @@ -330,7 +332,7 @@ private void ValidateAllWorkItemTypesHaveReflectedWorkItemIdField(List<WorkItemD
var ex = new InvalidFieldValueException(
"Not all work items in scope contain a valid ReflectedWorkItemId Field!");
Log.LogError(ex, "Not all work items in scope contain a valid ReflectedWorkItemId Field!");
throw ex;
Environment.Exit(-1);
}
}

Expand Down Expand Up @@ -370,7 +372,7 @@ private void ValiddateWorkItemTypesExistInTarget(List<WorkItemData> sourceWorkIt
var ex = new Exception(
"Not all WorkItemTypes present in the Source are present in the Target or mapped! Filter them from the query, or map the to target types.");
Log.LogError(ex, "Not all WorkItemTypes present in the Source are present in the Target or mapped using `WorkItemTypeDefinition` in the config.");
throw ex;
Environment.Exit(-1);
}
}
}
Expand All @@ -385,7 +387,7 @@ private void ValidatePatTokenRequirement()
{
var ex = new InvalidOperationException("Missing PersonalAccessToken from Target");
Log.LogError(ex, "When you are migrating to Azure DevOps you MUST provide an PAT so that we can call the REST API for certain actions. For example we would be unable to deal with a Work item Type change.");
throw ex;
Environment.Exit(-1);
}
}
}
Expand Down
Loading