PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/MassTransit.Tests/Serialization/JsonSerialization_Specs.cs

https://github.com/jasonlodice/MassTransit
C# | 481 lines | 383 code | 85 blank | 13 comment | 7 complexity | 087531e58e24d2ea33aa99545f2f4deb MD5 | raw file
Possible License(s): Apache-2.0
  1. // Copyright 2007-2011 Chris Patterson, Dru Sellers, Travis Smith, et. al.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"); you may not use
  4. // this file except in compliance with the License. You may obtain a copy of the
  5. // License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software distributed
  10. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  11. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  12. // specific language governing permissions and limitations under the License.
  13. namespace MassTransit.Tests.Serialization
  14. {
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Diagnostics;
  18. using System.IO;
  19. using System.Linq;
  20. using System.Text;
  21. using System.Xml.Linq;
  22. using Magnum.Reflection;
  23. using Magnum.TestFramework;
  24. using MassTransit.Serialization;
  25. using Newtonsoft.Json;
  26. using Newtonsoft.Json.Converters;
  27. using Newtonsoft.Json.Linq;
  28. using Newtonsoft.Json.Serialization;
  29. using NUnit.Framework;
  30. [Scenario]
  31. public class When_serializing_messages_with_json_dot_net
  32. {
  33. string _body;
  34. Envelope _envelope;
  35. TestMessage _message;
  36. JsonSerializer _serializer;
  37. XDocument _xml;
  38. static Type _proxyType = InterfaceImplementationBuilder.GetProxyFor(typeof(MessageA));
  39. JsonSerializer _deserializer;
  40. [When]
  41. public void Serializing_messages_with_json_dot_net()
  42. {
  43. _message = new TestMessage
  44. {
  45. Name = "Joe",
  46. Details = new List<TestMessageDetail>
  47. {
  48. new TestMessageDetail {Item = "A", Value = 27.5d},
  49. new TestMessageDetail {Item = "B", Value = 13.5d},
  50. },
  51. };
  52. _envelope = new Envelope
  53. {
  54. Message = _message,
  55. };
  56. _envelope.MessageType.Add(_message.GetType().ToMessageName());
  57. _envelope.MessageType.Add(typeof (MessageA).ToMessageName());
  58. _envelope.MessageType.Add(typeof (MessageB).ToMessageName());
  59. _serializer = JsonMessageSerializer.Serializer;
  60. _deserializer = JsonMessageSerializer.Deserializer;
  61. using (var memoryStream = new MemoryStream())
  62. using (var writer = new StreamWriter(memoryStream))
  63. using (var jsonWriter = new JsonTextWriter(writer))
  64. {
  65. jsonWriter.Formatting = Formatting.Indented;
  66. _serializer.Serialize(jsonWriter, _envelope);
  67. writer.Flush();
  68. _body = Encoding.UTF8.GetString(memoryStream.ToArray());
  69. }
  70. _xml = JsonConvert.DeserializeXNode(_body, "envelope");
  71. }
  72. [Then, Explicit]
  73. public void Show_me_the_message()
  74. {
  75. Trace.WriteLine(_body);
  76. Trace.WriteLine(_xml.ToString());
  77. }
  78. [Then]
  79. public void Should_be_able_to_ressurect_the_message()
  80. {
  81. Envelope result;
  82. using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(_body), false))
  83. using (var reader = new StreamReader(memoryStream))
  84. using (var jsonReader = new JsonTextReader(reader))
  85. {
  86. result = _deserializer.Deserialize<Envelope>(jsonReader);
  87. }
  88. result.MessageType.Count.ShouldEqual(3);
  89. result.MessageType[0].ShouldEqual(typeof (TestMessage).ToMessageName());
  90. result.MessageType[1].ShouldEqual(typeof (MessageA).ToMessageName());
  91. result.MessageType[2].ShouldEqual(typeof (MessageB).ToMessageName());
  92. result.Headers.Count.ShouldEqual(0);
  93. }
  94. [Then]
  95. public void Should_be_able_to_suck_out_an_interface()
  96. {
  97. Envelope result;
  98. using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(_body), false))
  99. using (var reader = new StreamReader(memoryStream))
  100. using (var jsonReader = new JsonTextReader(reader))
  101. {
  102. result = _deserializer.Deserialize<Envelope>(jsonReader);
  103. }
  104. using(var jsonReader = new JTokenReader(result.Message as JToken))
  105. {
  106. Type proxyType = InterfaceImplementationBuilder.GetProxyFor(typeof (MessageA));
  107. var message = (MessageA) FastActivator.Create(proxyType);
  108. _serializer.Populate(jsonReader, message);
  109. message.Name.ShouldEqual("Joe");
  110. }
  111. }
  112. [Then]
  113. public void Should_be_able_to_suck_out_an_object()
  114. {
  115. Envelope result;
  116. using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(_body), false))
  117. using (var reader = new StreamReader(memoryStream))
  118. using (var jsonReader = new JsonTextReader(reader))
  119. {
  120. result = _deserializer.Deserialize<Envelope>(jsonReader);
  121. }
  122. using(var jsonReader = new JTokenReader(result.Message as JToken))
  123. {
  124. var message = (TestMessage) _serializer.Deserialize(jsonReader, typeof (TestMessage));
  125. message.Name.ShouldEqual("Joe");
  126. message.Details.Count.ShouldEqual(2);
  127. }
  128. }
  129. [Then]
  130. public void Should_be_able_to_ressurect_the_message_from_xml()
  131. {
  132. XDocument document = XDocument.Parse(_xml.ToString());
  133. Trace.WriteLine(_xml.ToString());
  134. string body = JsonConvert.SerializeXNode(document, Formatting.None, true);
  135. Trace.WriteLine(body);
  136. var result = JsonConvert.DeserializeObject<Envelope>(body, new JsonSerializerSettings
  137. {
  138. Converters = new List<JsonConverter>(new JsonConverter[]{new ListJsonConverter()}),
  139. NullValueHandling = NullValueHandling.Ignore,
  140. DefaultValueHandling = DefaultValueHandling.Ignore,
  141. MissingMemberHandling = MissingMemberHandling.Ignore,
  142. ObjectCreationHandling = ObjectCreationHandling.Auto,
  143. ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
  144. ContractResolver = new CamelCasePropertyNamesContractResolver(),
  145. });
  146. result.MessageType.Count.ShouldEqual(3);
  147. result.MessageType[0].ShouldEqual(typeof (TestMessage).ToMessageName());
  148. result.MessageType[1].ShouldEqual(typeof (MessageA).ToMessageName());
  149. result.MessageType[2].ShouldEqual(typeof (MessageB).ToMessageName());
  150. result.Headers.Count.ShouldEqual(0);
  151. }
  152. [Then]
  153. public void Serialization_speed()
  154. {
  155. //warm it up
  156. for (int i = 0; i < 10; i++)
  157. {
  158. DoSerialize();
  159. DoDeserialize();
  160. }
  161. Stopwatch timer = Stopwatch.StartNew();
  162. const int iterations = 50000;
  163. for (int i = 0; i < iterations; i++)
  164. {
  165. DoSerialize();
  166. }
  167. timer.Stop();
  168. long perSecond = iterations*1000/timer.ElapsedMilliseconds;
  169. string msg = string.Format("Serialize: {0}ms, Rate: {1} m/s", timer.ElapsedMilliseconds, perSecond);
  170. Trace.WriteLine(msg);
  171. timer = Stopwatch.StartNew();
  172. for (int i = 0; i < 50000; i++)
  173. {
  174. DoDeserialize();
  175. }
  176. timer.Stop();
  177. perSecond = iterations*1000/timer.ElapsedMilliseconds;
  178. msg = string.Format("Deserialize: {0}ms, Rate: {1} m/s", timer.ElapsedMilliseconds, perSecond);
  179. Trace.WriteLine(msg);
  180. }
  181. void DoSerialize()
  182. {
  183. using (var memoryStream = new MemoryStream())
  184. using (var writer = new StreamWriter(memoryStream))
  185. using (var jsonWriter = new JsonTextWriter(writer))
  186. {
  187. jsonWriter.Formatting = Formatting.Indented;
  188. _serializer.Serialize(jsonWriter, _envelope);
  189. writer.Flush();
  190. _body = Encoding.UTF8.GetString(memoryStream.ToArray());
  191. }
  192. }
  193. void DoDeserialize()
  194. {
  195. Envelope result;
  196. using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(_body), false))
  197. using (var reader = new StreamReader(memoryStream))
  198. using (var jsonReader = new JsonTextReader(reader))
  199. {
  200. result = _deserializer.Deserialize<Envelope>(jsonReader);
  201. }
  202. using (var jsonReader = new JTokenReader(result.Message as JToken))
  203. {
  204. var message = (MessageA)FastActivator.Create(_proxyType);
  205. _serializer.Populate(jsonReader, message);
  206. }
  207. }
  208. class Envelope
  209. {
  210. public Envelope()
  211. {
  212. Headers = new Dictionary<string, string>();
  213. MessageType = new List<string>();
  214. }
  215. public IDictionary<string, string> Headers { get; set; }
  216. public object Message { get; set; }
  217. public IList<string> MessageType { get; set; }
  218. }
  219. class TestMessageDetail
  220. {
  221. public string Item { get; set; }
  222. public double Value { get; set; }
  223. }
  224. class TestMessage :
  225. MessageA
  226. {
  227. public string Address { get; set; }
  228. public IList<TestMessageDetail> Details { get; set; }
  229. public int Level { get; set; }
  230. public string Name { get; set; }
  231. }
  232. public static object Convert(string s)
  233. {
  234. object obj = JsonConvert.DeserializeObject(s);
  235. if (obj is string)
  236. {
  237. return obj as string;
  238. }
  239. return ConvertJson((JToken) obj);
  240. }
  241. public interface MessageA
  242. {
  243. string Name { get; }
  244. }
  245. public interface MessageB
  246. {
  247. string Address { get; }
  248. string Name { get; }
  249. }
  250. static object ConvertJson(JToken token)
  251. {
  252. if (token is JValue)
  253. {
  254. return ((JValue) token).Value;
  255. }
  256. if (token is JObject)
  257. {
  258. IDictionary<string, object> expando = new Dictionary<string, object>();
  259. (from childToken in (token) where childToken is JProperty select childToken as JProperty).ToList().ForEach(
  260. property => { expando.Add(property.Name, ConvertJson(property.Value)); });
  261. return expando;
  262. }
  263. if (token is JArray)
  264. {
  265. return (token).Select(ConvertJson).ToList();
  266. }
  267. throw new ArgumentException(string.Format("Unknown token type '{0}'", token.GetType()), "token");
  268. }
  269. }
  270. [TestFixture]
  271. public class Using_JsonConverterAttribute_on_a_class :
  272. SerializationTest<JsonMessageSerializer>
  273. {
  274. public class ModifyWhenSerializingConverter : JsonConverter
  275. {
  276. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  277. {
  278. writer.WriteStartObject();
  279. writer.WritePropertyName("value");
  280. writer.WriteValue("Monster");
  281. writer.WriteEndObject();
  282. }
  283. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  284. {
  285. reader.Read();
  286. reader.Value.ShouldEqual("value");
  287. reader.Read();
  288. var value = (string)reader.Value;
  289. return new MessageA { Value = value };
  290. }
  291. public override bool CanConvert(Type objectType)
  292. {
  293. return typeof(MessageA).IsAssignableFrom(objectType);
  294. }
  295. }
  296. public class ModifyWhenDeserializingConverter : JsonConverter
  297. {
  298. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  299. {
  300. var testMessage = (MessageB)value;
  301. writer.WriteStartObject();
  302. writer.WritePropertyName("value");
  303. writer.WriteValue(testMessage.Value);
  304. writer.WriteEndObject();
  305. }
  306. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  307. {
  308. return new MessageB { Value = "Monster" };
  309. }
  310. public override bool CanConvert(Type objectType)
  311. {
  312. return typeof(MessageB).IsAssignableFrom(objectType);
  313. }
  314. }
  315. [JsonConverter(typeof(ModifyWhenSerializingConverter))]
  316. public class MessageA
  317. {
  318. public string Value { get; set; }
  319. }
  320. [JsonConverter(typeof(ModifyWhenDeserializingConverter))]
  321. public class MessageB
  322. {
  323. public string Value { get; set; }
  324. }
  325. [Test]
  326. public void Should_use_converter_for_serialization()
  327. {
  328. var obj = new MessageA { Value = "Joe" };
  329. MessageA result = SerializeAndReturn(obj);
  330. result.Value.ShouldEqual("Monster");
  331. }
  332. [Test]
  333. public void Should_use_converter_for_deserialization()
  334. {
  335. var obj = new MessageB { Value = "Joe" };
  336. MessageB result = SerializeAndReturn(obj);
  337. result.Value.ShouldEqual("Monster");
  338. }
  339. }
  340. [TestFixture]
  341. public class Using_JsonConverterAttribute_on_a_property :
  342. SerializationTest<JsonMessageSerializer>
  343. {
  344. public class ModifyWhenSerializingConverter : JsonConverter
  345. {
  346. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  347. {
  348. writer.WriteValue("Monster");
  349. }
  350. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  351. {
  352. return reader.Value;
  353. }
  354. public override bool CanConvert(Type objectType)
  355. {
  356. return typeof(string).IsAssignableFrom(objectType);
  357. }
  358. }
  359. public class ModifyWhenDeserializingConverter : JsonConverter
  360. {
  361. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  362. {
  363. writer.WriteValue((string)value);
  364. }
  365. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  366. {
  367. return "Monster";
  368. }
  369. public override bool CanConvert(Type objectType)
  370. {
  371. return typeof(string).IsAssignableFrom(objectType);
  372. }
  373. }
  374. public class SimpleMessage
  375. {
  376. [JsonConverter(typeof(ModifyWhenSerializingConverter))]
  377. public string ValueA { get; set; }
  378. [JsonConverter(typeof(ModifyWhenDeserializingConverter))]
  379. public string ValueB { get; set; }
  380. }
  381. [Test]
  382. public void Should_use_converter_for_serialization()
  383. {
  384. var obj = new SimpleMessage { ValueA = "Joe" };
  385. SimpleMessage result = SerializeAndReturn(obj);
  386. result.ValueA.ShouldEqual("Monster");
  387. }
  388. [Test]
  389. public void Should_use_converter_for_deserialization()
  390. {
  391. var obj = new SimpleMessage { ValueB = "Joe" };
  392. SimpleMessage result = SerializeAndReturn(obj);
  393. result.ValueB.ShouldEqual("Monster");
  394. }
  395. }
  396. }