private static async Task DumpMessagesAsync()

in src/Azure.IIoT.OpcUa.Publisher.Module/cli/Program.cs [522:668]


        private static async Task DumpMessagesAsync(string messageMode, string? publishProfile,
            string? publishInitProfile, ILoggerFactory loggerFactory, TimeSpan duration,
            uint scaleunits, int errorRate, string? dumpMessagesOutput, string[] args, CancellationToken ct)
        {
            try
            {
                // Dump one message encoding at a time
                var rootFolder = Path.Combine(dumpMessagesOutput ?? ".", "dump");
                foreach (var messageProfile in MessagingProfile.Supported)
                {
                    if (messageProfile.MessageEncoding.HasFlag(MessageEncoding.IsGzipCompressed))
                    {
                        // No need to dump gzip
                        continue;
                    }

                    if (messageMode != "all" &&
                        !messageProfile.MessagingMode.ToString().Equals(
                            messageMode, StringComparison.OrdinalIgnoreCase) &&
                        !messageProfile.MessageEncoding.ToString().Equals(
                            messageMode, StringComparison.OrdinalIgnoreCase))
                    {
                        Console.WriteLine($"Skipping {messageProfile}...");
                        continue;
                    }

                    var outputFolder = Path.Combine(rootFolder, messageProfile.MessagingMode.ToString(),
                        messageProfile.MessageEncoding.ToString());
                    if (Directory.Exists(outputFolder) && Directory.EnumerateFiles(outputFolder).Any())
                    {
                        continue;
                    }
                    Directory.CreateDirectory(outputFolder);
                    await DumpPublishingProfiles(outputFolder, messageProfile, publishProfile,
                        publishInitProfile).ConfigureAwait(false);
                }
            }
            catch (OperationCanceledException) { }

            // Dump message profile for all publishing profiles
            async Task DumpPublishingProfiles(string rootFolder, MessagingProfile messageProfile,
                string? profile, string? publishInitProfile)
            {
                if (publishInitProfile != null)
                {
                    var outputFolder = Path.Combine(rootFolder, publishInitProfile);

                    await DumpMessagesForDuration(outputFolder, "Empty", messageProfile,
                        publishInitProfile, args).ConfigureAwait(false);

                    return;
                }

                foreach (var publishProfile in Directory.EnumerateFiles("./Profiles", "*.json"))
                {
                    var publishProfileName = Path.GetFileNameWithoutExtension(publishProfile);
                    if (profile == null &&
                       (publishProfileName.StartsWith("Unified", StringComparison.OrdinalIgnoreCase) ||
                        publishProfileName.StartsWith("Empty", StringComparison.OrdinalIgnoreCase) ||
                        publishProfileName.StartsWith("NoNodes", StringComparison.OrdinalIgnoreCase)))
                    {
                        continue;
                    }
                    if (profile != null && !publishProfileName.Equals(profile, StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }
                    var logger = loggerFactory.CreateLogger(publishProfileName);
                    var outputFolder = Path.Combine(rootFolder, publishProfileName);
                    if (Directory.Exists(outputFolder) && Directory.EnumerateFiles(outputFolder).Any())
                    {
                        continue;
                    }
                    Directory.CreateDirectory(outputFolder);
                    await DumpMessagesForDuration(outputFolder, publishProfile, messageProfile,
                        null, args).ConfigureAwait(false);
                }
            }

            async Task DumpMessagesForDuration(string outputFolder, string publishProfile,
                MessagingProfile messageProfile, string? publishInitProfile, string[] args)
            {
                using var runtime = new CancellationTokenSource(duration);
                try
                {
                    using var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(
                        ct, runtime.Token);
                    var name = Path.GetFileNameWithoutExtension(publishProfile);
                    Console.Title = $"Dumping {messageProfile} for {name}...";
                    await RunAsync(loggerFactory, publishProfile, messageProfile,
                        outputFolder, scaleunits, errorRate, args, publishInitProfile, linkedToken.Token).ConfigureAwait(false);
                }
                catch (OperationCanceledException) when (runtime.IsCancellationRequested) { }
            }

            static async Task RunAsync(ILoggerFactory loggerFactory, string publishProfile,
                MessagingProfile messageProfile, string outputFolder, uint scaleunits, int errorRate, string[] args,
                string? publishInitProfile, CancellationToken ct)
            {
                // Start test server
                using var server = new ServerWrapper(scaleunits, errorRate, loggerFactory, null);
                var name = Path.GetFileNameWithoutExtension(publishProfile);
                var endpointUrl = $"opc.tcp://localhost:{server.Port}/UA/SampleServer";

                var publishedNodesFilePath = await LoadPnJsonAsync(server, name, endpointUrl,
                    ct).ConfigureAwait(false);
                if (publishedNodesFilePath == null)
                {
                    return;
                }

                var publishInitFile = await LoadInitFileAsync(name, endpointUrl, ct).ConfigureAwait(false);

                //
                // Check whether the profile overrides the messaging mode, then set it to the desired
                // one regardless of whether it will work or not
                //
                var check = await File.ReadAllTextAsync(publishedNodesFilePath, ct).ConfigureAwait(false);
                if (check.Contains("\"MessagingMode\":", StringComparison.InvariantCulture) &&
                    !check.Contains($"\"MessagingMode\": \"{messageProfile.MessagingMode}\"",
                    StringComparison.InvariantCulture))
                {
                    check = ReplacePropertyValue(check, "MessagingMode", messageProfile.MessagingMode.ToString());
                    await File.WriteAllTextAsync(publishedNodesFilePath, check, ct).ConfigureAwait(false);
                }

                var arguments = new HashSet<string>
                    {
                        "-c",
                        "--ps",
                        $"--pf={publishedNodesFilePath}",
                        $"--me={messageProfile.MessageEncoding}",
                        $"--mm={messageProfile.MessagingMode}",
                        $"--ttt={name}/{{WriterGroup}}",
                        $"--mdt={name}/{{WriterGroup}}",
                        "-t=FileSystem",
                        $"-o={outputFolder}",
                        "--aa"
                    };
                if (publishInitFile != null)
                {
                    arguments.Add($"--pi={publishInitFile}");
                }
                args.ForEach(a => arguments.Add(a));
                await Publisher.Module.Program.RunAsync([.. arguments], ct).ConfigureAwait(false);
            }
        }