/// <summary> /// OnClose event /// </summary> /// <param name="timeout"></param> protected override void OnClose(TimeSpan timeout) { WCFLogger.Write(TraceEventType.Start, "Mail request channel starting to close..."); lock (_stateLock) { base.OnClose(timeout); AbortAllDequeueing(); WCFLogger.Write(TraceEventType.Verbose, "Mail request channel closed all dequeueing."); lock (_asyncRequests) { // Wait for all threads to die foreach (KeyValuePair <object, AsyncRequest> kvp in _asyncRequests) { IAsyncResult result = _asyncResults[kvp.Key]; kvp.Value.EndInvoke(result); WCFLogger.Write(TraceEventType.Verbose, "Mail request channel closed a thread."); } _asyncRequests.Clear(); _asyncResults.Clear(); } // Stop listening to the mailbox if (_mailHandler.InboxState == InboxState.Listening) { _mailHandler.Close(); } WCFLogger.Write(TraceEventType.Verbose, "Mail request channel closed mail handler"); } WCFLogger.Write(TraceEventType.Stop, "Mail request channel finished closing."); }
/// <summary> /// Replies to a request message /// </summary> /// <param name="message">The incoming System.ServiceModel.Channels.Message that contains the request</param> public override void Reply(Message message) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorRequestContext replies"); Message interceptedMessage = InterceptResponse(message); _innerContext.Reply(interceptedMessage); }
/// <summary> /// Implements the WaitForRequest method of the IReplyChannel interface. It bridges the /// call to the inner channel located in the channel base. /// </summary> /// <param name="timeout">The System.Timespan that specifies how long a request operation has to complete /// before timing out and returning false</param> /// <returns>true if a request is received before the specified interval of time elapses; /// otherwise false</returns> public bool WaitForRequest(TimeSpan timeout) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorReplyChannel waits for request"); bool succes = InnerChannel.WaitForRequest(timeout); return(succes); }
private MailSoap12TransportBinding CreateMailMessage(Message message) { MailSoap12TransportBinding mail = new MailSoap12TransportBinding(message); // 2. Check mail headers of incoming request if (_requestMessage.ReplyTo != null && _requestMessage.ReplyTo != "") { mail.To = _requestMessage.ReplyTo; } else if (_requestMessage.From != null && _requestMessage.From != "") { mail.To = _requestMessage.From; } else { throw new RaspEmailReplyCouldNotBeSentException(new dk.gov.oiosi.communication.handlers.email.MailBindingFieldMissingException("From")); } // Try to set the FROM header of the mail if (mail.From == null || mail.From == "") { mail.From = MailSoap12TransportBinding.TrimMailAddress(this.pMailHandler.InboxServerConfiguration.ReplyAddress); } //TODO: remove this hack, only for testing message.Headers.To = new Uri("mailto:" + _requestMessage.From); WCFLogger.Write(System.Diagnostics.TraceEventType.Verbose, "RequestContext created the reply mail"); return(mail); }
/// <summary> /// Begins an asynchronous operation to reply to the request associated with the current context /// </summary> /// <param name="message">The incoming System.ServiceModel.Channels.Message that contains the request</param> /// <param name="callback">The System.AsyncCallback delegate that receives the notification of the asynchronous /// reply operation completion</param> /// <param name="state">An object, specified by the application, that contains state information /// associated with the asynchronous reply operation</param> /// <returns>The System.IAsyncResult that references the asynchronous reply operation</returns> public override IAsyncResult BeginReply(Message message, AsyncCallback callback, object state) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorRequestContext begins reply"); Message interceptedMessage = InterceptResponse(message); return(_innerContext.BeginReply(interceptedMessage, callback, state)); }
/// <summary> /// Implements the RecieveRequest method of the IReplyChannel interface. It bridges the /// call to the inner channel located in the channel base. /// </summary> /// <returns>The System.ServiceModel.Channels.RequestContext used to construct replies</returns> public RequestContext ReceiveRequest() { WCFLogger.Write(TraceEventType.Verbose, "InterceptorReplyChannel receives request"); RequestContext requestContext = base.InnerChannel.ReceiveRequest(); return(requestContext); }
/// <summary> /// Implements the BeginWaitForRequest method of the IReplyChannel interface. It bridges the /// call to the inner channel located in the channel base. /// </summary> /// <param name="timeout">The System.Timespan that specifies the interval of time to wait for the reception /// of an available request</param> /// <param name="callback">The System.AsyncCallback delegate that receives the notification of the asynchronous /// receive that a request operation completes</param> /// <param name="state">An object, specified by the application, that contains state information /// associated with the asynchronous receive of a request operation</param> /// <returns>The System.IAsyncResult that references the asynchronous operation to wait /// for a request message to arrive</returns> public IAsyncResult BeginWaitForRequest(TimeSpan timeout, AsyncCallback callback, object state) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorReplyChannel begins wait for request"); IAsyncResult asyncResult = base.InnerChannel.BeginWaitForRequest(timeout, callback, state); return(asyncResult); }
/// <summary> /// Sends a message-based request and returns the correlated message-based response /// </summary> /// <param name="message">The request System.ServiceModel.Channels.Message to be transmitted</param> /// <returns>The System.ServiceModel.Channels.Message received in response to the request</returns> public Message Request(Message message) { WCFLogger.Write(TraceEventType.Start, "Beginning to intercept request"); base.ThrowIfDisposedOrNotOpen(); Message interceptedResponseMessage = null; try { Message interceptedRequestMessage = InterceptRequest(message); Message innerMessage = InnerChannel.Request(interceptedRequestMessage); interceptedResponseMessage = InterceptResponse(innerMessage); WCFLogger.Write(TraceEventType.Stop, "Finished intercepting request"); } catch (CryptographicException exception) { // Exception, if the service e.g. does not have acces to the private key in the certificate // So logging this special error this.logger.Fatal("The service migth not have permission right to the private key in the certificate", exception); // handling the error as normal HandleException(message); WCFLogger.Write(TraceEventType.Error, "Exception occurred while intercepting: " + exception); WCFLogger.Write(TraceEventType.Stop, "Finished intercepting request"); throw exception; } catch (Exception exception) { HandleException(message); WCFLogger.Write(TraceEventType.Error, "Exception occurred while intercepting: " + exception); WCFLogger.Write(TraceEventType.Stop, "Finished intercepting request"); throw exception; } return(interceptedResponseMessage); }
/// <summary> /// OnEndAcceptChannel event /// </summary> /// <param name="result"></param> /// <returns></returns> protected override TChannel OnEndAcceptChannel(IAsyncResult result) { WCFLogger.Write(TraceEventType.Verbose, "ChannelListener ends accept channel"); TChannel innerChannel = innerChannelListener.EndAcceptChannel(result); return(WrapChannel(innerChannel)); }
/// <summary> /// OnAcceptChannel event /// </summary> /// <param name="timeout"></param> /// <returns></returns> protected override TChannel OnAcceptChannel(TimeSpan timeout) { WCFLogger.Write(TraceEventType.Verbose, "ChannelListener accepts channel"); TChannel innerChannel = innerChannelListener.AcceptChannel(timeout); return(WrapChannel(innerChannel)); }
/// <summary> /// OnBeginAcceptChannel event /// </summary> /// <param name="timeout"></param> /// <param name="callback"></param> /// <param name="state"></param> /// <returns></returns> protected override IAsyncResult OnBeginAcceptChannel(TimeSpan timeout, AsyncCallback callback, object state) { WCFLogger.Write(TraceEventType.Verbose, "ChannelListener begins accept channel"); //_innerChannelListener. return(innerChannelListener.BeginAcceptChannel(timeout, callback, state)); }
/// <summary> /// Implements the BeginRecieveRequest method of the IReplyChannel interface. It bridges the /// call to the inner channel located in the channel base. /// </summary> /// <param name="callback">The System.AsyncCallback delegate that receives the notification of the asynchronous /// receive that a request operation completes</param> /// <param name="state">An object, specified by the application, that contains state information /// associated with the asynchronous receive of a request operation</param> /// <returns>The System.IAsyncResult that references the asynchronous reception of the /// request</returns> public IAsyncResult BeginReceiveRequest(AsyncCallback callback, object state) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorReplyChannel begins recieve request"); IAsyncResult asyncResult = base.InnerChannel.BeginReceiveRequest(callback, state); return(asyncResult); }
/// <summary> /// Implements the EndWaitForRequest method of the IReplyChannel interface. It bridges the /// call to the inner channel located in the channel base. /// </summary> /// <param name="result">The System.IAsyncResult that identifies the System.ServiceModel.Channels.IReplyChannel.BeginWaitForRequest() /// operation to finish, and from which to retrieve an end result</param> /// <returns>true if a request is received before the specified interval of time elapses; /// otherwise false</returns> public bool EndWaitForRequest(IAsyncResult result) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorReplyChannel ends wait for request"); bool succes = base.InnerChannel.EndWaitForRequest(result); return(succes); }
/// <summary> /// Implements the TryRecieveRequest method of the IReplyChannel interface. It bridges the /// call to the inner channel located in the channel base. /// </summary> /// <param name="timeout">The System.TimeSpan that specifies how long the receive of a request operation /// has to complete before timing out and returning false</param> /// <param name="context">The System.ServiceModel.Channels.RequestContext received</param> /// <returns>true if a request message is received before the specified interval of time /// elapses; otherwise false</returns> public bool TryReceiveRequest(TimeSpan timeout, out RequestContext context) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorReplyChannel tries to receive request"); bool succes = InnerChannel.TryReceiveRequest(timeout, out context); return(succes); }
/// <summary> /// Implements the EndBeginRecieveRequest method of the IReplyChannel interface. It bridges the /// call to the inner channel located in the channel base. Then it calls the reply interceptor /// so it can do whatever with the request context. /// </summary> /// <param name="result">The System.IAsyncResult returned by a call to the System.ServiceModel.Channels.IInputChannel.BeginReceive() /// method</param> /// <returns>The System.ServiceModel.Channels.RequestContext used to construct a reply /// to the request</returns> public RequestContext EndReceiveRequest(IAsyncResult result) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorReplyChannel ends receive request"); RequestContext innerContext = base.InnerChannel.EndReceiveRequest(result); RequestContext requestContext = this.EndReceiveRequest(innerContext); return(requestContext); }
private void SendSoapFault(InterceptorChannelException ex, RequestContext innerContext, InterceptorMessage message) { WCFLogger.Write(System.Diagnostics.TraceEventType.Start, "Interceptor is sending a SOAP fault..."); MessageFault messageFault = ex.GetMessageFault(); Message wcfMessage = Message.CreateMessage(MessageVersion.Default, messageFault, common.Definitions.DefaultOiosiNamespace2007 + messageFault.Code.SubCode.Name); innerContext.Reply(wcfMessage); WCFLogger.Write(System.Diagnostics.TraceEventType.Stop, "Interceptor finished sending the SOAP fault."); }
/// <summary> /// OnAbort event /// </summary> protected override void OnAbort() { WCFLogger.Write(System.Diagnostics.TraceEventType.Start, "Listener beginning to abort..."); _onEndDequeueing.Set(); if (pMailHandler != null) { pMailHandler.Close(); } WCFLogger.Write(System.Diagnostics.TraceEventType.Stop, "Listener finished aborting."); }
/// <summary> /// Completes an asynchronous operation to return a message-based response to /// a transmitted request /// </summary> /// <param name="result">The System.IAsyncResult returned by a call to the System.ServiceModel.Channels.IInputChannel.BeginRequest() /// method</param> /// <returns>The System.ServiceModel.Channels.Message received in response to the request</returns> public Message EndRequest(IAsyncResult result) { Message innerMessage = InnerChannel.EndRequest(result); WCFLogger.Write(TraceEventType.Start, "Beginning to intercept response"); Message interceptedMessage = InterceptResponse(innerMessage); WCFLogger.Write(TraceEventType.Stop, "Finished intercepting response"); return(interceptedMessage); }
/// <summary> /// The request /// </summary> /// <param name="message">The request System.ServiceModel.Channels.Message to be transmitted</param> /// <param name="timeout">The System.TimeSpan that specifies the interval of time within which a response /// must be received</param> /// <returns></returns> public Message Request(Message message, TimeSpan timeout) { WCFLogger.Write(TraceEventType.Start, "Mail request channel starting request"); Message reply = null; ThrowIfDisposedOrNotOpen(); // Send System.Diagnostics.Debug.Write("Mail requestChannel send request."); string id = _mailHandler.Send(CreateMailMessage(message)); // If the message sent was a fault, don't expect a reply if (message.IsFault) { message.Close(); WCFLogger.Write(TraceEventType.Stop, "Mail request channel finishing sending a fault"); return(null); } try { // Wait for the reply AutoResetEvent onAbort = new AutoResetEvent(false); _threadsDequeueing.Add(onAbort); MailSoap12TransportBinding mail = _mailHandler.Dequeue(id, timeout, onAbort); // If dequeue returned null, someone stopped it, throw aborted exception if (mail == null) { return(null); } // Get the WCF Message reply = mail.Attachment.WcfMessage; WCFLogger.Write(TraceEventType.Verbose, "Mail request channel got a reply"); } catch (CommunicationObjectAbortedException) { message.Close(); throw; } catch (TimeoutException) { message.Close(); throw; } catch (Exception e) { this.Fault(); message.Close(); throw new EmailResponseNotGottenException(e); } WCFLogger.Write(TraceEventType.Stop, "Mail request channel finishing requesting"); return(reply); }
/// <summary> /// Returns the body of a message /// </summary> /// <returns>a xmldocument with the body element only</returns> public XmlDocument GetBody() { WCFLogger.Write(TraceEventType.Verbose, "InterceptorMessage get body"); if (this.bufferCopy == null) { this.bufferCopy = this.originalMessage.CreateBufferedCopy(int.MaxValue); } Message message = this.bufferCopy.CreateMessage(); XmlDocument xmlDocument = Utilities.GetMessageBodyAsXmlDocument(message); return(xmlDocument); }
/// <summary> /// Returns the body of a message /// </summary> /// <returns>a xmldocument with the body element only</returns> public string GetBodyAsString() { WCFLogger.Write(TraceEventType.Verbose, "InterceptorMessage get body"); if (this.bufferCopy == null) { this.bufferCopy = this.originalMessage.CreateBufferedCopy(int.MaxValue); } Message message = this.bufferCopy.CreateMessage(); string body = Utilities.GetMessageBodyAsString(message); return(body); }
/// <summary> /// BeginRequest implementation of IRequest channel /// </summary> /// <param name="message">The request System.ServiceModel.Channels.Message to be transmitted</param> /// <param name="timeout">The System.TimeSpan that specifies the interval of time within which a response /// must be received</param> /// <param name="callback">The System.AsyncCallback delegate that receives the notification of the completion /// of the asynchronous operation transmitting a request message</param> /// <param name="state">An object, specified by the application, that contains state information /// associated with the asynchronous operation transmitting a request message</param> /// <returns>The System.IAsyncResult that references the asynchronous message transmission</returns> public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorReplyChannel begins request"); ThrowIfDisposedOrNotOpen(); try { Message interceptedMessage = InterceptRequest(message); return(InnerChannel.BeginRequest(interceptedMessage, timeout, callback, state)); } catch (Exception ex) { WCFLogger.Write(TraceEventType.Error, "InterceptorReplyChannel exception thrown " + ex); HandleException(message); throw ex; } }
/// <summary> /// Returns the wcf message headers. /// </summary> /// <returns></returns> public MessageHeaders GetHeaders() { MessageHeaders messageHeaders = null; WCFLogger.Write(TraceEventType.Verbose, "InterceptorMessage get headers"); if (this.bufferCopy == null) { messageHeaders = new MessageHeaders(originalMessage.Headers); } else { Message message = bufferCopy.CreateMessage(); messageHeaders = message.Headers; } return(messageHeaders); }
/// <summary> /// Sets a new body on the message /// </summary> /// <param name="body"></param> public void SetBody(XmlDocument body) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorMessage set body"); if (this.bufferCopy == null) { this.bufferCopy = this.originalMessage.CreateBufferedCopy(int.MaxValue); } XmlNodeReader xnr = new XmlNodeReader(body.DocumentElement); Message copy = this.bufferCopy.CreateMessage(); Message updatedMessage = Message.CreateMessage(copy.Version, copy.Headers.Action, xnr); updatedMessage.Headers.Clear(); updatedMessage.Headers.CopyHeadersFrom(copy.Headers); // ?? update buffer again this.bufferCopy = updatedMessage.CreateBufferedCopy(int.MaxValue); }
/// <summary> /// Replies to a request message /// </summary> /// <param name="message">The incoming System.ServiceModel.Channels.Message that contains the request</param> public override void Reply(Message message) { if (message == null) { WCFLogger.Write(System.Diagnostics.TraceEventType.Information, "RequestContext received a null message. Shutting down."); return; } WCFLogger.Write(System.Diagnostics.TraceEventType.Start, "RequestContext starting to reply..."); try { pMailHandler.Send(CreateMailMessage(message), _requestMessage.MessageId); } catch (Exception e) { _bindingElement.RaiseAsyncException(this, e); throw; } WCFLogger.Write(System.Diagnostics.TraceEventType.Stop, "RequestContext finished replying."); }
/// <summary> /// Returns a value that indicates whether a request is received before a specified /// interval of time elapses /// </summary> /// <param name="timeout">The System.TimeSpan that specifies how long the receive of a request operation /// has to complete before timing out and returning false</param> /// <param name="context">The System.ServiceModel.Channels.RequestContext received</param> /// <returns>true if a request message is received before the specified interval of time /// elapses; otherwise false</returns> public bool TryReceiveRequest(TimeSpan timeout, out RequestContext context) { context = null; try { if (_msg != null) { context = new EmailRequestContext(_msg, _mailHandler, _bindingElement); _msg = null; return(true); } WCFLogger.Write(System.Diagnostics.TraceEventType.Information, "Received an incoming mail"); } catch (TimeoutException) { return(false); } return(true); }
/// <summary> /// OnAcceptChannel event /// </summary> /// <param name="timeout"></param> /// <returns></returns> protected override IReplyChannel OnAcceptChannel(TimeSpan timeout) { Thread.CurrentThread.Name = "RaspEmailChannelListener.OnAcceptChannel"; WCFLogger.Write(System.Diagnostics.TraceEventType.Start, "Listener starting to listen for a mail..."); MailSoap12TransportBinding mail = pMailHandler.Dequeue(timeout, _onEndDequeueing); if (mail == null) { WCFLogger.Write(System.Diagnostics.TraceEventType.Information, "Listener got no mail."); WCFLogger.Write(System.Diagnostics.TraceEventType.Stop, "Listener finished listening for a mail."); return(null); } else { WCFLogger.Write(System.Diagnostics.TraceEventType.Information, "Listener found a mail."); WCFLogger.Write(System.Diagnostics.TraceEventType.Stop, "Listener finished listening for a mail."); return(new EmailReplyChannel(this, pMailHandler, mail, pContext.Binding.Elements.Find <EmailBindingElement>())); } }
/// <summary> /// Returns a copy of the message. /// </summary> /// <returns>the message</returns> public Message GetCopy() { // http://msdn.microsoft.com/en-us/library/ms734675.aspx WCFLogger.Write(TraceEventType.Verbose, "InterceptorMessage get copy of message"); if (this.bufferCopy == null) { bufferCopy = originalMessage.CreateBufferedCopy(int.MaxValue); } Message message = bufferCopy.CreateMessage(); foreach (KeyValuePair <string, object> pair in newProperties) { string key = pair.Key; object value = pair.Value; message.Properties.Add(key, value); } return(message); }
/// <summary> /// Trys to get the certificate subject from the message. /// </summary> /// <param name="certificateSubject"></param> /// <returns></returns> public bool TryGetCertificateSubject(out string certificateSubject) { WCFLogger.Write(TraceEventType.Verbose, "InterceptorMessage try get certificate subject"); bool success; try { string identityName = this.properties.Security.ServiceSecurityContext.PrimaryIdentity.Name; int index = identityName.LastIndexOf(';'); certificateSubject = identityName.Substring(0, index); success = true; } catch (Exception) { certificateSubject = string.Empty; success = false; } return(success); }
/// <summary> /// Begins an asynchronous operation to transmit a request message to the reply-side /// of a request-reply message exchange /// </summary> /// <param name="message">The request System.ServiceModel.Channels.Message to be transmitted</param> /// <param name="callback">The System.AsyncCallback delegate that receives the notification of the completion /// of the asynchronous operation transmitting a request message</param> /// <param name="state">An object, specified by the application, that contains state information /// associated with the asynchronous operation transmitting a request message</param> /// <returns>The System.IAsyncResult that references the asynchronous message transmission</returns> public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state) { base.ThrowIfDisposedOrNotOpen(); IAsyncResult asyncResult = null; try { WCFLogger.Write(TraceEventType.Start, "Beginning to intercept request"); Message interceptedMessage = InterceptRequest(message); WCFLogger.Write(TraceEventType.Stop, "Finished intercepting request"); asyncResult = InnerChannel.BeginRequest(interceptedMessage, callback, state); } catch (Exception ex) { HandleException(message); WCFLogger.Write(TraceEventType.Error, "Exception occurred while intercepting: " + ex); throw ex; } return(asyncResult); }