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; } } }
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; } }
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; } }
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; }
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; } } } }
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); } } }
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); }
private static ElasticsearchResponse <DynamicDictionary> ToDynamicResponse(ElasticsearchResponse <Dictionary <string, object> > response) { return(CloneFrom(response, response.Response != null ? DynamicDictionary.Create(response.Response) : null)); }
internal static ElasticsearchResponse <DynamicDictionary> Wrap(ElasticsearchResponse <Dictionary <string, object> > response) { return(ToDynamicResponse(response)); }
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); } }
private void SetVoidResult(ElasticsearchResponse <VoidResponse> result, Stream response) { response.Dispose(); result.Body = _void; }
private void SetStreamResult(ElasticsearchResponse <Stream> result, Stream response) => result.Body = response;
private void SetByteResult(ElasticsearchResponse <byte[]> result, byte[] bytes) => result.Body = bytes;
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);
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[]);