/** * <summary> * Finishes user request to the grid.</summary> * * <param name="fut">Future used to pass result to the user.</param> * <param name="resp">Incoming response message.</param> */ private void finishRequest(GridClientFuture fut, GridClientResponse resp) { switch (resp.Status) { case GridClientResponseStatus.Success: fut.Done(resp.Result); break; case GridClientResponseStatus.Failed: var error = resp.ErrorMessage; if (error == null) { error = "Unknown server error"; } fut.Fail(() => { throw new GridClientException(error); }); break; case GridClientResponseStatus.AuthFailure: fut.Fail(() => { throw new GridClientAuthenticationException("Authentication failed (session expired?)" + " errMsg=" + resp.ErrorMessage + ", [srv=" + ServerAddress + "]"); }); U.Async(() => Close(false)); break; case GridClientResponseStatus.AuthorizationFailure: fut.Fail(() => { throw new GridClientException("Client authorization failed: " + resp.ErrorMessage); }); break; default: fut.Fail(() => { throw new GridClientException("Unknown server response status code: " + resp.Status); }); break; } pendingReqs.Remove(resp.RequestId); }
/** * <summary> * Creates new future and passes it to the MakeJettyRequest.</summary> * * <param name="args">Request parameters.</param> * <param name="destNodeId">Node ID to route request to.</param> * <param name="converter">Response converter to pass into generated future.</param> * <returns>Future.</returns> * <exception cref="GridClientClosedException">If client was manually closed.</exception> */ private IGridClientFuture <T> MakeJettyRequest <T>(Guid destNodeId, IDictionary <String, Object> args, Func <Object, T> converter) { Dbg.Assert(args != null); Dbg.Assert(args.ContainsKey("cmd")); if (destNodeId != null && destNodeId != Guid.Empty) { args.Add("destId", destNodeId.ToString()); } var fut = new GridClientFuture <T>(); fut.DoneConverter = converter; busyLock.AcquireReaderLock(Timeout.Infinite); try { if (closed) { throw new GridClientConnectionResetException("Failed to perform request (connection was closed" + " before request is sent): " + ServerAddress); } lock (pendingReqs) { pendingReqs.Add(fut); } U.Async(() => { try { OnResponse(args, fut, LoadString(args, sessionToken)); } catch (Exception e) { fut.Fail(() => { throw new GridClientException(e.Message, e); }); } }); return(fut); } finally { busyLock.ReleaseReaderLock(); } }
/** * <summary> * Handle server response.</summary> * * <param name="args">Parameters map.</param> * <param name="fut">Future to use.</param> * <param name="str">Downloaded string response.</param> */ private void OnResponse(IDictionary <String, Object> args, GridClientFuture fut, String str) { try { JavaScriptSerializer s = new JavaScriptSerializer(); // Parse json response. var json = (IDictionary <String, Object>)s.Deserialize(str, typeof(Object)); // Recover status. GridClientResponseStatus statusCode = GridClientResponse.FindByCode((int)json["successStatus"]); // Retry with credentials, if authentication failed. if (statusCode == GridClientResponseStatus.AuthFailure) { // Reset session token. sessionToken = null; // Re-send request with credentials and without session token. str = LoadString(args, null); // Parse json response. json = (IDictionary <String, Object>)s.Deserialize(str, typeof(IDictionary <String, Object>)); // Recover status. statusCode = GridClientResponse.FindByCode((int)json["successStatus"]); } Object o; String errorMsg = null; if (json.TryGetValue("error", out o)) { errorMsg = (String)o; } if (String.IsNullOrEmpty(errorMsg)) { errorMsg = "Unknown server error"; } if (statusCode == GridClientResponseStatus.AuthFailure) { // Close this connection. Close(false); throw new GridClientAuthenticationException("Client authentication failed " + "[clientId=" + ClientId + ", srvAddr=" + ServerAddress + ", errMsg=" + errorMsg + ']'); } if (statusCode == GridClientResponseStatus.Failed) { throw new GridClientException(errorMsg); } if (statusCode == GridClientResponseStatus.AuthorizationFailure) { throw new GridClientException("Client authorization failed: " + errorMsg); } if (statusCode != GridClientResponseStatus.Success) { throw new GridClientException("Unsupported response status code: " + statusCode); } // Update session token only on success and auth-failed responses. if (json.TryGetValue("sessionToken", out o)) { sessionToken = o == null ? null : o.ToString(); } fut.Done(json["response"]); } catch (Exception e) { fut.Fail(() => { throw new GridClientException(e.Message, e); }); } finally { lock (pendingReqs) { pendingReqs.Remove(fut); } } }