protected static async Task <IBatchQueryResult> ExecuteOperationBatchAsync( HttpContext context, IRequestExecutor requestExecutor, IHttpRequestInterceptor requestInterceptor, IServerDiagnosticEvents diagnosticEvents, GraphQLRequest request, IReadOnlyList <string> operationNames) { diagnosticEvents.StartOperationBatchRequest(context, request, operationNames); var requestBatch = new IReadOnlyQueryRequest[operationNames.Count]; for (var i = 0; i < operationNames.Count; i++) { QueryRequestBuilder requestBuilder = QueryRequestBuilder.From(request); requestBuilder.SetOperation(operationNames[i]); await requestInterceptor.OnCreateAsync( context, requestExecutor, requestBuilder, context.RequestAborted); requestBatch[i] = requestBuilder.Create(); } return(await requestExecutor.ExecuteBatchAsync( requestBatch, cancellationToken : context.RequestAborted)); }
private async Task HandleRequestAsync(HttpContext context) { // first we need to get the request executor to be able to execute requests. IRequestExecutor requestExecutor = await GetExecutorAsync(context.RequestAborted); IHttpRequestInterceptor requestInterceptor = requestExecutor.GetRequestInterceptor(); IErrorHandler errorHandler = requestExecutor.GetErrorHandler(); HttpStatusCode? statusCode = null; IExecutionResult?result; try { // next we parse the GraphQL request. GraphQLRequest request = _requestParser.ReadParamsRequest(context.Request.Query); GraphQLServerOptions?options = context.GetGraphQLServerOptions(); result = await ExecuteSingleAsync( context, requestExecutor, requestInterceptor, request, options is null or { AllowedGetOperations : AllowedGetOperations.Query } ?_onlyQueries : null); }
/// <summary> /// Sets a custom <see cref="IHttpRequestInterceptor"/> /// </summary> /// <param name="httpRequestInterceptor">Interceptor for intercepting requests to Dynatrace/AppMon backends.</param> /// <returns><code>this</code></returns> public AbstractOpenKitBuilder WithHttpRequestInterceptor(IHttpRequestInterceptor httpRequestInterceptor) { if (httpRequestInterceptor != null) { HttpRequestInterceptor = httpRequestInterceptor; } return(this); }
private async Task HandleRequestAsync(HttpContext context) { // first we need to get the request executor to be able to execute requests. IRequestExecutor requestExecutor = await GetExecutorAsync(context.RequestAborted); IHttpRequestInterceptor requestInterceptor = requestExecutor.GetRequestInterceptor(); IErrorHandler errorHandler = requestExecutor.GetErrorHandler(); context.Items[WellKnownContextData.RequestExecutor] = requestExecutor; HttpStatusCode? statusCode = null; IExecutionResult?result; // next we parse the GraphQL request. GraphQLRequest request; using (_diagnosticEvents.ParseHttpRequest(context)) { try { request = _requestParser.ReadParamsRequest(context.Request.Query); } catch (GraphQLRequestException ex) { // A GraphQL request exception is thrown if the HTTP request body couldn't be // parsed. In this case we will return HTTP status code 400 and return a // GraphQL error result. statusCode = HttpStatusCode.BadRequest; IReadOnlyList <IError> errors = errorHandler.Handle(ex.Errors); result = QueryResultBuilder.CreateError(errors); _diagnosticEvents.ParserErrors(context, errors); goto HANDLE_RESULT; } catch (Exception ex) { statusCode = HttpStatusCode.InternalServerError; IError error = errorHandler.CreateUnexpectedError(ex).Build(); result = QueryResultBuilder.CreateError(error); _diagnosticEvents.HttpRequestError(context, error); goto HANDLE_RESULT; } } // after successfully parsing the request we now will attempt to execute the request. try { GraphQLServerOptions?options = context.GetGraphQLServerOptions(); result = await ExecuteSingleAsync( context, requestExecutor, requestInterceptor, _diagnosticEvents, request, options is null or { AllowedGetOperations : AllowedGetOperations.Query } ?_onlyQueries : null); }
public virtual Org.Apache.Http.Protocol.HttpProcessorBuilder AddLast(IHttpRequestInterceptor e) { if (e == null) { return(this); } GetRequestChainBuilder().AddLast(e); return(this); }
protected async Task <IExecutionResult> ExecuteSingleAsync( HttpContext context, IRequestExecutor requestExecutor, IHttpRequestInterceptor requestInterceptor, GraphQLRequest request) { QueryRequestBuilder requestBuilder = QueryRequestBuilder.From(request); await requestInterceptor.OnCreateAsync( context, requestExecutor, requestBuilder, context.RequestAborted); return(await requestExecutor.ExecuteAsync( requestBuilder.Create(), context.RequestAborted)); }
/// <summary>Adds this protocol interceptor to the tail of the protocol processing list. /// </summary> /// <remarks> /// Adds this protocol interceptor to the tail of the protocol processing list. /// <p/> /// Please note this value can be overridden by the /// <see cref="SetHttpProcessor(Apache.Http.Protocol.HttpProcessor)">SetHttpProcessor(Apache.Http.Protocol.HttpProcessor) /// </see> /// method. /// </remarks> public Apache.Http.Impl.Client.HttpClientBuilder AddInterceptorLast(IHttpRequestInterceptor itcp) { if (itcp == null) { return(this); } if (requestLast == null) { requestLast = new List <IHttpRequestInterceptor>(); } requestLast.AddLast(itcp); return(this); }
protected static async Task <IExecutionResult> ExecuteSingleAsync( HttpContext context, IRequestExecutor requestExecutor, IHttpRequestInterceptor requestInterceptor, IServerDiagnosticEvents diagnosticEvents, GraphQLRequest request, OperationType[]?allowedOperations = null) { diagnosticEvents.StartSingleRequest(context, request); var requestBuilder = QueryRequestBuilder.From(request); requestBuilder.SetAllowedOperations(allowedOperations); await requestInterceptor.OnCreateAsync( context, requestExecutor, requestBuilder, context.RequestAborted); return(await requestExecutor.ExecuteAsync( requestBuilder.Create(), context.RequestAborted)); }
protected async Task <IBatchQueryResult> ExecuteBatchAsync( HttpContext context, IRequestExecutor requestExecutor, IHttpRequestInterceptor requestInterceptor, IReadOnlyList <GraphQLRequest> requests) { var requestBatch = new IReadOnlyQueryRequest[requests.Count]; for (var i = 0; i < requests.Count; i++) { QueryRequestBuilder requestBuilder = QueryRequestBuilder.From(requests[0]); await requestInterceptor.OnCreateAsync( context, requestExecutor, requestBuilder, context.RequestAborted); requestBatch[i] = requestBuilder.Create(); } return(await requestExecutor.ExecuteBatchAsync( requestBatch, cancellationToken : context.RequestAborted)); }
private async Task HandleRequestAsync(HttpContext context) { // first we need to get the request executor to be able to execute requests. IRequestExecutor requestExecutor = await GetExecutorAsync(context.RequestAborted); IHttpRequestInterceptor requestInterceptor = requestExecutor.GetRequestInterceptor(); IErrorHandler errorHandler = requestExecutor.GetErrorHandler(); HttpStatusCode? statusCode = null; IExecutionResult?result; try { // next we parse the GraphQL request. GraphQLRequest request = _requestParser.ReadParamsRequest(context.Request.Query); result = await ExecuteSingleAsync( context, requestExecutor, requestInterceptor, request); } catch (GraphQLRequestException ex) { // A GraphQL request exception is thrown if the HTTP request body couldn't be // parsed. In this case we will return HTTP status code 400 and return a // GraphQL error result. statusCode = HttpStatusCode.BadRequest; result = QueryResultBuilder.CreateError(errorHandler.Handle(ex.Errors)); } catch (Exception ex) { statusCode = HttpStatusCode.InternalServerError; IError error = errorHandler.CreateUnexpectedError(ex).Build(); result = QueryResultBuilder.CreateError(error); } // in any case we will have a valid GraphQL result at this point that can be written // to the HTTP response stream. Debug.Assert(result is not null, "No GraphQL result was created."); await WriteResultAsync(context.Response, result, statusCode, context.RequestAborted); }
private async Task HandleRequestAsync( HttpContext context, AllowedContentType contentType) { // first we need to get the request executor to be able to execute requests. IRequestExecutor requestExecutor = await GetExecutorAsync(context.RequestAborted); IHttpRequestInterceptor requestInterceptor = requestExecutor.GetRequestInterceptor(); IErrorHandler errorHandler = requestExecutor.GetErrorHandler(); HttpStatusCode? statusCode = null; IExecutionResult?result; try { // next we parse the GraphQL request. IReadOnlyList <GraphQLRequest> requests = await _requestParser.ReadJsonRequestAsync( context.Request.Body, context.RequestAborted); switch (requests.Count) { // if the HTTP request body contains no GraphQL request structure the // whole request is invalid and we will create a GraphQL error response. case 0: { statusCode = HttpStatusCode.BadRequest; IError error = errorHandler.Handle(ErrorHelper.RequestHasNoElements()); result = QueryResultBuilder.CreateError(error); break; } // if the HTTP request body contains a single GraphQL request and we do have // the batch operations query parameter specified we need to execute an // operation batch. // // An operation batch consists of a single GraphQL request document that // contains multiple operations. The batch operation query parameter // defines the order in which the operations shall be executed. case 1 when context.Request.Query.ContainsKey(_batchOperations): { string operationNames = context.Request.Query[_batchOperations]; if (TryParseOperations(operationNames, out IReadOnlyList <string>?ops)) { result = await ExecuteOperationBatchAsync( context, requestExecutor, requestInterceptor, requests[0], ops); } else { IError error = errorHandler.Handle(ErrorHelper.InvalidRequest()); statusCode = HttpStatusCode.BadRequest; result = QueryResultBuilder.CreateError(error); } break; } // if the HTTP request body contains a single GraphQL request and // no batch query parameter is specified we need to execute a single // GraphQL request. // // Most GraphQL requests will be of this type where we want to execute // a single GraphQL query or mutation. case 1: { result = await ExecuteSingleAsync( context, requestExecutor, requestInterceptor, requests[0]); break; } // if the HTTP request body contains more than one GraphQL request than // we need to execute a request batch where we need to execute multiple // fully specified GraphQL requests at once. default: result = await ExecuteBatchAsync( context, requestExecutor, requestInterceptor, requests); break; } } catch (GraphQLRequestException ex) { // A GraphQL request exception is thrown if the HTTP request body couldn't be // parsed. In this case we will return HTTP status code 400 and return a // GraphQL error result. statusCode = HttpStatusCode.BadRequest; result = QueryResultBuilder.CreateError(errorHandler.Handle(ex.Errors)); } catch (Exception ex) { statusCode = HttpStatusCode.InternalServerError; IError error = errorHandler.CreateUnexpectedError(ex).Build(); result = QueryResultBuilder.CreateError(error); } // in any case we will have a valid GraphQL result at this point that can be written // to the HTTP response stream. Debug.Assert(result is not null, "No GraphQL result was created."); await WriteResultAsync(context.Response, result, statusCode, context.RequestAborted); }
public Builder WithHttpRequestInterceptor(IHttpRequestInterceptor httpRequestInterceptor) { HttpRequestInterceptor = httpRequestInterceptor; return(this); }
public virtual Org.Apache.Http.Protocol.HttpProcessorBuilder Add(IHttpRequestInterceptor e) { return(AddLast(e)); }
protected async Task HandleRequestAsync( HttpContext context, AllowedContentType contentType) { // first we need to get the request executor to be able to execute requests. IRequestExecutor requestExecutor = await GetExecutorAsync(context.RequestAborted); IHttpRequestInterceptor requestInterceptor = requestExecutor.GetRequestInterceptor(); IErrorHandler errorHandler = requestExecutor.GetErrorHandler(); context.Items[WellKnownContextData.RequestExecutor] = requestExecutor; HttpStatusCode? statusCode = null; IExecutionResult?result; // next we parse the GraphQL request. IReadOnlyList <GraphQLRequest> requests; using (DiagnosticEvents.ParseHttpRequest(context)) { try { requests = await GetRequestsFromBody(context.Request, context.RequestAborted); } catch (GraphQLRequestException ex) { // A GraphQL request exception is thrown if the HTTP request body couldn't be // parsed. In this case we will return HTTP status code 400 and return a // GraphQL error result. statusCode = HttpStatusCode.BadRequest; IReadOnlyList <IError> errors = errorHandler.Handle(ex.Errors); result = QueryResultBuilder.CreateError(errors); DiagnosticEvents.ParserErrors(context, errors); goto HANDLE_RESULT; } catch (Exception ex) { statusCode = HttpStatusCode.InternalServerError; IError error = errorHandler.CreateUnexpectedError(ex).Build(); result = QueryResultBuilder.CreateError(error); DiagnosticEvents.HttpRequestError(context, error); goto HANDLE_RESULT; } } // after successfully parsing the request we now will attempt to execute the request. try { switch (requests.Count) { // if the HTTP request body contains no GraphQL request structure the // whole request is invalid and we will create a GraphQL error response. case 0: { statusCode = HttpStatusCode.BadRequest; IError error = errorHandler.Handle(ErrorHelper.RequestHasNoElements()); result = QueryResultBuilder.CreateError(error); DiagnosticEvents.HttpRequestError(context, error); break; } // if the HTTP request body contains a single GraphQL request and we do have // the batch operations query parameter specified we need to execute an // operation batch. // // An operation batch consists of a single GraphQL request document that // contains multiple operations. The batch operation query parameter // defines the order in which the operations shall be executed. case 1 when context.Request.Query.ContainsKey(_batchOperations): { string operationNames = context.Request.Query[_batchOperations]; if (TryParseOperations(operationNames, out IReadOnlyList <string>?ops)) { result = await ExecuteOperationBatchAsync( context, requestExecutor, requestInterceptor, DiagnosticEvents, requests[0], ops); } else { IError error = errorHandler.Handle(ErrorHelper.InvalidRequest()); statusCode = HttpStatusCode.BadRequest; result = QueryResultBuilder.CreateError(error); DiagnosticEvents.HttpRequestError(context, error); } break; } // if the HTTP request body contains a single GraphQL request and // no batch query parameter is specified we need to execute a single // GraphQL request. // // Most GraphQL requests will be of this type where we want to execute // a single GraphQL query or mutation. case 1: { result = await ExecuteSingleAsync( context, requestExecutor, requestInterceptor, DiagnosticEvents, requests[0]); break; } // if the HTTP request body contains more than one GraphQL request than // we need to execute a request batch where we need to execute multiple // fully specified GraphQL requests at once. default: result = await ExecuteBatchAsync( context, requestExecutor, requestInterceptor, DiagnosticEvents, requests); break; } } catch (GraphQLException ex) { // This allows extensions to throw GraphQL exceptions in the GraphQL interceptor. statusCode = null; // we let the serializer determine the status code. result = QueryResultBuilder.CreateError(ex.Errors); foreach (IError error in ex.Errors) { DiagnosticEvents.HttpRequestError(context, error); } } catch (Exception ex) { statusCode = HttpStatusCode.InternalServerError; IError error = errorHandler.CreateUnexpectedError(ex).Build(); result = QueryResultBuilder.CreateError(error); DiagnosticEvents.HttpRequestError(context, error); } HANDLE_RESULT: IDisposable? formatScope = null; try { // if cancellation is requested we will not try to attempt to write the result to the // response stream. if (context.RequestAborted.IsCancellationRequested) { return; } // in any case we will have a valid GraphQL result at this point that can be written // to the HTTP response stream. Debug.Assert(result is not null, "No GraphQL result was created."); if (result is IQueryResult queryResult) { formatScope = DiagnosticEvents.FormatHttpResponse(context, queryResult); } await WriteResultAsync(context.Response, result, statusCode, context.RequestAborted); } finally { // we must dispose the diagnostic scope first. formatScope?.Dispose(); // query results use pooled memory an need to be disposed after we have // used them. if (result is IAsyncDisposable asyncDisposable) { await asyncDisposable.DisposeAsync(); } if (result is IDisposable disposable) { disposable.Dispose(); } } }