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); } } }