diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml deleted file mode 100644 index a49a230..0000000 --- a/checkstyle-suppressions.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/csharp/GlobalSuppressions.md b/csharp/GlobalSuppressions.md new file mode 100644 index 0000000..4a3ac02 --- /dev/null +++ b/csharp/GlobalSuppressions.md @@ -0,0 +1,50 @@ +# Global Suppression Notes + +## Overview + +Senzing has chosen to suppress some of the default coding guidance for .NET development in the +provided examples and code snippets via the use of `GlobalSuppressions.cs` files. This is done +to favor of readability and clarity of the examples and, in places, to encourage developers to +implement code that is more robust and easily maintained. The reasoning for each such suppression +is given here along with alternatives if you instead choose to follow the guidance from +the suppressed directives. + +### CA1859: Use concrete types when possible for improved performance + +Senzing encourages developers to use the `Senzing.Sdk.SzEnvironment` interface in favor of its concrete +implementation type throughout their code with the exception of the construction and initialization of +the `Senzing.Sdk.SzEnvironment` instance. This is encouraged so that your code can easily interchange one +implementation for another without concerns for dependencies on methods that may be specific to a concrete +implementation type. For example, one might swap `SzCoreEnvironment` for an open-source `SzGrpcEnvironment` +on a single line for initialization without concerns for searching out incompatibilities that might be +caused elsewhere in the code due to such a change. + +In short, Senzing feels that in the case of `SzEnvironment` the performance concerns referenced by `CA1859` +are insignificant and negligible especially when compared to the cost of sacrificing good Object-Oriented +Programming principles that would otherwise improve the maintainability of your source code. + +Therefore, Senzing encourages: + +```java +// initialize the Senzing environment +SzEnvironment env = SzCoreEnvironment.NewBuilder() + .Settings(settings) + .InstanceName(instanceName) + .VerboseLogging(false) + .Build(); +``` + +Over: + +```java +// initialize the Senzing environment +SzCoreEnvironment env = SzCoreEnvironment.NewBuilder() + .Settings(settings) + .InstanceName(instanceName) + .VerboseLogging(false) + .Build(); +``` + +If, however, you prefer to adhere to the guidance encouraged by `CA1859`, then simply use the +concrete type in your declaration of the environment variable **OR** use the `var` keyword in +place of a specific type name. diff --git a/csharp/README.md b/csharp/README.md index b52c549..98e475f 100644 --- a/csharp/README.md +++ b/csharp/README.md @@ -32,6 +32,12 @@ Further, you will need to set environment variables so the Senzing installation set Path=%SENZING_PATH%\er\lib;%Path% ``` +## Using Example Code + +Senzing encourages and allows you to freely copy the provided example code and modify it to your own needs as you +see fit. However, please refer to the [Global Suppression Notes] to understand how to best adapt the example code +to your own coding project. + ## Building The C# snippets can built using the `dotnet build [project-name]` command under each directory. They can be run using `dotnet run --project [project-name]` command. Attempting to run a snippet will also trigger building it. @@ -162,3 +168,5 @@ The `SnippetRunner` project will run one or more snippets for you and create a t - stewardship.ForceResolve - stewardship.ForceUnresolve ``` + +[Global Suppression Notes]: GlobalSuppressions.md \ No newline at end of file diff --git a/csharp/runner/SnippetRunner/GlobalSuppressions.cs b/csharp/runner/SnippetRunner/GlobalSuppressions.cs new file mode 100644 index 0000000..50397e6 --- /dev/null +++ b/csharp/runner/SnippetRunner/GlobalSuppressions.cs @@ -0,0 +1,10 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1854:Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method", Justification = "Nullable Dictionary making for less readable code.")] +[assembly: SuppressMessage("Usage", "CA2201:Do not raise reserved exception types", Justification = "These are examples and there is no need to use more specific exceptions")] +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "It is better to OOP principle to use interfaces rather than concrete types")] diff --git a/csharp/runner/SnippetRunner/InstallLocations.cs b/csharp/runner/SnippetRunner/InstallLocations.cs index e1ba735..8bf9f07 100644 --- a/csharp/runner/SnippetRunner/InstallLocations.cs +++ b/csharp/runner/SnippetRunner/InstallLocations.cs @@ -1,3 +1,5 @@ +namespace Senzing.Snippets.Runner; + using System.Text; using System.Text.Json; using System.Text.RegularExpressions; @@ -315,8 +317,7 @@ private static bool IsDirectory(string path) supportDir = (supportPath != null) ? new DirectoryInfo(supportPath) : null; // check if support dir is not defined AND we have a local dev build - if (supportDir == null && installDir != null - && "dist".Equals(installDir.Name, OrdinalIgnoreCase)) + if (supportDir == null && "dist".Equals(installDir.Name, OrdinalIgnoreCase)) { supportDir = new DirectoryInfo(Path.Combine(installDir.FullName, "data")); if (!supportDir.Exists) @@ -386,7 +387,7 @@ private static bool IsDirectory(string path) resourceDir = (resourcePath != null) ? new DirectoryInfo(resourcePath) : null; // try the "resources" sub-directory of the installation - if (resourceDir == null && installDir != null) + if (resourceDir == null) { resourceDir = new DirectoryInfo(Path.Combine(installDir.FullName, "resources")); if (!resourceDir.Exists) @@ -456,7 +457,7 @@ private static bool IsDirectory(string path) configDir = (configPath != null) ? new DirectoryInfo(configPath) : null; // check if config dir is not defined AND we have a local dev build - if (configDir == null && installDir != null && templatesDir != null + if (configDir == null && templatesDir != null && "dist".Equals(installDir.Name, OrdinalIgnoreCase)) { configDir = templatesDir; @@ -473,7 +474,7 @@ private static bool IsDirectory(string path) } // if still null, try to use the install's etc directory - if (configDir == null && installDir != null) + if (configDir == null) { configDir = new DirectoryInfo( Path.Combine(installDir.FullName, "etc")); @@ -572,7 +573,7 @@ private static bool IsDirectory(string path) result.supportDir = supportDir; result.resourceDir = resourceDir; result.templatesDir = templatesDir; - result.devBuild = (installDir != null) && ("dist".Equals(installDir.Name, OrdinalIgnoreCase)); + result.devBuild = ("dist".Equals(installDir.Name, OrdinalIgnoreCase)); // return the result return result; diff --git a/csharp/runner/SnippetRunner/Program.cs b/csharp/runner/SnippetRunner/Program.cs index 980b6d6..9246a8e 100644 --- a/csharp/runner/SnippetRunner/Program.cs +++ b/csharp/runner/SnippetRunner/Program.cs @@ -1,12 +1,18 @@ -using System.Collections; +using System.Collections; using System.Diagnostics; +using System.Globalization; using System.Reflection; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; + using Microsoft.Data.Sqlite; + using Senzing.Sdk; using Senzing.Sdk.Core; +using Senzing.Snippets.Runner; + +using static System.StringComparison; using static Senzing.Sdk.SzFlags; Assembly assembly = Assembly.GetExecutingAssembly(); @@ -52,7 +58,7 @@ if (snippetDir == null && runnerDir != null) { csharpDir = Directory.GetParent(runnerDir.FullName); - if (!"csharp".Equals(csharpDir?.Name)) + if (!"csharp".Equals(csharpDir?.Name, Ordinal)) { HandleWrongDirectory(); } @@ -86,7 +92,7 @@ SortedDictionary> snippetsMap { string group = entry.Key; IDictionary snippetMap = entry.Value; - IList<(string, string, string)> tuples + List<(string, string, string)> tuples = new List<(string, string, string)>(snippetMap.Count); foreach (KeyValuePair subEntry in snippetMap) @@ -106,7 +112,7 @@ SortedDictionary> snippetsMap { string snippet = subEntry.Key; string snippetPath = subEntry.Value; - IList<(string, string, string)> tuples = new List<(string, string, string)>(1); + List<(string, string, string)> tuples = new List<(string, string, string)>(1); tuples.Add((group, snippet, snippetPath)); snippetOptions.Add(snippet, tuples.AsReadOnly()); } @@ -132,7 +138,7 @@ SortedDictionary> snippetsMap settingsJson = JsonNode.Parse(settings)?.AsObject(); if (settingsJson == null) { - throw new Exception("Setting must be a JSON object: " + settings); + throw new ArgumentNullException("Setting must be a JSON object: " + settings); } } catch (Exception e) @@ -141,6 +147,7 @@ SortedDictionary> snippetsMap Console.Error.WriteLine("The provided Senzing settings were not valid JSON:"); Console.Error.WriteLine(); Environment.Exit(1); + throw; } } @@ -155,6 +162,7 @@ SortedDictionary> snippetsMap { Console.Error.WriteLine(e); Environment.Exit(1); + throw; } if (installLocations == null) { @@ -164,11 +172,11 @@ SortedDictionary> snippetsMap return; } - IList<(string, string)> snippets = new List<(string, string)>(100); + List<(string, string)> snippets = new List<(string, string)>(100); for (int index = 0; index < args.Length; index++) { string arg = args[index]; - if (arg.Equals("all")) + if (arg.Equals("all", Ordinal)) { foreach (IDictionary snippetMap in snippetsMap.Values) { @@ -230,7 +238,7 @@ SortedDictionary> snippetsMap { Console.WriteLine(); Stopwatch stopwatch = Stopwatch.StartNew(); - IDictionary properties = new Dictionary(); + Dictionary properties = new Dictionary(); string resourceName = $"""{assemblyName}.Resources.{snippet}.properties"""; LoadProperties(properties, resourceName); Console.WriteLine("Preparing repository for " + snippet + "..."); @@ -285,14 +293,14 @@ SortedDictionary> snippetsMap "Missing resource (" + fileName + ") for load file (" + loadKey + ") for snippet (" + snippet + ")"); } + StreamReader rdr = new StreamReader(stream, Encoding.UTF8); try { - StreamReader rdr = new StreamReader(stream, Encoding.UTF8); for (string? line = rdr.ReadLine(); line != null; line = rdr.ReadLine()) { line = line.Trim(); if (line.Length == 0) continue; - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; JsonObject? record = JsonNode.Parse(line)?.AsObject(); if (record == null) { @@ -307,6 +315,7 @@ SortedDictionary> snippetsMap } finally { + rdr.Close(); stream.Close(); } @@ -337,7 +346,7 @@ SortedDictionary> snippetsMap { Console.Error.WriteLine(e); Environment.Exit(1); - return; + throw; } static void LoadProperties(IDictionary properties, String resourceName) @@ -352,9 +361,9 @@ static void LoadProperties(IDictionary properties, String resour for (string? line = rdr.ReadLine(); line != null; line = rdr.ReadLine()) { if (line.Trim().Length == 0) continue; - if (line.StartsWith("#")) continue; - if (line.StartsWith("!")) continue; - int index = line.IndexOf('='); + if (line.StartsWith('#')) continue; + if (line.StartsWith('!')) continue; + int index = line.IndexOf('=', Ordinal); if (index < 1) continue; string key = line.Substring(0, index).Trim(); string value = ""; @@ -363,18 +372,19 @@ static void LoadProperties(IDictionary properties, String resour value = line.Substring(index + 1); } value = value.Trim(); - while (value.EndsWith("\\")) + while (value.EndsWith('\\')) { line = rdr.ReadLine(); if (line == null) break; line = line.Trim(); - value = value.Substring(0, value.Length - 1) + line; + value = string.Concat(value.AsSpan(0, value.Length - 1), line); } properties[key] = value; } } finally { + rdr.Close(); stream.Close(); } } @@ -393,11 +403,12 @@ SortedDictionary> snippetsMap { continue; } - if (!snippetsMap.ContainsKey(group)) + snippetsMap.TryGetValue(group, out SortedDictionary? snippetMap); + if (snippetMap == null) { - snippetsMap.Add(group, new SortedDictionary()); + snippetMap = new SortedDictionary(); + snippetsMap.Add(group, snippetMap); } - SortedDictionary snippetMap = snippetsMap[group]; foreach (string subdir in Directory.GetDirectories(dir)) { @@ -495,7 +506,7 @@ static void ExecuteSnippet(string snippet, Process? process = Process.Start(startInfo); if (process == null) { - throw new Exception("Failed to execute snippet; " + snippet); + throw new ArgumentNullException("Failed to execute snippet; " + snippet); } if (properties != null && properties.ContainsKey(InputKeyPrefix + 0)) @@ -520,7 +531,7 @@ static void ExecuteSnippet(string snippet, if (properties != null && properties.ContainsKey(DestroyAfterKey)) { string propValue = properties[DestroyAfterKey]; - int delay = Int32.Parse(propValue); + int delay = Int32.Parse(propValue, CultureInfo.InvariantCulture); bool exited = process.WaitForExit(delay); if (!exited && !process.HasExited) { @@ -622,11 +633,11 @@ static string SetupTempRepository(InstallLocations senzingInstall) } } - string supportPath = supportDir.FullName.Replace("\\", "\\\\"); - string configPath = configDir.FullName.Replace("\\", "\\\\"); ; - string resourcePath = resourcesDir.FullName.Replace("\\", "\\\\"); ; - string baseConfig = File.ReadAllText(configFile).Replace("\\", "\\\\"); - string databasePath = databaseFile.Replace("\\", "\\\\"); + string supportPath = supportDir.FullName.Replace("\\", "\\\\", Ordinal); + string configPath = configDir.FullName.Replace("\\", "\\\\", Ordinal); + string resourcePath = resourcesDir.FullName.Replace("\\", "\\\\", Ordinal); + string baseConfig = File.ReadAllText(configFile).Replace("\\", "\\\\", Ordinal); + string databasePath = databaseFile.Replace("\\", "\\\\", Ordinal); string settings = $$""" { "PIPELINE": { diff --git a/csharp/snippets/configuration/AddDataSources/GlobalSuppressions.cs b/csharp/snippets/configuration/AddDataSources/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/configuration/AddDataSources/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/configuration/AddDataSources/Program.cs b/csharp/snippets/configuration/AddDataSources/Program.cs index 01bc4f7..a94493a 100644 --- a/csharp/snippets/configuration/AddDataSources/Program.cs +++ b/csharp/snippets/configuration/AddDataSources/Program.cs @@ -41,7 +41,7 @@ // get the SzConfig for the config ID SzConfig config = configMgr.CreateConfig(configID); - + // create an array of the data sources to add string[] dataSources = { "CUSTOMERS", "EMPLOYEES", "WATCHLIST" }; @@ -56,7 +56,7 @@ // add the modified config to the repository with a comment long newConfigID = configMgr.RegisterConfig(modifiedConfig); - + try { // replace the default config diff --git a/csharp/snippets/configuration/InitDefaultConfig/GlobalSuppressions.cs b/csharp/snippets/configuration/InitDefaultConfig/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/configuration/InitDefaultConfig/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/configuration/InitDefaultConfig/Program.cs b/csharp/snippets/configuration/InitDefaultConfig/Program.cs index 200c1e4..20d0aac 100644 --- a/csharp/snippets/configuration/InitDefaultConfig/Program.cs +++ b/csharp/snippets/configuration/InitDefaultConfig/Program.cs @@ -32,12 +32,12 @@ SzConfigManager configMgr = env.GetConfigManager(); // prepare a config to be modified - SzConfig config = configMgr.CreateConfig(); - string configDefinition = config.Export(); + SzConfig config = configMgr.CreateConfig(); + string configDefinition = config.Export(); // add the modified config to the repository with a comment configMgr.SetDefaultConfig(configDefinition); - + } catch (SzException e) { diff --git a/csharp/snippets/deleting/DeleteViaFutures/GlobalSuppressions.cs b/csharp/snippets/deleting/DeleteViaFutures/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/deleting/DeleteViaFutures/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/deleting/DeleteViaFutures/LimitedConcurrenyLevelTaskScheduler.cs b/csharp/snippets/deleting/DeleteViaFutures/LimitedConcurrenyLevelTaskScheduler.cs index 487bdf1..c7893ac 100644 --- a/csharp/snippets/deleting/DeleteViaFutures/LimitedConcurrenyLevelTaskScheduler.cs +++ b/csharp/snippets/deleting/DeleteViaFutures/LimitedConcurrenyLevelTaskScheduler.cs @@ -15,13 +15,15 @@ public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler private readonly int _maxDegreeOfParallelism; // Indicates whether the scheduler is currently processing work items. - private int _delegatesQueuedOrRunning = 0; + private int _delegatesQueuedOrRunning; // Creates a new instance with the specified degree of parallelism. public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) { - if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); - _maxDegreeOfParallelism = maxDegreeOfParallelism; + ArgumentOutOfRangeException.ThrowIfLessThan( + maxDegreeOfParallelism, 1, nameof(maxDegreeOfParallelism)); + + this._maxDegreeOfParallelism = maxDegreeOfParallelism; } // Queues a task to the scheduler. diff --git a/csharp/snippets/deleting/DeleteViaFutures/Program.cs b/csharp/snippets/deleting/DeleteViaFutures/Program.cs index 0c228c4..f2ee5d1 100644 --- a/csharp/snippets/deleting/DeleteViaFutures/Program.cs +++ b/csharp/snippets/deleting/DeleteViaFutures/Program.cs @@ -50,10 +50,11 @@ TaskScheduler taskScheduler IList<(Task, Record)> pendingFutures = new List<(Task, Record)>(MaximumBacklog); FileStream fs = new FileStream(filePath, FileMode.Open); + +// create a reader +StreamReader rdr = new StreamReader(fs, Encoding.UTF8); try { - // create a reader - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); // get the engine from the environment SzEngine engine = env.GetEngine(); @@ -85,7 +86,7 @@ TaskScheduler taskScheduler if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; // construct the Record instance Record record = new Record(lineNumber, line); @@ -105,10 +106,13 @@ TaskScheduler taskScheduler string? recordID = recordJson[RecordID]?.GetValue(); Task task = factory.StartNew(() => - { - // call the DeleteRecord() function with no flags - engine.DeleteRecord(dataSourceCode, recordID, SzNoFlags); - }); + { + // call the DeleteRecord() function with no flags + engine.DeleteRecord(dataSourceCode, recordID); + }, + CancellationToken.None, + TaskCreationOptions.None, + taskScheduler); // add the future to the pending future list pendingFutures.Add((task, record)); @@ -130,15 +134,7 @@ TaskScheduler taskScheduler // briefly before trying again if (pendingFutures.Count >= MaximumBacklog) { - try - { - Thread.Sleep(PauseTimeout); - - } - catch (Exception) - { - // do nothing - } + Thread.Sleep(PauseTimeout); } } while (pendingFutures.Count >= MaximumBacklog); } @@ -159,8 +155,9 @@ TaskScheduler taskScheduler } finally { + rdr.Close(); fs.Close(); - + // IMPORTANT: make sure to destroy the environment env.Destroy(); @@ -330,12 +327,12 @@ public partial class Program private const string Critical = "CRITICAL"; - public record Record(int LineNumber, String Line) { } + private static int errorCount; + private static int successCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; - private static int errorCount = 0; - private static int successCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; +} -} \ No newline at end of file +internal sealed record Record(int LineNumber, String Line) { } diff --git a/csharp/snippets/deleting/DeleteViaLoop/GlobalSuppressions.cs b/csharp/snippets/deleting/DeleteViaLoop/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/deleting/DeleteViaLoop/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/deleting/DeleteViaLoop/Program.cs b/csharp/snippets/deleting/DeleteViaLoop/Program.cs index f49596a..35ffb64 100644 --- a/csharp/snippets/deleting/DeleteViaLoop/Program.cs +++ b/csharp/snippets/deleting/DeleteViaLoop/Program.cs @@ -32,10 +32,10 @@ string filePath = (args.Length > 0) ? args[0] : DefaultFilePath; FileStream fs = new FileStream(filePath, FileMode.Open); +// create a reader +StreamReader rdr = new StreamReader(fs, Encoding.UTF8); try { - // create a reader - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); // get the engine from the environment SzEngine engine = env.GetEngine(); @@ -55,7 +55,7 @@ if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; try { @@ -130,8 +130,9 @@ } finally { + rdr.Close(); fs.Close(); - + // IMPORTANT: make sure to destroy the environment env.Destroy(); @@ -188,18 +189,16 @@ public partial class Program private const string RecordID = "RECORD_ID"; - private const int PauseTimeout = 100; - private const string Error = "ERROR"; private const string Warning = "WARNING"; private const string Critical = "CRITICAL"; - private static int errorCount = 0; - private static int successCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static int errorCount; + private static int successCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; } \ No newline at end of file diff --git a/csharp/snippets/deleting/DeleteWithInfoViaFutures/GlobalSuppressions.cs b/csharp/snippets/deleting/DeleteWithInfoViaFutures/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/deleting/DeleteWithInfoViaFutures/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/deleting/DeleteWithInfoViaFutures/LimitedConcurrenyLevelTaskScheduler.cs b/csharp/snippets/deleting/DeleteWithInfoViaFutures/LimitedConcurrenyLevelTaskScheduler.cs index 487bdf1..c7893ac 100644 --- a/csharp/snippets/deleting/DeleteWithInfoViaFutures/LimitedConcurrenyLevelTaskScheduler.cs +++ b/csharp/snippets/deleting/DeleteWithInfoViaFutures/LimitedConcurrenyLevelTaskScheduler.cs @@ -15,13 +15,15 @@ public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler private readonly int _maxDegreeOfParallelism; // Indicates whether the scheduler is currently processing work items. - private int _delegatesQueuedOrRunning = 0; + private int _delegatesQueuedOrRunning; // Creates a new instance with the specified degree of parallelism. public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) { - if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); - _maxDegreeOfParallelism = maxDegreeOfParallelism; + ArgumentOutOfRangeException.ThrowIfLessThan( + maxDegreeOfParallelism, 1, nameof(maxDegreeOfParallelism)); + + this._maxDegreeOfParallelism = maxDegreeOfParallelism; } // Queues a task to the scheduler. diff --git a/csharp/snippets/deleting/DeleteWithInfoViaFutures/Program.cs b/csharp/snippets/deleting/DeleteWithInfoViaFutures/Program.cs index a930e2a..dfbcdcf 100644 --- a/csharp/snippets/deleting/DeleteWithInfoViaFutures/Program.cs +++ b/csharp/snippets/deleting/DeleteWithInfoViaFutures/Program.cs @@ -39,7 +39,7 @@ // execution to a specific limited pool of threads. In order to // improve performance and conserve memory we want to use the same // threads for Senzing work. The TaskScheduler implementation used -// here is directly pulled from Mirosoft's TaskScheduler documentation +// here is directly pulled from Microsoft's TaskScheduler documentation TaskScheduler taskScheduler = new LimitedConcurrencyLevelTaskScheduler(ThreadCount); @@ -51,10 +51,11 @@ TaskScheduler taskScheduler = new List<(Task, Record)>(MaximumBacklog); FileStream fs = new FileStream(filePath, FileMode.Open); + +// create a reader +StreamReader rdr = new StreamReader(fs, Encoding.UTF8); try { - // create a reader - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); // get the engine from the environment SzEngine engine = env.GetEngine(); @@ -86,7 +87,7 @@ TaskScheduler taskScheduler if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; // construct the Record instance Record record = new Record(lineNumber, line); @@ -106,10 +107,13 @@ TaskScheduler taskScheduler string? recordID = recordJson[RecordID]?.GetValue(); Task task = factory.StartNew(() => - { - // call the DeleteRecord() function with info flags - return engine.DeleteRecord(dataSourceCode, recordID, SzWithInfo); - }); + { + // call the DeleteRecord() function with info flags + return engine.DeleteRecord(dataSourceCode, recordID, SzWithInfo); + }, + CancellationToken.None, + TaskCreationOptions.None, + taskScheduler); // add the future to the pending future list pendingFutures.Add((task, record)); @@ -131,15 +135,7 @@ TaskScheduler taskScheduler // briefly before trying again if (pendingFutures.Count >= MaximumBacklog) { - try - { - Thread.Sleep(PauseTimeout); - - } - catch (Exception) - { - // do nothing - } + Thread.Sleep(PauseTimeout); } } while (pendingFutures.Count >= MaximumBacklog); } @@ -160,8 +156,9 @@ TaskScheduler taskScheduler } finally { + rdr.Close(); fs.Close(); - + // IMPORTANT: make sure to destroy the environment env.Destroy(); @@ -385,17 +382,17 @@ public partial class Program private const string Critical = "CRITICAL"; - public record Record(int LineNumber, String Line) { } - - private static int errorCount = 0; + private static int errorCount; - private static int successCount = 0; + private static int successCount; - private static int retryCount = 0; + private static int retryCount; - private static FileInfo? retryFile = null; + private static FileInfo? retryFile; - private static StreamWriter? retryWriter = null; + private static StreamWriter? retryWriter; private static readonly ISet entityIDSet = new HashSet(); -} \ No newline at end of file +} + +internal sealed record Record(int LineNumber, String Line) { } diff --git a/csharp/snippets/information/CheckDatastorePerformance/GlobalSuppressions.cs b/csharp/snippets/information/CheckDatastorePerformance/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/information/CheckDatastorePerformance/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/information/GetDatastoreInfo/GlobalSuppressions.cs b/csharp/snippets/information/GetDatastoreInfo/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/information/GetDatastoreInfo/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/information/GetLicense/GlobalSuppressions.cs b/csharp/snippets/information/GetLicense/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/information/GetLicense/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/information/GetVersion/GlobalSuppressions.cs b/csharp/snippets/information/GetVersion/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/information/GetVersion/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/initialization/EnginePriming/GlobalSuppressions.cs b/csharp/snippets/initialization/EnginePriming/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/initialization/EnginePriming/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/initialization/EnvironmentAndHubs/GlobalSuppressions.cs b/csharp/snippets/initialization/EnvironmentAndHubs/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/initialization/EnvironmentAndHubs/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/initialization/PurgeRepository/GlobalSuppressions.cs b/csharp/snippets/initialization/PurgeRepository/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/initialization/PurgeRepository/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/initialization/PurgeRepository/Program.cs b/csharp/snippets/initialization/PurgeRepository/Program.cs index 27c5ff1..082f4ed 100644 --- a/csharp/snippets/initialization/PurgeRepository/Program.cs +++ b/csharp/snippets/initialization/PurgeRepository/Program.cs @@ -9,6 +9,8 @@ using Senzing.Sdk; using Senzing.Sdk.Core; +#pragma warning disable CA1303 // Do not pass literals as localized parameters (example messages) + // confirm purge Console.WriteLine(PurgeMessage); string? response = Console.ReadLine(); @@ -78,6 +80,7 @@ public partial class Program { private const string PurgeMessage = """ + **************************************** WARNING **************************************** This example will purge all currently loaded data from the Senzing datastore! @@ -90,4 +93,6 @@ This example will purge all currently loaded data from the Senzing datastore! private static readonly ReadOnlyCollection YesAnswers = new ReadOnlyCollection(["y", "Y", "Yes", "yes", "YES"]); -} \ No newline at end of file +} + +#pragma warning restore CA1303 // Do not pass literals as localized parameters (example messages) diff --git a/csharp/snippets/loading/LoadRecords/GlobalSuppressions.cs b/csharp/snippets/loading/LoadRecords/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/loading/LoadRecords/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/loading/LoadTruthSetWithInfoViaLoop/GlobalSuppressions.cs b/csharp/snippets/loading/LoadTruthSetWithInfoViaLoop/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/loading/LoadTruthSetWithInfoViaLoop/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/loading/LoadTruthSetWithInfoViaLoop/Program.cs b/csharp/snippets/loading/LoadTruthSetWithInfoViaLoop/Program.cs index e88d41d..eb0b9f7 100644 --- a/csharp/snippets/loading/LoadTruthSetWithInfoViaLoop/Program.cs +++ b/csharp/snippets/loading/LoadTruthSetWithInfoViaLoop/Program.cs @@ -39,9 +39,10 @@ { FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); + StreamReader rdr = new StreamReader(fs, Encoding.UTF8); + try { - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); int lineNumber = 0; // loop through the example records and add them to the repository for (string? line = rdr.ReadLine(); line != null; line = rdr.ReadLine()) @@ -56,7 +57,7 @@ if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; try { @@ -125,6 +126,7 @@ } finally { + rdr.Close(); fs.Close(); } } @@ -259,10 +261,10 @@ public partial class Program private const string Critical = "CRITICAL"; // setup some class-wide variables - private static int errorCount = 0; - private static int successCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static int errorCount; + private static int successCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; private static readonly ISet entityIDSet = new HashSet(); } diff --git a/csharp/snippets/loading/LoadViaFutures/GlobalSuppressions.cs b/csharp/snippets/loading/LoadViaFutures/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/loading/LoadViaFutures/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/loading/LoadViaFutures/LimitedConcurrenyLevelTaskScheduler.cs b/csharp/snippets/loading/LoadViaFutures/LimitedConcurrenyLevelTaskScheduler.cs index 487bdf1..c7893ac 100644 --- a/csharp/snippets/loading/LoadViaFutures/LimitedConcurrenyLevelTaskScheduler.cs +++ b/csharp/snippets/loading/LoadViaFutures/LimitedConcurrenyLevelTaskScheduler.cs @@ -15,13 +15,15 @@ public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler private readonly int _maxDegreeOfParallelism; // Indicates whether the scheduler is currently processing work items. - private int _delegatesQueuedOrRunning = 0; + private int _delegatesQueuedOrRunning; // Creates a new instance with the specified degree of parallelism. public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) { - if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); - _maxDegreeOfParallelism = maxDegreeOfParallelism; + ArgumentOutOfRangeException.ThrowIfLessThan( + maxDegreeOfParallelism, 1, nameof(maxDegreeOfParallelism)); + + this._maxDegreeOfParallelism = maxDegreeOfParallelism; } // Queues a task to the scheduler. diff --git a/csharp/snippets/loading/LoadViaFutures/Program.cs b/csharp/snippets/loading/LoadViaFutures/Program.cs index 9821743..605ace2 100644 --- a/csharp/snippets/loading/LoadViaFutures/Program.cs +++ b/csharp/snippets/loading/LoadViaFutures/Program.cs @@ -50,10 +50,11 @@ TaskScheduler taskScheduler IList<(Task, Record)> pendingFutures = new List<(Task, Record)>(MaximumBacklog); FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); + +// create a reader +StreamReader rdr = new StreamReader(fs, Encoding.UTF8); try { - // create a reader - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); // get the engine from the environment SzEngine engine = env.GetEngine(); @@ -85,7 +86,7 @@ TaskScheduler taskScheduler if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; // construct the Record instance Record record = new Record(lineNumber, line); @@ -105,10 +106,13 @@ TaskScheduler taskScheduler string? recordID = recordJson[RecordID]?.GetValue(); Task task = factory.StartNew(() => - { - // call the addRecord() function with no flags - engine.AddRecord(dataSourceCode, recordID, record.Line, SzNoFlags); - }); + { + // call the addRecord() function with no flags + engine.AddRecord(dataSourceCode, recordID, record.Line); + }, + CancellationToken.None, + TaskCreationOptions.None, + taskScheduler); // add the future to the pending future list pendingFutures.Add((task, record)); @@ -130,15 +134,7 @@ TaskScheduler taskScheduler // briefly before trying again if (pendingFutures.Count >= MaximumBacklog) { - try - { - Thread.Sleep(PauseTimeout); - - } - catch (Exception) - { - // do nothing - } + Thread.Sleep(PauseTimeout); } } while (pendingFutures.Count >= MaximumBacklog); } @@ -159,6 +155,9 @@ TaskScheduler taskScheduler } finally { + // close the reader + rdr.Close(); + // close the file stream fs.Close(); @@ -330,12 +329,13 @@ public partial class Program private const string Critical = "CRITICAL"; - public record Record(int LineNumber, string Line) { } + private static int errorCount; + private static int successCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; + +} - private static int errorCount = 0; - private static int successCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; +internal sealed record Record(int LineNumber, string Line) { } -} \ No newline at end of file diff --git a/csharp/snippets/loading/LoadViaLoop/GlobalSuppressions.cs b/csharp/snippets/loading/LoadViaLoop/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/loading/LoadViaLoop/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/loading/LoadViaLoop/Program.cs b/csharp/snippets/loading/LoadViaLoop/Program.cs index fe61630..7870a98 100644 --- a/csharp/snippets/loading/LoadViaLoop/Program.cs +++ b/csharp/snippets/loading/LoadViaLoop/Program.cs @@ -32,11 +32,12 @@ string filePath = (args.Length > 0) ? args[0] : DefaultFilePath; FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); + +// create a reader +StreamReader rdr = new StreamReader(fs, Encoding.UTF8); + try { - // create a reader - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); - // get the engine from the environment SzEngine engine = env.GetEngine(); @@ -55,7 +56,7 @@ if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; try { @@ -130,6 +131,7 @@ } finally { + rdr.Close(); fs.Close(); // IMPORTANT: make sure to destroy the environment @@ -188,18 +190,16 @@ public partial class Program private const string RecordID = "RECORD_ID"; - private const int PauseTimeout = 100; - private const string Error = "ERROR"; private const string Warning = "WARNING"; private const string Critical = "CRITICAL"; - private static int errorCount = 0; - private static int successCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static int errorCount; + private static int successCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; } \ No newline at end of file diff --git a/csharp/snippets/loading/LoadViaQueue/GlobalSuppressions.cs b/csharp/snippets/loading/LoadViaQueue/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/loading/LoadViaQueue/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/loading/LoadViaQueue/Program.cs b/csharp/snippets/loading/LoadViaQueue/Program.cs index bb3c844..91ad306 100644 --- a/csharp/snippets/loading/LoadViaQueue/Program.cs +++ b/csharp/snippets/loading/LoadViaQueue/Program.cs @@ -35,6 +35,7 @@ Thread producer = new Thread(() => { FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); +#pragma warning disable CA1031 // Catch *all* exceptions so we can record it for the thread try { StreamReader rdr = new StreamReader(fs, Encoding.UTF8); @@ -57,7 +58,7 @@ if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; // add the record to the queue recordQueue.Add(new Record(lineNumber, line)); @@ -73,6 +74,7 @@ fs.Close(); recordQueue.CompleteAdding(); } +#pragma warning restore CA1031 // Catch *all* exceptions so we can record it for the thread }); // start the producer @@ -80,6 +82,7 @@ Thread consumer = new Thread(() => { +#pragma warning disable CA1031 // Catch *all* exceptions so we can record it for the thread try { // get the engine from the environment @@ -180,6 +183,7 @@ { consumerFailure = e; } +#pragma warning restore CA1031 // Catch *all* exceptions so we can record it for the thread }); // start the consumer @@ -259,7 +263,7 @@ static bool IsStopped(Thread thread) { - lock (thread) + lock (Monitor) { return (thread.ThreadState == ThreadState.Stopped); } @@ -301,21 +305,17 @@ public partial class Program private const string RecordID = "RECORD_ID"; - private const int PauseTimeout = 100; - private const string Error = "ERROR"; private const string Warning = "WARNING"; private const string Critical = "CRITICAL"; - public record Record(int LineNumber, String Line) { } - - private static int errorCount = 0; - private static int successCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static int errorCount; + private static int successCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; private const int MaximumBacklog = 100; @@ -326,7 +326,9 @@ public record Record(int LineNumber, String Line) { } private static readonly BlockingCollection recordQueue = new BlockingCollection(MaximumBacklog); - private static volatile Exception? producerFailure = null; - private static volatile Exception? consumerFailure = null; + private static volatile Exception? producerFailure; + private static volatile Exception? consumerFailure; } +internal sealed record Record(int LineNumber, String Line) { } + diff --git a/csharp/snippets/loading/LoadWithInfoViaFutures/GlobalSuppressions.cs b/csharp/snippets/loading/LoadWithInfoViaFutures/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/loading/LoadWithInfoViaFutures/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/loading/LoadWithInfoViaFutures/LimitedConcurrenyLevelTaskScheduler.cs b/csharp/snippets/loading/LoadWithInfoViaFutures/LimitedConcurrenyLevelTaskScheduler.cs index 487bdf1..c7893ac 100644 --- a/csharp/snippets/loading/LoadWithInfoViaFutures/LimitedConcurrenyLevelTaskScheduler.cs +++ b/csharp/snippets/loading/LoadWithInfoViaFutures/LimitedConcurrenyLevelTaskScheduler.cs @@ -15,13 +15,15 @@ public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler private readonly int _maxDegreeOfParallelism; // Indicates whether the scheduler is currently processing work items. - private int _delegatesQueuedOrRunning = 0; + private int _delegatesQueuedOrRunning; // Creates a new instance with the specified degree of parallelism. public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) { - if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); - _maxDegreeOfParallelism = maxDegreeOfParallelism; + ArgumentOutOfRangeException.ThrowIfLessThan( + maxDegreeOfParallelism, 1, nameof(maxDegreeOfParallelism)); + + this._maxDegreeOfParallelism = maxDegreeOfParallelism; } // Queues a task to the scheduler. diff --git a/csharp/snippets/loading/LoadWithInfoViaFutures/Program.cs b/csharp/snippets/loading/LoadWithInfoViaFutures/Program.cs index 75f2097..809e7dd 100644 --- a/csharp/snippets/loading/LoadWithInfoViaFutures/Program.cs +++ b/csharp/snippets/loading/LoadWithInfoViaFutures/Program.cs @@ -51,10 +51,11 @@ TaskScheduler taskScheduler = new List<(Task, Record)>(MaximumBacklog); FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); + +// create a reader +StreamReader rdr = new StreamReader(fs, Encoding.UTF8); try { - // create a reader - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); // get the engine from the environment SzEngine engine = env.GetEngine(); @@ -86,7 +87,7 @@ TaskScheduler taskScheduler if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; // construct the Record instance Record record = new Record(lineNumber, line); @@ -106,11 +107,14 @@ TaskScheduler taskScheduler string? recordID = recordJson[RecordID]?.GetValue(); Task task = factory.StartNew(() => - { - // call the addRecord() function with info flags - return engine.AddRecord( - dataSourceCode, recordID, record.Line, SzWithInfo); - }); + { + // call the addRecord() function with info flags + return engine.AddRecord( + dataSourceCode, recordID, record.Line, SzWithInfo); + }, + CancellationToken.None, + TaskCreationOptions.None, + taskScheduler); // add the future to the pending future list pendingFutures.Add((task, record)); @@ -132,15 +136,7 @@ TaskScheduler taskScheduler // briefly before trying again if (pendingFutures.Count >= MaximumBacklog) { - try - { - Thread.Sleep(PauseTimeout); - - } - catch (Exception) - { - // do nothing - } + Thread.Sleep(PauseTimeout); } } while (pendingFutures.Count >= MaximumBacklog); } @@ -161,8 +157,9 @@ TaskScheduler taskScheduler } finally { + rdr.Close(); fs.Close(); - + // IMPORTANT: make sure to destroy the environment env.Destroy(); @@ -388,17 +385,18 @@ public partial class Program private const string Critical = "CRITICAL"; - public record Record(int LineNumber, string Line) { } - - private static int errorCount = 0; + private static int errorCount; - private static int successCount = 0; + private static int successCount; - private static int retryCount = 0; + private static int retryCount; - private static FileInfo? retryFile = null; + private static FileInfo? retryFile; - private static StreamWriter? retryWriter = null; + private static StreamWriter? retryWriter; private static readonly ISet entityIDSet = new HashSet(); -} \ No newline at end of file +} + +internal sealed record Record(int LineNumber, string Line) { } + diff --git a/csharp/snippets/loading/LoadWithStatsViaLoop/GlobalSuppressions.cs b/csharp/snippets/loading/LoadWithStatsViaLoop/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/loading/LoadWithStatsViaLoop/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/loading/LoadWithStatsViaLoop/Program.cs b/csharp/snippets/loading/LoadWithStatsViaLoop/Program.cs index 31a672b..66845c3 100644 --- a/csharp/snippets/loading/LoadWithStatsViaLoop/Program.cs +++ b/csharp/snippets/loading/LoadWithStatsViaLoop/Program.cs @@ -32,11 +32,11 @@ string filePath = (args.Length > 0) ? args[0] : DefaultFilePath; FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); + +// create a reader +StreamReader rdr = new StreamReader(fs, Encoding.UTF8); try { - // create a reader - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); - // get the engine from the environment SzEngine engine = env.GetEngine(); @@ -55,7 +55,7 @@ if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; try { @@ -84,7 +84,7 @@ string stats = engine.GetStats(); if (stats.Length > StatsTruncate) { - stats = stats.Substring(0, StatsTruncate) + " ..."; + stats = string.Concat(stats.AsSpan(0, StatsTruncate), " ..."); } Console.WriteLine("* STATS: " + stats); @@ -151,8 +151,10 @@ } finally { + rdr.Close(); + fs.Close(); - + // IMPORTANT: make sure to destroy the environment env.Destroy(); @@ -209,8 +211,6 @@ public partial class Program private const string RecordID = "RECORD_ID"; - private const int PauseTimeout = 100; - private const string Error = "ERROR"; private const string Warning = "WARNING"; @@ -221,9 +221,9 @@ public partial class Program private const int StatsTruncate = 70; - private static int errorCount = 0; - private static int successCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static int errorCount; + private static int successCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; } \ No newline at end of file diff --git a/csharp/snippets/redo/LoadWithRedoViaLoop/GlobalSuppressions.cs b/csharp/snippets/redo/LoadWithRedoViaLoop/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/redo/LoadWithRedoViaLoop/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/redo/LoadWithRedoViaLoop/Program.cs b/csharp/snippets/redo/LoadWithRedoViaLoop/Program.cs index af1f8af..308a5f8 100644 --- a/csharp/snippets/redo/LoadWithRedoViaLoop/Program.cs +++ b/csharp/snippets/redo/LoadWithRedoViaLoop/Program.cs @@ -39,9 +39,10 @@ { FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); + StreamReader rdr = new StreamReader(fs, Encoding.UTF8); + try { - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); int lineNumber = 0; // loop through the example records and add them to the repository for (string? line = rdr.ReadLine(); line != null; line = rdr.ReadLine()) @@ -56,7 +57,7 @@ if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; try { @@ -102,6 +103,7 @@ } finally { + rdr.Close(); fs.Close(); } } @@ -263,10 +265,10 @@ public partial class Program private const string Critical = "CRITICAL"; // setup some class-wide variables - private static int errorCount = 0; - private static int successCount = 0; - private static int redoneCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static int errorCount; + private static int successCount; + private static int redoneCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; } diff --git a/csharp/snippets/redo/RedoContinuous/GlobalSuppressions.cs b/csharp/snippets/redo/RedoContinuous/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/redo/RedoContinuous/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/redo/RedoContinuous/Program.cs b/csharp/snippets/redo/RedoContinuous/Program.cs index b9e63eb..403fede 100644 --- a/csharp/snippets/redo/RedoContinuous/Program.cs +++ b/csharp/snippets/redo/RedoContinuous/Program.cs @@ -9,6 +9,8 @@ using static Senzing.Sdk.SzFlags; +#pragma warning disable CA1303 // Do not pass literals as localized parameters (example messages) + // get the senzing repository settings string? settings = Environment.GetEnvironmentVariable("SENZING_ENGINE_CONFIGURATION_JSON"); if (settings == null) @@ -187,9 +189,11 @@ public partial class Program private const string Critical = "CRITICAL"; // setup some class-wide variables - private static int errorCount = 0; - private static int redoneCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static int errorCount; + private static int redoneCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; } + +#pragma warning restore CA1303 // Do not pass literals as localized parameters (example messages) diff --git a/csharp/snippets/redo/RedoContinuousViaFutures/GlobalSuppressions.cs b/csharp/snippets/redo/RedoContinuousViaFutures/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/redo/RedoContinuousViaFutures/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/redo/RedoContinuousViaFutures/LimitedConcurrenyLevelTaskScheduler.cs b/csharp/snippets/redo/RedoContinuousViaFutures/LimitedConcurrenyLevelTaskScheduler.cs index 487bdf1..c7893ac 100644 --- a/csharp/snippets/redo/RedoContinuousViaFutures/LimitedConcurrenyLevelTaskScheduler.cs +++ b/csharp/snippets/redo/RedoContinuousViaFutures/LimitedConcurrenyLevelTaskScheduler.cs @@ -15,13 +15,15 @@ public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler private readonly int _maxDegreeOfParallelism; // Indicates whether the scheduler is currently processing work items. - private int _delegatesQueuedOrRunning = 0; + private int _delegatesQueuedOrRunning; // Creates a new instance with the specified degree of parallelism. public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) { - if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); - _maxDegreeOfParallelism = maxDegreeOfParallelism; + ArgumentOutOfRangeException.ThrowIfLessThan( + maxDegreeOfParallelism, 1, nameof(maxDegreeOfParallelism)); + + this._maxDegreeOfParallelism = maxDegreeOfParallelism; } // Queues a task to the scheduler. diff --git a/csharp/snippets/redo/RedoContinuousViaFutures/Program.cs b/csharp/snippets/redo/RedoContinuousViaFutures/Program.cs index e4f6a49..3d4cdc9 100644 --- a/csharp/snippets/redo/RedoContinuousViaFutures/Program.cs +++ b/csharp/snippets/redo/RedoContinuousViaFutures/Program.cs @@ -11,6 +11,8 @@ using static Senzing.Sdk.SzFlags; +#pragma warning disable CA1303 // Do not pass literals as localized parameters (example messages) + // get the senzing repository settings string? settings = Environment.GetEnvironmentVariable("SENZING_ENGINE_CONFIGURATION_JSON"); if (settings == null) @@ -46,6 +48,7 @@ TaskScheduler taskScheduler AppDomain.CurrentDomain.ProcessExit += (s, e) => { +#pragma warning disable CA1031 // Need to catch all exceptions here try { HandlePendingFutures(pendingFutures, true); @@ -54,6 +57,7 @@ TaskScheduler taskScheduler { Console.Error.WriteLine(exception); } +#pragma warning restore CA1031 // Need to catch all exceptions here // IMPORTANT: make sure to destroy the environment env.Destroy(); @@ -79,9 +83,12 @@ TaskScheduler taskScheduler if (redo == null) break; Task task = factory.StartNew(() => - { - engine.ProcessRedoRecord(redo, SzNoFlags); - }); + { + engine.ProcessRedoRecord(redo, SzNoFlags); + }, + CancellationToken.None, + TaskCreationOptions.None, + taskScheduler); // add the future to the pending future list pendingFutures.Add((task, redo)); @@ -300,11 +307,11 @@ public partial class Program private const string Critical = "CRITICAL"; // setup some class-wide variables - private static int errorCount = 0; - private static int redoneCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static int errorCount; + private static int redoneCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; private const int ThreadCount = 8; @@ -313,4 +320,6 @@ public partial class Program private const int MaximumBacklog = ThreadCount * BacklogFactor; private const int HandlePauseTimeout = 100; -} \ No newline at end of file +} + +#pragma warning restore CA1303 // Do not pass literals as localized parameters (example messages) diff --git a/csharp/snippets/redo/RedoWithInfoContinuous/GlobalSuppressions.cs b/csharp/snippets/redo/RedoWithInfoContinuous/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/redo/RedoWithInfoContinuous/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/redo/RedoWithInfoContinuous/Program.cs b/csharp/snippets/redo/RedoWithInfoContinuous/Program.cs index 1cadca9..ab3b831 100644 --- a/csharp/snippets/redo/RedoWithInfoContinuous/Program.cs +++ b/csharp/snippets/redo/RedoWithInfoContinuous/Program.cs @@ -9,6 +9,8 @@ using static Senzing.Sdk.SzFlag; +#pragma warning disable CA1303 // Do not pass literals as localized parameters (example messages) + // get the senzing repository settings string? settings = Environment.GetEnvironmentVariable("SENZING_ENGINE_CONFIGURATION_JSON"); if (settings == null) @@ -241,11 +243,13 @@ public partial class Program private const string EntityID = "ENTITY_ID"; // setup some class-wide variables - private static int errorCount = 0; - private static int redoneCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static int errorCount; + private static int redoneCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; private static readonly ISet entityIDSet = new HashSet(); } + +#pragma warning restore CA1303 // Do not pass literals as localized parameters (example messages) diff --git a/csharp/snippets/searching/SearchRecords/GlobalSuppressions.cs b/csharp/snippets/searching/SearchRecords/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/searching/SearchRecords/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/searching/SearchRecords/Program.cs b/csharp/snippets/searching/SearchRecords/Program.cs index f57c48c..81dec3f 100644 --- a/csharp/snippets/searching/SearchRecords/Program.cs +++ b/csharp/snippets/searching/SearchRecords/Program.cs @@ -58,10 +58,10 @@ obj = obj?["RESOLVED_ENTITY"]?.AsObject(); if (obj == null) { - throw new Exception("Unexpected result format: " + result); + throw new JsonException("Unexpected result format: " + result); } - long? entityID = obj?["ENTITY_ID"]?.GetValue(); - string? name = obj?["ENTITY_NAME"]?.GetValue(); + long? entityID = obj["ENTITY_ID"]?.GetValue(); + string? name = obj["ENTITY_NAME"]?.GetValue(); Console.WriteLine(entityID + ": " + name); } } diff --git a/csharp/snippets/searching/SearchViaFutures/GlobalSuppressions.cs b/csharp/snippets/searching/SearchViaFutures/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/searching/SearchViaFutures/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/searching/SearchViaFutures/LimitedConcurrenyLevelTaskScheduler.cs b/csharp/snippets/searching/SearchViaFutures/LimitedConcurrenyLevelTaskScheduler.cs index 487bdf1..c7893ac 100644 --- a/csharp/snippets/searching/SearchViaFutures/LimitedConcurrenyLevelTaskScheduler.cs +++ b/csharp/snippets/searching/SearchViaFutures/LimitedConcurrenyLevelTaskScheduler.cs @@ -15,13 +15,15 @@ public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler private readonly int _maxDegreeOfParallelism; // Indicates whether the scheduler is currently processing work items. - private int _delegatesQueuedOrRunning = 0; + private int _delegatesQueuedOrRunning; // Creates a new instance with the specified degree of parallelism. public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism) { - if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism"); - _maxDegreeOfParallelism = maxDegreeOfParallelism; + ArgumentOutOfRangeException.ThrowIfLessThan( + maxDegreeOfParallelism, 1, nameof(maxDegreeOfParallelism)); + + this._maxDegreeOfParallelism = maxDegreeOfParallelism; } // Queues a task to the scheduler. diff --git a/csharp/snippets/searching/SearchViaFutures/Program.cs b/csharp/snippets/searching/SearchViaFutures/Program.cs index 54987e7..5d97cfd 100644 --- a/csharp/snippets/searching/SearchViaFutures/Program.cs +++ b/csharp/snippets/searching/SearchViaFutures/Program.cs @@ -47,15 +47,15 @@ TaskScheduler taskScheduler TaskFactory factory = new TaskFactory(taskScheduler); // keep track of the pending tasks and don't backlog too many for memory's sake -IList<(Task, Criteria)> pendingFutures +List<(Task, Criteria)> pendingFutures = new List<(Task, Criteria)>(MaximumBacklog); FileStream fs = new FileStream(filePath, FileMode.Open); + +// create a reader +StreamReader rdr = new StreamReader(fs, Encoding.UTF8); try { - // create a reader - StreamReader rdr = new StreamReader(fs, Encoding.UTF8); - // get the engine from the environment SzEngine engine = env.GetEngine(); @@ -86,7 +86,7 @@ TaskScheduler taskScheduler if (line.Length == 0) continue; // skip any commented lines - if (line.StartsWith("#")) continue; + if (line.StartsWith('#')) continue; // construct the Record instance Criteria criteria = new Criteria(lineNumber, line); @@ -94,11 +94,14 @@ TaskScheduler taskScheduler try { Task task = factory.StartNew(() => - { - // call the addRecord() function with no flags - return engine.SearchByAttributes( - criteria.Line, SzSearchByAttributesDefaultFlags); - }); + { + // call the addRecord() function with no flags + return engine.SearchByAttributes( + criteria.Line, SzSearchByAttributesDefaultFlags); + }, + CancellationToken.None, + TaskCreationOptions.None, + taskScheduler); // add the future to the pending future list pendingFutures.Add((task, criteria)); @@ -120,15 +123,7 @@ TaskScheduler taskScheduler // briefly before trying again if (pendingFutures.Count >= MaximumBacklog) { - try - { - Thread.Sleep(PauseTimeout); - - } - catch (Exception) - { - // do nothing - } + Thread.Sleep(PauseTimeout); } } while (pendingFutures.Count >= MaximumBacklog); } @@ -149,6 +144,9 @@ TaskScheduler taskScheduler } finally { + rdr.Close(); + fs.Close(); + // IMPORTANT: make sure to destroy the environment env.Destroy(); @@ -328,14 +326,14 @@ public partial class Program private const string Critical = "CRITICAL"; - public record Criteria(int LineNumber, string Line) { } + private static int errorCount; + private static int successCount; + private static int retryCount; + private static FileInfo? retryFile; + private static StreamWriter? retryWriter; - private static int errorCount = 0; - private static int successCount = 0; - private static int retryCount = 0; - private static FileInfo? retryFile = null; - private static StreamWriter? retryWriter = null; + private static readonly HashSet foundEntities = new HashSet(); - private static readonly ISet foundEntities = new HashSet(); +} +internal sealed record Criteria(int LineNumber, string Line) { } -} \ No newline at end of file diff --git a/csharp/snippets/stewardship/ForceResolve/GlobalSuppressions.cs b/csharp/snippets/stewardship/ForceResolve/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/stewardship/ForceResolve/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/stewardship/ForceResolve/Program.cs b/csharp/snippets/stewardship/ForceResolve/Program.cs index ad31f04..6a61f53 100644 --- a/csharp/snippets/stewardship/ForceResolve/Program.cs +++ b/csharp/snippets/stewardship/ForceResolve/Program.cs @@ -9,6 +9,8 @@ using static Senzing.Sdk.SzFlags; +#pragma warning disable CA1303 // Do not pass literals as localized parameters (example messages) + // get the senzing repository settings string? settings = Environment.GetEnvironmentVariable("SENZING_ENGINE_CONFIGURATION_JSON"); if (settings == null) @@ -65,8 +67,8 @@ Console.WriteLine(); Console.WriteLine("Updating records with TRUSTED_ID to force resolve..."); - string record1 = engine.GetRecord(TEST, "1", SzRecordDefaultFlags); - string record3 = engine.GetRecord(TEST, "3", SzRecordDefaultFlags); + string record1 = engine.GetRecord(TestDataSource, "1", SzRecordDefaultFlags); + string record3 = engine.GetRecord(TestDataSource, "3", SzRecordDefaultFlags); JsonObject?[] jsonObjects = { JsonNode.Parse(record1)?.AsObject()?["JSON_DATA"]?.AsObject(), @@ -76,14 +78,14 @@ { if (obj == null) { - throw new Exception("Parsed record is unexpectedly null: " + throw new JsonException("Parsed record is unexpectedly null: " + record1 + " / " + record3); } obj["TRUSTED_ID_NUMBER"] = JsonNode.Parse("\"TEST_R1-TEST_R3\""); obj["TRUSTED_ID_TYPE"] = JsonNode.Parse("\"FORCE_RESOLVE\""); } - engine.AddRecord(TEST, "1", jsonObjects[0]?.ToJsonString()); - engine.AddRecord(TEST, "3", jsonObjects[1]?.ToJsonString()); + engine.AddRecord(TestDataSource, "1", jsonObjects[0]?.ToJsonString()); + engine.AddRecord(TestDataSource, "3", jsonObjects[1]?.ToJsonString()); Console.WriteLine(); @@ -135,7 +137,7 @@ /// static IDictionary<(string, string), string> GetRecords() { - IDictionary<(string, string), string> records + SortedDictionary<(string, string), string> records = new SortedDictionary<(string, string), string>(); records.Add( @@ -182,5 +184,7 @@ public partial class Program { - public const string TEST = "Test"; -} \ No newline at end of file + private const string TestDataSource = "Test"; +} + +#pragma warning restore CA1303 // Do not pass literals as localized parameters (example messages) diff --git a/csharp/snippets/stewardship/ForceUnresolve/GlobalSuppressions.cs b/csharp/snippets/stewardship/ForceUnresolve/GlobalSuppressions.cs new file mode 100644 index 0000000..dce1d18 --- /dev/null +++ b/csharp/snippets/stewardship/ForceUnresolve/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Performance hit is insignificant versus OOP best practices for code maintainability")] diff --git a/csharp/snippets/stewardship/ForceUnresolve/Program.cs b/csharp/snippets/stewardship/ForceUnresolve/Program.cs index dfbc53d..5e554b4 100644 --- a/csharp/snippets/stewardship/ForceUnresolve/Program.cs +++ b/csharp/snippets/stewardship/ForceUnresolve/Program.cs @@ -9,6 +9,8 @@ using static Senzing.Sdk.SzFlags; +#pragma warning disable CA1303 // Do not pass literals as localized parameters (example messages) + // get the senzing repository settings string? settings = Environment.GetEnvironmentVariable("SENZING_ENGINE_CONFIGURATION_JSON"); if (settings == null) @@ -65,8 +67,8 @@ Console.WriteLine(); Console.WriteLine("Updating records with TRUSTED_ID to force resolve..."); - string record4 = engine.GetRecord(TEST, "4", SzRecordDefaultFlags); - string record6 = engine.GetRecord(TEST, "6", SzRecordDefaultFlags); + string record4 = engine.GetRecord(TestDataSource, "4", SzRecordDefaultFlags); + string record6 = engine.GetRecord(TestDataSource, "6", SzRecordDefaultFlags); JsonObject? obj4 = JsonNode.Parse(record4)?.AsObject(); JsonObject? obj6 = JsonNode.Parse(record6)?.AsObject(); @@ -76,7 +78,7 @@ if (obj4 == null || obj6 == null) { - throw new Exception("The JSON_DATA parses as null: " + throw new JsonException("The JSON_DATA parses as null: " + record4 + " / " + record6); } @@ -86,8 +88,8 @@ obj6["TRUSTED_ID_NUMBER"] = JsonNode.Parse("\"TEST_R6-TEST_R4\""); obj6["TRUSTED_ID_TYPE"] = JsonNode.Parse("\"FORCE_UNRESOLVE\""); - engine.AddRecord(TEST, "4", obj4.ToJsonString()); - engine.AddRecord(TEST, "6", obj6.ToJsonString()); + engine.AddRecord(TestDataSource, "4", obj4.ToJsonString()); + engine.AddRecord(TestDataSource, "6", obj6.ToJsonString()); Console.WriteLine(); @@ -139,7 +141,7 @@ /// static IDictionary<(string, string), string> GetRecords() { - IDictionary<(string, string), string> records + SortedDictionary<(string, string), string> records = new SortedDictionary<(string, string), string>(); records.Add( @@ -185,5 +187,7 @@ public partial class Program { - public const string TEST = "Test"; -} \ No newline at end of file + private const string TestDataSource = "Test"; +} + +#pragma warning restore CA1303 // Do not pass literals as localized parameters (example messages) diff --git a/java/checkstyle-suppressions.xml b/java/checkstyle-suppressions.xml index a49a230..7730f6f 100644 --- a/java/checkstyle-suppressions.xml +++ b/java/checkstyle-suppressions.xml @@ -7,4 +7,16 @@ - \ No newline at end of file + + + + + + + + + + + + + diff --git a/java/snippets/configuration/AddDataSources.java b/java/snippets/configuration/AddDataSources.java index 442fc13..c6baf19 100644 --- a/java/snippets/configuration/AddDataSources.java +++ b/java/snippets/configuration/AddDataSources.java @@ -40,7 +40,7 @@ public static void main(String[] args) { SzConfig config = configMgr.createConfig(configId); // create an array of the data sources to add - String[] dataSources = { "CUSTOMERS", "EMPLOYEES", "WATCHLIST" }; + String[] dataSources = {"CUSTOMERS", "EMPLOYEES", "WATCHLIST"}; // loop through the array and add each data source for (String dataSource : dataSources) { @@ -88,4 +88,4 @@ public static void main(String[] args) { } } -} \ No newline at end of file +} diff --git a/java/snippets/configuration/InitDefaultConfig.java b/java/snippets/configuration/InitDefaultConfig.java index 8774bfa..ad33fc8 100644 --- a/java/snippets/configuration/InitDefaultConfig.java +++ b/java/snippets/configuration/InitDefaultConfig.java @@ -56,4 +56,4 @@ public static void main(String[] args) { } } -} \ No newline at end of file +} diff --git a/java/snippets/deleting/DeleteViaFutures.java b/java/snippets/deleting/DeleteViaFutures.java index ffa5729..fab9426 100644 --- a/java/snippets/deleting/DeleteViaFutures.java +++ b/java/snippets/deleting/DeleteViaFutures.java @@ -67,10 +67,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } // construct the Record instance Record record = new Record(lineNumber, line); @@ -165,18 +169,20 @@ private static void handlePendingFutures(Map, Record> pendingFutures, throws Exception { // check for completed futures - Iterator,Record>> iter + Iterator, Record>> iter = pendingFutures.entrySet().iterator(); // loop through the pending futures while (iter.hasNext()) { // get the next pending future - Map.Entry,Record> entry = iter.next(); + Map.Entry, Record> entry = iter.next(); Future future = entry.getKey(); Record record = entry.getValue(); // if not blocking and this one is not done then continue - if (!blocking && !future.isDone()) continue; + if (!blocking && !future.isDone()) { + continue; + } // remove the pending future from the map iter.remove(); @@ -209,7 +215,7 @@ private static void handlePendingFutures(Map, Record> pendingFutures, logFailedRecord(ERROR, e, record.lineNumber, record.line); errorCount++; // increment the error count - } catch (SzRetryableException|InterruptedException|CancellationException e) { + } catch (SzRetryableException | InterruptedException | CancellationException e) { // handle thread interruption and cancellation as retries logFailedRecord(WARNING, e, record.lineNumber, record.line); errorCount++; // increment the error count @@ -282,4 +288,4 @@ public record Record(int lineNumber, String line) { } private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; -} \ No newline at end of file +} diff --git a/java/snippets/deleting/DeleteViaLoop.java b/java/snippets/deleting/DeleteViaLoop.java index a4cf8a9..8fea4cd 100644 --- a/java/snippets/deleting/DeleteViaLoop.java +++ b/java/snippets/deleting/DeleteViaLoop.java @@ -48,10 +48,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } try { // parse the line as a JSON object @@ -68,7 +72,7 @@ public static void main(String[] args) { successCount++; - } catch (JsonException|SzBadInputException e) { + } catch (JsonException | SzBadInputException e) { logFailedRecord(ERROR, e, lineNumber, line); errorCount++; // increment the error count @@ -164,4 +168,4 @@ private static void logFailedRecord(String errorType, private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; -} \ No newline at end of file +} diff --git a/java/snippets/deleting/DeleteWithInfoViaFutures.java b/java/snippets/deleting/DeleteWithInfoViaFutures.java index 1ab9597..89b7de4 100644 --- a/java/snippets/deleting/DeleteWithInfoViaFutures.java +++ b/java/snippets/deleting/DeleteWithInfoViaFutures.java @@ -67,10 +67,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } // construct the Record instance Record record = new Record(lineNumber, line); @@ -166,18 +170,20 @@ private static void handlePendingFutures(SzEngine engine, throws Exception { // check for completed futures - Iterator,Record>> iter + Iterator, Record>> iter = pendingFutures.entrySet().iterator(); // loop through the pending futures while (iter.hasNext()) { // get the next pending future - Map.Entry,Record> entry = iter.next(); + Map.Entry, Record> entry = iter.next(); Future future = entry.getKey(); Record record = entry.getValue(); // if not blocking and this one is not done then continue - if (!blocking && !future.isDone()) continue; + if (!blocking && !future.isDone()) { + continue; + } // remove the pending future from the map iter.remove(); @@ -213,7 +219,7 @@ private static void handlePendingFutures(SzEngine engine, logFailedRecord(ERROR, e, record.lineNumber, record.line); errorCount++; // increment the error count - } catch (SzRetryableException|InterruptedException|CancellationException e) { + } catch (SzRetryableException | InterruptedException | CancellationException e) { // handle thread interruption and cancellation as retries logFailedRecord(WARNING, e, record.lineNumber, record.line); errorCount++; // increment the error count @@ -239,15 +245,18 @@ private static void handlePendingFutures(SzEngine engine, /** * Example method for parsing and handling the INFO message (formatted * as JSON). This example implementation simply tracks all entity ID's - * that appear as "AFFECTED_ENTITIES" to count the number + * that appear as "AFFECTED_ENTITIES" to count the number * of entities deleted for the records -- essentially a contrived * data mart. * + * @param engine the {@link SzEngine} to use. * @param info The info message. */ private static void processInfo(SzEngine engine, String info) { JsonObject jsonObject = Json.createReader(new StringReader(info)).readObject(); - if (!jsonObject.containsKey(AFFECTED_ENTITIES)) return; + if (!jsonObject.containsKey(AFFECTED_ENTITIES)) { + return; + } JsonArray affectedArr = jsonObject.getJsonArray(AFFECTED_ENTITIES); for (JsonObject affected : affectedArr.getValuesAs(JsonObject.class)) { JsonNumber number = affected.getJsonNumber(ENTITY_ID); @@ -320,5 +329,5 @@ public record Record(int lineNumber, String line) { } private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; - private static final Set entityIdSet = new HashSet<>(); -} \ No newline at end of file + private static Set entityIdSet = new HashSet<>(); +} diff --git a/java/snippets/information/CheckDatastorePerformance.java b/java/snippets/information/CheckDatastorePerformance.java index 146a611..1a482ff 100644 --- a/java/snippets/information/CheckDatastorePerformance.java +++ b/java/snippets/information/CheckDatastorePerformance.java @@ -56,4 +56,4 @@ public static void main(String[] args) { } private static final int SECONDS_TO_RUN = 3; -} \ No newline at end of file +} diff --git a/java/snippets/information/GetDatastoreInfo.java b/java/snippets/information/GetDatastoreInfo.java index 031d3b0..f6373e5 100644 --- a/java/snippets/information/GetDatastoreInfo.java +++ b/java/snippets/information/GetDatastoreInfo.java @@ -55,4 +55,4 @@ public static void main(String[] args) { } } -} \ No newline at end of file +} diff --git a/java/snippets/information/GetLicense.java b/java/snippets/information/GetLicense.java index 0a79d2c..a1774b4 100644 --- a/java/snippets/information/GetLicense.java +++ b/java/snippets/information/GetLicense.java @@ -53,4 +53,4 @@ public static void main(String[] args) { } } -} \ No newline at end of file +} diff --git a/java/snippets/information/GetVersion.java b/java/snippets/information/GetVersion.java index 956f54b..7f1189f 100644 --- a/java/snippets/information/GetVersion.java +++ b/java/snippets/information/GetVersion.java @@ -52,4 +52,4 @@ public static void main(String[] args) { } } -} \ No newline at end of file +} diff --git a/java/snippets/initialization/EnginePriming.java b/java/snippets/initialization/EnginePriming.java index 26a5d04..40c3555 100644 --- a/java/snippets/initialization/EnginePriming.java +++ b/java/snippets/initialization/EnginePriming.java @@ -60,4 +60,4 @@ public static void main(String[] args) { } private static final long ONE_MILLION = 1000000L; -} \ No newline at end of file +} diff --git a/java/snippets/initialization/EnvironmentAndHubs.java b/java/snippets/initialization/EnvironmentAndHubs.java index 4d79552..5d23b4f 100644 --- a/java/snippets/initialization/EnvironmentAndHubs.java +++ b/java/snippets/initialization/EnvironmentAndHubs.java @@ -62,4 +62,4 @@ public static void main(String[] args) { } } -} \ No newline at end of file +} diff --git a/java/snippets/initialization/PurgeRepository.java b/java/snippets/initialization/PurgeRepository.java index 79034ec..976883f 100644 --- a/java/snippets/initialization/PurgeRepository.java +++ b/java/snippets/initialization/PurgeRepository.java @@ -89,4 +89,4 @@ public static void main(String[] args) { env.destroy(); } } -} \ No newline at end of file +} diff --git a/java/snippets/loading/LoadRecords.java b/java/snippets/loading/LoadRecords.java index 8de197c..723842e 100644 --- a/java/snippets/loading/LoadRecords.java +++ b/java/snippets/loading/LoadRecords.java @@ -34,7 +34,7 @@ public static void main(String[] args) { SzEngine engine = env.getEngine(); // loop through the example records and add them to the repository - for (Map.Entry entry : getRecords().entrySet()) { + for (Map.Entry entry : getRecords().entrySet()) { SzRecordKey recordKey = entry.getKey(); String recordDefinition = entry.getValue(); @@ -168,4 +168,4 @@ public static Map getRecords() { return records; } -} \ No newline at end of file +} diff --git a/java/snippets/loading/LoadTruthSetWithInfoViaLoop.java b/java/snippets/loading/LoadTruthSetWithInfoViaLoop.java index 0e9f499..1d18c3e 100644 --- a/java/snippets/loading/LoadTruthSetWithInfoViaLoop.java +++ b/java/snippets/loading/LoadTruthSetWithInfoViaLoop.java @@ -39,7 +39,7 @@ public class LoadTruthSetWithInfoViaLoop { private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; - private static final Set entityIdSet = new HashSet<>(); + private static Set entityIdSet = new HashSet<>(); public static void main(String[] args) { // get the senzing repository settings @@ -79,10 +79,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } try { // parse the line as a JSON object @@ -102,7 +106,7 @@ public static void main(String[] args) { // process the info processInfo(engine, info); - } catch (JsonException|SzBadInputException e) { + } catch (JsonException | SzBadInputException e) { logFailedRecord(ERROR, e, filePath, lineNumber, line); errorCount++; // increment the error count @@ -162,7 +166,7 @@ public static void main(String[] args) { /** * Example method for parsing and handling the INFO message (formatted * as JSON). This example implementation simply tracks all entity ID's - * that appear as "AFFECTED_ENTITIES" to count the number + * that appear as "AFFECTED_ENTITIES" to count the number * of entities created for the records -- essentially a contrived * data mart. * @@ -171,7 +175,9 @@ public static void main(String[] args) { */ private static void processInfo(SzEngine engine, String info) { JsonObject jsonObject = Json.createReader(new StringReader(info)).readObject(); - if (!jsonObject.containsKey(AFFECTED_ENTITIES)) return; + if (!jsonObject.containsKey(AFFECTED_ENTITIES)) { + return; + } JsonArray affectedArr = jsonObject.getJsonArray(AFFECTED_ENTITIES); for (JsonObject affected : affectedArr.getValuesAs(JsonObject.class)) { JsonNumber number = affected.getJsonNumber(ENTITY_ID); @@ -197,6 +203,7 @@ private static void processInfo(SzEngine engine, String info) { * * @param errorType The error type description. * @param exception The exception itself. + * @param filePath The path to the file that was the source of the failed record. * @param lineNumber The line number of the failed record in the JSON input file. * @param recordJson The JSON text for the failed record. */ @@ -218,4 +225,4 @@ private static void logFailedRecord(String errorType, System.err.flush(); } -} \ No newline at end of file +} diff --git a/java/snippets/loading/LoadViaFutures.java b/java/snippets/loading/LoadViaFutures.java index f9d7b45..5de5175 100644 --- a/java/snippets/loading/LoadViaFutures.java +++ b/java/snippets/loading/LoadViaFutures.java @@ -67,10 +67,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } // construct the Record instance Record record = new Record(lineNumber, line); @@ -166,18 +170,20 @@ private static void handlePendingFutures(Map, Record> pendingFutures, throws Exception { // check for completed futures - Iterator,Record>> iter + Iterator, Record>> iter = pendingFutures.entrySet().iterator(); // loop through the pending futures while (iter.hasNext()) { // get the next pending future - Map.Entry,Record> entry = iter.next(); + Map.Entry, Record> entry = iter.next(); Future future = entry.getKey(); Record record = entry.getValue(); // if not blocking and this one is not done then continue - if (!blocking && !future.isDone()) continue; + if (!blocking && !future.isDone()) { + continue; + } // remove the pending future from the map iter.remove(); @@ -210,7 +216,7 @@ private static void handlePendingFutures(Map, Record> pendingFutures, logFailedRecord(ERROR, e, record.lineNumber, record.line); errorCount++; // increment the error count - } catch (SzRetryableException|InterruptedException|CancellationException e) { + } catch (SzRetryableException | InterruptedException | CancellationException e) { // handle thread interruption and cancellation as retries logFailedRecord(WARNING, e, record.lineNumber, record.line); errorCount++; // increment the error count @@ -283,5 +289,4 @@ public record Record(int lineNumber, String line) { } private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; - -} \ No newline at end of file +} diff --git a/java/snippets/loading/LoadViaLoop.java b/java/snippets/loading/LoadViaLoop.java index f898c7e..209b5f1 100644 --- a/java/snippets/loading/LoadViaLoop.java +++ b/java/snippets/loading/LoadViaLoop.java @@ -48,10 +48,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } try { // parse the line as a JSON object @@ -68,7 +72,7 @@ public static void main(String[] args) { successCount++; - } catch (JsonException|SzBadInputException e) { + } catch (JsonException | SzBadInputException e) { logFailedRecord(ERROR, e, lineNumber, line); errorCount++; // increment the error count @@ -164,4 +168,4 @@ private static void logFailedRecord(String errorType, private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; -} \ No newline at end of file +} diff --git a/java/snippets/loading/LoadViaQueue.java b/java/snippets/loading/LoadViaQueue.java index 34fb025..70090ea 100644 --- a/java/snippets/loading/LoadViaQueue.java +++ b/java/snippets/loading/LoadViaQueue.java @@ -53,10 +53,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } // add the record to the queue recordQueue.put(new Record(lineNumber, line)); @@ -109,7 +113,7 @@ public static void main(String[] args) { successCount++; } - } catch (JsonException|SzBadInputException e) { + } catch (JsonException | SzBadInputException e) { logFailedRecord(ERROR, e, lineNumber, line); synchronized (MONITOR) { errorCount++; // increment the error count @@ -262,9 +266,9 @@ private static void logFailedRecord(String errorType, public record Record(int lineNumber, String line) { } - private static final BlockingQueue recordQueue + private static BlockingQueue recordQueue = new LinkedBlockingQueue<>(MAXIMUM_BACKLOG); private static volatile Exception producerFailure = null; private static volatile Exception consumerFailure = null; -} \ No newline at end of file +} diff --git a/java/snippets/loading/LoadWithInfoViaFutures.java b/java/snippets/loading/LoadWithInfoViaFutures.java index 26b96d0..e6dcaaf 100644 --- a/java/snippets/loading/LoadWithInfoViaFutures.java +++ b/java/snippets/loading/LoadWithInfoViaFutures.java @@ -67,10 +67,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } // construct the Record instance Record record = new Record(lineNumber, line); @@ -166,18 +170,20 @@ private static void handlePendingFutures(SzEngine engine, throws Exception { // check for completed futures - Iterator,Record>> iter + Iterator, Record>> iter = pendingFutures.entrySet().iterator(); // loop through the pending futures while (iter.hasNext()) { // get the next pending future - Map.Entry,Record> entry = iter.next(); + Map.Entry, Record> entry = iter.next(); Future future = entry.getKey(); Record record = entry.getValue(); // if not blocking and this one is not done then continue - if (!blocking && !future.isDone()) continue; + if (!blocking && !future.isDone()) { + continue; + } // remove the pending future from the map iter.remove(); @@ -213,7 +219,7 @@ private static void handlePendingFutures(SzEngine engine, logFailedRecord(ERROR, e, record.lineNumber, record.line); errorCount++; // increment the error count - } catch (SzRetryableException|InterruptedException|CancellationException e) { + } catch (SzRetryableException | InterruptedException | CancellationException e) { // handle thread interruption and cancellation as retries logFailedRecord(WARNING, e, record.lineNumber, record.line); errorCount++; // increment the error count @@ -239,15 +245,18 @@ private static void handlePendingFutures(SzEngine engine, /** * Example method for parsing and handling the INFO message (formatted * as JSON). This example implementation simply tracks all entity ID's - * that appear as "AFFECTED_ENTITIES" to count the number + * that appear as "AFFECTED_ENTITIES" to count the number * of entities created for the records -- essentially a contrived * data mart. * + * @param engine The {@link SzEngine} to use. * @param info The info message. */ private static void processInfo(SzEngine engine, String info) { JsonObject jsonObject = Json.createReader(new StringReader(info)).readObject(); - if (!jsonObject.containsKey(AFFECTED_ENTITIES)) return; + if (!jsonObject.containsKey(AFFECTED_ENTITIES)) { + return; + } JsonArray affectedArr = jsonObject.getJsonArray(AFFECTED_ENTITIES); for (JsonObject affected : affectedArr.getValuesAs(JsonObject.class)) { JsonNumber number = affected.getJsonNumber(ENTITY_ID); @@ -320,5 +329,5 @@ public record Record(int lineNumber, String line) { } private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; - private static final Set entityIdSet = new HashSet<>(); -} \ No newline at end of file + private static Set entityIdSet = new HashSet<>(); +} diff --git a/java/snippets/loading/LoadWithStatsViaLoop.java b/java/snippets/loading/LoadWithStatsViaLoop.java index a812ba6..716e7e8 100644 --- a/java/snippets/loading/LoadWithStatsViaLoop.java +++ b/java/snippets/loading/LoadWithStatsViaLoop.java @@ -48,10 +48,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } try { // parse the line as a JSON object @@ -84,7 +88,7 @@ public static void main(String[] args) { } } - } catch (JsonException|SzBadInputException e) { + } catch (JsonException | SzBadInputException e) { logFailedRecord(ERROR, e, lineNumber, line); errorCount++; // increment the error count @@ -183,4 +187,4 @@ private static void logFailedRecord(String errorType, private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; -} \ No newline at end of file +} diff --git a/java/snippets/redo/LoadWithRedoViaLoop.java b/java/snippets/redo/LoadWithRedoViaLoop.java index 715bc2a..bf853b4 100644 --- a/java/snippets/redo/LoadWithRedoViaLoop.java +++ b/java/snippets/redo/LoadWithRedoViaLoop.java @@ -52,10 +52,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } try { // parse the line as a JSON object @@ -72,7 +76,7 @@ public static void main(String[] args) { successCount++; - } catch (JsonException|SzBadInputException e) { + } catch (JsonException | SzBadInputException e) { logFailedRecord(ERROR, e, filePath, lineNumber, line); errorCount++; // increment the error count @@ -156,6 +160,7 @@ public static void main(String[] args) { * * @param errorType The error type description. * @param exception The exception itself. + * @param filePath The path to the file that was the source of the failed record. * @param lineNumber The line number of the failed record in the JSON input file. * @param recordJson The JSON text for the failed record. */ @@ -239,4 +244,4 @@ private static void trackRetryRecord(String recordJson) private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; -} \ No newline at end of file +} diff --git a/java/snippets/redo/RedoContinuous.java b/java/snippets/redo/RedoContinuous.java index 72583ce..d750fd7 100644 --- a/java/snippets/redo/RedoContinuous.java +++ b/java/snippets/redo/RedoContinuous.java @@ -122,8 +122,7 @@ private static void outputRedoStatistics() { * * @param errorType The error type description. * @param exception The exception itself. - * @param lineNumber The line number of the failed record in the JSON input file. - * @param recordJson The JSON text for the failed record. + * @param redoRecord The JSON text for the redo record. */ private static void logFailedRedo(String errorType, Exception exception, @@ -174,4 +173,4 @@ private static void trackRetryRecord(String recordJson) private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; -} \ No newline at end of file +} diff --git a/java/snippets/redo/RedoContinuousViaFutures.java b/java/snippets/redo/RedoContinuousViaFutures.java index 41bced3..5d30d96 100644 --- a/java/snippets/redo/RedoContinuousViaFutures.java +++ b/java/snippets/redo/RedoContinuousViaFutures.java @@ -42,7 +42,9 @@ public static void main(String[] args) { // make sure we cleanup if exiting by CTRL-C or due to an exception Runtime.getRuntime().addShutdownHook(new Thread(() -> { // shutdown the executor service - if (!executor.isShutdown()) executor.shutdown(); + if (!executor.isShutdown()) { + executor.shutdown(); + } try { handlePendingFutures(pendingFutures, true); @@ -68,7 +70,9 @@ public static void main(String[] args) { String redo = engine.getRedoRecord(); // check if no redo reords are available - if (redo == null) break; + if (redo == null) { + break; + } Future future = executor.submit(() -> { // process the redo record @@ -139,18 +143,20 @@ private static void handlePendingFutures(Map, String> pendingFutures, throws Exception { // check for completed futures - Iterator,String>> iter + Iterator, String>> iter = pendingFutures.entrySet().iterator(); // loop through the pending futures while (iter.hasNext()) { // get the next pending future - Map.Entry,String> entry = iter.next(); + Map.Entry, String> entry = iter.next(); Future future = entry.getKey(); String redoRecord = entry.getValue(); // if not blocking and this one is not done then continue - if (!blocking && !future.isDone()) continue; + if (!blocking && !future.isDone()) { + continue; + } // remove the pending future from the map iter.remove(); @@ -179,7 +185,7 @@ private static void handlePendingFutures(Map, String> pendingFutures, throw ((Exception) cause); } - } catch (SzRetryableException|InterruptedException|CancellationException e) { + } catch (SzRetryableException | InterruptedException | CancellationException e) { // handle thread interruption and cancellation as retries logFailedRedo(WARNING, e, redoRecord); errorCount++; // increment the error count @@ -219,8 +225,7 @@ private static void outputRedoStatistics() { * * @param errorType The error type description. * @param exception The exception itself. - * @param lineNumber The line number of the failed record in the JSON input file. - * @param recordJson The JSON text for the failed record. + * @param redoRecord The JSON text for the redo record. */ private static void logFailedRedo(String errorType, Exception exception, @@ -279,4 +284,4 @@ private static void trackRetryRecord(String recordJson) private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; -} \ No newline at end of file +} diff --git a/java/snippets/redo/RedoWithInfoContinuous.java b/java/snippets/redo/RedoWithInfoContinuous.java index 44f566e..161740e 100644 --- a/java/snippets/redo/RedoWithInfoContinuous.java +++ b/java/snippets/redo/RedoWithInfoContinuous.java @@ -134,8 +134,7 @@ private static void outputRedoStatistics() { * * @param errorType The error type description. * @param exception The exception itself. - * @param lineNumber The line number of the failed record in the JSON input file. - * @param recordJson The JSON text for the failed record. + * @param redoRecord The JSON text for the redo record. */ private static void logFailedRedo(String errorType, Exception exception, @@ -172,15 +171,18 @@ private static void trackRetryRecord(String recordJson) /** * Example method for parsing and handling the INFO message (formatted * as JSON). This example implementation simply tracks all entity ID's - * that appear as "AFFECTED_ENTITIES" to count the number + * that appear as "AFFECTED_ENTITIES" to count the number * of entities created for the records -- essentially a contrived * data mart. * + * @param engine The {@link SzEngine} to use. * @param info The info message. */ private static void processInfo(SzEngine engine, String info) { JsonObject jsonObject = Json.createReader(new StringReader(info)).readObject(); - if (!jsonObject.containsKey(AFFECTED_ENTITIES)) return; + if (!jsonObject.containsKey(AFFECTED_ENTITIES)) { + return; + } JsonArray affectedArr = jsonObject.getJsonArray(AFFECTED_ENTITIES); for (JsonObject affected : affectedArr.getValuesAs(JsonObject.class)) { JsonNumber number = affected.getJsonNumber(ENTITY_ID); @@ -221,5 +223,5 @@ private static void processInfo(SzEngine engine, String info) { private static int retryCount = 0; private static File retryFile = null; private static PrintWriter retryWriter = null; - private static final Set entityIdSet = new HashSet<>(); -} \ No newline at end of file + private static Set entityIdSet = new HashSet<>(); +} diff --git a/java/snippets/searching/SearchRecords.java b/java/snippets/searching/SearchRecords.java index 45a3592..c1e3df1 100644 --- a/java/snippets/searching/SearchRecords.java +++ b/java/snippets/searching/SearchRecords.java @@ -119,4 +119,4 @@ public static List getSearchCriteria() { return records; } -} \ No newline at end of file +} diff --git a/java/snippets/searching/SearchViaFutures.java b/java/snippets/searching/SearchViaFutures.java index bf4d691..7b0f501 100644 --- a/java/snippets/searching/SearchViaFutures.java +++ b/java/snippets/searching/SearchViaFutures.java @@ -68,10 +68,14 @@ public static void main(String[] args) { line = line.trim(); // skip any blank lines - if (line.length() == 0) continue; + if (line.length() == 0) { + continue; + } // skip any commented lines - if (line.startsWith("#")) continue; + if (line.startsWith("#")) { + continue; + } // construct the Record instance Criteria criteria = new Criteria(lineNumber, line); @@ -161,18 +165,20 @@ private static void handlePendingFutures(Map, Criteria> pendingF throws Exception { // check for completed futures - Iterator,Criteria>> iter + Iterator, Criteria>> iter = pendingFutures.entrySet().iterator(); // loop through the pending futures while (iter.hasNext()) { // get the next pending future - Map.Entry,Criteria> entry = iter.next(); + Map.Entry, Criteria> entry = iter.next(); Future future = entry.getKey(); Criteria criteria = entry.getValue(); // if not blocking and this one is not done then continue - if (!blocking && !future.isDone()) continue; + if (!blocking && !future.isDone()) { + continue; + } // remove the pending future from the map iter.remove(); @@ -218,7 +224,7 @@ private static void handlePendingFutures(Map, Criteria> pendingF logFailedSearch(ERROR, e, criteria.lineNumber, criteria.line); errorCount++; // increment the error count - } catch (SzRetryableException|InterruptedException|CancellationException e) { + } catch (SzRetryableException | InterruptedException | CancellationException e) { // handle thread interruption and cancellation as retries logFailedSearch(WARNING, e, criteria.lineNumber, criteria.line); errorCount++; // increment the error count @@ -290,4 +296,4 @@ public record Criteria(int lineNumber, String line) { } private static PrintWriter retryWriter = null; private static Set foundEntities = new HashSet<>(); -} \ No newline at end of file +} diff --git a/java/snippets/stewardship/ForceResolve.java b/java/snippets/stewardship/ForceResolve.java index 0829183..4030aa0 100644 --- a/java/snippets/stewardship/ForceResolve.java +++ b/java/snippets/stewardship/ForceResolve.java @@ -38,7 +38,7 @@ public static void main(String[] args) { Map recordMap = getRecords(); // loop through the example records and add them to the repository - for (Map.Entry entry : recordMap.entrySet()) { + for (Map.Entry entry : recordMap.entrySet()) { SzRecordKey recordKey = entry.getKey(); String recordDefinition = entry.getValue(); @@ -171,4 +171,4 @@ public static Map getRecords() { } private static final String TEST = "TEST"; -} \ No newline at end of file +} diff --git a/java/snippets/stewardship/ForceUnresolve.java b/java/snippets/stewardship/ForceUnresolve.java index 703c37a..a887314 100644 --- a/java/snippets/stewardship/ForceUnresolve.java +++ b/java/snippets/stewardship/ForceUnresolve.java @@ -38,7 +38,7 @@ public static void main(String[] args) { Map recordMap = getRecords(); // loop through the example records and add them to the repository - for (Map.Entry entry : recordMap.entrySet()) { + for (Map.Entry entry : recordMap.entrySet()) { SzRecordKey recordKey = entry.getKey(); String recordDefinition = entry.getValue(); @@ -169,4 +169,4 @@ public static Map getRecords() { } private static final String TEST = "TEST"; -} \ No newline at end of file +}