PageRenderTime 59ms CodeModel.GetById 30ms app.highlight 22ms RepoModel.GetById 2ms app.codeStats 0ms

/src/MassTransit.HangfireIntegration/HangfireScheduledMessageData.cs

http://github.com/MassTransit/MassTransit
C# | 130 lines | 100 code | 30 blank | 0 comment | 10 complexity | cabb8e7a0d61b5f2c91bc0ce791bf8f6 MD5 | raw file
  1namespace MassTransit.HangfireIntegration
  2{
  3    using System;
  4    using System.Collections.Generic;
  5    using System.IO;
  6    using System.Linq;
  7    using System.Text;
  8    using System.Xml.Linq;
  9    using Newtonsoft.Json;
 10    using Newtonsoft.Json.Linq;
 11    using Scheduling;
 12    using Serialization;
 13
 14
 15    class HangfireScheduledMessageData : SerializedMessage
 16    {
 17        public string DestinationAddress { get; set; }
 18        public Uri Destination => new Uri(DestinationAddress);
 19        public string ContentType { get; set; }
 20        public string ExpirationTime { get; set; }
 21        public string ResponseAddress { get; set; }
 22        public string FaultAddress { get; set; }
 23        public string Body { get; set; }
 24        public string MessageId { get; set; }
 25        public string RequestId { get; set; }
 26        public string CorrelationId { get; set; }
 27        public string ConversationId { get; set; }
 28        public string InitiatorId { get; set; }
 29        public string HeadersAsJson { get; set; }
 30        public string PayloadMessageHeadersAsJson { get; set; }
 31
 32        public static HangfireScheduledMessageData Create(ConsumeContext<ScheduleMessage> context)
 33        {
 34            var message = new HangfireScheduledMessageData();
 35
 36            SetBaseProperties(message, context, context.Message.Destination);
 37
 38            return message;
 39        }
 40
 41        protected static void SetBaseProperties(HangfireScheduledMessageData message, ConsumeContext context, Uri destination)
 42        {
 43            message.DestinationAddress = destination?.ToString() ?? "";
 44            message.Body = ExtractBody(context.ReceiveContext.ContentType?.MediaType, context.ReceiveContext.GetBody(), destination);
 45            message.ContentType = context.ReceiveContext.ContentType?.MediaType;
 46            message.FaultAddress = context.FaultAddress?.ToString() ?? "";
 47            message.ResponseAddress = context.ResponseAddress?.ToString() ?? "";
 48
 49            if (context.MessageId.HasValue)
 50                message.MessageId = context.MessageId.Value.ToString();
 51
 52            if (context.CorrelationId.HasValue)
 53                message.CorrelationId = context.CorrelationId.Value.ToString();
 54
 55            if (context.ConversationId.HasValue)
 56                message.ConversationId = context.ConversationId.Value.ToString();
 57
 58            if (context.InitiatorId.HasValue)
 59                message.InitiatorId = context.InitiatorId.Value.ToString();
 60
 61            if (context.RequestId.HasValue)
 62                message.RequestId = context.RequestId.Value.ToString();
 63
 64            if (context.ExpirationTime.HasValue)
 65                message.ExpirationTime = context.ExpirationTime.Value.ToString("O");
 66
 67            IEnumerable<KeyValuePair<string, object>> headers = context.Headers.GetAll();
 68            if (headers.Any())
 69                message.HeadersAsJson = JsonConvert.SerializeObject(headers);
 70        }
 71
 72        protected static string ExtractBody(string mediaType, byte[] bytes, Uri destination)
 73        {
 74            var body = Encoding.UTF8.GetString(bytes);
 75            if (JsonMessageSerializer.JsonContentType.MediaType.Equals(mediaType, StringComparison.OrdinalIgnoreCase))
 76                body = TranslateJsonBody(body, destination.ToString());
 77            else if (XmlMessageSerializer.XmlContentType.MediaType.Equals(mediaType, StringComparison.OrdinalIgnoreCase))
 78                body = TranslateXmlBody(body, destination.ToString());
 79            else
 80                throw new InvalidOperationException("Only JSON and XML messages can be scheduled");
 81            return body;
 82        }
 83
 84        static string TranslateJsonBody(string body, string destination)
 85        {
 86            var envelope = JObject.Parse(body);
 87
 88            envelope["destinationAddress"] = destination;
 89
 90            var message = envelope["message"];
 91
 92            var payload = message["payload"];
 93            var payloadType = message["payloadType"];
 94
 95            envelope["message"] = payload;
 96            envelope["messageType"] = payloadType;
 97
 98            return JsonConvert.SerializeObject(envelope, Formatting.Indented);
 99        }
100
101        static string TranslateXmlBody(string body, string destination)
102        {
103            using var reader = new StringReader(body);
104            var document = XDocument.Load(reader);
105
106            var envelope = (from e in document.Descendants("envelope") select e).Single();
107
108            var destinationAddress = (from a in envelope.Descendants("destinationAddress") select a).Single();
109
110            var message = (from m in envelope.Descendants("message") select m).Single();
111            IEnumerable<XElement> messageType = (from mt in envelope.Descendants("messageType") select mt);
112
113            var payload = (from p in message.Descendants("payload") select p).Single();
114            IEnumerable<XElement> payloadType = (from pt in message.Descendants("payloadType") select pt);
115
116            message.Remove();
117            messageType.Remove();
118
119            destinationAddress.Value = destination;
120
121            message = new XElement("message");
122            message.Add(payload.Descendants());
123            envelope.Add(message);
124
125            envelope.Add(payloadType.Select(x => new XElement("messageType", x.Value)));
126
127            return document.ToString(SaveOptions.DisableFormatting);
128        }
129    }
130}