public async Task InvokeAsync(IQueryContext context)
        {
            if (IsContextIncomplete(context))
            {
                context.Result = QueryResultBuilder.CreateError(
                    ErrorBuilder.New()
                    .SetMessage(CoreResources.Write_PQ_Middleware_Incomplete)
                    .SetCode(ErrorCodes.Execution.Incomplete).Build());
                return;
            }

            if (_writeStoredQueries != null &&
                context.Request.Query != null &&
                context.QueryKey != null &&
                context.Result is IReadOnlyQueryResult result &&
                context.Request.Extensions != null &&
                context.Request.Extensions.TryGetValue(_persistedQuery, out var s) &&
                s is IReadOnlyDictionary <string, object> settings)
            {
                IQueryResultBuilder builder = QueryResultBuilder.FromResult(result);

                // hash is found and matches the query key -> store the query
                if (DoHashesMatch(settings, context.QueryKey, _hashName, out string userHash))
                {
                    // save the  query
                    await _writeStoredQueries.WriteQueryAsync(
                        context.QueryKey,
                        context.Request.Query)
                    .ConfigureAwait(false);

                    // add persistence receipt to the result
                    builder.SetExtension(
                        _persistedQuery,
                        new Dictionary <string, object>
                    {
                        { _hashName, userHash },
                        { _persisted, true }
                    });

                    context.ContextData[ContextDataKeys.DocumentSaved] = true;
                }
                else
                {
                    builder.SetExtension(
                        _persistedQuery,
                        new Dictionary <string, object>
                    {
                        { _hashName, userHash },
                        { _expectedValue, context.QueryKey },
                        { _expectedType, _hashName },
                        { _expectedFormat, _hashFormat.ToString() },
                        { _persisted, false }
                    });
                }

                context.Result = builder.Create();
            }

            await _next(context).ConfigureAwait(false);
        }
Пример #2
0
        public async Task UseDelegateMiddleware()
        {
            // arrange
            var schema = Schema.Create(@"
                type Query { a: String }
                ", c =>
            {
                c.BindResolver(() => "hello world")
                .To("Query", "a");
            });

            IQueryExecutor executor = QueryExecutionBuilder
                                      .New()
                                      .Use(next => context =>
            {
                var queryResult =
                    QueryResultBuilder.New()
                    .SetData(new Dictionary <string, object> {
                    { "done", true }
                })
                    .Create();
                context.Result = queryResult;

                return(next(context));
            })
                                      .Build(schema);

            // act
            IExecutionResult result = await executor.ExecuteAsync("{ a }");

            // assert
            result.MatchSnapshot();
        }
        public async Task InvokeAsync(IQueryContext context)
        {
            if (IsContextIncomplete(context))
            {
                context.Result = QueryResultBuilder.CreateError(
                    ErrorBuilder.New()
                    .SetMessage(CoreResources.ExecuteOperationMiddleware_InComplete)
                    .SetCode(ErrorCodes.Execution.Incomplete)
                    .Build());
            }
            else
            {
                Activity activity = _diagnosticEvents.BeginOperation(context);

                try
                {
                    IExecutionStrategy strategy = _strategyResolver
                                                  .Resolve(context.Operation.Type);
                    IExecutionContext executionContext =
                        CreateExecutionContext(context);

                    context.Result = await strategy.ExecuteAsync(
                        executionContext, executionContext.RequestAborted)
                                     .ConfigureAwait(false);
                }
                finally
                {
                    _diagnosticEvents.EndOperation(activity, context);
                }
            }

            await _next(context).ConfigureAwait(false);
        }
Пример #4
0
        private async Task <IExecutionResult> ExecuteMiddlewareAsync(
            IQueryContext context)
        {
            try
            {
                await _queryDelegate(context).ConfigureAwait(false);

                if (context.Result == null)
                {
                    return(QueryResultBuilder.CreateError(new Error
                    {
                        Message = CoreResources.QueryExecutor_NoResult
                    }));
                }

                return(context.Result);
            }
            finally
            {
                if (!context.ServiceScope.IsLifetimeHandled)
                {
                    context.ServiceScope.Dispose();
                }
            }
        }
Пример #5
0
        public void Create_Result_Without_Data_And_Errors()
        {
            // arrange
            // act
            Action result = () => QueryResultBuilder.New().Create();

            // assert
            Assert.Throws <ArgumentException>(result);
        }
        public async Task InvokeAsync(IQueryContext context)
        {
            try
            {
                await _next(context).ConfigureAwait(false);
            }
            catch (GraphQLException ex)
            {
                context.Exception = ex;
                context.Result    = QueryResultBuilder.CreateError(
                    _errorHandler.Handle(ex.Errors));
            }
            catch (SyntaxException ex)
            {
                IError error = _errorHandler.CreateUnexpectedError(ex)
                               .SetMessage(ex.Message)
                               .AddLocation(ex.Line, ex.Column)
                               .Build();

                error = _errorHandler.Handle(error);

                context.Exception = ex;
                context.Result    = QueryResultBuilder.CreateError(error);
            }
            catch (ScalarSerializationException ex)
            {
                IError error = _errorHandler.CreateUnexpectedError(ex)
                               .SetMessage(ex.Message)
                               .Build();

                error = _errorHandler.Handle(error);

                context.Exception = ex;
                context.Result    = QueryResultBuilder.CreateError(error);
            }
            catch (InputObjectSerializationException ex)
            {
                IError error = _errorHandler.CreateUnexpectedError(ex)
                               .SetMessage(ex.Message)
                               .Build();

                error = _errorHandler.Handle(error);

                context.Exception = ex;
                context.Result    = QueryResultBuilder.CreateError(error);
            }
            catch (Exception ex)
            {
                IError error = _errorHandler.CreateUnexpectedError(ex)
                               .Build();

                error = _errorHandler.Handle(error);

                context.Exception = ex;
                context.Result    = QueryResultBuilder.CreateError(error);
            }
        }
Пример #7
0
 public static IQueryResult OperationKindNotAllowed() =>
 QueryResultBuilder.CreateError(
     ErrorBuilder.New()
     .SetMessage("The specified operation kind is not allowed.")
     .Build(),
     new Dictionary <string, object?>
 {
     { WellKnownContextData.OperationNotAllowed, null }
 });
        public async Task InvokeAsync(IQueryContext context)
        {
            if (IsContextIncomplete(context))
            {
                context.Result = QueryResultBuilder.CreateError(
                    ErrorBuilder.New()
                    .SetMessage(CoreResources.ParseQueryMiddleware_InComplete)
                    .SetCode(ErrorCodes.Execution.Incomplete)
                    .Build());
            }
            else
            {
                Activity activity = _diagnosticEvents.BeginParsing(context);

                try
                {
                    bool         documentRetrievedFromCache = true;
                    ICachedQuery cachedQuery = null;
                    string       queryKey    = ResolveQueryKey(context.Request);

                    if (context.Request.Query is null)
                    {
                        _queryCache.TryGet(queryKey, out cachedQuery);
                    }
                    else
                    {
                        cachedQuery = _queryCache.GetOrCreate(
                            queryKey,
                            () =>
                        {
                            documentRetrievedFromCache = false;
                            DocumentNode document      =
                                ParseDocument(context.Request.Query);
                            return(new CachedQuery(queryKey, document));
                        });
                    }

                    // update context
                    context.QueryKey = queryKey;

                    if (cachedQuery != null)
                    {
                        context.CachedQuery = cachedQuery;
                        context.Document    = cachedQuery.Document;
                        context.ContextData[ContextDataKeys.DocumentCached] =
                            documentRetrievedFromCache;
                    }
                }
                finally
                {
                    _diagnosticEvents.EndParsing(activity, context);
                }

                await _next(context).ConfigureAwait(false);
            }
        }
Пример #9
0
            public Task InvokeAsync(IQueryContext context)
            {
                context.Result = QueryResultBuilder.New()
                                 .SetData(new Dictionary <string, object> {
                    { "done", true }
                })
                                 .Create();

                return(_next(context));
            }
Пример #10
0
 public static IQueryResult MaxComplexityReached(
     int complexity,
     int allowedComplexity) =>
 QueryResultBuilder.CreateError(
     new Error(
         ErrorHelper_MaxComplexityReached,
         ErrorCodes.Execution.ComplexityExceeded,
         extensions: new Dictionary <string, object?>
 {
     { nameof(complexity), complexity },
     { nameof(allowedComplexity), allowedComplexity }
 }));
Пример #11
0
        public void Create_Result_Set_Data()
        {
            // arrange
            var builder = new QueryResultBuilder();

            // act
            builder.SetData(new Dictionary <string, object> {
                { "a", "b" }
            });

            // assert
            builder.Create().MatchSnapshot();
        }
        public Task InvokeAsync(IQueryContext context)
        {
            if (_options.UseComplexityMultipliers == true &&
                _options.MaxOperationComplexity.HasValue)
            {
                if (IsContextIncomplete(context))
                {
                    context.Result = QueryResultBuilder.CreateError(
                        ErrorBuilder.New()
                        .SetMessage(CoreResources.MaxComplexityMiddleware_Prerequisite)
                        .SetCode(ErrorCodes.Execution.Incomplete)
                        .Build());
                    return(Task.CompletedTask);
                }
                else
                {
                    var visitorContext = MaxComplexityVisitorContext.New(
                        context.Schema,
                        context.Operation.Variables,
                        _calculation);

                    int complexity = _visitor.Visit(
                        context.Document,
                        context.Operation.Definition,
                        visitorContext);

                    if (IsAllowedComplexity(complexity))
                    {
                        return(_next(context));
                    }
                    else
                    {
                        IError error = ErrorBuilder.New()
                                       .SetMessage(string.Format(
                                                       CultureInfo.InvariantCulture,
                                                       CoreResources.MaxComplexityMiddleware_NotAllowed,
                                                       complexity,
                                                       _options.MaxOperationComplexity))
                                       .AddLocation(context.Operation.Definition)
                                       .Build();

                        context.Result = QueryResultBuilder.CreateError(error);
                        return(Task.CompletedTask);
                    }
                }
            }

            return(_next(context));
        }
 public Task InvokeAsync(IQueryContext context)
 {
     if (context.Document is null)
     {
         context.Result = QueryResultBuilder.CreateError(
             _errorHandler.Handle(ErrorBuilder.New()
                                  .SetMessage("CachedQueryNotFound")
                                  .SetCode(ErrorCodes.Execution.CachedQueryNotFound)
                                  .Build()));
         return(Task.CompletedTask);
     }
     else
     {
         return(_next.Invoke(context));
     }
 }
Пример #14
0
        public async Task InvokeAsync(IQueryContext context)
        {
            if (IsContextIncomplete(context))
            {
                context.Result = QueryResultBuilder.CreateError(
                    ErrorBuilder.New()
                    .SetMessage(CoreResources.Read_PQ_Middleware_Incomplete)
                    .SetCode(ErrorCodes.Execution.Incomplete)
                    .Build());
                return;
            }

            if (context.Document is null)
            {
                ICachedQuery cachedQuery = null;
                IQuery       query       =
                    await _readStoredQueries.TryReadQueryAsync(context.QueryKey)
                    .ConfigureAwait(false);

                if (query == null)
                {
                    context.Result = QueryResultBuilder.CreateError(
                        _errorHandler.Handle(ErrorBuilder.New()
                                             .SetMessage(CoreResources.Read_PQ_Middleware_QueryNotFound)
                                             .SetCode(ErrorCodes.Execution.QueryNotFound)
                                             .Build()));
                    return;
                }

                cachedQuery = _queryCache.GetOrCreate(
                    context.QueryKey,
                    () =>
                {
                    DocumentNode document =
                        ParseDocument(query);
                    return(new CachedQuery(context.QueryKey, document));
                });

                // update context
                context.CachedQuery = cachedQuery;
                context.Document    = context.CachedQuery.Document;
                context.ContextData[ContextDataKeys.DocumentCached] = true;
            }

            await _next(context).ConfigureAwait(false);
        }
        public async Task InvokeAsync(IQueryContext context)
        {
            CancellationTokenSource requestTimeoutCts = null;
            CancellationTokenSource combinedCts       = null;
            CancellationToken       requestAborted    = context.RequestAborted;

            if (!Debugger.IsAttached)
            {
                requestTimeoutCts = new CancellationTokenSource(
                    _options.ExecutionTimeout);
                combinedCts = CancellationTokenSource.CreateLinkedTokenSource(
                    requestTimeoutCts.Token,
                    context.RequestAborted);
                context.RequestAborted = combinedCts.Token;
            }

            try
            {
                await _next(context).ConfigureAwait(false);
            }
            catch (TaskCanceledException ex)
            {
                if (requestAborted.IsCancellationRequested)
                {
                    throw;
                }

                context.Exception = ex;
                context.Result    = QueryResultBuilder.CreateError(
                    ErrorBuilder.New()
                    .SetMessage(CoreResources.RequestTimeoutMiddleware_Timeout)
                    .SetCode(ErrorCodes.Execution.Timeout)
                    .Build());
            }
            finally
            {
                combinedCts?.Dispose();
                requestTimeoutCts?.Dispose();
            }
        }
Пример #16
0
        public ExecutionContext(
            ISchema schema,
            IOperation operation,
            IRawRequestContext requestContext,
            CancellationToken requestAborted)
        {
            Schema = schema ??
                     throw new ArgumentNullException(nameof(schema));
            Operation = operation ??
                        throw new ArgumentNullException(nameof(operation));
            _requestContext = requestContext
                              ?? throw new ArgumentNullException(nameof(requestContext));

            RequestAborted = requestAborted;

            _cachedQuery = _requestContext.CachedQuery;

            IServiceProvider services = requestContext.ServiceScope.ServiceProvider;

            ErrorHandler = services.GetRequiredService <IErrorHandler>();

            Result = new QueryResultBuilder();

            var fragments = new FragmentCollection(
                schema, operation.Document);

            Converter = services.GetTypeConversion();

            _fieldCollector = new FieldCollector(
                fragments,
                requestContext.ResolveMiddleware,
                Converter,
                services.GetService <IEnumerable <IArgumentCoercionHandler> >());

            Activator = new Activator(services);
        }
        public async Task InvokeAsync(IQueryContext context)
        {
            if (context.Document == null)
            {
                context.Result = QueryResultBuilder.CreateError(
                    ErrorBuilder.New()
                    .SetMessage(CoreResources.ValidateQueryMiddleware_NoDocument)
                    .SetCode(ErrorCodes.Execution.Incomplete)
                    .Build());
            }
            else
            {
                Activity activity = _diagnostics.BeginValidation(context);
                try
                {
                    context.ValidationResult = _validatorCache.GetOrCreate(
                        context.QueryKey,
                        () => Validate(context.Schema, context.Document));
                }
                finally
                {
                    _diagnostics.EndValidation(activity, context);
                }

                if (context.ValidationResult.HasErrors)
                {
                    context.Result = QueryResultBuilder.CreateError(
                        context.ValidationResult.Errors);
                    _diagnostics.ValidationError(context);
                }
                else
                {
                    await _next(context).ConfigureAwait(false);
                }
            }
        }
Пример #18
0
 public static IQueryResult StateInvalidForComplexityAnalyzer() =>
 QueryResultBuilder.CreateError(
     ErrorBuilder.New()
     .SetMessage(ErrorHelper_StateInvalidForComplexityAnalyzer_Message)
     .SetCode(ErrorCodes.Execution.ComplexityStateInvalid)
     .Build());
Пример #19
0
 public static IQueryResult RootTypeNotFound(OperationType operationType) =>
 QueryResultBuilder.CreateError(
     ErrorBuilder.New()
     .SetMessage(ErrorHelper_RootTypeNotFound_Message, operationType)
     .Build());
Пример #20
0
 public static IQueryResult OperationCanceled() =>
 QueryResultBuilder.CreateError(
     new Error(
         ErrorHelper_OperationCanceled_Message,
         ErrorCodes.Execution.Canceled));
Пример #21
0
 public static IQueryResult RequestTimeout(TimeSpan timeout) =>
 QueryResultBuilder.CreateError(
     new Error(
         string.Format(ErrorHelper_RequestTimeout, timeout),
         ErrorCodes.Execution.Timeout));
Пример #22
0
 public static IQueryResult StateInvalidForOperationExecution() =>
 QueryResultBuilder.CreateError(
     ErrorBuilder.New()
     .SetMessage(ErrorHelper_StateInvalidForOperationExecution_Message)
     .Build());
Пример #23
0
 public static IQueryResult StateInvalidForDocumentValidation() =>
 QueryResultBuilder.CreateError(
     ErrorBuilder.New()
     .SetMessage(ErrorHelper_StateInvalidForDocumentValidation_Message)
     .SetCode(ErrorCodes.Execution.QueryNotFound)
     .Build());