/// <summary> /// Gets the broker frontend /// </summary> /// <param name="callbackInstance">indicating response service callback</param> /// <returns>returns the broker frontend instance</returns> public IBrokerFrontend GetFrontendForInprocessBroker(IResponseServiceCallback callbackInstance) { BrokerTracing.TraceInfo("[BrokerEntry] GetFrontendForInprocessBroker..."); try { if (this.closeFlag != 0) { if (this.cleanData) { ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerUnavailable, SR.BrokerIsUnavailable); } else { ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_BrokerSuspending, SR.BrokerSuspending); } } this.sharedData.WaitForInitializationComplete(); BrokerTracing.TraceInfo("[BrokerEntry] GetFrontendForInprocessBroker successfully."); return(new BrokerController(this.clientManager, callbackInstance, this.observer)); } catch (Exception e) { BrokerTracing.TraceError("[BrokerEntry] GetFrontendForInprocessBroker failed: {0}", e); throw; } }
/// <summary> /// Initializes a new instance of the WebBrokerFrontendForGetResponse class /// </summary> /// <param name="sessionId">indicating the session id</param> /// <param name="brokerNode">indicating the broker node</param> /// <param name="credential">indicating the network credential</param> /// <param name="callback">indicating the response callback instance</param> public WebBrokerFrontendForGetResponse(int sessionId, string brokerNode, NetworkCredential credential, IResponseServiceCallback callback) { this.sessionId = sessionId; this.brokerNode = brokerNode; this.credential = credential; this.callback = callback; }
/// <summary> /// Reply the fault message. /// </summary> /// <param name="callback">the response service callback.</param> /// <param name="faultMessage">indicating the fault message</param> /// <param name="clientData">the client data.</param> private void ReplyFaultMessage(IResponseServiceCallback callback, Message faultMessage, string clientData) { if (this.callbackChannelDisposed) { return; } this.ResetTimeout(); try { faultMessage.Headers.Add(MessageHeader.CreateHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS, clientData)); if (callback is AzureQueueProxy) { callback.SendResponse(faultMessage, clientData); } else { callback.SendResponse(faultMessage); } this.IncreaseResponsesCount(); } catch (ObjectDisposedException) { this.callbackChannelDisposed = true; this.Queue.ResetResponsesCallback(); } catch (Exception e) { BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerClient] Client {0}: Failed to send fault message, Exception, {1}", this.clientId, e); } }
/// <summary> /// Initializes a new instance of the BrokerController class /// </summary> /// <param name="isSingleton">indicating whether the BrokerController is a singleton</param> /// <param name="clientManager">indicating the client manager</param> /// <param name="brokerAuth">indicating the broker authorization</param> /// <param name="observer">indicating broker observer</param> /// <param name="azureQueueProxy">the Azure storage proxy</param> public BrokerController(bool isSingleton, BrokerClientManager clientManager, BrokerAuthorization brokerAuth, BrokerObserver observer, AzureQueueProxy azureQueueProxy) { this.isSingleton = isSingleton; this.clientManager = clientManager; this.brokerAuth = brokerAuth; this.observer = observer; this.callbackInstance = azureQueueProxy; }
/// <summary> /// Initializes a new instance of the WebResponseHandler class /// </summary> /// <param name="response">indicating the web request</param> /// <param name="clientData">indicating the client data</param> /// <param name="callback">indicating the callback instance</param> public WebResponseHandler(HttpWebRequest request, string clientData, IResponseServiceCallback callback) { this.request = request; this.clientData = clientData; this.callback = callback; this.parsingResponseThread = new Thread(this.ParsingResponseThreadProc); this.parsingResponseThread.IsBackground = true; this.parsingResponseThread.Start(); }
public BrokerResponseServiceClient(IController controller, IResponseServiceCallback callback, bool useAzureQueue, AzureQueueProxy azureQueueProxy) { this.controller = controller; this.callback = callback; if (useAzureQueue) { this.useAzureQueue = useAzureQueue; this.azureQueueProxy = azureQueueProxy; this.sessionHash = azureQueueProxy.SessionHash; } }
/// <summary> /// Gets broker frontend instance /// </summary> /// <param name="callbackInstance">indicating callback instance</param> /// <returns>returns broker frontend instance</returns> public IBrokerFrontend GetBrokerFrontend(IResponseServiceCallback callbackInstance) { this.ThrowIfClosed(); InprocessBrokerFrontendAdapter frontendAdapter = new InprocessBrokerFrontendAdapter(this.brokerEntry, callbackInstance); lock (this.frontendAdapters) { this.frontendAdapters.Add(frontendAdapter); } return(frontendAdapter); }
/// <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); }
/// <summary> /// We need to multiplex callbacks for multiple enumerators and async listeners /// or else we will have to reconnect for each /// This handles registration of internal callback /// </summary> /// <param name="callback">Callback to register with the manager</param> /// <returns>Returns a registration ID</returns> public string Register(IResponseServiceCallback callback) { lock (this.responseCallbacks) { // BUG 5023 : In v3 only one response enumerator (via GetResponses or AddResponseHandler is allowed per BrokerClient) if (this.responseCallbacks.Count != 0) { throw new NotSupportedException(SR.OneResponseEnumerationPerBrokerClient); } // Add the callback string id = Guid.NewGuid().ToString(); this.responseCallbacks.Add(id, callback); return(id); } }
/// <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); } }
/// <summary> /// Called when responses arrive from broker response service /// </summary> /// <param name="message">Response message </param> public void SendResponse(Message message) { if (message == null || message.Headers == null) { SessionBase.TraceSource.TraceData(TraceEventType.Error, 0, "Null or headerless message received in main callback"); return; } if (this.isSchedulerOnAzure) { // Use heartbeat to avoid being idle 1 minute. if (message.Headers.Action == Constant.BrokerHeartbeatAction) { return; } } int index = message.Headers.FindHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS); if (index != -1) { string responseCallbackId = message.Headers.GetHeader <string>(index); IResponseServiceCallback responseServiceCallback = null; bool callbackExists = false; lock (this.responseCallbacks) { callbackExists = this.responseCallbacks.TryGetValue(responseCallbackId, out responseServiceCallback); } if (callbackExists) { responseServiceCallback.SendResponse(message); } else { SessionBase.TraceSource.TraceInformation("call back {0} doesn't exist. callbacks count: {1}", responseCallbackId, this.responseCallbacks.Count); // Enumerator or async listener exited early so ignore further responses } } else { SessionBase.TraceSource.TraceData(TraceEventType.Error, 0, "Unexpected message received in main callback - {0}", message.Headers.Action); } }
/// <summary> /// reply the end of message to the client. /// </summary> /// <param name="callback">the response service callback.</param> /// <param name="clientData">the client data.</param> /// <param name="clientPurged">indicating the client purged flag</param> private void ReplyEndOfMessage(IResponseServiceCallback callback, string clientData, EndOfResponsesReason reason) { if (this.callbackChannelDisposed) { return; } BrokerTracing.TraceInfo("[GetResponsesHandler] Client {0}: Send end of response, clientPurged = {1}", this.clientId, reason); this.ResetTimeout(); TypedMessageConverter converter = TypedMessageConverter.Create(typeof(EndOfResponses), Constant.EndOfMessageAction); EndOfResponses endOfResponses = new EndOfResponses(); endOfResponses.Count = this.ResponsesCount; endOfResponses.Reason = reason; Message eom = converter.ToMessage(endOfResponses, this.Version); eom.Headers.Add(MessageHeader.CreateHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS, clientData)); this.eorReplied = true; try { if (callback is AzureQueueProxy) { callback.SendResponse(eom, clientData); } else { callback.SendResponse(eom); } } catch (ObjectDisposedException) { BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerClient] Client {0}: Send end of response error: communication object is disposed.", this.clientId); this.callbackChannelDisposed = true; this.Queue.ResetResponsesCallback(); } catch (Exception ce) { BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerClient] Client {0}: Send end of response error: {1}", this.clientId, ce); // Swallow exception } }
/// <summary> /// Get responses from client /// </summary> /// <param name="action">indicating the action</param> /// <param name="clientData">indicating the client data</param> /// <param name="resetToBegin">indicating the position</param> /// <param name="count">indicating the count</param> /// <param name="clientId">indicating the client id</param> public void GetResponses(string action, string clientData, GetResponsePosition resetToBegin, int count, string clientId) { try { BrokerTracing.TraceVerbose("[BrokerController] GetResponses is called for Client {0}.", clientId); ParamCheckUtility.ThrowIfOutofRange(count <= 0 && count != -1, "count"); ParamCheckUtility.ThrowIfNull(clientId, "clientId"); ParamCheckUtility.ThrowIfTooLong(clientId.Length, "clientId", Constant.MaxClientIdLength, SR.ClientIdTooLong); ParamCheckUtility.ThrowIfNotMatchRegex(ParamCheckUtility.ClientIdValid, clientId, "clientId", SR.InvalidClientId); BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] GetResponses for Client {2}, Count = {0}, Position = {1}", count, resetToBegin, clientId); this.ThrowIfDisposed(); this.CheckAuth(); // Try to get callback instance for inprocess broker IResponseServiceCallback callbackInstance = this.callbackInstance; // If callback instance is null, get callback instance from operation context if (callbackInstance == null) { callbackInstance = OperationContext.Current.GetCallbackChannel <IResponseServiceCallback>(); } this.GetClient(clientId).GetResponses(action, clientData, resetToBegin, count, callbackInstance, GetMessageVersion()); #region Debug Failure Test SimulateFailure.FailOperation(1); #endregion BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Information, 0, "[BrokerController] GetResponses for Client {0} Succeeded.", clientId); } catch (Exception e) { BrokerTracing.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[BrokerController] GetResponses for Client {1} Failed: {0}", e, clientId); throw TranslateException(e); } }
public HttpResponseHandler( IController controller, string action, string clientData, GetResponsePosition resetToBegin, int count, string clientId, IResponseServiceCallback callback, BrokerResponseServiceClient responseClient) { this.controller = controller; this.action = action; this.clientData = clientData; this.resetToBegin = resetToBegin; this.count = count; this.clientId = clientId; this.callback = callback; this.responseClient = responseClient; this.HttpResponseThread = new Thread(this.HttpGetResponseThread); this.HttpResponseThread.IsBackground = true; this.HttpResponseThread.Start(); }
public AzureQueueResponseHandler( AzureQueueProxy azureQueueProxy, string action, string clientData, GetResponsePosition resetToBegin, int count, string clientId, IResponseServiceCallback callback, BrokerResponseServiceClient responseClient) { this.action = action; this.clientData = clientData; this.resetToBegin = resetToBegin; this.count = count; this.clientId = clientId; this.callback = callback; this.responseClient = responseClient; this.azureQueueProxy = azureQueueProxy; this.AzureQueueResponseThread = new Thread(new ThreadStart(this.GetResponseThread)); this.AzureQueueResponseThread.IsBackground = true; this.AzureQueueResponseThread.Start(); }
/// <summary> /// Initializes a new instance of the BrokerFrontendFactory class /// </summary> /// <param name="clientId">indicating the client id</param> /// <param name="callback">indicating the response callback</param> protected BrokerFrontendFactory(string clientId, IResponseServiceCallback callback) { this.clientId = clientId; this.responseCallback = callback; }
/// <summary> /// It is used by the service side to keep the Response connetion alive. /// </summary> /// <param name="responseCallback"></param> public void KeepConnectionAlive(IResponseServiceCallback responseCallback) { this.responseCallback = responseCallback; }
/// <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(); } } }
/// <summary> /// Initializes a new instance of the BrokerController class /// This constructor is for inprocess broker as IResponseServiceCallback is directly passed /// isSingleton is set to false and BrokerAuth is set to null for inprocess broker /// </summary> /// <param name="clientManager">indicating the client manager</param> /// <param name="callbackInstance">indicating the callback instance</param> /// <param name="observer">indicating broker observer</param> public BrokerController(BrokerClientManager clientManager, IResponseServiceCallback callbackInstance, BrokerObserver observer) : this(false, clientManager, null, observer, null) { this.callbackInstance = callbackInstance; }
/// <summary> /// reply the end of message to the client. /// </summary> /// <param name="callback">the response service callback.</param> /// <param name="clientData">the client data.</param> private void ReplyEndOfMessage(IResponseServiceCallback callback, string clientData) { this.ReplyEndOfMessage(callback, clientData, EndOfResponsesReason.Success); }
// /// <summary> // /// Stores the web session info instance // /// </summary> // private WebSessionInfo info; /// <summary> /// Initializes a new instance of the WebBrokerFrontendFactory class /// </summary> /// <param name="info">indicating the web session info</param> public WebBrokerFrontendFactory(WebSessionInfo info, string clientId, IResponseServiceCallback callback) : base(clientId, callback) { this.info = info; }
/// <summary> /// Initializes a new instance of the InprocessBrokerFrontendAdapter class /// </summary> /// <param name="brokerEntry">indicating the broker entry instance</param> /// <param name="callbackInstance">indicating the callback instance</param> public InprocessBrokerFrontendAdapter(IBrokerEntry brokerEntry, IResponseServiceCallback callbackInstance) { this.brokerEntry = brokerEntry; this.callbackInstance = callbackInstance; this.BuildFrontend(); }
/// <summary> /// Get responses /// </summary> /// <param name="action">indicating the action</param> /// <param name="clientData">indicating the client data</param> /// <param name="resetToBegin">indicating the position</param> /// <param name="count">indicating the count</param> /// <param name="callbackInstance">indicating the callback instance</param> /// <param name="version">indicating the message version</param> public void GetResponses(string action, string clientData, GetResponsePosition resetToBegin, int count, IResponseServiceCallback callbackInstance, MessageVersion version) { this.CheckDisconnected(); this.timeoutManager.ResetTimeout(); if (this.responsesClient is GetResponsesHandler) { GetResponsesHandler handler = this.responsesClient as GetResponsesHandler; if (handler.Matches(action, clientData)) { handler.GetResponses(resetToBegin, count, callbackInstance); return; } } if (this.responsesClient != null) { this.responsesClient.Dispose(); } this.responsesClient = new GetResponsesHandler(this.queue, action, clientData, this.clientId, this.timeoutManager, this.observer, this.sharedData, version); (this.responsesClient as GetResponsesHandler).GetResponses(resetToBegin, count, callbackInstance); }
/// <summary> /// Initializes a new instance of the BrokerFrontendFactory class /// </summary> /// <param name="clientId">indicating the client id</param> /// <param name="binding">indicating the binding</param> /// <param name="info">indicating the session info</param> /// <param name="scheme">indicating the scheme</param> /// <param name="responseCallback">indicating the response callback</param> public HttpBrokerFrontendFactory(string clientId, Binding binding, SessionBase session, TransportScheme scheme, IResponseServiceCallback responseCallback) : base(clientId, responseCallback) { this.info = session.Info as SessionInfo; this.binding = binding; this.scheme = scheme; if (this.info.UseAzureStorage == true) { this.useAzureQueue = true; this.azureQueueProxy = session.AzureQueueProxy; } if (this.info.UseInprocessBroker) { this.brokerFrontend = this.info.InprocessBrokerAdapter.GetBrokerFrontend(responseCallback); this.sendRequestClient = new SendRequestAdapter(this.brokerFrontend); this.brokerControllerClient = this.brokerFrontend; this.responseServiceClient = this.brokerFrontend; } }
/// <summary> /// Initializes a new instance of the BrokerFrontendFactory class /// </summary> /// <param name="clientId">indicating the client id</param> /// <param name="binding">indicating the binding</param> /// <param name="info">indicating the session info</param> /// <param name="scheme">indicating the scheme</param> /// <param name="responseCallback">indicating the response callback</param> public WSBrokerFrontendFactory(string clientId, Binding binding, SessionInfo info, TransportScheme scheme, IResponseServiceCallback responseCallback) : base(clientId, responseCallback) { this.info = info; this.schedulerOnAzure = SoaHelper.IsSchedulerOnAzure(this.info.BrokerLauncherEpr, this.info.UseInprocessBroker); this.schedulerOnIaaS = SoaHelper.IsSchedulerOnIaaS(this.info.Headnode); this.binding = binding; this.scheme = scheme; if (info.UseInprocessBroker) { this.brokerFrontend = this.info.InprocessBrokerAdapter.GetBrokerFrontend(responseCallback); this.sendRequestClient = new SendRequestAdapter(this.brokerFrontend); this.brokerControllerClient = this.brokerFrontend; this.responseServiceClient = this.brokerFrontend; } }