Skip to content

Commit

Permalink
Minor improvements for JSON node extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderkozlenko committed Nov 4, 2024
1 parent 3889fe2 commit b37147b
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 31 deletions.
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project>
<ItemGroup>
<PackageVersion Include="MSTest" Version="3.6.2" />
<PackageVersion Include="Microsoft.Azure.Cosmos" Version="3.45.0" />
<PackageVersion Include="Microsoft.CommonDataModel.ObjectModel" Version="1.7.6" />
<PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
<PackageVersion Include="MSTest" Version="3.6.2" />
<PackageVersion Include="System.CommandLine.Hosting" Version="0.4.0-alpha.22272.1" />
<PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
<PackageVersion Include="System.IO.Packaging" Version="8.0.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ internal abstract class HostCommandHandler : ICommandHandler
{
public int Invoke(InvocationContext context)
{
return InvokeAsync(context).GetAwaiter().GetResult();
throw new NotSupportedException();
}

public async Task<int> InvokeAsync(InvocationContext context)
{
var logger = context.GetHost().Services.GetRequiredService<ILogger<HostCommandHandler>>();
var version = typeof(Program).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
var logger = context.GetHost().Services.GetRequiredService<ILogger<HostCommandHandler>>();

logger.LogInformation("Cotopaxi {Version}", version);
logger.LogInformation("");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System.Text.Json.Nodes;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Cotopaxi.Cosmos.PackageManagement.UnitTests;

[TestClass]
public sealed class JsonNodeExtensionsTest
{
[DataTestMethod]
[DataRow("", "$")]
[DataRow("/foo", "$.foo")]
[DataRow("/foo/0", "$.foo[0]")]
[DataRow("/", "$.")]
[DataRow("/a~1b", "$['a/b']")]
[DataRow("/c%d", "$.c%d")]
[DataRow("/e^f", "$.e^f")]
[DataRow("/g|h", "$.g|h")]
[DataRow("/i\\\\j", "$['i\\\\j']")]
[DataRow("/k\\\"l", "$['k\\\"l']")]
[DataRow("/ ", "$[' ']")]
[DataRow("/m~0n", "$.m~n")]
public void TryGetValue(string jsonPointerValue, string jsonPath)
{
var jsonObject = new JsonObject
{
["foo"] = new JsonArray
{
"bar",
"baz",
},
[""] = 0,
["a/b"] = 1,
["c%d"] = 2,
["e^f"] = 3,
["g|h"] = 4,
["i\\\\j"] = 5,
["k\\\"l"] = 6,
[" "] = 7,
["m~n"] = 8,
};

var jsonPointer = new JsonPointer(jsonPointerValue);
var result = jsonObject.TryGetValue(jsonPointer, out var value);

Assert.IsTrue(result);
Assert.IsNotNull(value);
Assert.AreEqual(jsonPath, value.GetPath());
}
}
20 changes: 11 additions & 9 deletions src/Cotopaxi.Cosmos.PackageManagement.UnitTests/JsonPointerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@ public sealed class JsonPointerTest
[DataRow("", new string[] { })]
[DataRow("/foo", new string[] { "foo" })]
[DataRow("/foo/0", new string[] { "foo", "0" })]
[DataRow("/~0", new string[] { "~" })]
[DataRow("/~1", new string[] { "/" })]
[DataRow("/~0~1", new string[] { "~/", })]
[DataRow("/a/b/c", new string[] { "a", "b", "c" })]
[DataRow("/a~1b~1c", new string[] { "a/b/c" })]
[DataRow("/", new string[] { "" })]
[DataRow("/a~1b", new string[] { "a/b" })]
[DataRow("/c%d", new string[] { "c%d" })]
[DataRow("/e^f", new string[] { "e^f" })]
[DataRow("/g|h", new string[] { "g|h" })]
[DataRow("/i\\\\j", new string[] { "i\\\\j" })]
[DataRow("/k\\\"l", new string[] { "k\\\"l" })]
[DataRow("/ ", new string[] { " " })]
[DataRow("/m~0n", new string[] { "m~n" })]
public void RFC6901(string value, string[] expectedTokens)
public void RFC6901(string jsonPointerValue, string[] jsonPointerTokens)
{
var jsonPointer = new JsonPointer(value);
var jsonPointerTokens = jsonPointer.Tokens.ToArray();
var jsonPointer = new JsonPointer(jsonPointerValue);

CollectionAssert.AreEqual(expectedTokens, jsonPointerTokens);
CollectionAssert.AreEqual(jsonPointerTokens, jsonPointer.Tokens.ToArray());
}
}
21 changes: 7 additions & 14 deletions src/Cotopaxi.Cosmos.PackageManagement/JsonNodeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,26 @@

namespace Cotopaxi.Cosmos.PackageManagement;

internal static class JsonNodeExtensions
public static class JsonNodeExtensions
{
public static bool TryGetValue(this JsonNode root, JsonPointer pointer, out JsonNode? result)
public static bool TryGetValue(this JsonNode root, JsonPointer path, out JsonNode? value)
{
Debug.Assert(root is not null);

if (pointer.Tokens.IsEmpty)
{
result = root;

return true;
}

var current = root;

for (var i = 0; i < pointer.Tokens.Length; i++)
for (var i = 0; i < path.Tokens.Length; i++)
{
if (current is JsonObject jsonObject)
{
if (jsonObject.TryGetPropertyValue(pointer.Tokens[i], out current))
if (jsonObject.TryGetPropertyValue(path.Tokens[i], out current))
{
continue;
}
}
else if (current is JsonArray jsonArray)
{
if (int.TryParse(pointer.Tokens[i], NumberStyles.None, CultureInfo.InvariantCulture, out var index))
if (int.TryParse(path.Tokens[i], NumberStyles.None, CultureInfo.InvariantCulture, out var index))
{
if (index < jsonArray.Count)
{
Expand All @@ -43,12 +36,12 @@ public static bool TryGetValue(this JsonNode root, JsonPointer pointer, out Json
}
}

result = default;
value = default;

return false;
}

result = current;
value = current;

return true;
}
Expand Down
10 changes: 5 additions & 5 deletions src/Cotopaxi.Cosmos.PackageManagement/PackageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ public async Task<bool> DeployPackageAsync(IReadOnlyCollection<FileInfo> package

using var cosmosClient = cosmosCredential.IsConnectionString ?
new CosmosClient(cosmosCredential.ConnectionString, cosmosClientOptions) :
new CosmosClient(cosmosCredential.AccountEndpoint.OriginalString, cosmosCredential.AuthKeyOrResourceToken, cosmosClientOptions);
new CosmosClient(cosmosCredential.AccountEndpoint.AbsoluteUri, cosmosCredential.AuthKeyOrResourceToken, cosmosClientOptions);

_logger.LogInformation("Deploying {PackageCount} packages to {CosmosEndpoint}", packageFiles.Count, cosmosClient.Endpoint.OriginalString.TrimEnd('/'));
_logger.LogInformation("Deploying {PackageCount} packages to {CosmosEndpoint}", packageFiles.Count, cosmosClient.Endpoint.AbsoluteUri.TrimEnd('/'));

var partitionKeyPathsRegistry = new Dictionary<(string, string), JsonPointer[]>();
var deployCharge = 0.0;
Expand Down Expand Up @@ -219,7 +219,7 @@ public async Task<bool> DeployPackageAsync(IReadOnlyCollection<FileInfo> package

_logger.LogError(
"Aborted a deployment to {CosmosEndpoint} ({RU} RU)",
cosmosClient.Endpoint.OriginalString.TrimEnd('/'),
cosmosClient.Endpoint.AbsoluteUri.TrimEnd('/'),
Math.Round(deployCharge, 2));

return false;
Expand Down Expand Up @@ -275,7 +275,7 @@ public async Task<bool> DeployPackageAsync(IReadOnlyCollection<FileInfo> package

_logger.LogError(
"Aborted a deployment to {CosmosEndpoint} ({RU} RU)",
cosmosClient.Endpoint.OriginalString.TrimEnd('/'),
cosmosClient.Endpoint.AbsoluteUri.TrimEnd('/'),
Math.Round(deployCharge, 2));

return false;
Expand All @@ -292,7 +292,7 @@ public async Task<bool> DeployPackageAsync(IReadOnlyCollection<FileInfo> package
_logger.LogInformation(
"Successfully deployed {PackageCount} packages to {CosmosEndpoint} ({RU} RU)",
packageFiles.Count,
cosmosClient.Endpoint.OriginalString.TrimEnd('/'),
cosmosClient.Endpoint.AbsoluteUri.TrimEnd('/'),
Math.Round(deployCharge, 2));

return true;
Expand Down

0 comments on commit b37147b

Please sign in to comment.