| | | 1 | | using System.Globalization; |
| | | 2 | | using System.Text; |
| | | 3 | | |
| | | 4 | | namespace AsyncResponse.Transports.AzureServiceBus; |
| | | 5 | | |
| | | 6 | | /// <summary> |
| | | 7 | | /// Extracts the AsyncResponse correlation id from an inbound response message: first from the |
| | | 8 | | /// broker's own CorrelationId, then the configured application property, then from the JSON body |
| | | 9 | | /// via the configured paths (walked by the shared <see cref="CorrelationIdJsonPaths"/>). |
| | | 10 | | /// </summary> |
| | | 11 | | internal static class AzureServiceBusCorrelationIdExtractor |
| | | 12 | | { |
| | | 13 | | /// <summary>Extracts the correlation id from the supplied Service Bus delivery.</summary> |
| | | 14 | | public static string? Extract( |
| | | 15 | | AzureServiceBusTransportDelivery delivery, |
| | | 16 | | string messageJson, |
| | | 17 | | AzureServiceBusAsyncResponseOptions options) |
| | | 18 | | { |
| | 44 | 19 | | if (!string.IsNullOrWhiteSpace(delivery.CorrelationId)) |
| | 4 | 20 | | return delivery.CorrelationId; |
| | | 21 | | |
| | 40 | 22 | | if (!string.IsNullOrWhiteSpace(options.CorrelationIdProperty) |
| | 40 | 23 | | && delivery.ApplicationProperties.TryGetValue(options.CorrelationIdProperty, out var property) |
| | 40 | 24 | | && TryConvertProperty(property) is { } propertyValue |
| | 40 | 25 | | && !string.IsNullOrWhiteSpace(propertyValue)) |
| | | 26 | | { |
| | 16 | 27 | | return propertyValue; |
| | | 28 | | } |
| | | 29 | | |
| | 24 | 30 | | return CorrelationIdJsonPaths.Extract(messageJson, options.CorrelationIdJsonPaths); |
| | | 31 | | } |
| | | 32 | | |
| | | 33 | | internal static string? TryConvertProperty(object? property) |
| | 18 | 34 | | => property switch |
| | 18 | 35 | | { |
| | 0 | 36 | | null => null, |
| | 4 | 37 | | string s => s, |
| | 2 | 38 | | byte[] bytes => Encoding.UTF8.GetString(bytes), |
| | 2 | 39 | | ReadOnlyMemory<byte> memory => Encoding.UTF8.GetString(memory.Span), |
| | 2 | 40 | | BinaryData data => data.ToString(), |
| | 18 | 41 | | // AMQP application properties legally carry numeric/timestamp values, and the id must |
| | 18 | 42 | | // render the same on every consumer: a locale-formatted "1,5" here never matches the |
| | 18 | 43 | | // "1.5" the waiter registered under, so the wait runs to timeout on hosts with another |
| | 18 | 44 | | // CurrentCulture. |
| | 8 | 45 | | IFormattable formattable => formattable.ToString(null, CultureInfo.InvariantCulture), |
| | 0 | 46 | | _ => property.ToString() |
| | 18 | 47 | | }; |
| | | 48 | | } |