예제 #1
0
        BuildQueryContextAsync(ExecutionOptions options,
                               Extensions extensions,
                               ILogger logger)
        {
            await extensions.BeginParseDocumentAsync();

            var document = options.Document;
            await extensions.EndParseDocumentAsync(document);

            var operation = Operations.GetOperation(document, options.OperationName);

            logger.Operation(operation);

            var coercedVariableValues = Variables.CoerceVariableValues(
                options.Schema,
                operation,
                options.VariableValues);

            var queryContext = new QueryContext(
                options.FormatError,
                document,
                operation,
                options.Schema,
                coercedVariableValues,
                options.InitialValue,
                extensions);

            logger.Validate(options.Validate);
            var validationResult = new ValidationResult();

            if (options.Validate)
            {
                await extensions.BeginValidationAsync();

                validationResult = Validator.Validate(
                    ExecutionRules.All,
                    options.Schema,
                    document,
                    coercedVariableValues);

                logger.ValidationResult(validationResult);

                await extensions.EndValidationAsync(validationResult);
            }

            return(queryContext, validationResult);
        }
예제 #2
0
        public async Task BeginExecuteAsync(ExecutionOptions options)
        {
            var scopes = await Task.WhenAll(_extensions.Select(e => e.BeginExecuteAsync(options)));

            _scopes.AddRange(scopes);
        }
예제 #3
0
        /// <summary>
        ///     Execute subscription
        /// </summary>
        /// <param name="options"></param>
        /// <param name="unsubscribe">Unsubscribe</param>
        /// <returns></returns>
        public static async Task <SubscriptionResult> SubscribeAsync(
            ExecutionOptions options,
            CancellationToken unsubscribe)
        {
            if (!unsubscribe.CanBeCanceled)
            {
                throw new InvalidOperationException("Unsubscribe token must be cancelable");
            }

            var extensions = new ExtensionsRunner(Enumerable.Empty <IExecutorExtension>());
            await extensions.BeginExecuteAsync(options);

            var logger = options.LoggerFactory.CreateLogger(typeof(Executor).FullName);

            using (logger.Begin(options.OperationName))
            {
                var(queryContext, validationResult) = await BuildQueryContextAsync(
                    options,
                    extensions,
                    logger);

                if (!validationResult.IsValid)
                {
                    return new SubscriptionResult
                           {
                               Errors = validationResult.Errors.Select(e => e.ToError())
                                        .ToList(),
                               Extensions = validationResult.Extensions.ToDictionary(kv => kv.Key, kv => kv.Value)
                           }
                }
                ;

                SubscriptionResult subscriptionResult;
                switch (queryContext.OperationDefinition.Operation)
                {
                case OperationType.Subscription:
                    subscriptionResult = await Subscription.SubscribeAsync(
                        queryContext,
                        unsubscribe).ConfigureAwait(false);

                    break;

                default:
                    throw new InvalidOperationException(
                              $"Operation type {queryContext.OperationDefinition.Operation} not supported. Did you mean to use {nameof(ExecuteAsync)}?");
                }

                //todo: this looks ugly
                if (validationResult.Extensions != null)
                {
                    foreach (var validationExtension in validationResult.Extensions)
                    {
                        subscriptionResult.AddExtension(validationExtension.Key, validationExtension.Value);
                    }
                }

                logger.ExecutionResult(subscriptionResult);
                return(subscriptionResult);
            }
        }
    }
예제 #4
0
        /// <summary>
        ///     Execute query or mutation
        /// </summary>
        /// <param name="options"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task <ExecutionResult> ExecuteAsync(
            ExecutionOptions options,
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var extensions = new ExtensionsRunner(options.Extensions);
            await extensions.BeginExecuteAsync(options);

            var logger = options.LoggerFactory.CreateLogger(typeof(Executor).FullName);

            using (logger.Begin(options.OperationName))
            {
                var(queryContext, validationResult) = await BuildQueryContextAsync(
                    options,
                    extensions,
                    logger);

                if (!validationResult.IsValid)
                {
                    return new ExecutionResult
                           {
                               Errors = validationResult.Errors.Select(e => e.ToError())
                                        .ToList(),
                               Extensions = validationResult.Extensions.ToDictionary(kv => kv.Key, kv => kv.Value)
                           }
                }
                ;

                ExecutionResult executionResult;
                switch (queryContext.OperationDefinition.Operation)
                {
                case OperationType.Query:
                    executionResult = await Query.ExecuteQueryAsync(queryContext).ConfigureAwait(false);

                    break;

                case OperationType.Mutation:
                    executionResult = await Mutation.ExecuteMutationAsync(queryContext).ConfigureAwait(false);

                    break;

                case OperationType.Subscription:
                    throw new InvalidOperationException($"Use {nameof(SubscribeAsync)}");

                default:
                    throw new InvalidOperationException(
                              $"Operation type {queryContext.OperationDefinition.Operation} not supported.");
                }

                if (validationResult.Extensions != null)
                {
                    foreach (var validationExtension in validationResult.Extensions)
                    {
                        executionResult.AddExtension(validationExtension.Key, validationExtension.Value);
                    }
                }

                logger.ExecutionResult(executionResult);
                await extensions.EndExecuteAsync(executionResult);

                return(executionResult);
            }
        }
    }