Skip to content

Commit

Permalink
Add generic json mapper
Browse files Browse the repository at this point in the history
  • Loading branch information
Toby Henderson authored and holytshirt committed Feb 4, 2022
1 parent 3950599 commit 4c2477d
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/Paramore.Brighter/GenericJsonMessageMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.IO;
using System.Text;
using Newtonsoft.Json;

namespace Paramore.Brighter
{
public class GenericJsonMessageMapper<T> : IAmAMessageMapper<T> where T : class, IRequest
{
private readonly IRequestContext _requestContext;
private readonly Func<T, string> _routingAction;
private readonly RoutingKey _routingKey;
private readonly JsonSerializer _serializer = new JsonSerializer();

public GenericJsonMessageMapper(IRequestContext requestContext, RoutingKey routingKey = null, Func<T, string> routingKeyFunc = null)
{
_requestContext = requestContext;
_routingKey = routingKey;
_routingAction = routingKeyFunc;
}

public Message MapToMessage(T request)
{
MessageType messageType;
if (request is Command)
messageType = MessageType.MT_COMMAND;
else if (request is Event)
messageType = MessageType.MT_EVENT;
else
{
throw new ArgumentException("This message mapper can only map Commands and Events", nameof(request));
}

var topic = _routingAction?.Invoke(request) ?? _routingKey ?? request.GetType().Name;

using (var memoryStream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(memoryStream, new UTF8Encoding(false)))
using (var jsonTextWriter = new JsonTextWriter(streamWriter))
{
_serializer.Serialize(jsonTextWriter, request, typeof(T));
}

return new Message(new MessageHeader(request.Id, topic, messageType, _requestContext.Header.CorrelationId, contentType: "application/json"), new MessageBody(memoryStream.ToArray(), "JSON"));
}
}

public T MapToRequest(Message message)
{
_requestContext.Header.CorrelationId = message.Header.CorrelationId;

using (var memoryStream = new MemoryStream(message.Body.Bytes))
using (var streamReader = new StreamReader(memoryStream, Encoding.UTF8))
using (JsonReader reader = new JsonTextReader(streamReader))
{
return _serializer.Deserialize<T>(reader);
}
}
}
}
2 changes: 2 additions & 0 deletions src/Paramore.Brighter/IRequestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,7 @@ public interface IRequestContext
/// Gets the Feature Switches
/// </summary>
IAmAFeatureSwitchRegistry FeatureSwitches { get; }

Header Header { get; }
}
}
8 changes: 8 additions & 0 deletions src/Paramore.Brighter/RequestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ THE SOFTWARE. */

#endregion

using System;
using System.Collections.Generic;
using Paramore.Brighter.FeatureSwitch;
using Polly.Registry;
Expand Down Expand Up @@ -58,5 +59,12 @@ public RequestContext()
/// Gets the Feature Switches
/// </summary>
public IAmAFeatureSwitchRegistry FeatureSwitches { get; set; }

public Header Header { get; } = new Header();
}

public class Header
{
public Guid CorrelationId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
using System;
using System.Text;
using Xunit;

namespace Paramore.Brighter.Tests.MessageMapper
{
public class JsonMessageMapperTests
{
[Fact]
public void When_mapping_an_event_to_a_message_as_json()
{
var requestContext = new RequestContext();

var mapper = new GenericJsonMessageMapper<TestedEvent>(requestContext);

DateTime dateTime = DateTime.UtcNow;
TestedEvent testedEvent = new TestedEvent
{
Message = "This is a message",
Number = 999,
DateNow = dateTime
};

requestContext.Header.CorrelationId = Guid.NewGuid();

var message = mapper.MapToMessage(testedEvent);

// Message checks
Assert.Equal(testedEvent.Id, message.Id);

// Header checks
Assert.Equal("application/json", message.Header.ContentType);
Assert.Equal("TestedEvent", message.Header.Topic);
Assert.Equal(MessageType.MT_EVENT , message.Header.MessageType);
Assert.Equal( requestContext.Header.CorrelationId , message.Header.CorrelationId);

// Body checks
Assert.Equal("JSON", message.Body.BodyType);
Assert.Equal($"{{\"Message\":\"{testedEvent.Message}\",\"Number\":{testedEvent.Number},\"DateNow\":\"{dateTime:O}\",\"Id\":\"{testedEvent.Id}\"}}", message.Body.Value);
}


[Fact]
public void When_mapping_a_command_to_a_message_as_json()
{
var requestContext = new RequestContext();

var mapper = new GenericJsonMessageMapper<TestCommand>(requestContext);

DateTime dateTime = DateTime.UtcNow;
TestCommand testCommand = new TestCommand
{
Message = "This is a message",
Number = 999,
DateNow = dateTime
};

requestContext.Header.CorrelationId = Guid.NewGuid();

var message = mapper.MapToMessage(testCommand);

// Message checks
Assert.Equal(testCommand.Id, message.Id);

// Header checks
Assert.Equal("application/json", message.Header.ContentType);
Assert.Equal("TestCommand", message.Header.Topic);
Assert.Equal(MessageType.MT_COMMAND , message.Header.MessageType);
Assert.Equal( requestContext.Header.CorrelationId , message.Header.CorrelationId);

// Body checks
Assert.Equal("JSON", message.Body.BodyType);
Assert.Equal($"{{\"Message\":\"{testCommand.Message}\",\"Number\":{testCommand.Number},\"DateNow\":\"{dateTime:O}\",\"Id\":\"{testCommand.Id}\"}}", message.Body.Value);
}

[Fact]
public void When_mapping_with_custom_routing_key_to_a_message()
{
var mapper = new GenericJsonMessageMapper<TestCommand>(new RequestContext(), new RoutingKey("MyTestRoute"));

var testCommand = new TestCommand();

var message = mapper.MapToMessage(testCommand);

Assert.Equal("MyTestRoute", message.Header.Topic);
}

[Fact]
public void When_mapping_with_custom_routing_key_to_a_message2()
{
var mapper = new GenericJsonMessageMapper<TestCommand>(new RequestContext(), routingKeyFunc: request =>
{
string topic = "TestPreAmble.";

string name = request.GetType().Name;

if (name.EndsWith("Command", StringComparison.InvariantCultureIgnoreCase))
topic = topic + name.Replace("Command", "", StringComparison.InvariantCultureIgnoreCase);
else if (name.EndsWith("Event", StringComparison.InvariantCultureIgnoreCase))
topic = topic + name.Replace("Event", "", StringComparison.InvariantCultureIgnoreCase);
else
{
topic = topic + name;
}

return topic;
} );

var testCommand = new TestCommand();

var message = mapper.MapToMessage(testCommand);

Assert.Equal("TestPreAmble.Test", message.Header.Topic);
}


}

public class TestCommand : Command
{
public TestCommand() : base(Guid.NewGuid())
{
}

public string Message { get; set; }
public int Number { get; set; }
public DateTime DateNow { get; set; }
}

public class TestedEvent : Event
{
public TestedEvent() : base(Guid.NewGuid())
{
}

public string Message { get; set; }
public int Number { get; set; }
public DateTime DateNow { get; set; }
}
}

0 comments on commit 4c2477d

Please sign in to comment.