Skip to content

Commit 307d0bb

Browse files
authored
feat: optimize JSON serializer (#111)
- optimize the JSON serializer with generated code - remove part of warning for trim unused code - optimize binary load time Resolve part of #109 Signed-off-by: Junjie Gao <[email protected]>
1 parent f2a6eac commit 307d0bb

File tree

15 files changed

+167
-82
lines changed

15 files changed

+167
-82
lines changed

Notation.Plugin.AzureKeyVault.Tests/Protocol/DescribeKeyTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ public void DescribeKeyResponse_ValidParameters()
5151

5252
// Act
5353
DescribeKeyResponse response = new DescribeKeyResponse(keyId, keySpec);
54+
var json = response.ToJson();
5455

5556
// Assert
5657
Assert.Equal(keyId, response.KeyId);
5758
Assert.Equal(keySpec, response.KeySpec);
59+
Assert.Equal("{\"keyId\":\"test-key-id\",\"keySpec\":\"RSA-2048\"}", json);
5860
}
5961

6062
[Theory]

Notation.Plugin.AzureKeyVault.Tests/Protocol/GenerateSignatureTests.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,26 @@ public void GenerateSignatureResponse_ThrowsArgumentNullException_WhenFieldsAreE
4040
Assert.Throws<ArgumentNullException>(() => new GenerateSignatureResponse(keyId, signature, string.Empty, certificateChain));
4141
Assert.Throws<ArgumentNullException>(() => new GenerateSignatureResponse(keyId, signature, signingAlgorithm, new List<byte[]>()));
4242
}
43+
44+
[Fact]
45+
public void GenerateSignatureResponse_Valid()
46+
{
47+
// Arrange
48+
string keyId = "test-key-id";
49+
byte[] signature = new byte[] { 1, 2, 3, 4, 5 };
50+
string signingAlgorithm = "RSA-PSS";
51+
List<byte[]> certificateChain = new List<byte[]> { new byte[] { 6, 7, 8, 9, 10 } };
52+
53+
// Act
54+
GenerateSignatureResponse response = new GenerateSignatureResponse(keyId, signature, signingAlgorithm, certificateChain);
55+
var json = response.ToJson();
56+
57+
// Assert
58+
Assert.Equal(keyId, response.KeyId);
59+
Assert.Equal(signature, response.Signature);
60+
Assert.Equal(signingAlgorithm, response.SigningAlgorithm);
61+
Assert.Equal(certificateChain, response.CertificateChain);
62+
Assert.Equal("{\"keyId\":\"test-key-id\",\"signature\":\"AQIDBAU=\",\"signingAlgorithm\":\"RSA-PSS\",\"certificateChain\":[\"BgcICQo=\"]}", json);
63+
}
4364
}
4465
}

Notation.Plugin.AzureKeyVault.Tests/Protocol/GetMetadataResponseTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public void GetMetadataResponse_CreatesInstance_WithCorrectValues()
1717

1818
// Act
1919
GetMetadataResponse response = new GetMetadataResponse(name, description, version, url, supportedContractVersions, capabilities);
20+
var json = response.ToJson();
21+
var expectedJson = "{\"name\":\"Test Plugin\",\"description\":\"A test plugin for Notation\",\"version\":\"1.0.0\",\"url\":\"https://github.com/example/test-plugin\",\"supportedContractVersions\":[\"1.0\"],\"capabilities\":[\"describe-key\",\"generate-signature\"]}";
2022

2123
// Assert
2224
Assert.Equal(name, response.Name);
@@ -25,6 +27,7 @@ public void GetMetadataResponse_CreatesInstance_WithCorrectValues()
2527
Assert.Equal(url, response.Url);
2628
Assert.Equal(supportedContractVersions, response.SupportedContractVersions);
2729
Assert.Equal(capabilities, response.Capabilities);
30+
Assert.Equal(expectedJson, json);
2831
}
2932
}
3033
}

Notation.Plugin.AzureKeyVault.Tests/Protocol/PluginIOTests.cs

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,32 +36,5 @@ public void ReadInput_ThrowsValidationExceptionOnEmptyInput()
3636
// Act & Assert
3737
Assert.Throws<ValidationException>(() => PluginIO.ReadInput());
3838
}
39-
40-
[Theory]
41-
[InlineData(false)]
42-
[InlineData(true)]
43-
public void WriteOutput_WritesCorrectOutput(bool stderr)
44-
{
45-
// Arrange
46-
var obj = new { test = "value" };
47-
const string expectedOutput = "{\"test\":\"value\"}\n";
48-
49-
using var stringWriter = new StringWriter();
50-
if (stderr)
51-
{
52-
Console.SetError(stringWriter);
53-
}
54-
else
55-
{
56-
Console.SetOut(stringWriter);
57-
}
58-
59-
// Act
60-
PluginIO.WriteOutput(obj, stderr);
61-
62-
// Assert
63-
string actualOutput = stringWriter.ToString();
64-
Assert.Equal(expectedOutput, actualOutput);
65-
}
6639
}
6740
}

Notation.Plugin.AzureKeyVault/Command/DescribeKey.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class DescribeKey : IPluginCommand
1919
public DescribeKey(string inputJson)
2020
{
2121
// Deserialize JSON string to DescribeKeyRequest object
22-
var request = JsonSerializer.Deserialize<DescribeKeyRequest>(inputJson);
22+
var request = JsonSerializer.Deserialize(inputJson, DescribeKeyRequestContext.Default.DescribeKeyRequest);
2323
if (request == null)
2424
{
2525
throw new ValidationException(invalidInputError);
@@ -37,7 +37,7 @@ public DescribeKey(DescribeKeyRequest request, IKeyVaultClient keyVaultClient)
3737
this._keyVaultClient = keyVaultClient;
3838
}
3939

40-
public async Task<object> RunAsync()
40+
public async Task<IPluginResponse> RunAsync()
4141
{
4242
// Get certificate from Azure Key Vault
4343
var cert = await _keyVaultClient.GetCertificateAsync();

Notation.Plugin.AzureKeyVault/Command/GenerateSignature.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class GenerateSignature : IPluginCommand
2020
public GenerateSignature(string inputJson)
2121
{
2222
// Parse the input
23-
var request = JsonSerializer.Deserialize<GenerateSignatureRequest>(inputJson);
23+
var request = JsonSerializer.Deserialize(inputJson, GenerateSignatureRequestContext.Default.GenerateSignatureRequest);
2424
if (request == null)
2525
{
2626
throw new ValidationException("Invalid input");
@@ -38,7 +38,7 @@ public GenerateSignature(GenerateSignatureRequest request, IKeyVaultClient keyVa
3838
this._keyVaultClient = keyVaultClient;
3939
}
4040

41-
public async Task<object> RunAsync()
41+
public async Task<IPluginResponse> RunAsync()
4242
{
4343
// Obtain the certificate chain
4444
X509Certificate2Collection certBundle;

Notation.Plugin.AzureKeyVault/Command/GetPluginMetadata.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ public partial class GetPluginMetadata : IPluginCommand
1010
public static readonly string Version;
1111
public static readonly string CommitHash;
1212

13-
public async Task<object> RunAsync()
13+
public async Task<IPluginResponse> RunAsync()
1414
{
15-
return await Task.FromResult<object>(new GetMetadataResponse(
15+
return await Task.FromResult<IPluginResponse>(new GetMetadataResponse(
1616
name: "azure-kv",
1717
description: "Notation Azure Key Vault plugin",
1818
version: Version,
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
using Notation.Plugin.Protocol;
2+
13
namespace Notation.Plugin.AzureKeyVault.Command
24
{
35
/// <summary>
46
/// Interface for plugin commands.
57
/// </summary>
68
public interface IPluginCommand
79
{
8-
Task<object> RunAsync();
10+
Task<IPluginResponse> RunAsync();
911
}
1012
}

Notation.Plugin.AzureKeyVault/Program.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ static async Task ExecuteAsync(string[] args)
5151
}
5252

5353
// execute the command
54-
var resp = await cmd.RunAsync();
54+
var response = await cmd.RunAsync();
5555

56-
// print the output
57-
PluginIO.WriteOutput(resp);
56+
// write output
57+
Console.WriteLine(response.ToJson());
5858
}
5959

6060
static void PrintHelp()

Notation.Plugin.AzureKeyVault/Protocol/DescribeKey.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Text.Json;
12
using System.Text.Json.Serialization;
23

34
namespace Notation.Plugin.Protocol
@@ -39,11 +40,17 @@ public DescribeKeyRequest(string contractVersion, string keyId)
3940
}
4041
}
4142

43+
/// <summary>
44+
/// Context class for describe-key command.
45+
/// </summary>
46+
[JsonSerializable(typeof(DescribeKeyRequest))]
47+
internal partial class DescribeKeyRequestContext : JsonSerializerContext { }
48+
4249
/// <summary>
4350
/// Response class for describe-key command.
4451
/// The class implement the <a href="https://github.com/notaryproject/notaryproject/blob/main/specs/plugin-extensibility.md#describe-key">describe-key</a> response.
4552
/// </summary>
46-
public class DescribeKeyResponse
53+
public class DescribeKeyResponse : IPluginResponse
4754
{
4855
[JsonPropertyName("keyId")]
4956
public string KeyId { get; }
@@ -66,5 +73,21 @@ public DescribeKeyResponse(string keyId, string keySpec)
6673
KeyId = keyId;
6774
KeySpec = keySpec;
6875
}
76+
77+
/// <summary>
78+
/// Serializes the response object to JSON string.
79+
/// </summary>
80+
public string ToJson()
81+
{
82+
return JsonSerializer.Serialize(
83+
value: this,
84+
jsonTypeInfo: new DescribeKeyResponseContext(PluginIO.GetRelaxedJsonSerializerOptions()).DescribeKeyResponse);
85+
}
6986
}
70-
}
87+
88+
/// <summary>
89+
/// Context class for describe-key command.
90+
/// </summary>
91+
[JsonSerializable(typeof(DescribeKeyResponse))]
92+
internal partial class DescribeKeyResponseContext : JsonSerializerContext { }
93+
}

0 commit comments

Comments
 (0)