< Summary - AsyncResponse (Release / net8.0+net10.0 / unit+integration)

Information
Class: AsyncResponse.Transports.GooglePubSub.GooglePubSubCorrelationIdExtractor
Assembly: AsyncResponse.Transports.GooglePubSub
File(s): /home/runner/work/AsyncResponse/AsyncResponse/src/Transports/AsyncResponse.Transports.GooglePubSub/GooglePubSubCorrelationIdExtractor.cs
Line coverage
100%
Covered lines: 52
Uncovered lines: 0
Coverable lines: 52
Total lines: 107
Line coverage: 100%
Branch coverage
100%
Covered branches: 46
Total branches: 46
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Extract(...)100%1818100%
TryReadPath(...)100%1212100%
TryGetProperty(...)100%66100%
UnwrapJsonString(...)100%1010100%

File(s)

/home/runner/work/AsyncResponse/AsyncResponse/src/Transports/AsyncResponse.Transports.GooglePubSub/GooglePubSubCorrelationIdExtractor.cs

#LineLine coverage
 1using Google.Cloud.PubSub.V1;
 2using System.Text.Json;
 3using System.Text.Json.Nodes;
 4
 5namespace AsyncResponse.Transports.GooglePubSub;
 6
 7internal static class GooglePubSubCorrelationIdExtractor
 8{
 9    /// <summary>Extracts the correlation id from the supplied message.</summary>
 10    public static string? Extract(
 11        PubsubMessage message,
 12        string messageJson,
 13        GooglePubSubAsyncResponseOptions options)
 14    {
 315        if (!string.IsNullOrWhiteSpace(options.CorrelationIdAttribute)
 316            && message.Attributes.TryGetValue(options.CorrelationIdAttribute, out var attributeValue)
 317            && !string.IsNullOrWhiteSpace(attributeValue))
 18        {
 319            return attributeValue;
 20        }
 21
 322        var jsonPaths = options.CorrelationIdJsonPaths;
 323        if (jsonPaths is null || jsonPaths.Length == 0 || string.IsNullOrWhiteSpace(messageJson))
 324            return null;
 25
 26        JsonNode? root;
 27        try
 28        {
 329            root = JsonNode.Parse(messageJson);
 330        }
 331        catch (JsonException)
 32        {
 333            return null;
 34        }
 35
 336        if (root is null)
 337            return null;
 38
 339        foreach (var path in jsonPaths)
 40        {
 341            var value = TryReadPath(root, path);
 342            if (!string.IsNullOrWhiteSpace(value))
 343                return value;
 44        }
 45
 246        return null;
 347    }
 48
 49    private static string? TryReadPath(JsonNode root, string path)
 50    {
 351        if (string.IsNullOrWhiteSpace(path))
 352            return null;
 53
 354        var current = root;
 355        foreach (var segment in path.Split('.', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
 56        {
 357            current = UnwrapJsonString(current);
 358            if (current is not JsonObject obj)
 359                return null;
 60
 361            current = TryGetProperty(obj, segment);
 362            if (current is null)
 363                return null;
 64        }
 65
 366        current = UnwrapJsonString(current);
 367        return current switch
 368        {
 369            JsonValue value when value.TryGetValue<string>(out var s) => s,
 270            JsonValue value => value.ToString(),
 371            _ => null
 372        };
 73    }
 74
 75    private static JsonNode? TryGetProperty(JsonObject obj, string name)
 76    {
 377        if (obj.TryGetPropertyValue(name, out var exact))
 378            return exact;
 79
 280        foreach (var property in obj)
 81        {
 282            if (string.Equals(property.Key, name, StringComparison.OrdinalIgnoreCase))
 283                return property.Value;
 84        }
 85
 286        return null;
 387    }
 88
 89    private static JsonNode? UnwrapJsonString(JsonNode? node)
 90    {
 391        if (node is not JsonValue value || !value.TryGetValue<string>(out var text))
 392            return node;
 93
 394        var trimmed = text.AsSpan().TrimStart();
 395        if (trimmed.Length == 0 || (trimmed[0] != '{' && trimmed[0] != '['))
 396            return node;
 97
 98        try
 99        {
 2100            return JsonNode.Parse(text);
 101        }
 2102        catch (JsonException)
 103        {
 2104            return node;
 105        }
 3106    }
 107}