Skip to content

Commit 4097cfe

Browse files
jjaguirre394Juan Aguirre
andauthored
Remove Newtonsoft dependency (#13787)
* Removing newtonsoft * Fixing null reference issue in parameter predictor Co-authored-by: Juan Aguirre <[email protected]>
1 parent f220a97 commit 4097cfe

File tree

6 files changed

+204
-30
lines changed

6 files changed

+204
-30
lines changed

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/ModelEntry.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,36 @@
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
14-
15-
using Newtonsoft.Json;
16-
using Newtonsoft.Json.Serialization;
14+
using System.Text.Json.Serialization;
1715

1816
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Test
1917
{
2018
/// <summary>
2119
/// Represents a command entry in the model files.
2220
/// </summary>
23-
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
2421
public class ModelEntry
2522
{
2623
/// <summary>
2724
/// The command in the model.
2825
/// </summary>
29-
[JsonProperty("suggestion", Required = Required.Always)]
26+
[JsonPropertyName("suggestion")]
3027
public string Command { get; set; }
3128

3229
/// <summary>
3330
/// The description of the command in the model.
3431
/// </summary>
35-
[JsonProperty(Required = Required.Always)]
3632
public string Description { get; set; }
3733

3834
/// <summary>
3935
/// The prediction count in the model.
4036
/// </summary>
41-
[JsonProperty("suggestion count", Required = Required.Always)]
37+
[JsonPropertyName("suggestion count")]
4238
public int PredictionCount { get; set; }
4339

4440
/// <summary>
4541
/// The history count in the model.
4642
/// </summary>
47-
[JsonProperty("history count", Required = Required.Always)]
43+
[JsonPropertyName("history count")]
4844
public int HistoryCount { get; set; }
4945

5046
/// <summary>

tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/ModelFixture.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15-
using Newtonsoft.Json;
15+
using Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities;
1616
using System;
1717
using System.Collections.Generic;
1818
using System.IO;
1919
using System.IO.Compression;
2020
using System.Linq;
21+
using System.Text.Json;
2122
using Xunit;
2223

2324
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Test
@@ -54,8 +55,8 @@ public ModelFixture()
5455
var fileInfo = new FileInfo(currentLocation);
5556
var directory = fileInfo.DirectoryName;
5657
var dataDirectory = Path.Join(directory, ModelFixture.DataDirectoryName);
57-
var commandsModelVersions= JsonConvert.DeserializeObject<IDictionary<Version, IList<ModelEntry>>>(ModelFixture.ReadZipEntry(Path.Join(dataDirectory, ModelFixture.CommandsModelZip), ModelFixture.CommandsModelJson));
58-
var predictionsModelVersions = JsonConvert.DeserializeObject<IDictionary<Version, Dictionary<string, IList<ModelEntry>>>>(ModelFixture.ReadZipEntry(Path.Join(dataDirectory, ModelFixture.PredictionsModelZip), ModelFixture.PredictionsModelJson));
58+
var commandsModelVersions = JsonSerializer.Deserialize<IDictionary<Version, IList<ModelEntry>>>(ModelFixture.ReadZipEntry(Path.Join(dataDirectory, ModelFixture.CommandsModelZip), ModelFixture.CommandsModelJson), JsonUtilities.DefaultSerializerOptions);
59+
var predictionsModelVersions = JsonSerializer.Deserialize<IDictionary<Version, Dictionary<string, IList<ModelEntry>>>>(ModelFixture.ReadZipEntry(Path.Join(dataDirectory, ModelFixture.PredictionsModelZip), ModelFixture.PredictionsModelJson), JsonUtilities.DefaultSerializerOptions);
5960

6061
var commandsModel = commandsModelVersions[CommandsVersionToUse];
6162
var predictionsModel = predictionsModelVersions[PredictionsVersionToUse];

tools/Az.Tools.Predictor/Az.Tools.Predictor/ParameterValuePredictor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ private void ExtractLocalParameters(System.Collections.ObjectModel.ReadOnlyColle
101101
// We need to extract the noun to construct the parameter name.
102102

103103
var commandName = command.FirstOrDefault()?.ToString();
104-
var commandNoun = ParameterValuePredictor.GetAzCommandNoun(commandName).ToLower();
104+
var commandNoun = ParameterValuePredictor.GetAzCommandNoun(commandName)?.ToLower();
105105
if (commandNoun == null)
106106
{
107107
return;
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using System.Collections.Generic;
17+
using System.Reflection;
18+
using System.Text.Json;
19+
using System.Text.Json.Serialization;
20+
21+
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities.Converters
22+
{
23+
internal sealed class DictionaryTKeyVersionTValueConverter : JsonConverterFactory
24+
{
25+
public override bool CanConvert(Type typeToConvert)
26+
{
27+
if (!typeToConvert.IsGenericType)
28+
{
29+
return false;
30+
}
31+
32+
if (typeToConvert.GetGenericTypeDefinition() != typeof(IDictionary<,>))
33+
{
34+
return false;
35+
}
36+
37+
return typeToConvert.GetGenericArguments()[0] == typeof(Version);
38+
}
39+
40+
public override JsonConverter CreateConverter(
41+
Type type,
42+
JsonSerializerOptions options)
43+
{
44+
Type keyType = type.GetGenericArguments()[0];
45+
Type valueType = type.GetGenericArguments()[1];
46+
47+
JsonConverter converter = (JsonConverter)Activator.CreateInstance(
48+
typeof(DictionaryVersionConverterInner<,>).MakeGenericType(
49+
new Type[] { keyType, valueType }),
50+
BindingFlags.Instance | BindingFlags.Public,
51+
binder: null,
52+
args: new object[] { options },
53+
culture: null);
54+
55+
return converter;
56+
}
57+
58+
private class DictionaryVersionConverterInner<TKey, TValue> :
59+
JsonConverter<IDictionary<Version, TValue>>
60+
{
61+
private readonly JsonConverter<TValue> _valueConverter;
62+
private readonly Type _keyType;
63+
private readonly Type _valueType;
64+
65+
public DictionaryVersionConverterInner(JsonSerializerOptions options)
66+
{
67+
// For performance, use the existing converter if available.
68+
_valueConverter = (JsonConverter<TValue>)options
69+
.GetConverter(typeof(TValue));
70+
71+
// Cache the key and value types.
72+
_keyType = typeof(TKey);
73+
_valueType = typeof(TValue);
74+
}
75+
76+
public override IDictionary<Version, TValue> Read(
77+
ref Utf8JsonReader reader,
78+
Type typeToConvert,
79+
JsonSerializerOptions options)
80+
{
81+
if (reader.TokenType != JsonTokenType.StartObject)
82+
{
83+
throw new JsonException();
84+
}
85+
86+
var dictionary = new Dictionary<Version, TValue>();
87+
88+
while (reader.Read())
89+
{
90+
if (reader.TokenType == JsonTokenType.EndObject)
91+
{
92+
return dictionary;
93+
}
94+
95+
// Get the key.
96+
if (reader.TokenType != JsonTokenType.PropertyName)
97+
{
98+
throw new JsonException();
99+
}
100+
101+
string propertyName = reader.GetString();
102+
103+
if (!Version.TryParse(propertyName, out Version key))
104+
{
105+
throw new JsonException(
106+
$"Unable to convert \"{propertyName}\" to System.Version.");
107+
}
108+
109+
// Get the value.
110+
TValue value;
111+
if (_valueConverter != null)
112+
{
113+
reader.Read();
114+
value = _valueConverter.Read(ref reader, _valueType, options);
115+
}
116+
else
117+
{
118+
value = JsonSerializer.Deserialize<TValue>(ref reader, options);
119+
}
120+
121+
// Add to dictionary.
122+
dictionary.Add(key, value);
123+
}
124+
125+
throw new JsonException();
126+
}
127+
128+
public override void Write(
129+
Utf8JsonWriter writer,
130+
IDictionary<Version, TValue> dictionary,
131+
JsonSerializerOptions options)
132+
{
133+
writer.WriteStartObject();
134+
135+
foreach ((Version key, TValue value) in dictionary)
136+
{
137+
var propertyName = key.ToString();
138+
writer.WritePropertyName
139+
(options.PropertyNamingPolicy?.ConvertName(propertyName) ?? propertyName);
140+
141+
if (_valueConverter != null)
142+
{
143+
_valueConverter.Write(writer, value, options);
144+
}
145+
else
146+
{
147+
JsonSerializer.Serialize(writer, value, options);
148+
}
149+
}
150+
151+
writer.WriteEndObject();
152+
}
153+
}
154+
}
155+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using System;
16+
using System.Text.Json;
17+
using System.Text.Json.Serialization;
18+
19+
namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities.Converters
20+
{
21+
internal sealed class VersionConverter : JsonConverter<Version>
22+
{
23+
public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
24+
{
25+
if (Version.TryParse(reader.GetString(), out var version))
26+
{
27+
return version;
28+
}
29+
30+
throw new JsonException();
31+
}
32+
33+
public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
34+
{
35+
writer.WriteStringValue(value.ToString());
36+
}
37+
}
38+
}

tools/Az.Tools.Predictor/Az.Tools.Predictor/Utilities/JsonUtilities.cs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15+
using Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities.Converters;
1516
using System;
1617
using System.Text.Encodings.Web;
1718
using System.Text.Json;
@@ -24,24 +25,6 @@ namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities
2425
/// </summary>
2526
internal static class JsonUtilities
2627
{
27-
private sealed class VersionConverter : JsonConverter<Version>
28-
{
29-
public override Version Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
30-
{
31-
if (Version.TryParse(reader.GetString(), out var version))
32-
{
33-
return version;
34-
}
35-
36-
throw new JsonException();
37-
}
38-
39-
public override void Write (Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
40-
{
41-
writer.WriteStringValue(value.ToString());
42-
}
43-
}
44-
4528
/// <summary>
4629
/// The default serialization options:
4730
/// 1. Use camel case in the naming.
@@ -54,6 +37,7 @@ public override void Write (Utf8JsonWriter writer, Version value, JsonSerializer
5437
{
5538
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),
5639
new VersionConverter(),
40+
new DictionaryTKeyVersionTValueConverter()
5741
},
5842
};
5943

0 commit comments

Comments
 (0)