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

Information
Class: AsyncResponse.Transports.SQS.SqsCorrelationIdExtractor
Assembly: AsyncResponse.Transports.SQS
File(s): /home/runner/work/AsyncResponse/AsyncResponse/src/Transports/AsyncResponse.Transports.SQS/SqsCorrelationIdExtractor.cs
Line coverage
100%
Covered lines: 52
Uncovered lines: 0
Coverable lines: 52
Total lines: 106
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.SQS/SqsCorrelationIdExtractor.cs

#LineLine coverage
 1using System.Text.Json;
 2using System.Text.Json.Nodes;
 3
 4namespace AsyncResponse.Transports.SQS;
 5
 6internal static class SqsCorrelationIdExtractor
 7{
 8    /// <summary>Extracts the correlation id from the supplied SQS delivery.</summary>
 9    public static string? Extract(
 10        SqsTransportDelivery delivery,
 11        string messageJson,
 12        SqsAsyncResponseOptions options)
 13    {
 314        if (!string.IsNullOrWhiteSpace(options.CorrelationIdAttribute)
 315            && delivery.MessageAttributes.TryGetValue(options.CorrelationIdAttribute, out var attributeValue)
 316            && !string.IsNullOrWhiteSpace(attributeValue))
 17        {
 318            return attributeValue;
 19        }
 20
 321        var jsonPaths = options.CorrelationIdJsonPaths;
 322        if (jsonPaths is null || jsonPaths.Length == 0 || string.IsNullOrWhiteSpace(messageJson))
 223            return null;
 24
 25        JsonNode? root;
 26        try
 27        {
 328            root = JsonNode.Parse(messageJson);
 329        }
 230        catch (JsonException)
 31        {
 232            return null;
 33        }
 34
 335        if (root is null)
 236            return null;
 37
 338        foreach (var path in jsonPaths)
 39        {
 340            var value = TryReadPath(root, path);
 341            if (!string.IsNullOrWhiteSpace(value))
 342                return value;
 43        }
 44
 245        return null;
 246    }
 47
 48    private static string? TryReadPath(JsonNode root, string path)
 49    {
 350        if (string.IsNullOrWhiteSpace(path))
 251            return null;
 52
 353        var current = root;
 354        foreach (var segment in path.Split('.', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
 55        {
 356            current = UnwrapJsonString(current);
 357            if (current is not JsonObject obj)
 258                return null;
 59
 360            current = TryGetProperty(obj, segment);
 361            if (current is null)
 262                return null;
 63        }
 64
 365        current = UnwrapJsonString(current);
 366        return current switch
 367        {
 368            JsonValue value when value.TryGetValue<string>(out var s) => s,
 269            JsonValue value => value.ToString(),
 270            _ => null
 371        };
 72    }
 73
 74    private static JsonNode? TryGetProperty(JsonObject obj, string name)
 75    {
 376        if (obj.TryGetPropertyValue(name, out var exact))
 377            return exact;
 78
 279        foreach (var property in obj)
 80        {
 281            if (string.Equals(property.Key, name, StringComparison.OrdinalIgnoreCase))
 282                return property.Value;
 83        }
 84
 285        return null;
 286    }
 87
 88    private static JsonNode? UnwrapJsonString(JsonNode? node)
 89    {
 390        if (node is not JsonValue value || !value.TryGetValue<string>(out var text))
 391            return node;
 92
 393        var trimmed = text.AsSpan().TrimStart();
 394        if (trimmed.Length == 0 || (trimmed[0] != '{' && trimmed[0] != '['))
 395            return node;
 96
 97        try
 98        {
 299            return JsonNode.Parse(text);
 100        }
 2101        catch (JsonException)
 102        {
 2103            return node;
 104        }
 2105    }
 106}