コード例 #1
0
 /// <summary>
 /// the event when the session failed.
 /// </summary>
 public override void SessionFailed()
 {
     if (this.Queue.ProcessedRequestsCount <= 0)
     {
         this.ReplyFaultMessage(this.lastResponseServiceCallback, FrontEndFaultMessage.GenerateFaultMessage(null, this.Version, SOAFaultCode.Broker_SessionFailure, SR.SessionFailure), this.clientData);
         this.ReplyEndOfMessage(this.lastResponseServiceCallback, this.clientData);
     }
 }
コード例 #2
0
            /// <summary>
            /// generate the fault message when the session failed.
            /// </summary>
            private void GenerateSessionFailureFaultMessage()
            {
                XmlDocument doc = new XmlDocument()
                {
                    XmlResolver = null
                };
                Message        soap11FaultMessage = FrontEndFaultMessage.GenerateFaultMessage(null, MessageVersion.Soap11, SOAFaultCode.Broker_SessionFailure, SR.SessionFailure);
                XPathNavigator nav = soap11FaultMessage.CreateBufferedCopy(BrokerEntry.MaxMessageSize).CreateNavigator();

                doc.Load(nav.ReadSubtree());
                this.messages.Add(doc.DocumentElement);
            }
コード例 #3
0
        /// <summary>
        /// End of responses received
        /// </summary>
        /// <param name="eventId">indicating the event id</param>
        /// <param name="eventArgs">indicating the event args</param>
        public override void EndOfResponses(BrokerQueueEventId eventId, ResponseEventArgs eventArgs)
        {
            IResponseServiceCallback callback = (IResponseServiceCallback)(eventArgs.State as object[])[0];
            string clientData = (eventArgs.State as object[])[1].ToString();

            // if the broker fails and the last available response received, then append the session failure fault message let the client API to handle the failure gracefully.
            if (eventId == BrokerQueueEventId.AvailableResponsesDispatched)
            {
                this.ReplyFaultMessage(callback, FrontEndFaultMessage.GenerateFaultMessage(null, this.Version, SOAFaultCode.Broker_SessionFailure, SR.SessionFailure), clientData);
            }

            this.ReplyEndOfMessage(callback, clientData);
        }
コード例 #4
0
        /// <summary>
        /// Get more responses
        /// </summary>
        /// <param name="position">indicating the position</param>
        /// <param name="count">indicating the count</param>
        /// <param name="callbackInstance">indicating the callback instance</param>
        public void GetResponses(GetResponsePosition position, int count, IResponseServiceCallback callbackInstance)
        {
            if (position == GetResponsePosition.Begin)
            {
                this.ResponsesCount = 0;
                if (this.IsSessionFailed())
                {
                    IResponseServiceCallback callback = callbackInstance;
                    this.ReplyFaultMessage(callback, FrontEndFaultMessage.GenerateFaultMessage(null, this.Version, SOAFaultCode.Broker_SessionFailure, SR.SessionFailure), this.clientData);
                    this.ReplyEndOfMessage(callback, this.clientData);
                    return;
                }

                if (this.cacheBrokerQueueItem)
                {
                    // ACK the items as they were failed to send back to client
                    lock (this.lockCacheItemList)
                    {
                        this.Queue.AckResponses(this.cachedItemList, false);
                        this.cachedItemList = new List <BrokerQueueItem>();
                    }
                }

                this.Queue.ResetResponsesCallback();
            }
            else
            {
                if (this.cacheBrokerQueueItem)
                {
                    // ACK the items as they were succeeded to send back to client
                    lock (this.lockCacheItemList)
                    {
                        this.Queue.AckResponses(this.cachedItemList, true);
                        this.cachedItemList = new List <BrokerQueueItem>();
                    }
                }
            }

            ResponseActionFilter filter = GenerateResponseActionFilter(this.Action);

            this.lastResponseServiceCallback = callbackInstance;
            if (!this.Queue.RegisterResponsesCallback(this.ReceiveResponse, this.Version, filter, count, new object[] { this.lastResponseServiceCallback, this.clientData }))
            {
                this.ReplyEndOfMessage(this.lastResponseServiceCallback, this.clientData);
            }
        }
コード例 #5
0
            /// <summary>
            /// generate the fault message when the session failed.
            /// </summary>
            private void GenerateFaultMessage(EndOfResponsesReason reason)
            {
                XmlDocument doc = new XmlDocument()
                {
                    XmlResolver = null
                };
                Message soap11FaultMessage = null;

                switch (reason)
                {
                case EndOfResponsesReason.ClientPurged:
                    soap11FaultMessage = FrontEndFaultMessage.GenerateFaultMessage(null, MessageVersion.Soap11, SOAFaultCode.ClientPurged, SR.ClientPurged);
                    break;

                case EndOfResponsesReason.ClientTimeout:
                    soap11FaultMessage = FrontEndFaultMessage.GenerateFaultMessage(null, MessageVersion.Soap11, SOAFaultCode.ClientTimeout, SR.ClientTimeout);
                    break;
                }

                XPathNavigator nav = soap11FaultMessage.CreateBufferedCopy(BrokerEntry.MaxMessageSize).CreateNavigator();

                doc.Load(nav.ReadSubtree());
                this.messages.Add(doc.DocumentElement);
            }
コード例 #6
0
        /// <summary>
        /// Receive response message
        /// </summary>
        /// <param name="item">broker queue item</param>
        /// <param name="asyncState">async state</param>
        private void ReceiveResponse(BrokerQueueItem item, object asyncState)
        {
            if (this.callbackChannelDisposed)
            {
                throw new Exception("Callback channel was disposed");
            }

            this.ResetTimeout();
            BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0, "[BrokerClient] Client {0}: Receive Response from BrokerQueue", this.clientId);
            object[] objArray = asyncState as object[];
            IResponseServiceCallback callback = (IResponseServiceCallback)objArray[0];
            string  clientData = objArray[1].ToString();
            Message response   = this.ConvertMessage(item.Message);
            int     index      = response.Headers.FindHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS);

            if (index < 0)
            {
                response.Headers.Add(MessageHeader.CreateHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS, clientData));
            }

            Exception exception = null;

            try
            {
                if (callback is AzureQueueProxy)
                {
                    callback.SendResponse(response, clientData);
                }
                else
                {
                    callback.SendResponse(response);
                }
                BrokerTracing.EtwTrace.LogFrontEndResponseSent(this.SharedData.BrokerInfo.SessionId, this.clientId, Utility.GetMessageIdFromResponse(response));
                this.IncreaseResponsesCount();
            }
            catch (ObjectDisposedException e)
            {
                this.callbackChannelDisposed = true;
                exception = new Exception("Callback channel is disposed", e);
                throw exception;
            }
            catch (CommunicationObjectFaultedException e)
            {
                this.callbackChannelDisposed = true;
                exception = new Exception("Callback channel is faulted", e);
                throw exception;
            }
            catch (CommunicationObjectAbortedException e)
            {
                this.callbackChannelDisposed = true;
                exception = new Exception("Callback channel is abroted", e);
                throw exception;
            }
            catch (Exception ce)
            {
                BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerClient] Client {0}: Send back response error: {1}", this.clientId, ce);

                // Reply a fault message indicating failed to send back the response and reply EOR and finish.
                this.ReplyFaultMessage(callback, FrontEndFaultMessage.GenerateFaultMessage(null, MessageVersion.Default, SOAFaultCode.Broker_SendBackResponseFailed, SR.SendBackResponseFailed), clientData);
                this.ReplyEndOfMessage(callback, clientData);
            }
            finally
            {
                // We do not need to lock here because this callback is designed to be
                // triggered by BrokerQueue synchronizely
                if (this.cacheBrokerQueueItem)
                {
                    lock (this.lockCacheItemList)
                    {
                        this.cachedItemList.Add(item);
                    }
                }
                else
                {
                    this.Queue.AckResponse(item, (exception == null));
                }

                if (this.callbackChannelDisposed)
                {
                    this.Queue.ResetResponsesCallback();
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Put response back into broker queue
        /// </summary>
        /// <param name="data">indicating the instance of dispatch data</param>
        public void PutResponseBack(DispatchData data)
        {
            Contract.Requires(data.BrokerQueueItem != null);

            // Either the exception is null or it is a FaultException<RetryOperationError>;
            var faultException = data.Exception as FaultException <RetryOperationError>;

            Contract.Requires(data.Exception == null || faultException != null);

            // Either we will get a reply message or an exception.
            Contract.Requires(data.ReplyMessage != null || data.Exception != null);

            Contract.Requires(data.DispatchTime != null);

            Contract.Ensures(data.ReplyMessage == null);
            Contract.Ensures(data.BrokerQueueItem == null);
            Contract.Ensures(data.Exception == null);

            // Indicate that a call has completed
            try
            {
                long callDuration = DateTime.Now.Subtract(data.DispatchTime).Ticks / 10000 / (this.serviceRequestPrefetchCount + 1);
                this.observer.CallComplete(callDuration);
            }
            catch (Exception e)
            {
                // There may be some null reference exception while cleaning up
                // Ignore these exceptions
                BrokerTracing.TraceEvent(TraceEventType.Warning, 0, "[ResponseQueueAdapter] ID = {0} Exception throwed while updating the broker observer: {1}", data.TaskId, e);
            }

            var item = data.BrokerQueueItem;

            if (item.Context is DummyRequestContext)
            {
                Message reply = null;
                if (data.Exception != null)
                {
                    if (faultException != null)
                    {
                        reply = Message.CreateMessage(MessageVersion.Default, faultException.CreateMessageFault(), faultException.Action);

                        // Only add relatesTo header to WSAddressing messages
                        if (item.Message.Headers.MessageId != null && MessageVersion.Default.Addressing == AddressingVersion.WSAddressing10)
                        {
                            reply.Headers.RelatesTo = item.Message.Headers.MessageId;
                        }

                        BrokerTracing.EtwTrace.LogBackendGeneratedFaultReply(data.SessionId, data.TaskId, data.MessageId, reply.ToString());
                    }
                    else
                    {
                        Debug.Fail("The exception in DispatchData should be an instance of FaultException<RetryOperationError>");
                    }
                }
                else if (data.ReplyMessage != null)
                {
                    reply = data.ReplyMessage;

                    // Put the response to the broker queue
                    BrokerTracing.EtwTrace.LogBackendResponseStored(data.SessionId, data.TaskId, data.MessageId, reply.IsFault);
                }
                else
                {
                    Debug.Fail("Both ReplyMessage and Exception are null. This shouldn't happen.");
                }

                this.queueFactory.PutResponseAsync(reply, item);
            }
            else
            {
                Message reply = null;
                if (data.Exception != null)
                {
                    if (faultException != null)
                    {
                        reply = FrontEndFaultMessage.GenerateFaultMessage(item.Message, item.Context.MessageVersion, faultException);
                        BrokerTracing.EtwTrace.LogBackendGeneratedFaultReply(data.SessionId, data.TaskId, data.MessageId, reply.ToString());
                    }
                    else
                    {
                        Debug.Fail("The exception in DispatchData should be an instance of FaultException<RetryOperationError>");
                    }
                }
                else if (data.ReplyMessage != null)
                {
                    reply = data.ReplyMessage;

                    // Reply the message
                    // Convert the message version
                    if (reply.Version != item.Context.MessageVersion)
                    {
                        if (reply.IsFault)
                        {
                            MessageFault fault = MessageFault.CreateFault(reply, int.MaxValue);
                            reply = Message.CreateMessage(item.Context.MessageVersion, fault, reply.Headers.Action);
                        }
                        else
                        {
                            reply = Message.CreateMessage(item.Context.MessageVersion, reply.Headers.Action, reply.GetReaderAtBodyContents());
                        }
                    }
                }
                else
                {
                    Debug.Fail("Both ReplyMessage and Exception are null. This shouldn't happen.");
                }

                this.TryReplyMessage(data.SessionId, item.Context, reply, data.MessageId);

                // dispose request item
                item.Dispose();
            }

            // Set to null since we returned it back to queue
            data.BrokerQueueItem = null;
            data.ReplyMessage    = null;
            data.Exception       = null;
        }