PageRenderTime 59ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/Release/02.00/src/RockBus.ServiceModel/MessageExtensions.cs

#
C# | 267 lines | 239 code | 22 blank | 6 comment | 43 complexity | 769239f481494d5d051017792537ce14 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ServiceModel;
  4. using System.ServiceModel.Channels;
  5. using System.Xml;
  6. namespace RockBus.ServiceModel
  7. {
  8. public static class OperationContextExtensions
  9. {
  10. public static void CopyMessageContext(this OperationContext operationContext)
  11. {
  12. Guid messageId;
  13. if ((null != operationContext.IncomingMessageHeaders.MessageId) && operationContext.IncomingMessageHeaders.MessageId.TryGetGuid(out messageId))
  14. {
  15. operationContext.IncomingMessageProperties.SetMessageId(messageId);
  16. }
  17. else
  18. {
  19. operationContext.IncomingMessageProperties.SetMessageId(Guid.NewGuid());
  20. }
  21. RemoteEndpointMessageProperty endpointProperty = null;
  22. if (operationContext.IncomingMessageProperties.ContainsKey(RemoteEndpointMessageProperty.Name))
  23. {
  24. object endpointPropertyObj = operationContext.IncomingMessageProperties[RemoteEndpointMessageProperty.Name];
  25. if (null != endpointPropertyObj)
  26. {
  27. endpointProperty = endpointPropertyObj as RemoteEndpointMessageProperty;
  28. if (null != endpointProperty)
  29. {
  30. operationContext.IncomingMessageProperties.SetReceiveAddress(endpointProperty.Address);
  31. }
  32. }
  33. }
  34. if (null == endpointProperty)
  35. {
  36. operationContext.IncomingMessageProperties.SetReceiveAddress(operationContext.EndpointDispatcher.EndpointAddress.Uri.ToString());
  37. }
  38. }
  39. }
  40. public static class MessageExtensions
  41. {
  42. private const string MessageIdKey = "52630844-2D28-484C-BEAD-741F53D13AAB";
  43. public static Guid GetMessageId(this MessageProperties messageProperties)
  44. {
  45. return (Guid)messageProperties[MessageIdKey];
  46. }
  47. public static void SetMessageId(this MessageProperties messageProperties, Guid messageId)
  48. {
  49. messageProperties[MessageIdKey] = messageId;
  50. }
  51. private const string ReceiveAddressKey = "883A5E31-FBFD-4D8A-B6B5-67CB494A3E8E";
  52. public static string GetReceiveAddress(this MessageProperties messageProperties)
  53. {
  54. if (messageProperties.ContainsKey(ReceiveAddressKey))
  55. {
  56. return messageProperties[ReceiveAddressKey] as string;
  57. }
  58. return null;
  59. }
  60. public static void SetReceiveAddress(this MessageProperties messageProperties, string receiveAddress)
  61. {
  62. messageProperties[ReceiveAddressKey] = receiveAddress;
  63. }
  64. private const string TopicHeaderKey = "50F5AC9E-523A-4F53-B41D-842A109FBF90";
  65. public static object GetTopicHeader(this MessageProperties messageProperties)
  66. {
  67. if (messageProperties.ContainsKey(TopicHeaderKey))
  68. {
  69. return messageProperties[TopicHeaderKey];
  70. }
  71. return null;
  72. }
  73. public static void SetTopicHeader(this MessageProperties messageProperties, object topicHeader)
  74. {
  75. messageProperties[TopicHeaderKey] = topicHeader;
  76. }
  77. public static T FindHeader<T>(this MessageHeaders messageHeaders, string headerName, string headerNamespace, bool remove = false)
  78. where T : class
  79. {
  80. T header = null;
  81. int messageHeaderIndex = messageHeaders.FindHeader(headerName, headerNamespace);
  82. if (messageHeaderIndex >= 0)
  83. {
  84. header = messageHeaders.GetHeader<T>(messageHeaderIndex);
  85. if (remove)
  86. {
  87. messageHeaders.RemoveAt(messageHeaderIndex);
  88. }
  89. }
  90. return header;
  91. }
  92. public static Message MarshalMessageCloseSource(this Message source, Uri to, MessageVersion targetVersion)
  93. {
  94. Message marshalledMessage = null;
  95. try
  96. {
  97. marshalledMessage = source.MarshalMessage(to, targetVersion);
  98. return marshalledMessage;
  99. }
  100. finally
  101. {
  102. // Test for reference equality
  103. // If a new message was created by MarshalMessage, close the original (which we created just before)
  104. if (source != marshalledMessage)
  105. {
  106. source.Close();
  107. }
  108. }
  109. }
  110. public static Message MarshalMessage(this Message source, Uri to, MessageVersion targetVersion)
  111. {
  112. Message message;
  113. MessageHeaders headers = source.Headers;
  114. MessageVersion version = source.Version;
  115. UnderstoodHeaders understoodHeaders = headers.UnderstoodHeaders;
  116. HashSet<string> understoodHeadersSet = CreateKeys(understoodHeaders);
  117. if ((version == targetVersion) && !RoutingUtilities.IsMessageUsingWSSecurity(understoodHeaders))
  118. {
  119. FilterHeaders(headers, understoodHeadersSet);
  120. FilterProperties(source.Properties);
  121. return source;
  122. }
  123. if (source.IsFault)
  124. {
  125. MessageFault fault = MessageFault.CreateFault(source, 0x7fffffff);
  126. string action = headers.Action;
  127. //if (string.Equals(action, version.Addressing.DefaultFaultAction, StringComparison.Ordinal))
  128. //{
  129. // action = targetVersion.Addressing.DefaultFaultAction;
  130. //}
  131. message = Message.CreateMessage(targetVersion, fault, action);
  132. }
  133. else if (source.IsEmpty)
  134. {
  135. message = Message.CreateMessage(targetVersion, headers.Action);
  136. }
  137. else
  138. {
  139. XmlDictionaryReader readerAtBodyContents = source.GetReaderAtBodyContents();
  140. message = Message.CreateMessage(targetVersion, headers.Action, readerAtBodyContents);
  141. }
  142. CloneHeaders(message.Headers, headers, to, understoodHeadersSet);
  143. CloneProperties(message.Properties, source.Properties);
  144. return message;
  145. }
  146. private static HashSet<string> CreateKeys(UnderstoodHeaders headers)
  147. {
  148. HashSet<string> set = new HashSet<string>();
  149. foreach (MessageHeaderInfo info in headers)
  150. {
  151. set.Add(MessageHeaderKey(info));
  152. }
  153. return set;
  154. }
  155. private static string MessageHeaderKey(MessageHeaderInfo header)
  156. {
  157. return (header.Name + "+" + header.Namespace);
  158. }
  159. private static void FilterHeaders(MessageHeaders headers, HashSet<string> understoodHeadersSet)
  160. {
  161. string addressingNamespace = RoutingUtilities.GetAddressingNamespace(headers.MessageVersion.Addressing);
  162. for (int i = headers.Count - 1; i >= 0; i--)
  163. {
  164. MessageHeaderInfo header = headers[i];
  165. bool flag = false;
  166. if (!string.Equals(header.Namespace, addressingNamespace, StringComparison.Ordinal) || (!addressingHeadersToFlow.Contains(header.Name) && !manualAddressing))
  167. {
  168. if (understoodHeadersSet.Contains(MessageHeaderKey(header)))
  169. {
  170. flag = true;
  171. }
  172. else if (ActorIsNextDestination(header, headers.MessageVersion) && !header.Relay)
  173. {
  174. flag = true;
  175. }
  176. if (flag)
  177. {
  178. headers.RemoveAt(i);
  179. }
  180. }
  181. }
  182. }
  183. private static bool ActorIsNextDestination(MessageHeaderInfo header, MessageVersion messageVersion)
  184. {
  185. return ((header.Actor != null) && string.Equals(header.Actor, messageVersion.Envelope.NextDestinationActorValue));
  186. }
  187. private static void FilterProperties(MessageProperties destination)
  188. {
  189. object obj2;
  190. if (destination.TryGetValue(HttpRequestMessageProperty.Name, out obj2))
  191. {
  192. destination["IncomingHttpRequest"] = obj2;
  193. destination.Remove(HttpRequestMessageProperty.Name);
  194. }
  195. destination.Remove(HttpResponseMessageProperty.Name);
  196. Uri via = destination.Via;
  197. if (via != null)
  198. {
  199. destination["IncomingVia"] = via;
  200. }
  201. }
  202. private static bool manualAddressing = false;
  203. private static void CloneHeaders(MessageHeaders targetHeaders, MessageHeaders sourceHeaders, Uri to, HashSet<string> understoodHeadersSet)
  204. {
  205. for (int i = 0; i < sourceHeaders.Count; i++)
  206. {
  207. MessageHeaderInfo info = sourceHeaders[i];
  208. if (!understoodHeadersSet.Contains(MessageHeaderKey(info)) && (!ActorIsNextDestination(info, sourceHeaders.MessageVersion) || info.Relay))
  209. {
  210. MessageHeader header = new DelegatingHeader(info, sourceHeaders);
  211. targetHeaders.Add(header);
  212. }
  213. }
  214. targetHeaders.To = to;
  215. if (targetHeaders.MessageVersion.Addressing != AddressingVersion.None)
  216. {
  217. targetHeaders.MessageId = sourceHeaders.MessageId;
  218. targetHeaders.RelatesTo = sourceHeaders.RelatesTo;
  219. if (manualAddressing)
  220. {
  221. targetHeaders.FaultTo = sourceHeaders.FaultTo;
  222. targetHeaders.ReplyTo = sourceHeaders.ReplyTo;
  223. targetHeaders.From = sourceHeaders.From;
  224. }
  225. }
  226. }
  227. private static void CloneProperties(MessageProperties destination, MessageProperties source)
  228. {
  229. MessageEncoder encoder = destination.Encoder;
  230. destination.CopyProperties(source);
  231. destination.Encoder = encoder;
  232. FilterProperties(destination);
  233. }
  234. private static HashSet<string> addressingHeadersToFlow = InitializeHeadersToFlow();
  235. private static HashSet<string> InitializeHeadersToFlow()
  236. {
  237. HashSet<string> set = new HashSet<string>(StringComparer.Ordinal);
  238. set.Add("Action");
  239. set.Add("MessageID");
  240. set.Add("RelatesTo");
  241. set.Add("To");
  242. return set;
  243. }
  244. }
  245. }