예제 #1
0
        private ElasticsearchResponse <T> DoRequest <T>(TransportRequestState <T> requestState, int retried = 0)
        {
            if (!SniffingDisabled(requestState.RequestConfiguration))
            {
                SniffIfInformationIsTooOld(retried);
            }

            var aliveResponse = false;

            int initialSeed; bool shouldPingHint;
            var baseUri = GetNextBaseUri(requestState, out initialSeed, out shouldPingHint);

            requestState.Seed = initialSeed;

            var  uri       = CreateUriToPath(baseUri, requestState.Path);
            bool seenError = false;

            try
            {
                if (shouldPingHint &&
                    !this.ConfigurationValues.DisablePings &&
                    (requestState.RequestConfiguration == null ||
                     !requestState.RequestConfiguration.PingDisabled.GetValueOrDefault(false))
                    )
                {
                    this.Ping(baseUri);
                }

                var streamResponse = _doRequest(requestState.Method, uri, requestState.PostData, requestState.RequestConfiguration);
                if (streamResponse != null && streamResponse.SuccessOrKnownError)
                {
                    var error = ThrowOrGetErrorFromStreamResponse(requestState, streamResponse);

                    var typedResponse = this.StreamToTypedResponse <T>(streamResponse, requestState.DeserializationState);
                    typedResponse.NumberOfRetries = retried;
                    this.SetErrorDiagnosticsAndPatchSuccess(requestState, error, typedResponse, streamResponse);
                    aliveResponse = typedResponse.SuccessOrKnownError;
                    return(typedResponse);
                }
            }
            catch (Exception e)
            {
                var maxRetries = this.GetMaximumRetries(requestState.RequestConfiguration);
                if (maxRetries == 0 && retried == 0)
                {
                    throw;
                }
                seenError = true;
                return(RetryRequest <T>(requestState, baseUri, retried, e));
            }
            finally
            {
                //make sure we always call markalive on the uri if the connection was succesful
                if (!seenError && aliveResponse)
                {
                    this._connectionPool.MarkAlive(baseUri);
                }
            }
            return(RetryRequest <T>(requestState, baseUri, retried));
        }
예제 #2
0
 public Task <ElasticsearchResponse <T> > DoRequestAsync <T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
 {
     using (var requestState = new TransportRequestState <T>(this.Settings, requestParameters, method, path))
     {
         return(this._requestHandlerAsync.RequestAsync(requestState, data));
     }
 }
예제 #3
0
        private ElasticsearchServerError ThrowOrGetErrorFromStreamResponse <T>(TransportRequestState <T> requestState,
                                                                               ElasticsearchResponse <Stream> streamResponse)
        {
            ElasticsearchServerError error = null;

            if ((!streamResponse.Success && requestState.RequestConfiguration == null) ||
                (!streamResponse.Success &&
                 requestState.RequestConfiguration != null &&
                 requestState.RequestConfiguration.AllowedStatusCodes.All(i => i != streamResponse.HttpStatusCode)))
            {
                if (streamResponse.Response != null)
                {
                    error = this.Serializer.Deserialize <ElasticsearchServerError>(streamResponse.Response);
                }
                else
                {
                    error = new ElasticsearchServerError
                    {
                        Status = streamResponse.HttpStatusCode.GetValueOrDefault(-1)
                    }
                };
                if (this.Settings.ThrowOnElasticsearchServerExceptions)
                {
                    throw new ElasticsearchServerException(error);
                }
            }
            return(error);
        }
예제 #4
0
        /* ASYNC		*** ********************************************/

        public Task <ElasticsearchResponse <T> > DoRequestAsync <T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
        {
            using (var requestState = new TransportRequestState <T>(this.Settings, requestParameters, method, path))
            {
                var bytes = PostData(data);
                requestState.TickSerialization(bytes);

                return(this.DoRequestAsync <T>(requestState)
                       .ContinueWith(t =>
                {
                    var tcs = new TaskCompletionSource <ElasticsearchResponse <T> >();
                    if (t.Exception != null)
                    {
                        tcs.SetException(t.Exception.Flatten());
                        requestState.SetResult(null);
                    }
                    else
                    {
                        tcs.SetResult(t.Result);
                        requestState.SetResult(t.Result);
                    }

                    return tcs.Task;
                }).Unwrap()
                       );
            }
        }
예제 #5
0
        private Task <ElasticsearchResponse <Stream> > CallIntoConnectionAsync <T>(TransportRequestState <T> requestState)
        {
            var uri                  = requestState.CreatePathOnCurrentNode();
            var postData             = requestState.PostData;
            var requestConfiguration = requestState.RequestConfiguration;
            var method               = requestState.Method.ToLowerInvariant();

            try
            {
                switch (method)
                {
                case "head": return(this.Connection.Head(uri, requestConfiguration));

                case "get": return(this.Connection.Get(uri, requestConfiguration));

                case "post": return(this.Connection.Post(uri, postData, requestConfiguration));

                case "put": return(this.Connection.Put(uri, postData, requestConfiguration));

                case "delete":
                    return(postData == null || postData.Length == 0
                                                        ? this.Connection.Delete(uri, requestConfiguration)
                                                        : this.Connection.Delete(uri, postData, requestConfiguration));

                default:
                    throw new Exception("Unknown HTTP method " + requestState.Method);
                }
            }
            catch (Exception e)
            {
                var tcs = new TaskCompletionSource <ElasticsearchResponse <Stream> >();
                tcs.SetException(e);
                return(tcs.Task);
            }
        }
예제 #6
0
        private Task <ElasticsearchResponse <T> > DoRequestAsync <T>(TransportRequestState <T> requestState)
        {
            this.SniffIfInformationIsTooOld(requestState);

            var uriRequiresPing = this.SelectNextNode(requestState);

            if (uriRequiresPing)
            {
                return(this.PingAsync(requestState)
                       .ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        requestState.SeenExceptions.Add(t.Exception.InnerException);
                        return this.RetryRequestAsync(requestState);
                    }
                    if (t.IsCompleted)
                    {
                        return this.FinishOrRetryRequestAsync(requestState);
                    }
                    return null;
                }).Unwrap());
            }

            return(FinishOrRetryRequestAsync(requestState));
        }
예제 #7
0
        private Task <ElasticsearchResponse <T> > DoRequestAsync <T>(TransportRequestState <T> requestState, int retried = 0)
        {
            SniffIfInformationIsTooOld(retried);

            int initialSeed; bool shouldPingHint;
            var baseUri = this.GetNextBaseUri(requestState, out initialSeed, out shouldPingHint);

            requestState.Seed = initialSeed;

            var uri = CreateUriToPath(baseUri, requestState.Path);

            if (shouldPingHint && !this._configurationValues.DisablePings)
            {
                return(this.PingAsync(baseUri)
                       .ContinueWith(t =>
                {
                    if (t.IsCompleted)
                    {
                        return this._doRequestAsyncOrRetry(requestState, retried, uri, baseUri);
                    }

                    return this.RetryRequestAsync(requestState, baseUri, retried, t.Exception);
                }).Unwrap());
            }

            return(_doRequestAsyncOrRetry(requestState, retried, uri, baseUri));
        }
예제 #8
0
        /* ASYNC *** */
        public Task <ElasticsearchResponse <T> > DoRequestAsync <T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
        {
            using (var tracer = new ElasticsearchResponseTracer <T>(this.Settings.TraceEnabled))
            {
                var postData     = PostData(data);
                var requestState = new TransportRequestState <T>(tracer, method, path, postData, requestParameters);

                return(this.DoRequestAsync <T>(requestState)
                       .ContinueWith(t =>
                {
                    var tcs = new TaskCompletionSource <ElasticsearchResponse <T> >();
                    if (t.Exception != null)
                    {
                        tcs.SetException(t.Exception.Flatten());
                    }
                    else
                    {
                        tcs.SetResult(t.Result);
                    }

                    requestState.Tracer.SetResult(t.Result);
                    return tcs.Task;
                }).Unwrap());
            }
        }
예제 #9
0
 private Task <ElasticsearchResponse <T> > _doRequestAsyncOrRetry <T>(
     TransportRequestState <T> requestState, int retried, Uri uri, Uri baseUri)
 {
     return
         (_doRequestAsync(requestState.Method, uri, requestState.PostData, requestState.RequestConfiguration).ContinueWith(t =>
     {
         if (t.IsCanceled)
         {
             return null;
         }
         if (t.IsFaulted)
         {
             return this.RetryRequestAsync <T>(requestState, baseUri, retried, t.Exception);
         }
         if (t.Result.SuccessOrKnownError)
         {
             return this.StreamToTypedResponseAsync <T>(t.Result, requestState.DeserializationState)
             .ContinueWith(tt =>
             {
                 tt.Result.NumberOfRetries = retried;
                 return tt;
             }).Unwrap();
         }
         return this.RetryRequestAsync <T>(requestState, baseUri, retried);
     }).Unwrap());
 }
예제 #10
0
        public IList <Uri> Sniff()
        {
            var pingTimeout      = this.Settings.PingTimeout.GetValueOrDefault(50);
            var requestOverrides = new RequestConfiguration()
                                   .ConnectTimeout(pingTimeout)
                                   .RequestTimeout(pingTimeout)
                                   .DisableSniffing();
            var requestParameters = new FluentRequestParameters()
                                    .RequestConfiguration(r => requestOverrides);

            var path = "_nodes/_all/clear?timeout=" + pingTimeout;

            using (var tracer = new ElasticsearchResponseTracer <Stream>(this.Settings.TraceEnabled))
            {
                var requestState = new TransportRequestState <Stream>(tracer, "GET", path, requestParameters: requestParameters);
                var response     = this.DoRequest(requestState);
                if (response.Response == null)
                {
                    return(null);
                }

                using (response.Response)
                {
                    return(Sniffer.FromStream(response, response.Response, this.Serializer));
                }
            }
        }
예제 #11
0
 private Task <ElasticsearchResponse <T> > _doRequestAsyncOrRetry <T>(
     TransportRequestState <T> requestState, int retried, Uri uri, Uri baseUri)
 {
     return
         (_doRequestAsync(requestState.Method, uri, requestState.PostData, requestState.RequestConfiguration).ContinueWith(t =>
     {
         if (t.IsCanceled)
         {
             return null;
         }
         if (t.IsFaulted)
         {
             return this.RetryRequestAsync <T>(requestState, baseUri, retried, t.Exception);
         }
         if (t.Result.SuccessOrKnownError)
         {
             var error = ThrowOrGetErrorFromStreamResponse(requestState, t.Result);
             return this.StreamToTypedResponseAsync <T>(t.Result, requestState.DeserializationState)
             .ContinueWith(tt =>
             {
                 tt.Result.NumberOfRetries = retried;
                 this.SetErrorDiagnosticsAndPatchSuccess(requestState, error, tt.Result, t.Result);
                 if (tt.Result.SuccessOrKnownError)
                 {
                     this._connectionPool.MarkAlive(baseUri);
                 }
                 return tt;
             }).Unwrap();
         }
         return this.RetryRequestAsync <T>(requestState, baseUri, retried);
     }).Unwrap());
 }
예제 #12
0
        private static string CreateMaxRetryExceptionMessage <T>(TransportRequestState <T> requestState, Exception e)
        {
            string innerException = null;

            if (e != null)
            {
                var aggregate = e as AggregateException;
                if (aggregate != null)
                {
                    aggregate = aggregate.Flatten();
                    var innerExceptions = aggregate.InnerExceptions
                                          .Select(ae => MaxRetryInnerMessage.F(ae.GetType().Name, ae.Message, ae.StackTrace))
                                          .ToList();
                    innerException = "\r\n" + string.Join("\r\n", innerExceptions);
                }
                else
                {
                    innerException = "\r\n" + MaxRetryInnerMessage.F(e.GetType().Name, e.Message, e.StackTrace);
                }
            }
            var exceptionMessage = MaxRetryExceptionMessage
                                   .F(requestState.Method, requestState.Path, requestState.Retried, innerException);

            return(exceptionMessage);
        }
예제 #13
0
        private Task <ElasticsearchResponse <T> > FinishOrRetryRequestAsync <T>(TransportRequestState <T> requestState)
        {
            var rq = requestState.InitiateRequest(RequestType.ElasticsearchCall);

            return(CallIntoConnectionAsync(requestState)
                   .ContinueWith(t =>
            {
                var retried = requestState.Retried;
                if (t.IsCanceled)
                {
                    return null;
                }
                var maxRetries = this.GetMaximumRetries(requestState.RequestConfiguration);
                if (t.IsFaulted)
                {
                    rq.Dispose();
                    requestState.SeenExceptions.Add(t.Exception);
                    if (!requestState.UsingPooling || maxRetries == 0 && retried == 0)
                    {
                        throw t.Exception;
                    }
                    return this.RetryRequestAsync <T>(requestState);
                }

                if (t.Result.SuccessOrKnownError ||
                    (
                        maxRetries == 0 && retried == 0 && !SniffOnFaultDiscoveredMoreNodes(requestState, retried, t.Result))
                    )
                {
                    rq.Finish(t.Result.Success, t.Result.HttpStatusCode);
                    rq.Dispose();
                    var error = ThrowOrGetErrorFromStreamResponse(requestState, t.Result);
                    return this.StreamToTypedResponseAsync <T>(t.Result, requestState)
                    .ContinueWith(tt =>
                    {
                        this.SetErrorDiagnosticsAndPatchSuccess(requestState, error, tt.Result, t.Result);


                        if (tt.Result.SuccessOrKnownError)
                        {
                            this._connectionPool.MarkAlive(requestState.CurrentNode);
                        }
                        return tt;
                    }).Unwrap();
                }
                if (t.Result != null)
                {
                    rq.Finish(t.Result.Success, t.Result.HttpStatusCode);
                }
                rq.Dispose();
                return this.RetryRequestAsync <T>(requestState);
            }).Unwrap());
        }
예제 #14
0
        private IList <Uri> Sniff(ITransportRequestState ownerState = null)
        {
            var pingTimeout      = this.Settings.PingTimeout.GetValueOrDefault(50);
            var requestOverrides = new RequestConfiguration
            {
                ConnectTimeout = pingTimeout,
                RequestTimeout = pingTimeout,
                DisableSniff   = true               //sniff call should never recurse
            };

            var requestParameters = new RequestParameters {
                RequestConfiguration = requestOverrides
            };

            try
            {
                var path = "_nodes/_all/clear?timeout=" + pingTimeout;
                ElasticsearchResponse <Stream> response;
                using (var requestState = new TransportRequestState <Stream>(this.Settings, requestParameters, "GET", path))
                {
                    response = this.DoRequest(requestState);

                    //inform the owing request state of the requests the sniffs did.
                    if (requestState.RequestMetrics != null && ownerState != null)
                    {
                        foreach (var r in requestState.RequestMetrics.Where(p => p.RequestType == RequestType.ElasticsearchCall))
                        {
                            r.RequestType = RequestType.Sniff;
                        }


                        if (ownerState.RequestMetrics == null)
                        {
                            ownerState.RequestMetrics = new List <RequestMetrics>();
                        }
                        ownerState.RequestMetrics.AddRange(requestState.RequestMetrics);
                    }
                    if (response.Response == null)
                    {
                        return(null);
                    }

                    using (response.Response)
                    {
                        return(Sniffer.FromStream(response, response.Response, this.Serializer));
                    }
                }
            }
            catch (MaxRetryException e)
            {
                throw new MaxRetryException(new SniffException(e));
            }
        }
예제 #15
0
        private Task <ElasticsearchResponse <T> > RetryRequestAsync <T>(TransportRequestState <T> requestState)
        {
            var maxRetries = this.GetMaximumRetries(requestState.RequestConfiguration);

            this._connectionPool.MarkDead(requestState.CurrentNode, this.ConfigurationValues.DeadTimeout, this.ConfigurationValues.MaxDeadTimeout);

            this.SniffOnConnectionFailure(requestState);

            ThrowMaxRetryExceptionWhenNeeded(requestState, maxRetries);

            return(this.DoRequestAsync <T>(requestState));
        }
예제 #16
0
        private Uri GetNextBaseUri <T>(TransportRequestState <T> requestState, out int initialSeed, out bool shouldPingHint)
        {
            if (requestState.RequestConfiguration != null && requestState.RequestConfiguration.ForcedNode != null)
            {
                initialSeed    = 0;
                shouldPingHint = false;
                return(requestState.RequestConfiguration.ForcedNode);
            }
            var baseUri = this._connectionPool.GetNext(requestState.Seed, out initialSeed, out shouldPingHint);

            return(baseUri);
        }
예제 #17
0
        /* SYNC *** */
        public ElasticsearchResponse <T> DoRequest <T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
        {
            using (var tracer = new ElasticsearchResponseTracer <T>(this.Settings.TraceEnabled))
            {
                var postData     = PostData(data);
                var requestState = new TransportRequestState <T>(tracer, method, path, postData, requestParameters);

                var result = this.DoRequest <T>(requestState);
                tracer.SetResult(result);
                return(result);
            }
        }
예제 #18
0
        /* SYNC			*** ********************************************/

        public ElasticsearchResponse <T> DoRequest <T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
        {
            using (var requestState = new TransportRequestState <T>(this.Settings, requestParameters, method, path))
            {
                var bytes = PostData(data);
                requestState.TickSerialization(bytes);

                var result = this.DoRequest <T>(requestState);

                requestState.SetResult(result);

                return(result);
            }
        }
예제 #19
0
 private void SetErrorDiagnosticsAndPatchSuccess <T>(TransportRequestState <T> requestState,
                                                     ElasticsearchServerError error, ElasticsearchResponse <T> typedResponse, ElasticsearchResponse <Stream> streamResponse)
 {
     if (error != null)
     {
         typedResponse.Success           = false;
         typedResponse.OriginalException = new ElasticsearchServerException(error);
     }
     if (!typedResponse.Success &&
         requestState.RequestConfiguration != null &&
         requestState.RequestConfiguration.AllowedStatusCodes.HasAny(i => i == streamResponse.HttpStatusCode))
     {
         typedResponse.Success = true;
     }
 }
예제 #20
0
        private static void ThrowMaxRetryExceptionWhenNeeded <T>(TransportRequestState <T> requestState, int maxRetries)
        {
            if (requestState.Retried < maxRetries)
            {
                return;
            }
            var innerExceptions = requestState.SeenExceptions.Where(e => e != null).ToList();
            var innerException  = !innerExceptions.HasAny()
                                ? null
                                : (innerExceptions.Count() == 1)
                                        ? innerExceptions.First()
                                        : new AggregateException(requestState.SeenExceptions);
            var exceptionMessage = CreateMaxRetryExceptionMessage(requestState, innerException);

            throw new MaxRetryException(exceptionMessage, innerException);
        }
예제 #21
0
        /* SYNC *** */
        public ElasticsearchResponse <T> DoRequest <T>(string method, string path, object data = null, IRequestParameters requestParameters = null)
        {
            using (var tracer = new ElasticsearchResponseTracer <T>(this.Settings.TraceEnabled))
            {
                var postData     = PostData(data);
                var requestState = new TransportRequestState <T>(tracer, method, path, postData, requestParameters);

                var result = this.DoRequest <T>(requestState);
                var objectNeedsResponseRef = result.Response as IResponseWithRequestInformation;
                if (objectNeedsResponseRef != null)
                {
                    objectNeedsResponseRef.RequestInformation = result;
                }
                tracer.SetResult(result);
                return(result);
            }
        }
예제 #22
0
        private Task <ElasticsearchResponse <T> > RetryRequestAsync <T>(TransportRequestState <T> requestState, Uri baseUri, int retried, Exception e = null)
        {
            var maxRetries       = this.GetMaximumRetries(requestState.RequestConfiguration);
            var exceptionMessage = MaxRetryExceptionMessage.F(requestState.Method, requestState.Path, retried);

            this._connectionPool.MarkDead(baseUri, this._configurationValues.DeadTimeout, this._configurationValues.MaxDeadTimeout);

            if (this._configurationValues.SniffsOnConnectionFault && retried == 0)
            {
                this.SniffClusterState();
            }

            if (retried < maxRetries)
            {
                return(this.DoRequestAsync <T>(requestState, ++retried));
            }

            throw new MaxRetryException(exceptionMessage, e);
        }
예제 #23
0
        private ElasticsearchResponse <T> RetryRequest <T>(TransportRequestState <T> requestState, Uri baseUri, int retried, Exception e = null)
        {
            var maxRetries       = this.GetMaximumRetries(requestState.RequestConfiguration);
            var exceptionMessage = MaxRetryExceptionMessage.F(requestState.Method, requestState.Path.IsNullOrEmpty() ? "/" : "", retried);

            this._connectionPool.MarkDead(baseUri, this._configurationValues.DeadTimeout, this._configurationValues.MaxDeadTimeout);
            if (!SniffingDisabled(requestState.RequestConfiguration) &&
                this._configurationValues.SniffsOnConnectionFault &&
                retried == 0)
            {
                this.SniffClusterState();
            }

            if (retried >= maxRetries)
            {
                throw new MaxRetryException(exceptionMessage, e);
            }

            return(this.DoRequest <T>(requestState, ++retried));
        }
예제 #24
0
        private ElasticsearchServerError ThrowOrGetErrorFromStreamResponse <T>(
            TransportRequestState <T> requestState,
            ElasticsearchResponse <Stream> streamResponse)
        {
            ElasticsearchServerError error = null;

            if ((!streamResponse.Success && requestState.RequestConfiguration == null) ||
                (!streamResponse.Success &&
                 requestState.RequestConfiguration != null &&
                 requestState.RequestConfiguration.AllowedStatusCodes.All(i => i != streamResponse.HttpStatusCode)))
            {
                if (streamResponse.Response != null && !this.Settings.KeepRawResponse)
                {
                    var e = this.Serializer.Deserialize <OneToOneServerException>(streamResponse.Response);
                    error = ElasticsearchServerError.Create(e);
                }
                else if (streamResponse.Response != null && this.Settings.KeepRawResponse)
                {
                    var ms = new MemoryStream();
                    streamResponse.Response.CopyTo(ms);
                    ms.Position = 0;
                    streamResponse.ResponseRaw = ms.ToArray();
                    var e = this.Serializer.Deserialize <OneToOneServerException>(ms);
                    error                   = ElasticsearchServerError.Create(e);
                    ms.Position             = 0;
                    streamResponse.Response = ms;
                }
                else
                {
                    error = new ElasticsearchServerError
                    {
                        Status = streamResponse.HttpStatusCode.GetValueOrDefault(-1)
                    }
                };
                if (this.Settings.ThrowOnElasticsearchServerExceptions)
                {
                    throw new ElasticsearchServerException(error);
                }
            }
            return(error);
        }
예제 #25
0
        private ElasticsearchResponse <Stream> CallInToConnection <T>(TransportRequestState <T> requestState)
        {
            var uri                  = requestState.CreatePathOnCurrentNode();
            var postData             = requestState.PostData;
            var requestConfiguration = requestState.RequestConfiguration;

            switch (requestState.Method.ToLowerInvariant())
            {
            case "post": return(this.Connection.PostSync(uri, postData, requestConfiguration));

            case "put": return(this.Connection.PutSync(uri, postData, requestConfiguration));

            case "head": return(this.Connection.HeadSync(uri, requestConfiguration));

            case "get": return(this.Connection.GetSync(uri, requestConfiguration));

            case "delete":
                return(postData == null || postData.Length == 0
                                                ? this.Connection.DeleteSync(uri, requestConfiguration)
                                                : this.Connection.DeleteSync(uri, postData, requestConfiguration));
            }
            throw new Exception("Unknown HTTP method " + requestState.Method);
        }
예제 #26
0
        private ElasticsearchResponse <T> DoRequest <T>(TransportRequestState <T> requestState)
        {
            var retried = requestState.Retried;

            this.SniffIfInformationIsTooOld(requestState);

            var aliveResponse = false;

            var nodeRequiresPinging = this.SelectNextNode(requestState);

            var seenError  = false;
            var maxRetries = this.GetMaximumRetries(requestState.RequestConfiguration);

            try
            {
                if (nodeRequiresPinging)
                {
                    var pingSuccess = this.Ping(requestState);
                    if (!pingSuccess)
                    {
                        return(RetryRequest <T>(requestState));
                    }
                }

                ElasticsearchResponse <Stream> streamResponse;
                using (var rq = requestState.InitiateRequest(RequestType.ElasticsearchCall))
                {
                    streamResponse = this.CallInToConnection(requestState);
                    rq.Finish(streamResponse.Success, streamResponse.HttpStatusCode);
                }

                if (streamResponse.SuccessOrKnownError ||
                    (
                        maxRetries == 0 && retried == 0 && !SniffOnFaultDiscoveredMoreNodes(requestState, retried, streamResponse))
                    )
                {
                    var error = ThrowOrGetErrorFromStreamResponse(requestState, streamResponse);

                    var typedResponse = this.StreamToTypedResponse <T>(streamResponse, requestState);
                    this.SetErrorDiagnosticsAndPatchSuccess(requestState, error, typedResponse, streamResponse);
                    aliveResponse = typedResponse.SuccessOrKnownError;
                    return(typedResponse);
                }
            }
            catch (MaxRetryException)
            {
                throw;
            }
            catch (ElasticsearchServerException)
            {
                throw;
            }
            catch (Exception e)
            {
                requestState.SeenExceptions.Add(e);
                if (!requestState.UsingPooling || maxRetries == 0 && retried == 0)
                {
                    if (_throwMaxRetry)
                    {
                        new MaxRetryException(e);
                    }
                    else
                    {
                        throw;
                    }
                }
                seenError = true;
                return(RetryRequest <T>(requestState));
            }
            finally
            {
                //make sure we always call markalive on the uri if the connection was succesful
                if (!seenError && aliveResponse)
                {
                    this._connectionPool.MarkAlive(requestState.CurrentNode);
                }
            }
            return(RetryRequest <T>(requestState));
        }
예제 #27
0
        /* STREAM HANDLING	********************************************/

        private ElasticsearchServerError ThrowOrGetErrorFromStreamResponse <T>(
            TransportRequestState <T> requestState,
            ElasticsearchResponse <Stream> streamResponse)
        {
            if (((streamResponse.HttpStatusCode.HasValue && streamResponse.HttpStatusCode.Value <= 0) ||
                 !streamResponse.HttpStatusCode.HasValue) && streamResponse.OriginalException != null)
            {
                throw streamResponse.OriginalException;
            }

            if (IsValidResponse(requestState, streamResponse))
            {
                return(null);
            }

            ElasticsearchServerError error = null;

            var type = typeof(T);

            if (typeof(Stream).IsAssignableFrom(typeof(T)) || typeof(T) == typeof(VoidResponse))
            {
                return(null);
            }

            if (streamResponse.Response != null && !(this.Settings.KeepRawResponse || this.TypeOfResponseCopiesDirectly <T>()))
            {
                var e = this.Serializer.Deserialize <OneToOneServerException>(streamResponse.Response);
                error = ElasticsearchServerError.Create(e);
            }
            else if (streamResponse.Response != null)
            {
                var ms = new MemoryStream();
                streamResponse.Response.CopyTo(ms);
                ms.Position = 0;
                streamResponse.ResponseRaw = this.Settings.KeepRawResponse ? ms.ToArray() : null;
                try
                {
                    var e = this.Serializer.Deserialize <OneToOneServerException>(ms);
                    error = ElasticsearchServerError.Create(e);
                }
                catch (Exception)
                {
                    var raw = ms.ToArray().Utf8String();
                }
                ms.Position = 0;
                streamResponse.Response.Close();
                streamResponse.Response = ms;
            }
            else
            {
                error = new ElasticsearchServerError
                {
                    Status = streamResponse.HttpStatusCode.GetValueOrDefault(-1)
                }
            };
            if (this.Settings.ThrowOnElasticsearchServerExceptions)
            {
                throw new ElasticsearchServerException(error);
            }
            return(error);
        }