-
Notifications
You must be signed in to change notification settings - Fork 259
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3950599
commit 4c2477d
Showing
4 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
tests/Paramore.Brighter.Core.Tests/MessageMapper/JsonMessageMapperTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | ||
} | ||
} |