Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Use System.Text.Json instead of Newton.Json #525

Merged
merged 12 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>10.0</LangVersion>
<RootNamespace>ApplicationInspector.Benchmarks</RootNamespace>
<Company>Microsoft Corporation</Company>
</PropertyGroup>

<ItemGroup>
Expand All @@ -13,6 +15,7 @@

</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AppInspector.CLI\AppInspector.CLI.csproj" />
<ProjectReference Include="..\AppInspector\AppInspector.Commands.csproj" />
<ProjectReference Include="..\AppInspector.Tests\AppInspector.Tests.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public static void Main(string[] args)
{
// new DebugInProcessConfig()
//BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new DebugInProcessConfig());
var summary = BenchmarkRunner.Run<AnalyzeBenchmark>();
var summary = BenchmarkRunner.Run<WriterBench>();
}
}
71 changes: 71 additions & 0 deletions AppInspector.Benchmarks/WriterBench.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using System.IO;
using System.Reflection;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using DotLiquid;
using Microsoft.ApplicationInspector.CLI;
using Microsoft.ApplicationInspector.Commands;
using Microsoft.ApplicationInspector.RulesEngine;

namespace ApplicationInspector.Benchmarks;
[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net70)]
public class WriterBench
{
[Params(1000, 10000)]
public int N;

// Holds the result object which will be serialized
private AnalyzeResult _result;

[GlobalSetup]
public void GlobalSetup()
{
var _exerpt = "Hello World";
var helper = new MetaDataHelper("..");
var matchRecord = new MatchRecord("rule-id", "rule-name")
{
Boundary = new Boundary() { Index = 0, Length = 1 },
EndLocationColumn = 0,
EndLocationLine = 1,
Excerpt = _exerpt,
FileName = "TestFile",
LanguageInfo = new LanguageInfo(),
Tags = new []{"TestTag"}
};
for (int i = 0; i < N; i++)
{
helper.AddMatchRecord(matchRecord);
}
helper.PrepareReport();

_result = new AnalyzeResult() { Metadata = helper.Metadata, ResultCode = 0 };
}

[Benchmark(Baseline = true)]
public void ExportRecordsToJson()
{
var tmpPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
CLIAnalyzeCmdOptions analyzeOpts = new CLIAnalyzeCmdOptions()
{
OutputFileFormat = "json",
OutputFilePath = tmpPath
};
var writerFactory = new WriterFactory();
var writer = writerFactory.GetWriter(analyzeOpts);
writer.WriteResults(_result,analyzeOpts);
File.Delete(tmpPath);
}

public static string GetExecutingDirectoryName()
{
if (Assembly.GetEntryAssembly()?.GetName().CodeBase is string codeBaseLoc)
{
var location = new Uri(codeBaseLoc);
return new FileInfo(location.AbsolutePath).Directory?.FullName ?? string.Empty;
}

return string.Empty;
}
}
41 changes: 21 additions & 20 deletions AppInspector.CLI/TagInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using DotLiquid;
using Microsoft.ApplicationInspector.RulesEngine;
using Newtonsoft.Json;

namespace Microsoft.ApplicationInspector.Commands;

Expand All @@ -21,17 +21,18 @@ public enum tagInfoType
allTags
}

[JsonProperty(PropertyName = "type")] public tagInfoType Type;
[JsonPropertyName("type")]
public tagInfoType Type;

public TagCategory()
{
Groups = new List<TagGroup>();
}

[JsonProperty(PropertyName = "categoryName")]
[JsonPropertyName("categoryName")]
public string? Name { get; set; }

[JsonProperty(PropertyName = "groups")]
[JsonPropertyName("groups")]
public List<TagGroup>? Groups { get; set; }
}

Expand All @@ -45,14 +46,14 @@ public TagGroup()
Patterns = new List<TagSearchPattern>();
}

[JsonProperty(PropertyName = "title")] public string? Title { get; set; }
[JsonPropertyName("title")] public string? Title { get; set; }

[JsonIgnore] public string? IconURL { get; set; }

[JsonProperty(PropertyName = "dataRef")]
[JsonPropertyName("dataRef")]
public string? DataRef { get; set; }

[JsonProperty(PropertyName = "patterns")]
[JsonPropertyName("patterns")]
public List<TagSearchPattern>? Patterns { get; set; }
}

Expand All @@ -61,7 +62,7 @@ public class TagSearchPattern : Drop
private Regex? _expression;
private string _searchPattern = "";

[JsonProperty(PropertyName = "searchPattern")]
[JsonPropertyName("searchPattern")]
public string SearchPattern
{
get => _searchPattern;
Expand All @@ -85,19 +86,19 @@ public Regex Expression
}
}

[JsonProperty(PropertyName = "displayName")]
[JsonPropertyName("displayName")]
public string? DisplayName { get; set; }

[JsonProperty(PropertyName = "detectedIcon")]
[JsonPropertyName("detectedIcon")]
public string? DetectedIcon { get; set; } = "fas fa-cat"; //default

[JsonProperty(PropertyName = "notDetectedIcon")]
[JsonPropertyName("notDetectedIcon")]
public string? NotDetectedIcon { get; set; }

[JsonProperty(PropertyName = "detected")]
[JsonPropertyName("detected")]
public bool Detected { get; set; }

[JsonProperty(PropertyName = "details")]
[JsonPropertyName("details")]
public string Details
{
get
Expand All @@ -107,7 +108,7 @@ public string Details
}
}

[JsonProperty(PropertyName = "confidence")]
[JsonPropertyName("confidence")]
public string Confidence { get; set; } = "Medium";

public static bool ShouldSerializeExpression()
Expand All @@ -123,14 +124,14 @@ public class TagInfo : Drop
{
private string _confidence = "Medium";

[JsonProperty(PropertyName = "tag")] public string? Tag { get; set; }
[JsonPropertyName("tag")] public string? Tag { get; set; }

[JsonProperty(PropertyName = "displayName")]
[JsonPropertyName("displayName")]
public string? ShortTag { get; set; }

[JsonIgnore] public string? StatusIcon { get; set; }

[JsonProperty(PropertyName = "confidence")]
[JsonPropertyName("confidence")]
public string Confidence
{
get => _confidence;
Expand All @@ -143,14 +144,14 @@ public string Confidence
}
}

[JsonProperty(PropertyName = "severity")]
[JsonPropertyName("severity")]
public string Severity { get; set; } = "Moderate";

[JsonProperty(PropertyName = "detected")]
[JsonPropertyName("detected")]
public bool Detected { get; set; }
}

public class TagException
{
[JsonProperty(PropertyName = "tag")] public string? Tag { get; set; }
[JsonPropertyName("tag")] public string? Tag { get; set; }
}
37 changes: 27 additions & 10 deletions AppInspector.CLI/Writers/AnalyzeHtmlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
using Microsoft.ApplicationInspector.RulesEngine;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using System.Text.Json;

namespace Microsoft.ApplicationInspector.CLI;

Expand All @@ -27,7 +28,7 @@ public class AnalyzeHtmlWriter : CommandResultsWriter

private MetaData? _appMetaData;

public AnalyzeHtmlWriter(TextWriter textWriter, ILoggerFactory? loggerFactory = null) : base(textWriter)
public AnalyzeHtmlWriter(StreamWriter textWriter, ILoggerFactory? loggerFactory = null) : base(textWriter)
{
_logger = loggerFactory?.CreateLogger<AnalyzeHtmlWriter>() ?? NullLogger<AnalyzeHtmlWriter>.Instance;
KeyedTagInfoLists = new Dictionary<string, List<TagInfo>>();
Expand Down Expand Up @@ -91,7 +92,7 @@ private void WriteHtmlResult()
string? jsonData;
try
{
jsonData = JsonConvert.SerializeObject(data);
jsonData = JsonSerializer.Serialize(data);
}
catch (Exception e)
{
Expand Down Expand Up @@ -232,9 +233,23 @@ public void PopulateTagGroups()
//read default/user preferences on what tags to report presence on and groupings
if (File.Exists(Utils.GetPath(Utils.AppPath.tagGroupPref)))
{
TagGroupPreferences =
JsonConvert.DeserializeObject<List<TagCategory>>(
File.ReadAllText(Utils.GetPath(Utils.AppPath.tagGroupPref)));
try
{
var options = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip, // Allow strings to start with '/', e.g., "// Copyright (C) Microsoft. All rights reserved"
};
TagGroupPreferences =
JsonSerializer.Deserialize<List<TagCategory>>(
File.ReadAllText(Utils.GetPath(Utils.AppPath.tagGroupPref)), options);
}
catch (Exception e)
{
_logger.LogError(
"Failed to populate tag groups. Failed to serialize JSON representation of results in memory. {Type} : {Message}",
e.GetType().Name, e.Message);
throw;
}
}
else
{
Expand Down Expand Up @@ -627,13 +642,15 @@ public List<TagCounterUI> ConvertTagCounters(IEnumerable<MetricTagCounter> metri
/// </summary>
public class TagCounterUI : Drop
{
[JsonProperty(PropertyName = "tag")] public string? Tag { get; set; }
[JsonPropertyName("tag")]
public string? Tag { get; set; }

[JsonProperty(PropertyName = "displayName")]
[JsonPropertyName("displayName")]
public string? ShortTag { get; set; }

[JsonProperty(PropertyName = "count")] public int Count { get; set; }
[JsonPropertyName("count")]
public int Count { get; set; }

[JsonProperty(PropertyName = "includeAsMatch")]
[JsonPropertyName("includeAsMatch")]
public bool IncludeAsMatch => false;
}
30 changes: 23 additions & 7 deletions AppInspector.CLI/Writers/AnalyzeJsonWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
using Microsoft.ApplicationInspector.Commands;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using System.Text.Json;
using System;

namespace Microsoft.ApplicationInspector.CLI;

Expand All @@ -20,20 +22,33 @@ public class AnalyzeJsonWriter : CommandResultsWriter
{
private readonly ILogger<AnalyzeJsonWriter> _logger;

public AnalyzeJsonWriter(TextWriter textWriter, ILoggerFactory? loggerFactory = null) : base(textWriter)
public AnalyzeJsonWriter(StreamWriter textWriter, ILoggerFactory? loggerFactory = null) : base(textWriter)
{
_logger = loggerFactory?.CreateLogger<AnalyzeJsonWriter>() ?? NullLogger<AnalyzeJsonWriter>.Instance;
}

public override void WriteResults(Result result, CLICommandOptions commandOptions, bool autoClose = true)
{
var analyzeResult = (AnalyzeResult)result;
if (StreamWriter == null)
{
throw new ArgumentNullException(nameof(StreamWriter));
}

JsonSerializer jsonSerializer = new();
jsonSerializer.Formatting = Formatting.Indented;
if (TextWriter != null)
try
{
var options = new JsonSerializerOptions
{
WriteIndented = true,
};
JsonSerializer.Serialize(StreamWriter.BaseStream, analyzeResult, options);
}
catch (Exception e)
{
jsonSerializer.Serialize(TextWriter, analyzeResult);
_logger.LogError(
"Failed to serialize JSON representation of results in memory. {Type} : {Message}",
e.GetType().Name, e.Message);
throw;
}

if (autoClose)
Expand All @@ -47,6 +62,7 @@ public override void WriteResults(Result result, CLICommandOptions commandOption
/// </summary>
private class TagsFile
{
[JsonProperty(PropertyName = "tags")] public string[]? Tags { get; set; }
[JsonPropertyName("tags")]
public string[]? Tags { get; set; }
}
}
Loading