diff --git a/src/RMWorkflowMigrator.CmdLine/Options.cs b/src/RMWorkflowMigrator.CmdLine/Options.cs index 8d5ae45..4aa4bdf 100644 --- a/src/RMWorkflowMigrator.CmdLine/Options.cs +++ b/src/RMWorkflowMigrator.CmdLine/Options.cs @@ -45,6 +45,9 @@ internal class Options [Option('v', "Verbose", DefaultValue = false, HelpText = "Prints the detailed messages to standard output.")] public bool Verbose { get; set; } + [Option('m', "NoMetrics", DefaultValue = false, HelpText = "Stops all metrics from being captured.")] + public bool NoMetrics { get; set; } + public string ConnectionString { get diff --git a/src/RMWorkflowMigrator.CmdLine/Program.cs b/src/RMWorkflowMigrator.CmdLine/Program.cs index a4e4ebb..2bd03b9 100644 --- a/src/RMWorkflowMigrator.CmdLine/Program.cs +++ b/src/RMWorkflowMigrator.CmdLine/Program.cs @@ -12,21 +12,25 @@ namespace Microsoft.ALMRangers.RMWorkflowMigrator.CmdLine using System; using System.Collections.Generic; using System.Data.SqlClient; + using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; - using CommandLine; - using DataAccess.Model; using DataAccess.Repository; using Generator.PowerShell; using Generator.PowerShell.Model; using Parser; using Parser.Model; - + using ApplicationInsights; + using ApplicationInsights.Extensibility; + + public static class Program { + private const string ApplicationInsightsKey = "8493dd94-b866-47d8-ab6d-f61556fcc31a"; + private static readonly Dictionary SupportedVersions = new Dictionary { { "12.0.21031.1", false }, @@ -36,7 +40,8 @@ public static class Program // Everything above this point is untested. U3 may work. Earlier is unlikely. { "12.0.31101.0", true }, - { "14.0.23102.0", true } + { "14.0.23102.0", true }, + { "14.0.24712.0", true } }; private static readonly Dictionary VersionMapping = new Dictionary @@ -46,7 +51,8 @@ public static class Program { "12.0.30501.0", "2013 Update 2" }, { "12.0.30723.0", "2013 Update 3" }, { "12.0.31101.0", "2013 Update 4" }, - { "14.0.23102.0", "2015 RTM" } + { "14.0.23102.0", "2015 RTM" }, + { "14.0.24712.0", "2015 Update 1" } }; private static Options options; @@ -55,24 +61,43 @@ public static void Main(string[] args) { options = GetOptions(args); - if (!string.IsNullOrEmpty(options.OutputFolder) && options.OutputFolder.Contains("\"")) + var telemetryClient = CreateTelemetryClient(ApplicationInsightsKey, options.NoMetrics); + try { - Console.WriteLine("ERROR: The OutputPath (-o) parameter was provided with a trailing backslash. Please remove the trailing backslash and try again."); - DisplayParameters(); - return; - } + if (!string.IsNullOrEmpty(options.OutputFolder) && options.OutputFolder.Contains("\"")) + { + telemetryClient.TrackEvent("DisplayParameters/OutputPath"); - if (options.LastParserState != null && options.LastParserState.Errors.Any()) - { - DisplayParameters(); - return; - } + Console.WriteLine("ERROR: The OutputPath (-o) parameter was provided with a trailing backslash. Please remove the trailing backslash and try again."); + DisplayParameters(); + return; + } + + if (options.LastParserState != null && options.LastParserState.Errors.Any()) + { + telemetryClient.TrackEvent("DisplayParameters/All"); + + DisplayParameters(); + return; + } - // Check we have at least been passed a server name - if (!string.IsNullOrEmpty(options.SqlServerName)) + // Check we have at least been passed a server name + if (!string.IsNullOrEmpty(options.SqlServerName)) + { + var stopwatch = Stopwatch.StartNew(); + + var generatorTask = RunGeneratorAsync(); + + Task.WaitAll(generatorTask); + + stopwatch.Stop(); + telemetryClient.TrackEvent("Executed"); + telemetryClient.TrackMetric("Execution Duration", stopwatch.ElapsedMilliseconds); + } + } + finally { - var generatorTask = RunGeneratorAsync(); - Task.WaitAll(generatorTask); + telemetryClient.Flush(); } } @@ -103,6 +128,10 @@ private static async Task RetrieveRmVersion() { var versionRepo = new RMVersionRepository(options.ConnectionString); var version = await versionRepo.GetRMVersion(); + if (!VersionMapping.ContainsKey(version)) + { + throw new UnsupportedReleaseManagementVersionException(GenerateUnsupportedVersionExceptionMessage(version)); + } PrintOnlyIfVerbose($"Release Management version detected: {version} ({VersionMapping[version]})"); if (SupportedVersions[version]) @@ -110,13 +139,20 @@ private static async Task RetrieveRmVersion() return version.StartsWith("14.") ? RMVersion.Rm2015 : RMVersion.Rm2013; } + throw new UnsupportedReleaseManagementVersionException(GenerateUnsupportedVersionExceptionMessage(version)); + } + + private static string GenerateUnsupportedVersionExceptionMessage(string version) + { var exceptionMessage = new StringBuilder(); - exceptionMessage.AppendLine($"Version {version} ({VersionMapping[version]}) is unsupported."); - var supportedVersions = SupportedVersions.Where(srv => srv.Value).Select(srv => VersionMapping[srv.Key]); + exceptionMessage.AppendLine( + !VersionMapping.ContainsKey(version) + ? $"Version {version} is unsupported." + : $"Version {version} ({VersionMapping[version]}) is unsupported."); + var supportedVersions = SupportedVersions.Where(srv => srv.Value).Select(srv => $"{VersionMapping[srv.Key]} ({srv.Key})"); exceptionMessage.AppendLine("Supported versions:"); exceptionMessage.AppendLine(string.Join($",{Environment.NewLine}", supportedVersions)); - - throw new UnsupportedReleaseManagementVersionException(exceptionMessage.ToString()); + return exceptionMessage.ToString(); } private static async Task RunGeneratorAsync() @@ -172,7 +208,7 @@ private static async Task RunGeneratorAsync() private static ScriptGenerator ConfigureScriptGenerator(RMVersion version) { PrintOnlyIfVerbose($"Generating the scripts for the workflow '{options.TemplateName}' stage '{options.TemplateStage}' into folder '{options.OutputFolder}'{Environment.NewLine}"); - + // make sure we have the output folder var fs = new FileSystem(); fs.CreateDirectory(options.OutputFolder); @@ -196,10 +232,10 @@ private static async Task RetrieveWorkflow(RMVersion versi var repository = new RMReleaseTemplateRepository( options.ConnectionString, options.TemplateName, - options.TemplateStage, + options.TemplateStage, version); - PrintOnlyIfVerbose($"{Environment.NewLine}Connecting to the DB '{options.DatabaseName}' on the SQL server '{options.SqlServerName}'"); + PrintOnlyIfVerbose($"{Environment.NewLine}Connecting to the DB '{options.DatabaseName}' on the SQL server '{options.SqlServerName}'"); // get the workflow var workflow = await repository.GetDeploymentSequence(); @@ -247,5 +283,13 @@ private static void DisplayParameters() Console.WriteLine($"Verbose:\t\t\t{options.Verbose}{Environment.NewLine}"); Console.WriteLine(); } + + private static TelemetryClient CreateTelemetryClient(string instrumentationKey, bool noMetrics) + { + var configuration = TelemetryConfiguration.CreateDefault(); + configuration.InstrumentationKey = instrumentationKey; + configuration.DisableTelemetry = noMetrics; + return new TelemetryClient(configuration); + } } } diff --git a/src/RMWorkflowMigrator.CmdLine/RMWorkflowMigrator.CmdLine.csproj b/src/RMWorkflowMigrator.CmdLine/RMWorkflowMigrator.CmdLine.csproj index e889c36..ec79833 100644 --- a/src/RMWorkflowMigrator.CmdLine/RMWorkflowMigrator.CmdLine.csproj +++ b/src/RMWorkflowMigrator.CmdLine/RMWorkflowMigrator.CmdLine.csproj @@ -45,6 +45,10 @@ ..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll True + + ..\packages\Microsoft.ApplicationInsights.1.2.3\lib\net45\Microsoft.ApplicationInsights.dll + True + diff --git a/src/RMWorkflowMigrator.CmdLine/packages.config b/src/RMWorkflowMigrator.CmdLine/packages.config index 0d9f591..eea443c 100644 --- a/src/RMWorkflowMigrator.CmdLine/packages.config +++ b/src/RMWorkflowMigrator.CmdLine/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file