Exemple #1
0
        public async Task <OpenWeatherMap> GetWeatherByLocationAsync(string location)
        {
            string url = $"{_appSettings.Value.OpenWeatherMap.ForecastUrl}?q={location}&APPID={_appSettings.Value.OpenWeatherMap.ApiKey}";

            return(await WebAPIUtility.CreateWebRequest <OpenWeatherMap>(url));
        }
        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
            }
        }
                /// <summary>
                /// Parsing response stream and fetch response mesage from it
                /// </summary>
                private void ParsingResponseThreadProc()
                {
                    try
                    {
                        using (WebResponse response = this.request.GetResponse())
                            using (Stream responseStream = response.GetResponseStream())
                                using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(responseStream, DefaultReaderQuotas))
                                {
                                    reader.ReadStartElement();

                                    // this.disposeFlag is marked volatile so that the compiler
                                    // won't cache the value here
                                    while (!this.disposeFlag)
                                    {
                                        // In case of network failure and hang,
                                        // this call should eventually timed out
                                        Message m = ReadMessage(reader);
                                        if (m == null)
                                        {
                                            return;
                                        }

                                        if (m.Headers.Action.Equals(BrokerInstanceUnavailable.Action, StringComparison.InvariantCultureIgnoreCase))
                                        {
                                            TypedMessageConverter     converter = TypedMessageConverter.Create(typeof(BrokerInstanceUnavailable), BrokerInstanceUnavailable.Action);
                                            BrokerInstanceUnavailable biu       = (BrokerInstanceUnavailable)converter.FromMessage(m);
                                            SessionBase.TraceSource.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[WebResponseHandler] Received broker unavailable message, BrokerLauncherEpr = {0}, BrokerNodeDown= {1}", biu.BrokerLauncherEpr, biu.IsBrokerNodeDown);
                                            this.callback.SendBrokerDownSignal(biu.IsBrokerNodeDown);
                                            break;
                                        }
                                        else
                                        {
                                            SessionBase.TraceSource.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0, "[WebResponseHandler] Received response message:  MessageId = {0}, Action = {1}", m.Headers.MessageId, m.Headers.Action);
                                            this.callback.SendResponse(m);
                                        }
                                    }
                                }
                    }
                    catch (Exception e)
                    {
                        SessionBase.TraceSource.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "[WebBrokerFrontendForGetResponse] Failed to read response from the response stream: {0}", e);
                        if (this.disposeFlag)
                        {
                            // If it has already been disposed, do not
                            // pass the exception to the enumerator
                            return;
                        }

                        Exception    exceptionToThrow = e;
                        WebException we = e as WebException;
                        if (we != null)
                        {
                            exceptionToThrow = WebAPIUtility.ConvertWebException(we);
                            FaultException <SessionFault> faultException = exceptionToThrow as FaultException <SessionFault>;
                            if (faultException != null)
                            {
                                exceptionToThrow = Utility.TranslateFaultException(faultException);
                            }
                        }

                        //Bug #15946: throw exception instead of signaling broker down.
                        //Note: To pass the exception to AsyncResponseCallback, wrap it as a response message with special action field.
                        Message exceptionMessage = Message.CreateMessage(MessageVersion.Default, Constant.WebAPI_ClientSideException);
                        exceptionMessage.Headers.Add(MessageHeader.CreateHeader(Constant.ResponseCallbackIdHeaderName, Constant.ResponseCallbackIdHeaderNS, clientData));
                        exceptionMessage.Properties.Add(Constant.WebAPI_ClientSideException, exceptionToThrow);

                        this.callback.SendResponse(exceptionMessage);
                    }
                    finally
                    {
                        // Two threads are involved here:
                        // first thread: it is disposing BrokerClient, and now it is at WebBrokerFrontendForGetResponse.Dispose
                        // second thread: it is "ParsingResponseThreadProc" worker thread

                        // The first thread holds a lock "lockObjectToProtectHandlers" and calls WebResponseHandler.Dispose method,
                        // which attempts to abort second thread. But the second thread is in finally block here, it indefinitely
                        // delays the abort. So the first thread is blocked at "this.parsingResponseThread.Abort()".

                        // The second thread calls following "this.Completed" method, which waits for the same lock "lockObjectToProtectHandlers".
                        // So the second thread is blocked on that lock.

                        // In order to avoid deadlock, change the first thread. It should not hold a lock when aborts the second thread.

                        if (this.Completed != null)
                        {
                            this.Completed(this, EventArgs.Empty);
                        }
                    }
                }