/Release/02.00/src/RockBus.ServiceModel/MessageExtensions.cs
# · C# · 267 lines · 239 code · 22 blank · 6 comment · 43 complexity · 769239f481494d5d051017792537ce14 MD5 · raw file
- using System;
- using System.Collections.Generic;
- using System.ServiceModel;
- using System.ServiceModel.Channels;
- using System.Xml;
-
- namespace RockBus.ServiceModel
- {
- public static class OperationContextExtensions
- {
- public static void CopyMessageContext(this OperationContext operationContext)
- {
- Guid messageId;
- if ((null != operationContext.IncomingMessageHeaders.MessageId) && operationContext.IncomingMessageHeaders.MessageId.TryGetGuid(out messageId))
- {
- operationContext.IncomingMessageProperties.SetMessageId(messageId);
- }
- else
- {
- operationContext.IncomingMessageProperties.SetMessageId(Guid.NewGuid());
- }
-
- RemoteEndpointMessageProperty endpointProperty = null;
- if (operationContext.IncomingMessageProperties.ContainsKey(RemoteEndpointMessageProperty.Name))
- {
- object endpointPropertyObj = operationContext.IncomingMessageProperties[RemoteEndpointMessageProperty.Name];
- if (null != endpointPropertyObj)
- {
- endpointProperty = endpointPropertyObj as RemoteEndpointMessageProperty;
- if (null != endpointProperty)
- {
- operationContext.IncomingMessageProperties.SetReceiveAddress(endpointProperty.Address);
- }
- }
- }
-
- if (null == endpointProperty)
- {
- operationContext.IncomingMessageProperties.SetReceiveAddress(operationContext.EndpointDispatcher.EndpointAddress.Uri.ToString());
- }
- }
- }
-
- public static class MessageExtensions
- {
- private const string MessageIdKey = "52630844-2D28-484C-BEAD-741F53D13AAB";
- public static Guid GetMessageId(this MessageProperties messageProperties)
- {
- return (Guid)messageProperties[MessageIdKey];
- }
-
- public static void SetMessageId(this MessageProperties messageProperties, Guid messageId)
- {
- messageProperties[MessageIdKey] = messageId;
- }
-
- private const string ReceiveAddressKey = "883A5E31-FBFD-4D8A-B6B5-67CB494A3E8E";
- public static string GetReceiveAddress(this MessageProperties messageProperties)
- {
- if (messageProperties.ContainsKey(ReceiveAddressKey))
- {
- return messageProperties[ReceiveAddressKey] as string;
- }
-
- return null;
- }
-
- public static void SetReceiveAddress(this MessageProperties messageProperties, string receiveAddress)
- {
- messageProperties[ReceiveAddressKey] = receiveAddress;
- }
-
- private const string TopicHeaderKey = "50F5AC9E-523A-4F53-B41D-842A109FBF90";
- public static object GetTopicHeader(this MessageProperties messageProperties)
- {
- if (messageProperties.ContainsKey(TopicHeaderKey))
- {
- return messageProperties[TopicHeaderKey];
- }
-
- return null;
- }
-
- public static void SetTopicHeader(this MessageProperties messageProperties, object topicHeader)
- {
- messageProperties[TopicHeaderKey] = topicHeader;
- }
-
- public static T FindHeader<T>(this MessageHeaders messageHeaders, string headerName, string headerNamespace, bool remove = false)
- where T : class
- {
- T header = null;
- int messageHeaderIndex = messageHeaders.FindHeader(headerName, headerNamespace);
- if (messageHeaderIndex >= 0)
- {
- header = messageHeaders.GetHeader<T>(messageHeaderIndex);
- if (remove)
- {
- messageHeaders.RemoveAt(messageHeaderIndex);
- }
- }
- return header;
- }
-
- public static Message MarshalMessageCloseSource(this Message source, Uri to, MessageVersion targetVersion)
- {
- Message marshalledMessage = null;
- try
- {
- marshalledMessage = source.MarshalMessage(to, targetVersion);
- return marshalledMessage;
- }
- finally
- {
- // Test for reference equality
- // If a new message was created by MarshalMessage, close the original (which we created just before)
- if (source != marshalledMessage)
- {
- source.Close();
- }
- }
- }
-
- public static Message MarshalMessage(this Message source, Uri to, MessageVersion targetVersion)
- {
- Message message;
- MessageHeaders headers = source.Headers;
- MessageVersion version = source.Version;
- UnderstoodHeaders understoodHeaders = headers.UnderstoodHeaders;
- HashSet<string> understoodHeadersSet = CreateKeys(understoodHeaders);
- if ((version == targetVersion) && !RoutingUtilities.IsMessageUsingWSSecurity(understoodHeaders))
- {
- FilterHeaders(headers, understoodHeadersSet);
- FilterProperties(source.Properties);
- return source;
- }
- if (source.IsFault)
- {
- MessageFault fault = MessageFault.CreateFault(source, 0x7fffffff);
- string action = headers.Action;
- //if (string.Equals(action, version.Addressing.DefaultFaultAction, StringComparison.Ordinal))
- //{
- // action = targetVersion.Addressing.DefaultFaultAction;
- //}
- message = Message.CreateMessage(targetVersion, fault, action);
- }
- else if (source.IsEmpty)
- {
- message = Message.CreateMessage(targetVersion, headers.Action);
- }
- else
- {
- XmlDictionaryReader readerAtBodyContents = source.GetReaderAtBodyContents();
- message = Message.CreateMessage(targetVersion, headers.Action, readerAtBodyContents);
- }
- CloneHeaders(message.Headers, headers, to, understoodHeadersSet);
- CloneProperties(message.Properties, source.Properties);
- return message;
- }
-
- private static HashSet<string> CreateKeys(UnderstoodHeaders headers)
- {
- HashSet<string> set = new HashSet<string>();
- foreach (MessageHeaderInfo info in headers)
- {
- set.Add(MessageHeaderKey(info));
- }
- return set;
- }
-
- private static string MessageHeaderKey(MessageHeaderInfo header)
- {
- return (header.Name + "+" + header.Namespace);
-
- }
- private static void FilterHeaders(MessageHeaders headers, HashSet<string> understoodHeadersSet)
- {
- string addressingNamespace = RoutingUtilities.GetAddressingNamespace(headers.MessageVersion.Addressing);
- for (int i = headers.Count - 1; i >= 0; i--)
- {
- MessageHeaderInfo header = headers[i];
- bool flag = false;
- if (!string.Equals(header.Namespace, addressingNamespace, StringComparison.Ordinal) || (!addressingHeadersToFlow.Contains(header.Name) && !manualAddressing))
- {
- if (understoodHeadersSet.Contains(MessageHeaderKey(header)))
- {
- flag = true;
- }
- else if (ActorIsNextDestination(header, headers.MessageVersion) && !header.Relay)
- {
- flag = true;
- }
- if (flag)
- {
- headers.RemoveAt(i);
- }
- }
- }
- }
-
- private static bool ActorIsNextDestination(MessageHeaderInfo header, MessageVersion messageVersion)
- {
- return ((header.Actor != null) && string.Equals(header.Actor, messageVersion.Envelope.NextDestinationActorValue));
- }
-
- private static void FilterProperties(MessageProperties destination)
- {
- object obj2;
- if (destination.TryGetValue(HttpRequestMessageProperty.Name, out obj2))
- {
- destination["IncomingHttpRequest"] = obj2;
- destination.Remove(HttpRequestMessageProperty.Name);
- }
- destination.Remove(HttpResponseMessageProperty.Name);
- Uri via = destination.Via;
- if (via != null)
- {
- destination["IncomingVia"] = via;
- }
- }
-
- private static bool manualAddressing = false;
- private static void CloneHeaders(MessageHeaders targetHeaders, MessageHeaders sourceHeaders, Uri to, HashSet<string> understoodHeadersSet)
- {
- for (int i = 0; i < sourceHeaders.Count; i++)
- {
- MessageHeaderInfo info = sourceHeaders[i];
- if (!understoodHeadersSet.Contains(MessageHeaderKey(info)) && (!ActorIsNextDestination(info, sourceHeaders.MessageVersion) || info.Relay))
- {
- MessageHeader header = new DelegatingHeader(info, sourceHeaders);
- targetHeaders.Add(header);
- }
- }
- targetHeaders.To = to;
- if (targetHeaders.MessageVersion.Addressing != AddressingVersion.None)
- {
- targetHeaders.MessageId = sourceHeaders.MessageId;
- targetHeaders.RelatesTo = sourceHeaders.RelatesTo;
- if (manualAddressing)
- {
- targetHeaders.FaultTo = sourceHeaders.FaultTo;
- targetHeaders.ReplyTo = sourceHeaders.ReplyTo;
- targetHeaders.From = sourceHeaders.From;
- }
- }
- }
-
- private static void CloneProperties(MessageProperties destination, MessageProperties source)
- {
- MessageEncoder encoder = destination.Encoder;
- destination.CopyProperties(source);
- destination.Encoder = encoder;
- FilterProperties(destination);
- }
-
- private static HashSet<string> addressingHeadersToFlow = InitializeHeadersToFlow();
- private static HashSet<string> InitializeHeadersToFlow()
- {
- HashSet<string> set = new HashSet<string>(StringComparer.Ordinal);
- set.Add("Action");
- set.Add("MessageID");
- set.Add("RelatesTo");
- set.Add("To");
- return set;
- }
- }
- }