Esempio n. 1
0
        /**
         * <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);
                }
            }
        }