/// <summary>
 /// Starts a new HTTP request to send requests
 /// </summary>
 private void StartNewRequest()
 {
     this.webRequestToSendRequest = SOAWebServiceRequestBuilder.GenerateSendRequestWebRequest(this.brokerNode, this.sessionId, this.clientId, false, this.credential);
     this.webRequestToSendRequest.AllowWriteStreamBuffering = false;
     this.requestContentStream = this.webRequestToSendRequest.GetRequestStream();
     this.writer = XmlDictionaryWriter.CreateTextWriter(this.requestContentStream);
     this.writer.WriteStartElement(Constant.WSMessageArrayElementName);
     this.webRequestCreated = true;
 }
            /// <summary>
            /// Gets broker client status
            /// </summary>
            /// <param name="clientId">indicating the client id</param>
            /// <returns>returns broker client status</returns>
            BrokerClientStatus IController.GetBrokerClientStatus(string clientId)
            {
                HttpWebRequest request = SOAWebServiceRequestBuilder.GenerateGetBatchStatusWebRequest(this.brokerNode, this.sessionId, clientId, this.credential, WebMessageFormat.Xml);

                using (WebResponse response = request.GetResponse())
                    using (Stream stream = response.GetResponseStream())
                    {
                        return((BrokerClientStatus)serializerForBrokerClientStatus.ReadObject(stream));
                    }
            }
            /// <summary>
            /// Send EndRequest signal to broker controller
            /// </summary>
            /// <param name="count">indicating the count</param>
            /// <param name="clientid">indicating the client id</param>
            /// <param name="timeoutThrottlingMs">indicating the timeout for throttling</param>
            /// <param name="timeoutFlushMs">indicating the timeout for flush</param>
            void IController.EndRequests(int count, string clientid, int batchId, int timeoutThrottlingMs, int timeoutEOMMs)
            {
                if (this.endRequestCalled)
                {
                    ThrowHelper.ThrowSessionFault(SOAFaultCode.Broker_EOMReject_EndRequests, SR.Broker_EOMReject_EndRequests);
                }

                this.CloseCurrentWebRequest(true);

                HttpWebRequest request = SOAWebServiceRequestBuilder.GenerateCommitBatchWebRequest(this.brokerNode, this.sessionId, this.clientId, this.credential);

                using (request.GetResponse()) { }
                this.endRequestCalled = true;
            }
            /// <summary>
            /// Get responses
            /// </summary>
            /// <param name="action">indicating the action</param>
            /// <param name="clientData">indicating the client data</param>
            /// <param name="resetToBegin">indicating the get response position</param>
            /// <param name="count">indicating the count</param>
            /// <param name="clientId">indicating the client id</param>
            void IResponseService.GetResponses(string action, string clientData, GetResponsePosition resetToBegin, int count, string clientId)
            {
                lock (this.lockObjectToProtectHandlers)
                {
                    if (this.handlers == null)
                    {
                        throw new ObjectDisposedException("WebBrokerFrontendForGetResponse");
                    }

                    HttpWebRequest     request = SOAWebServiceRequestBuilder.GenerateGetResponseWebRequest(this.brokerNode, this.sessionId, clientId, this.credential, action, clientData, count, resetToBegin == GetResponsePosition.Begin);
                    WebResponseHandler handler = new WebResponseHandler(request, clientData, this.callback);
                    this.handlers.Add(handler);
                    handler.Completed += new EventHandler(Handler_Completed);
                }
            }
        public override Task <SessionBase> CreateSession(SessionStartInfo startInfo, bool durable, int timeoutMilliseconds, Binding binding)
        {
            SessionBase.CheckSessionStartInfo(startInfo);
            DateTime targetTimeout = DateTime.Now.AddMilliseconds(Constant.DefaultCreateSessionTimeout);

            // if following env variable is set, we will launch the service host in an admin job.
            string adminJobEnv = Environment.GetEnvironmentVariable(SessionBase.EnvVarNameForAdminJob, EnvironmentVariableTarget.Process);

            if (!string.IsNullOrEmpty(adminJobEnv) && adminJobEnv.Equals("1", StringComparison.InvariantCultureIgnoreCase))
            {
                startInfo.AdminJobForHostInDiag = true;
            }

            NetworkCredential credential           = null;
            HttpWebRequest    createSessionRequest = null;
            WebSessionInfo    sessionInfo          = null;

            int  retry                 = 0;
            bool askForCredential      = false;
            int  askForCredentialTimes = 0;

            // Align the retry behavior of the RestSession with the original session.
            // User can try credential at most SessionBase.MaxRetryCount times.
            while (true)
            {
                retry++;

                SessionBase.TraceSource.TraceInformation("[Session:Unknown] Try to create session via REST API. TryCount = {0}, IsDurable = {1}", retry, durable);
                askForCredential = SessionBase.RetrieveCredentialOnAzure(startInfo);
                if (askForCredential)
                {
                    askForCredentialTimes++;
                }

                credential = Utility.BuildNetworkCredential(startInfo.Username, startInfo.InternalPassword);

                try
                {
                    // Following method needs to get cluster name, it may throw WebException because
                    // of invalid credential. Give chance to users to re-enter the credential.
                    createSessionRequest = SOAWebServiceRequestBuilder.GenerateCreateSessionWebRequest(startInfo.Headnode, durable, credential, WebMessageFormat.Xml);
                }
                catch (WebException e)
                {
                    if (e.Status == WebExceptionStatus.ProtocolError)
                    {
                        HttpWebResponse response = (HttpWebResponse)e.Response;
                        if (response.StatusCode == HttpStatusCode.Forbidden)
                        {
                            SessionBase.TraceSource.TraceInformation("[Session:Unknown] Authentication failed. Try to ask for credential again.");

                            // cleanup local cached invalid credential
                            startInfo.ClearCredential();
                            SessionBase.PurgeCredential(startInfo);

                            if (Utility.CanRetry(retry, askForCredential, askForCredentialTimes))
                            {
                                response.Close();
                                continue;
                            }
                        }
                    }

                    SessionBase.TraceSource.TraceEvent(TraceEventType.Error, 0, "[Session:Unknown] Failed to build CreateSession request: {0}", e);

                    Utility.HandleWebException(e);
                }

                try
                {
                    using (Stream stream = createSessionRequest.GetRequestStream())
                    {
                        WebSessionStartInfo info = WebAPIUtility.ToWebSessionStartInfo(startInfo.Data);
                        this.sessionStartInfoSerializer.WriteObject(stream, info);
                    }

                    using (HttpWebResponse response = (HttpWebResponse)createSessionRequest.GetResponse())
                        using (Stream stream = response.GetResponseStream())
                        {
                            sessionInfo = Utility.BuildWebSessionInfoFromDataContract((WebSessionInfoContract)this.webSessionInfoSerializer.ReadObject(stream));
                        }

                    break;
                }
                catch (WebException e)
                {
                    SessionBase.TraceSource.TraceEvent(
                        TraceEventType.Error, 0, "[Session:Unknown] Failed to create session via REST API: {0}", e);

                    Utility.HandleWebException(e);
                }
            }

            SessionBase.SaveCrendential(startInfo, binding);
            sessionInfo.HeadNode   = startInfo.Headnode;
            sessionInfo.Credential = credential;

            if (durable)
            {
#if net40
                return(TaskEx.FromResult <SessionBase>(new DurableSession(sessionInfo, startInfo.Headnode, binding)));
#else
                return(Task.FromResult <SessionBase>(new DurableSession(sessionInfo, startInfo.Headnode, binding)));
#endif
            }
            else
            {
#if net40
                return(TaskEx.FromResult <SessionBase>(new V3Session(sessionInfo, startInfo.Headnode, startInfo.ShareSession, binding)));
#else
                return(Task.FromResult <SessionBase>(new V3Session(sessionInfo, startInfo.Headnode, startInfo.ShareSession, binding)));
#endif
            }
        }
        public override Task <SessionBase> AttachSession(SessionAttachInfo attachInfo, bool durable, int timeoutMilliseconds, Binding binding)
        {
            SessionAttachInfo info = attachInfo as SessionAttachInfo;

            NetworkCredential credential  = null;
            WebSessionInfo    sessionInfo = null;

            int  retry                 = 0;
            bool askForCredential      = false;
            int  askForCredentialTimes = 0;

            // User can try credential at most SessionBase.MaxRetryCount times.
            while (true)
            {
                retry++;
                SessionBase.TraceSource.TraceInformation("[Session:Unknown] Try to attach session via REST API. TryCount = {0}, IsDurable = {1}", retry, durable);
                askForCredential = SessionBase.RetrieveCredentialOnAzure(info);

                if (askForCredential)
                {
                    askForCredentialTimes++;
                }

                credential = Utility.BuildNetworkCredential(info.Username, info.InternalPassword);

                sessionInfo = null;

                HttpWebRequest attachSessionRequest = null;

                try
                {
                    // Following method needs to get cluster name, it may throw WebException because
                    // of invalid credential. Give chance to users to re-enter the credential.
                    attachSessionRequest = SOAWebServiceRequestBuilder.GenerateAttachSessionWebRequest(info.Headnode, info.SessionId, durable, credential);
                }
                catch (WebException e)
                {
                    if (e.Status == WebExceptionStatus.ProtocolError)
                    {
                        HttpWebResponse response = (HttpWebResponse)e.Response;
                        if (response.StatusCode == HttpStatusCode.Forbidden)
                        {
                            // cleanup local cached invalid credential
                            info.ClearCredential();
                            SessionBase.PurgeCredential(info);

                            if (Utility.CanRetry(retry, askForCredential, askForCredentialTimes))
                            {
                                response.Close();
                                continue;
                            }
                        }
                    }

                    SessionBase.TraceSource.TraceEvent(
                        TraceEventType.Error, 0, "[Session:Unknown] Failed to build AttachSession request: {0}", e);

                    Utility.HandleWebException(e);
                }

                try
                {
                    using (WebResponse response = attachSessionRequest.GetResponse())
                        using (Stream stream = response.GetResponseStream())
                        {
                            sessionInfo = Utility.BuildWebSessionInfoFromDataContract((WebSessionInfoContract)this.webSessionInfoSerializer.ReadObject(stream));
                        }

                    break;
                }
                catch (WebException e)
                {
                    SessionBase.TraceSource.TraceEvent(
                        TraceEventType.Error, 0, "[Session:Unknown] Failed to attach session via REST API: {0}", e);

                    Utility.HandleWebException(e);
                }
            }

            SessionBase.SaveCrendential(info);

            sessionInfo.HeadNode   = info.Headnode;
            sessionInfo.Credential = credential;

            if (durable)
            {
#if net40
                return(TaskEx.FromResult <SessionBase>(new DurableSession(sessionInfo, attachInfo.Headnode, binding)));
#else
                return(Task.FromResult <SessionBase>(new DurableSession(sessionInfo, attachInfo.Headnode, binding)));
#endif
            }
            else
            {
#if net40
                return(TaskEx.FromResult <SessionBase>(new V3Session(sessionInfo, attachInfo.Headnode, true, binding)));
#else
                return(Task.FromResult <SessionBase>(new V3Session(sessionInfo, attachInfo.Headnode, true, binding)));
#endif
            }
        }
            /// <summary>
            /// Purge the client
            /// </summary>
            /// <param name="clientid">indicating the client id</param>
            void IController.Purge(string clientid)
            {
                HttpWebRequest request = SOAWebServiceRequestBuilder.GeneratePurgeBatchWebRequest(this.brokerNode, this.sessionId, this.clientId, this.credential);

                using (request.GetResponse()) { }
            }