Skip to content

Commit

Permalink
Remove Newtonsoft dependency (#13787)
Browse files Browse the repository at this point in the history
* Removing newtonsoft

* Fixing null reference issue in parameter predictor

Co-authored-by: Juan Aguirre <[email protected]>
  • Loading branch information
jjaguirre394 and Juan Aguirre authored Dec 20, 2020
1 parent f220a97 commit 4097cfe
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 30 deletions.
12 changes: 4 additions & 8 deletions tools/Az.Tools.Predictor/Az.Tools.Predictor.Test/ModelEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,36 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Text.Json.Serialization;

namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Test
{
/// <summary>
/// Represents a command entry in the model files.
/// </summary>
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class ModelEntry
{
/// <summary>
/// The command in the model.
/// </summary>
[JsonProperty("suggestion", Required = Required.Always)]
[JsonPropertyName("suggestion")]
public string Command { get; set; }

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

/// <summary>
/// The prediction count in the model.
/// </summary>
[JsonProperty("suggestion count", Required = Required.Always)]
[JsonPropertyName("suggestion count")]
public int PredictionCount { get; set; }

/// <summary>
/// The history count in the model.
/// </summary>
[JsonProperty("history count", Required = Required.Always)]
[JsonPropertyName("history count")]
public int HistoryCount { get; set; }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
// limitations under the License.
// ----------------------------------------------------------------------------------

using Newtonsoft.Json;
using Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.Json;
using Xunit;

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

var commandsModel = commandsModelVersions[CommandsVersionToUse];
var predictionsModel = predictionsModelVersions[PredictionsVersionToUse];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private void ExtractLocalParameters(System.Collections.ObjectModel.ReadOnlyColle
// We need to extract the noun to construct the parameter name.

var commandName = command.FirstOrDefault()?.ToString();
var commandNoun = ParameterValuePredictor.GetAzCommandNoun(commandName).ToLower();
var commandNoun = ParameterValuePredictor.GetAzCommandNoun(commandName)?.ToLower();
if (commandNoun == null)
{
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities.Converters
{
internal sealed class DictionaryTKeyVersionTValueConverter : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert)
{
if (!typeToConvert.IsGenericType)
{
return false;
}

if (typeToConvert.GetGenericTypeDefinition() != typeof(IDictionary<,>))
{
return false;
}

return typeToConvert.GetGenericArguments()[0] == typeof(Version);
}

public override JsonConverter CreateConverter(
Type type,
JsonSerializerOptions options)
{
Type keyType = type.GetGenericArguments()[0];
Type valueType = type.GetGenericArguments()[1];

JsonConverter converter = (JsonConverter)Activator.CreateInstance(
typeof(DictionaryVersionConverterInner<,>).MakeGenericType(
new Type[] { keyType, valueType }),
BindingFlags.Instance | BindingFlags.Public,
binder: null,
args: new object[] { options },
culture: null);

return converter;
}

private class DictionaryVersionConverterInner<TKey, TValue> :
JsonConverter<IDictionary<Version, TValue>>
{
private readonly JsonConverter<TValue> _valueConverter;
private readonly Type _keyType;
private readonly Type _valueType;

public DictionaryVersionConverterInner(JsonSerializerOptions options)
{
// For performance, use the existing converter if available.
_valueConverter = (JsonConverter<TValue>)options
.GetConverter(typeof(TValue));

// Cache the key and value types.
_keyType = typeof(TKey);
_valueType = typeof(TValue);
}

public override IDictionary<Version, TValue> Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}

var dictionary = new Dictionary<Version, TValue>();

while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return dictionary;
}

// Get the key.
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException();
}

string propertyName = reader.GetString();

if (!Version.TryParse(propertyName, out Version key))
{
throw new JsonException(
$"Unable to convert \"{propertyName}\" to System.Version.");
}

// Get the value.
TValue value;
if (_valueConverter != null)
{
reader.Read();
value = _valueConverter.Read(ref reader, _valueType, options);
}
else
{
value = JsonSerializer.Deserialize<TValue>(ref reader, options);
}

// Add to dictionary.
dictionary.Add(key, value);
}

throw new JsonException();
}

public override void Write(
Utf8JsonWriter writer,
IDictionary<Version, TValue> dictionary,
JsonSerializerOptions options)
{
writer.WriteStartObject();

foreach ((Version key, TValue value) in dictionary)
{
var propertyName = key.ToString();
writer.WritePropertyName
(options.PropertyNamingPolicy?.ConvertName(propertyName) ?? propertyName);

if (_valueConverter != null)
{
_valueConverter.Write(writer, value, options);
}
else
{
JsonSerializer.Serialize(writer, value, options);
}
}

writer.WriteEndObject();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities.Converters
{
internal sealed class VersionConverter : JsonConverter<Version>
{
public override Version Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (Version.TryParse(reader.GetString(), out var version))
{
return version;
}

throw new JsonException();
}

public override void Write(Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// limitations under the License.
// ----------------------------------------------------------------------------------

using Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities.Converters;
using System;
using System.Text.Encodings.Web;
using System.Text.Json;
Expand All @@ -24,24 +25,6 @@ namespace Microsoft.Azure.PowerShell.Tools.AzPredictor.Utilities
/// </summary>
internal static class JsonUtilities
{
private sealed class VersionConverter : JsonConverter<Version>
{
public override Version Read (ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (Version.TryParse(reader.GetString(), out var version))
{
return version;
}

throw new JsonException();
}

public override void Write (Utf8JsonWriter writer, Version value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}

/// <summary>
/// The default serialization options:
/// 1. Use camel case in the naming.
Expand All @@ -54,6 +37,7 @@ public override void Write (Utf8JsonWriter writer, Version value, JsonSerializer
{
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase),
new VersionConverter(),
new DictionaryTKeyVersionTValueConverter()
},
};

Expand Down

0 comments on commit 4097cfe

Please sign in to comment.