private CorrelationContext CorrelateMessage(MultiPartMessage msg) { _correlationSyncLock.AcquireReaderLock(LockMillisecondsTimeout); try { if (msg.Metadata.Contains("CorrelationId")) { string correlationId = (string)msg.Metadata.Read("CorrelationId"); if (_correlationDictionary.ContainsKey(correlationId)) { CorrelationContext context = _correlationDictionary[correlationId]; context.ResponseMessages.Add(msg); return(context); } } } finally { _correlationSyncLock.ReleaseReaderLock(); } return(null); }
internal Collection <MultiPartMessage> Execute(MultiPartMessage msg) { if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Verbose) == SourceLevels.Verbose) { MessageEngine.Instance.Tracing.TraceEvent(TraceEventType.Verbose, 0, "Executing component pipeline..."); } int indentLevel = Trace.IndentLevel; Collection <MultiPartMessage> resultCollection = null; try { resultCollection = Execute(msg, 0); if (resultCollection != null) { if ((resultCollection.Count > 1) && (pipelineType == PipelineType.Send)) { throw new PipelineException("The send Pipeline returned more than one output message."); } } } finally { Trace.IndentLevel = indentLevel; } return(resultCollection); }
public override Collection <MultiPartMessage> Invoke(MultiPartMessage msg) { Collection <MultiPartMessage> resultCollection = new Collection <MultiPartMessage>(); resultCollection.Add(msg); return(resultCollection); }
/// <summary> /// Transmits a message. /// </summary> /// <param name="msg">The message to transmit.</param> public void TransmitMessage(MultiPartMessage msg) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().Name); } if (!_isRunning) { throw new InvalidOperationException("Message Engine is not running."); } CheckMetadata(msg); AdapterBase adapter = AdapterProxy.GetAdapterById(msg.Metadata.ReadAsString("SendAdapterId")); ComponentPipeline pipeline = _sendPipelineDictionary[adapter]; Collection <MultiPartMessage> resultCollection = pipeline.Execute(msg); if (resultCollection != null) { //Check if message should be part of a transaction if (TransactionScope.Current != null) { if (adapter is ITransactional) { ITransactional transactionalAdapter = adapter as ITransactional; AdapterTransaction transaction = transactionalAdapter.StartTransaction(resultCollection[0]); transaction.State = TransactionState.Started; TransactionScope.Current.EnlistTransaction(transaction); transactionalAdapter.TransmitMessage(resultCollection[0], transaction); } else { throw new AdapterException("Adapter: \"" + adapter.AdapterId + "\" is not transactional."); } } else { adapter.TransmitMessage(resultCollection[0]); } } }
private void CheckMetadata(MultiPartMessage msg) { #region Loopback Metadata if (msg.Metadata.Contains("Loopback")) { if ((bool)msg.Metadata.Read("Loopback") == true) { if (msg.Metadata.Contains("ReceiveUri")) { msg.Metadata.Write("SendUri", msg.Metadata.Read("ReceiveUri")); } else { throw new MetadataException("Metadata property: \"ReceiveUri\" is required for loopback."); } } } #endregion Uri uri = null; if (msg.Metadata.Contains("SendUri")) { uri = msg.Metadata.Read("SendUri") as Uri; } else { throw new MetadataException("Metadata property: \"SendUri\" is required for transmission."); } if (!msg.Metadata.Contains("SendAdapterId")) { AdapterBase adapter = _adapterProxy.ResolveUriToAdapter(uri); if (adapter != null) { msg.Metadata.Write("SendAdapterId", adapter.AdapterId); } else { throw new MetadataException("Metadata property: \"SendAdapterId\" is required for transmission."); } } }
private static void InvokeSubscriber(MultiPartMessage msg, SubscriberBase subscriber) { if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Verbose) == SourceLevels.Verbose) { MessageEngine.Instance.Tracing.TraceEvent(TraceEventType.Verbose, 0, "Invoking subscriber: \"{0}\"...", subscriber.GetType().Name); } try { subscriber.InternalInvoke(msg); } catch (Exception ex) { if (ExceptionHelper.IsCritical(ex)) { throw; } else { try { if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Error) == SourceLevels.Error) { MessageEngine.Instance.Tracing.TraceData(TraceEventType.Error, 0, ex); } if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Error) == SourceLevels.Error) { MessageEngine.Instance.Tracing.TraceData(TraceEventType.Error, 0, string.Format("Message content:\n{0}", msg.ToXmlString())); } } catch (Exception logEx) { if (ExceptionHelper.IsCritical(logEx)) { throw; } } } } }
private static void CopyMetadata(MultiPartMessage sourceMsg, MultiPartMessage destMsg) { if (!destMsg.Metadata.Contains("ReceiveUri")) { sourceMsg.Metadata.Copy("ReceiveUri", destMsg.Metadata); } if (!destMsg.Metadata.Contains("ReceiveAdapterId")) { sourceMsg.Metadata.Copy("ReceiveAdapterId", destMsg.Metadata); } if (!destMsg.Metadata.Contains("SendUri")) { sourceMsg.Metadata.Copy("SendUri", destMsg.Metadata); } if (!destMsg.Metadata.Contains("SendAdapterId")) { sourceMsg.Metadata.Copy("SendAdapterId", destMsg.Metadata); } }
internal void DistributeMessage(MultiPartMessage msg) { if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Verbose) == SourceLevels.Verbose) { MessageEngine.Instance.Tracing.TraceEvent(TraceEventType.Verbose, 0, "Distributing message: \"{0}\"...", msg.MessageType); } if (subscriberDictionary.ContainsKey(msg.MessageType)) { foreach (SubscriberBase subscriber in subscriberDictionary[msg.MessageType]) { InvokeSubscriber(msg, subscriber); } } if (subscriberDictionary.ContainsKey(allMessageTypes)) { foreach (SubscriberBase subscriber in subscriberDictionary[allMessageTypes]) { InvokeSubscriber(msg, subscriber); } } }
private Collection <MultiPartMessage> Execute(MultiPartMessage msg, int componentIndex) { if (msg == null) { throw new ArgumentNullException("msg"); } PipelineComponent component = instanceManagerCollection[componentIndex].GetInstance(msg); try { if (component.Supports(msg)) { if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Verbose) == SourceLevels.Verbose) { MessageEngine.Instance.Tracing.TraceEvent(TraceEventType.Verbose, 0, "Invoking pipeline component: \"{0}\"...", component.GetType().Name); } Collection <MultiPartMessage> componentResultCollection = component.Invoke(msg); if (componentResultCollection != null) { foreach (MultiPartMessage resultMsg in componentResultCollection) { CopyMetadata(msg, resultMsg); } componentIndex++; if (componentIndex < instanceManagerCollection.Count) { Collection <MultiPartMessage> pipelineResultCollection = new Collection <MultiPartMessage>(); foreach (MultiPartMessage componentResultMsg in componentResultCollection) { Collection <MultiPartMessage> executeResultCollection = Execute(componentResultMsg, componentIndex); if (executeResultCollection != null) { foreach (MultiPartMessage pipelineResultMsg in executeResultCollection) { pipelineResultCollection.Add(pipelineResultMsg); } } } if (pipelineResultCollection.Count > 0) { return(pipelineResultCollection); } else { return(null); } } return(componentResultCollection); } } return(null); } catch (Exception ex) { if (ExceptionHelper.IsCritical(ex)) { throw; } else { try { if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Error) == SourceLevels.Error) { MessageEngine.Instance.Tracing.TraceData(TraceEventType.Error, 0, ex); } if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Error) == SourceLevels.Error) { MessageEngine.Instance.Tracing.TraceData(TraceEventType.Error, 0, string.Format("Message content:\n{0}", msg.ToXmlString())); } } catch (Exception logEx) { if (ExceptionHelper.IsCritical(logEx)) { throw; } } } } return(null); }
/// <summary> /// Checks if the component supports processing of a specified message. /// </summary> /// <param name="msg">The message to process.</param> /// <returns>True if the message is supported, othwerwise false.</returns> public abstract bool Supports(MultiPartMessage msg);
/// <summary> /// Called by the pipeline to invoke the component. /// </summary> /// <param name="msg">The message to process.</param> /// <returns>A collection of messages produced by this component.</returns> public abstract Collection <MultiPartMessage> Invoke(MultiPartMessage msg);
/// <summary> /// <para>Initializes an instance of the <see cref="RequestTimeoutException"/> class.</para> /// </summary> /// <param name="message"> /// The error message string. /// </param> /// <param name="request"> /// The request message. /// </param> /// <param name="inner"> /// The inner exception reference. /// </param> public RequestTimeoutException(string message, MultiPartMessage request, Exception inner) : base(message, inner) { this.request = request; }
/// <summary> /// Internal invokation method. /// </summary> /// <param name="msg">A reference to the subscribed message.</param> protected internal virtual void InternalInvoke(MultiPartMessage msg) { Invoke(msg); }
public override bool Supports(MultiPartMessage msg) { return(true); }
/// <summary> /// Transmits a request and blocks until a response has been received. /// </summary> /// <param name="msg">The request message to transmit.</param> /// <param name="correlationId">A string used to correlate the request with the response.</param> /// <param name="context"> /// The <see cref="CorrelationContext"/> containing one or more response messages. /// </param> public void TransmitRequestMessage(MultiPartMessage msg, string correlationId, out CorrelationContext context) { TransmitRequestMessage(msg, correlationId, Timeout.Infinite, out context); }
/// <summary> /// Transmits a request and blocks until a response has been received, /// or until the specified timeout has elapsed. /// </summary> /// <param name="msg">The request message to transmit.</param> /// <param name="correlationId">A string used to correlate the request with the response.</param> /// <param name="millisecondsTimeout">Timeout in milliseconds.</param> /// <param name="context"> /// The <see cref="CorrelationContext"/> containing one or more response messages. /// </param> public void TransmitRequestMessage(MultiPartMessage msg, string correlationId, int millisecondsTimeout, out CorrelationContext context) { if (_isDisposed) { throw new ObjectDisposedException(this.GetType().Name); } if (!_isRunning) { throw new InvalidOperationException("Message Engine is not running."); } if (correlationId == null) { throw new ArgumentNullException("correlationId"); } msg.Metadata.Write("CorrelationId", correlationId); context = new CorrelationContext(); _correlationSyncLock.AcquireWriterLock(LockMillisecondsTimeout); try { _correlationDictionary.Add(correlationId, context); } finally { _correlationSyncLock.ReleaseWriterLock(); } try { TransmitMessage(msg); if (!context.WaitForResponse(millisecondsTimeout)) { Uri sendUri = (Uri)msg.Metadata.Read("SendUri"); throw new RequestTimeoutException("Request timed out: \"" + sendUri + "\".", msg); } } finally { try { context.Dispose(); } finally { _correlationSyncLock.AcquireWriterLock(LockMillisecondsTimeout); try { _correlationDictionary.Remove(correlationId); } finally { _correlationSyncLock.ReleaseWriterLock(); } } } }
private void MessageReceivedEventHandler(object sender, AdapterReceiveEventArgs e) { if (!_isRunning) { return; } MultiPartMessage msg = e.Message; try { //Block incoming messages if startup in progress _blockThreadsWaitEvent.WaitOne(); //Create message metadata msg.Metadata.Write("ReceiveUri", e.ReceiveEndPoint.Uri); msg.Metadata.Write("ReceiveAdapterId", e.ReceiveEndPoint.Adapter.AdapterId); ComponentPipeline pipeline = _receivePipelineDictionary[e.ReceiveEndPoint.Adapter]; Collection <MultiPartMessage> resultCollection = pipeline.Execute(msg); if (resultCollection != null) { List <CorrelationContext> contextCollection = new List <CorrelationContext>(); foreach (MultiPartMessage resultMsg in resultCollection) { CorrelationContext context = CorrelateMessage(resultMsg); if (context == null) { SubscriptionManager.DistributeMessage(resultMsg); } else { contextCollection.Add(context); } } foreach (CorrelationContext context in contextCollection) { //Signal the requestor thread that a response has been received context.CompleteRequest(); } } } catch (Exception ex) { if (ExceptionHelper.IsCritical(ex)) { throw; } else if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Error) == SourceLevels.Error && _isRunning) { if (msg != null) { MessageEngine.Instance.Tracing.TraceData(TraceEventType.Error, msg.GetHashCode(), ex); } else { MessageEngine.Instance.Tracing.TraceData(TraceEventType.Error, 0, ex); } } } }
/// <summary> /// <para>Initializes an instance of the <see cref="MessageEventArgs"/> class.</para> /// </summary> /// <param name="msg"> /// A reference to the message involved in the event. /// </param> public MessageEventArgs(MultiPartMessage msg) { this.msg = msg; }
/// <summary> /// <para>Initializes an instance of the <see cref="RequestTimeoutException"/> class.</para> /// </summary> /// <param name="message"> /// The error message string. /// </param> /// <param name="request"> /// The request message. /// </param> public RequestTimeoutException(string message, MultiPartMessage request) : this(message, request, null) { }
/// <summary> /// Invokes the subscriber for processing of the message. /// </summary> /// <param name="msg">A reference to the subscribed message.</param> public abstract void Invoke(MultiPartMessage msg);
internal PipelineComponent GetInstance(MultiPartMessage msg) { PipelineComponent component = null; object instanceKey = null; if (persistenceMode == PersistenceMode.Adapter) { if (pipelineType == PipelineType.Receive) { instanceKey = msg.Metadata.Read("ReceiveAdapterId"); } else { instanceKey = msg.Metadata.Read("SendAdapterId"); } } else if (persistenceMode == PersistenceMode.EndPoint) { if (pipelineType == PipelineType.Receive) { instanceKey = msg.Metadata.Read("ReceiveUri"); } else { if (msg.Metadata.Contains("SendUri")) { instanceKey = msg.Metadata.Read("SendUri"); } else { throw new PipelineException("Cannot create Component with EndPoint persistency when no EndPoint exists"); } } } syncLock.AcquireReaderLock(MessageEngine.Instance.LockMillisecondsTimeout); try { if (instanceDictionary.ContainsKey(instanceKey)) { component = instanceDictionary[instanceKey]; } } finally { syncLock.ReleaseReaderLock(); } if (component == null) { syncLock.AcquireWriterLock(MessageEngine.Instance.LockMillisecondsTimeout); try { if (instanceDictionary.ContainsKey(instanceKey)) { if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Verbose) == SourceLevels.Verbose) { MessageEngine.Instance.Tracing.TraceEvent(TraceEventType.Verbose, 0, "{0}: Instance already created by another thread.", componentType.Name); } component = instanceDictionary[instanceKey]; } else { component = (PipelineComponent)componentConstructor.Invoke(new object[] { configuration }); instanceDictionary.Add(instanceKey, component); if (persistenceMode == PersistenceMode.EndPoint) { if (endPointEventHandler == null) { endPointEventHandler = new EventHandler <AdapterEndPointEventArgs>(EndPointDestroyedEventHandler); AdapterBase adapter = MessageEngine.Instance.AdapterProxy.ResolveUriToAdapter((Uri)instanceKey); adapter.EndPointDestroyed += endPointEventHandler; } } if ((MessageEngine.Instance.Tracing.Switch.Level & SourceLevels.Verbose) == SourceLevels.Verbose) { MessageEngine.Instance.Tracing.TraceEvent(TraceEventType.Verbose, 0, "{0}: Instance created for: \"{1}\".", componentType.Name, instanceKey); } } } finally { syncLock.ReleaseWriterLock(); } } return(component); }