private bool SetSpecialTypes(Stream responseStream, ElasticsearchResponse <TReturn> cs, byte[] bytes)
        {
            var setSpecial = true;

            if (_disableDirectStreaming)
            {
                cs.ResponseBodyInBytes = bytes;
            }
            var returnType = typeof(TReturn);

            if (returnType == typeof(string))
            {
                this.SetStringResult(cs as ElasticsearchResponse <string>, bytes);
            }
            else if (returnType == typeof(byte[]))
            {
                this.SetByteResult(cs as ElasticsearchResponse <byte[]>, bytes);
            }
            else if (returnType == typeof(VoidResponse))
            {
                this.SetVoidResult(cs as ElasticsearchResponse <VoidResponse>, responseStream);
            }
            else if (returnType == typeof(Stream))
            {
                this.SetStreamResult(cs as ElasticsearchResponse <Stream>, responseStream);
            }
            else
            {
                setSpecial = false;
            }
            return(setSpecial);
        }
        public ElasticsearchResponse <TReturn> CallElasticsearch <TReturn>(RequestData requestData) where TReturn : class
        {
            using (var audit = this.Audit(HealthyResponse))
            {
                audit.Node = requestData.Node;
                audit.Path = requestData.Path;

                ElasticsearchResponse <TReturn> response = null;
                try
                {
                    response            = this._connection.Request <TReturn>(requestData);
                    response.AuditTrail = this.AuditTrail;
                    ThrowBadAuthPipelineExceptionWhenNeeded(response);
                    if (!response.Success)
                    {
                        audit.Event = requestData.OnFailureAuditEvent;
                    }
                    return(response);
                }
                catch (Exception e)
                {
                    (response as ElasticsearchResponse <Stream>)?.Body?.Dispose();
                    audit.Event     = requestData.OnFailureAuditEvent;
                    audit.Exception = e;
                    throw;
                }
            }
        }
        public async Task <ElasticsearchResponse <TReturn> > CallElasticsearchAsync <TReturn>(RequestData requestData, CancellationToken cancellationToken) where TReturn : class
        {
            using (var audit = this.Audit(HealthyResponse))
            {
                audit.Node = requestData.Node;
                audit.Path = requestData.Path;

                ElasticsearchResponse <TReturn> response = null;
                try
                {
                    response = await this._connection.RequestAsync <TReturn>(requestData, cancellationToken).ConfigureAwait(false);

                    response.AuditTrail = this.AuditTrail;
                    ThrowBadAuthPipelineExceptionWhenNeeded(response);
                    if (!response.Success)
                    {
                        audit.Event = requestData.OnFailureAuditEvent;
                    }
                    return(response);
                }
                catch (Exception e)
                {
                    (response as ElasticsearchResponse <Stream>)?.Body?.Dispose();
                    audit.Event     = requestData.OnFailureAuditEvent;
                    audit.Exception = e;
                    throw;
                }
            }
        }
示例#4
0
        public async Task <ElasticsearchResponse <TReturn> > RequestAsync <TReturn>(HttpMethod method, string path, PostData <object> data = null, IRequestParameters requestParameters = null)
            where TReturn : class
        {
            using (var pipeline = this.PipelineProvider.Create(this.Settings, this.DateTimeProvider, this.MemoryStreamFactory, requestParameters))
            {
                await pipeline.FirstPoolUsageAsync(this._semaphore);

                var requestData = new RequestData(method, path, data, this.Settings, requestParameters, this.MemoryStreamFactory);
                ElasticsearchResponse <TReturn> response = null;

                var seenExceptions = new List <PipelineException>();
                foreach (var node in pipeline.NextNode())
                {
                    requestData.Node = node;
                    try
                    {
                        await pipeline.SniffOnStaleClusterAsync();
                        await PingAsync(pipeline, node, seenExceptions);

                        response = await pipeline.CallElasticsearchAsync <TReturn>(requestData);

                        if (!response.SuccessOrKnownError)
                        {
                            pipeline.MarkDead(node);
                            await pipeline.SniffOnConnectionFailureAsync();
                        }
                    }
                    catch (PipelineException pipelineException) when(!pipelineException.Recoverable)
                    {
                        pipeline.MarkDead(node);
                        seenExceptions.Add(pipelineException);
                        break;
                    }
                    catch (PipelineException pipelineException)
                    {
                        pipeline.MarkDead(node);
                        seenExceptions.Add(pipelineException);
                    }
                    catch (Exception killerException)
                    {
                        throw new UnexpectedElasticsearchClientException(killerException, seenExceptions)
                              {
                                  Request    = requestData,
                                  Response   = response,
                                  AuditTrail = pipeline.AuditTrail
                              };
                    }
                    if (response != null && response.SuccessOrKnownError)
                    {
                        pipeline.MarkAlive(node);
                        break;
                    }
                }
                if (response == null || !response.Success)
                {
                    pipeline.BadResponse(ref response, requestData, seenExceptions);
                }
                return(response);
            }
        }
        private async Task ReadServerErrorAsync(ElasticsearchResponse <TReturn> response, Stream stream, byte[] bytes)
        {
            response.ServerError = await ServerError.TryCreateAsync(stream, this._cancellationToken).ConfigureAwait(false);

            if (_disableDirectStreaming)
            {
                response.ResponseBodyInBytes = bytes;
            }
        }
示例#6
0
        private void Finalize(ElasticsearchResponse <TReturn> response)
        {
            var passAlongConnectionStatus = response.Body as IBodyWithApiCallDetails;

            if (passAlongConnectionStatus != null)
            {
                passAlongConnectionStatus.CallDetails = response;
            }
        }
 private void ReadServerError(ElasticsearchResponse <TReturn> response, Stream stream, byte[] bytes)
 {
     if (ServerError.TryCreate(stream, out var serverError))
     {
         response.ServerError = serverError;
     }
     if (_disableDirectStreaming)
     {
         response.ResponseBodyInBytes = bytes;
     }
 }
示例#8
0
        public void BadResponse <TReturn>(ref ElasticsearchResponse <TReturn> response, RequestData data, List <PipelineException> pipelineExceptions)
            where TReturn : class
        {
            var callDetails     = response ?? pipelineExceptions.LastOrDefault()?.Response;
            var pipelineFailure = PipelineFailure.BadResponse;

            if (pipelineExceptions.HasAny())
            {
                pipelineFailure = pipelineExceptions.Last().FailureReason;
            }

            var innerException = pipelineExceptions.HasAny()
                                ? new AggregateException(pipelineExceptions)
                                : callDetails?.OriginalException;

            var exceptionMessage = innerException?.Message ?? "Could not complete the request to Elasticsearch.";

            if (this.IsTakingTooLong)
            {
                pipelineFailure = PipelineFailure.MaxTimeoutReached;
                this.Audit(MaxTimeoutReached);
                exceptionMessage = "Maximum timout reached while retrying request";
            }
            else if (this.Retried >= this.MaxRetries && this.MaxRetries > 0)
            {
                pipelineFailure = PipelineFailure.MaxRetriesReached;
                this.Audit(MaxRetriesReached);
                exceptionMessage = "Maximum number of retries reached.";
            }

            var clientException = new ElasticsearchClientException(pipelineFailure, exceptionMessage, innerException)
            {
                Request    = data,
                Response   = callDetails,
                AuditTrail = this.AuditTrail
            };

            if (_settings.ThrowExceptions)
            {
                this._settings.OnRequestCompleted?.Invoke(clientException.Response);
                throw clientException;
            }

            if (response == null)
            {
                response = new ResponseBuilder <TReturn>(data)
                {
                    Exception = clientException
                }.ToResponse();
            }

            response.AuditTrail = this.AuditTrail;
        }
示例#9
0
        private void SetBody(ElasticsearchResponse <TReturn> response, Stream stream)
        {
            byte[] bytes = null;
            if (NeedsToEagerReadStream())
            {
                var inMemoryStream = this._requestData.MemoryStreamFactory.Create();
                stream.CopyTo(inMemoryStream, BufferSize);
                bytes = this.SwapStreams(ref stream, ref inMemoryStream);
            }

            var needsDispose = typeof(TReturn) != typeof(Stream);

            using (needsDispose ? stream : EmptyDisposable)
            {
                if (response.Success)
                {
                    if (!SetSpecialTypes(stream, response, bytes))
                    {
                        if (this._requestData.CustomConverter != null)
                        {
                            response.Body = this._requestData.CustomConverter(response, stream) as TReturn;
                        }
                        else
                        {
                            response.Body = this._requestData.ConnectionSettings.Serializer.Deserialize <TReturn>(stream);
                        }
                    }
                }
                else if (response.HttpStatusCode != null)
                {
                    ServerError serverError;
                    if (ServerError.TryCreate(stream, out serverError))
                    {
                        response.ServerError = serverError;
                    }
                    if (_disableDirectStreaming)
                    {
                        response.ResponseBodyInBytes = bytes;
                    }
                }
            }
        }
示例#10
0
        private async Task SetBodyAsync(ElasticsearchResponse <TReturn> response, Stream stream)
        {
            byte[] bytes = null;
            if (NeedsToEagerReadStream())
            {
                var inMemoryStream = this._requestData.MemoryStreamFactory.Create();
                await stream.CopyToAsync(inMemoryStream, BufferSize, this._cancellationToken).ConfigureAwait(false);

                bytes = this.SwapStreams(ref stream, ref inMemoryStream);
            }

            var needsDispose = typeof(TReturn) != typeof(Stream);

            using (needsDispose ? stream : EmptyDisposable)
            {
                if (response.Success)
                {
                    if (!SetSpecialTypes(stream, response, bytes))
                    {
                        if (this._requestData.CustomConverter != null)
                        {
                            response.Body = this._requestData.CustomConverter(response, stream) as TReturn;
                        }
                        else
                        {
                            response.Body = await this._requestData.ConnectionSettings.Serializer.DeserializeAsync <TReturn>(stream, this._cancellationToken).ConfigureAwait(false);
                        }
                    }
                }
                else if (response.HttpStatusCode != null)
                {
                    response.ServerError = await ServerError.TryCreateAsync(stream, this._cancellationToken).ConfigureAwait(false);

                    if (_disableDirectStreaming)
                    {
                        response.ResponseBodyInBytes = bytes;
                    }
                }
            }
        }
        private void SetBody(ElasticsearchResponse <TReturn> response, Stream stream)
        {
            byte[] bytes = null;
            if (NeedsToEagerReadStream(response))
            {
                var inMemoryStream = this._requestData.MemoryStreamFactory.Create();
                stream.CopyTo(inMemoryStream, BufferSize);
                bytes = this.SwapStreams(ref stream, ref inMemoryStream);
            }

            var needsDispose = typeof(TReturn) != typeof(Stream);

            using (needsDispose ? stream : EmptyDisposable)
            {
                if (response.Success || response.AllowAllStatusCodes)
                {
                    if (!SetSpecialTypes(stream, response, bytes))
                    {
                        if (this._requestData.CustomConverter != null)
                        {
                            response.Body = this._requestData.CustomConverter(response, stream) as TReturn;
                        }
                        else
                        {
                            response.Body = this._requestData.ConnectionSettings.RequestResponseSerializer.Deserialize <TReturn>(stream);
                        }
                    }
                    if (NeedsDoubleReadForError(response))
                    {
                        ReadServerError(response, new MemoryStream(bytes), bytes);
                    }
                }
                else if (response.HttpStatusCode != null)
                {
                    ReadServerError(response, stream, bytes);
                }
            }
        }
示例#12
0
        public static ElasticsearchResponse <TTo> CloneFrom <TTo>(IElasticsearchResponse from, TTo to)
        {
            var response = new ElasticsearchResponse <TTo>(from.Settings)
            {
                OriginalException = from.OriginalException,
                HttpStatusCode    = from.HttpStatusCode,
                Request           = from.Request,
                RequestMethod     = from.RequestMethod,
                RequestUrl        = from.RequestUrl,
                Response          = to,
                ResponseRaw       = from.ResponseRaw,
                Serializer        = from.Settings.Serializer,
                Settings          = from.Settings,
                Success           = from.Success
            };
            var tt = to as IResponseWithRequestInformation;

            if (tt != null)
            {
                tt.RequestInformation = response;
            }
            return(response);
        }
示例#13
0
 private static ElasticsearchResponse <DynamicDictionary> ToDynamicResponse(ElasticsearchResponse <Dictionary <string, object> > response)
 {
     return(CloneFrom(response, response.Response != null ? DynamicDictionary.Create(response.Response) : null));
 }
示例#14
0
 internal static ElasticsearchResponse <DynamicDictionary> Wrap(ElasticsearchResponse <Dictionary <string, object> > response)
 {
     return(ToDynamicResponse(response));
 }
示例#15
0
        public ElasticsearchResponse <TReturn> Request <TReturn>(HttpMethod method, string path, PostData <object> data = null, IRequestParameters requestParameters = null)
            where TReturn : class
        {
            using (var pipeline = this.PipelineProvider.Create(this.Settings, this.DateTimeProvider, this.MemoryStreamFactory, requestParameters))
            {
                pipeline.FirstPoolUsage(this.Settings.BootstrapLock);

                var requestData = new RequestData(method, path, data, this.Settings, requestParameters, this.MemoryStreamFactory);
                this.Settings.OnRequestDataCreated?.Invoke(requestData);
                ElasticsearchResponse <TReturn> response = null;

                var seenExceptions = new List <PipelineException>();
                foreach (var node in pipeline.NextNode())
                {
                    requestData.Node = node;
                    try
                    {
                        pipeline.SniffOnStaleCluster();
                        Ping(pipeline, node);
                        response = pipeline.CallElasticsearch <TReturn>(requestData);
                        if (!response.SuccessOrKnownError)
                        {
                            pipeline.MarkDead(node);
                            pipeline.SniffOnConnectionFailure();
                        }
                    }
                    catch (PipelineException pipelineException) when(!pipelineException.Recoverable)
                    {
                        pipeline.MarkDead(node);
                        seenExceptions.Add(pipelineException);
                        break;
                    }
                    catch (PipelineException pipelineException)
                    {
                        pipeline.MarkDead(node);
                        seenExceptions.Add(pipelineException);
                    }
                    catch (Exception killerException)
                    {
                        throw new UnexpectedElasticsearchClientException(killerException, seenExceptions)
                              {
                                  Request    = requestData,
                                  Response   = response,
                                  AuditTrail = pipeline?.AuditTrail
                              };
                    }
                    if (response == null || !response.SuccessOrKnownError)
                    {
                        continue;
                    }
                    pipeline.MarkAlive(node);
                    break;
                }
                if (requestData.Node == null)                 //foreach never ran
                {
                    pipeline.ThrowNoNodesAttempted(requestData, seenExceptions);
                }

                if (response == null || !response.Success)
                {
                    pipeline.BadResponse(ref response, requestData, seenExceptions);
                }

                this.Settings.OnRequestCompleted?.Invoke(response);

                return(response);
            }
        }
示例#16
0
 private void SetVoidResult(ElasticsearchResponse <VoidResponse> result, Stream response)
 {
     response.Dispose();
     result.Body = _void;
 }
示例#17
0
 private void SetStreamResult(ElasticsearchResponse <Stream> result, Stream response) => result.Body = response;
示例#18
0
 private void SetByteResult(ElasticsearchResponse <byte[]> result, byte[] bytes) => result.Body = bytes;
示例#19
0
 private void SetStringResult(ElasticsearchResponse <string> result, byte[] bytes) => result.Body = bytes.Utf8String();
 private bool NeedsDoubleReadForError(ElasticsearchResponse <TReturn> response) =>
 response.AllowAllStatusCodes ||              //need to double read for error and TReturn
 (_requestData.AllowedStatusCodes.Contains(404) && response.HttpStatusCode == 404);
示例#21
0
 private bool NeedsToEagerReadStream(ElasticsearchResponse <TReturn> response) =>
 response.AllowAllStatusCodes ||              //need to double read for error and TReturn
 _disableDirectStreaming || typeof(TReturn) == typeof(string) || typeof(TReturn) == typeof(byte[]);
 private bool NeedsToEagerReadStream(ElasticsearchResponse <TReturn> response) =>
 NeedsDoubleReadForError(response) ||
 _disableDirectStreaming || typeof(TReturn) == typeof(string) || typeof(TReturn) == typeof(byte[]);