Skip to content

Commit

Permalink
🔧 Case insensitive deserialization for complex json queue messages
Browse files Browse the repository at this point in the history
  • Loading branch information
PureKrome authored Dec 29, 2023
1 parent 62cfc8b commit eeda85d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Azure.Storage.Queues.Models;


namespace WorldDomination.SimpleAzure.Storage.HybridQueues.Tests.IntegrationTests.HybridQueueTests
{
public class ParseMessageAsyncTests : CustomAzuriteTestContainer
{
public record FakePerson(string Name, int Age);

[Theory]
[InlineData("{\"Name\": \"Anabel\", \"Age\": 30}")] // Note: Capitalized keys.
[InlineData("{\"name\": \"Anabel\", \"age\": 30}")] // Note: Lowercase keys.
[InlineData("{\"nAmE\": \"Anabel\", \"aGe\": 30}")] // Note: Mixed case keys.
public async Task ParseMessageAsync_LowercaseJsonKeys_CaseInsensitive(string json)
{
// Arrange.
var queueMessage = QueuesModelFactory.QueueMessage(
"1",
"2",
new BinaryData(json),
0);

// Act.
var fakePerson = await HybridQueue.ParseMessageAsync<FakePerson>(queueMessage, CancellationToken.None);

// Assert.
fakePerson.ShouldNotBeNull();
fakePerson.Content.ShouldNotBeNull();
fakePerson.Content.Name.ShouldBe("Anabel");
fakePerson.Content.Age.ShouldBe(30);
}
}
}
18 changes: 16 additions & 2 deletions src/SimpleAzure.Storage.HybridQueues/HybridQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public sealed class HybridQueue(
ContentType = "application/json",
};

private static readonly JsonSerializerOptions _jsonSerializerOptions = new()
{
PropertyNameCaseInsensitive = true
};

public async Task SetupContainerStorageAsync(bool isLoggingEnabled, CancellationToken cancellationToken)
{
var blobAzureResponse = await _blobContainerClient
Expand Down Expand Up @@ -234,6 +239,8 @@ public async Task<HybridMessage<T>> ParseMessageAsync<T>(QueueMessage queueMessa
{
var message = queueMessage.Body.ToString().AssumeNotNull();

// Queue Message: Guid == item is in Blob Storage.
// Blob Storage: Complex Type. Json message.
if (Guid.TryParse(message, out var blobId))
{
using var _ = _logger.BeginCustomScope((nameof(blobId), blobId));
Expand All @@ -245,7 +252,8 @@ public async Task<HybridMessage<T>> ParseMessageAsync<T>(QueueMessage queueMessa
using var stream = await blobClient.OpenReadAsync(null, cancellationToken).ConfigureAwait(false);

_logger.LogDebug("About to deserialize stream for a blob item from Blob Storage.");
var blobItem = await JsonSerializer.DeserializeAsync<T>(stream, cancellationToken: cancellationToken).ConfigureAwait(false);

var blobItem = await JsonSerializer.DeserializeAsync<T>(stream, _jsonSerializerOptions, cancellationToken).ConfigureAwait(false);
_logger.LogDebug("Finished deserializing stream for a blob item from Blob Storage.");

if (blobItem is null)
Expand All @@ -256,6 +264,9 @@ public async Task<HybridMessage<T>> ParseMessageAsync<T>(QueueMessage queueMessa
var hybridMessage = new HybridMessage<T>(blobItem, queueMessage.MessageId, queueMessage.PopReceipt, blobId);
return hybridMessage;
}

// Queue Message: simple type. Not JSON.
// Blob Storage: N/A
else if (typeof(T).IsASimpleType())
{
_logger.LogDebug("Retrieving item: which is a simle type and not a guid/not in Blob Storage.");
Expand All @@ -266,12 +277,15 @@ public async Task<HybridMessage<T>> ParseMessageAsync<T>(QueueMessage queueMessa
var hybridMessage = new HybridMessage<T>(value, queueMessage.MessageId, queueMessage.PopReceipt, null);
return hybridMessage;
}

// Queue Message: complex type. Json.
// Blob Storage: N/A
else
{
// Complex type, so lets assume it was serialized as Json ... so now we deserialize it.
_logger.LogDebug("Retrieving a complex item: assumed as json so deserializing it.");

var item = JsonSerializer.Deserialize<T>(message);
var item = JsonSerializer.Deserialize<T>(message, _jsonSerializerOptions);
if (item is null)
{
throw new InvalidOperationException($"Could not deserialize complex type for message '{queueMessage.MessageId}'.");
Expand Down

0 comments on commit eeda85d

Please sign in to comment.