Example #1
0
 private static Task <ExecutionResult> ExecuteRequestAsync(GraphQLRequest gqlRequest, IDictionary <string, object> userContext, IGraphQLExecuter <TSchema> executer, IServiceProvider requestServices, CancellationToken token)
 => executer.ExecuteAsync(
     gqlRequest.OperationName,
     gqlRequest.Query,
     gqlRequest.Inputs,
     userContext,
     requestServices,
     token);
Example #2
0
        public async static Task <ExecutionResult> ExecuteAsync(this IGraphQLExecuter graphQLExecuter, HttpRequest request, ILogger logger)
        {
            string?operationName = null;
            string query;
            Inputs variables;

            if (HttpMethods.IsGet(request.Method) || (HttpMethods.IsPost(request.Method) && request.Query.ContainsKey(QUERY_KEY)))
            {
                (operationName, query, variables) = ExtractGraphQLAttributesFromQueryString(request);
            }
            else if (HttpMethods.IsPost(request.Method))
            {
                if (!MediaTypeHeaderValue.TryParse(request.ContentType, out var mediaTypeHeader))
                {
                    throw new GraphQLBadRequestException($"Could not parse 'Content-Type' header value '{request.ContentType}'.");
                }

                switch (mediaTypeHeader.MediaType)
                {
                case JSON_MEDIA_TYPE:
                    (operationName, query, variables) = await ExtractGraphQLAttributesFromJsonBodyAsync(request);

                    break;

                case GRAPHQL_MEDIA_TYPE:
                    query = await ExtractGraphQLQueryFromGraphQLBodyAsync(request.Body);

                    variables = new Inputs();
                    break;

                case FORM_URLENCODED_MEDIA_TYPE:
                    (operationName, query, variables) = await ExtractGraphQLAttributesFromFormCollectionAsync(request);

                    break;

                default:
                    throw new GraphQLBadRequestException($"Not supported 'Content-Type' header value '{request.ContentType}'.");
                }
            }
            else
            {
                throw new GraphQLBadRequestException($"Not supported 'HttpMethod' header value '{request.Method}'.");
            }

            logger.LogDebug("got graphql query: {operationName}, {query}, {variables}", operationName, query, variables);
            var stopwatch = new Stopwatch();

            stopwatch.Start();
            var executonResult = await graphQLExecuter.ExecuteAsync(operationName, query, variables, null, request.HttpContext.RequestAborted);

            stopwatch.Stop();
            logger.LogMetric($"graphql.{operationName}", stopwatch.ElapsedMilliseconds);
            return(executonResult);
        }
        public async Task Failed_Subscribe_does_not_add()
        {
            /* Given */
            var id      = "1";
            var payload = new OperationMessagePayload();

            _executer.ExecuteAsync(null, null, null).ReturnsForAnyArgs(
                new SubscriptionExecutionResult
            {
                Errors = new ExecutionErrors
                {
                    new ExecutionError("error")
                }
            });

            /* When */
            await _sut.SubscribeOrExecuteAsync(id, payload, _writer);

            /* Then */
            Assert.Empty(_sut);
        }
        public async Task Receive_start_mutation()
        {
            /* Given */
            _documentExecuter.ExecuteAsync(null, null, null).ReturnsForAnyArgs(
                new ExecutionResult());
            var expected = new OperationMessage
            {
                Type    = MessageType.GQL_START,
                Id      = "1",
                Payload = JObject.FromObject(new OperationMessagePayload
                {
                    Query = @"mutation AddMessage($message: MessageInputType!) {
  addMessage(message: $message) {
    from {
      id
      displayName
    }
    content
  }
}"
                })
            };

            _transportReader.AddMessageToRead(expected);
            await _transportReader.Complete();

            /* When */
            await _sut.OnConnect();

            /* Then */
            Assert.Empty(_sut.Subscriptions);
            Assert.Contains(_transportWriter.WrittenMessages,
                            message => message.Type == MessageType.GQL_DATA);
            Assert.Contains(_transportWriter.WrittenMessages,
                            message => message.Type == MessageType.GQL_COMPLETE);
        }
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger logger)
        {
            try
            {
                ExecutionResult executionResult = await _graphQLExecuter.ExecuteAsync(req, logger);

                if (executionResult.Errors != null)
                {
                    logger.LogError("GraphQL execution error(s): {Errors}", executionResult.Errors);
                }

                return(new GraphQLExecutionResult(executionResult));
            }
            catch (Exception ex)
            {
                return(new BadRequestObjectResult(new { message = ex.Message }));
            }
        }
        public async static Task <ExecutionResult> ExecuteAsync(this IGraphQLExecuter graphQLExecuter, HttpRequest request)
        {
            string  operationName = null;
            string  query         = null;
            JObject variables     = null;

            if (HttpMethods.IsGet(request.Method) || (HttpMethods.IsPost(request.Method) && request.Query.ContainsKey(QUERY_KEY)))
            {
                (operationName, query, variables) = ExtractGraphQLAttributesFromQueryString(request);
            }
            else if (HttpMethods.IsPost(request.Method))
            {
                if (!MediaTypeHeaderValue.TryParse(request.ContentType, out var mediaTypeHeader))
                {
                    throw new GraphQLBadRequestException($"Could not parse 'Content-Type' header value '{request.ContentType}'.");
                }

                switch (mediaTypeHeader.MediaType)
                {
                case JSON_MEDIA_TYPE:
                    (operationName, query, variables) = await ExtractGraphQLAttributesFromJsonBodyAsync(request);

                    break;

                case GRAPHQL_MEDIA_TYPE:
                    query = await ExtractGraphQLQueryFromGraphQLBodyAsync(request.Body);

                    break;

                case FORM_URLENCODED_MEDIA_TYPE:
                    (operationName, query, variables) = await ExtractGraphQLAttributesFromFormCollectionAsync(request);

                    break;

                default:
                    throw new GraphQLBadRequestException($"Not supported 'Content-Type' header value '{request.ContentType}'.");
                }
            }

            return(await graphQLExecuter.ExecuteAsync(operationName, query, variables?.ToInputs(), null, request.HttpContext.RequestAborted));
        }
Example #7
0
 public ProtocolHandlerFacts()
 {
     _transport        = new TestableSubscriptionTransport();
     _transportReader  = _transport.Reader as TestableReader;
     _transportWriter  = _transport.Writer as TestableWriter;
     _documentExecuter = Substitute.For <IGraphQLExecuter>();
     _documentExecuter.ExecuteAsync(null, null, null, null, null).ReturnsForAnyArgs(
         new SubscriptionExecutionResult
     {
         Streams = new Dictionary <string, IObservable <ExecutionResult> >
         {
             { "1", Substitute.For <IObservable <ExecutionResult> >() }
         }
     });
     _subscriptionManager = new SubscriptionManager(_documentExecuter, new NullLoggerFactory());
     _sut    = new ProtocolMessageListener(new NullLogger <ProtocolMessageListener>());
     _server = new SubscriptionServer(
         _transport,
         _subscriptionManager,
         new[] { _sut },
         new NullLogger <SubscriptionServer>());
 }
Example #8
0
        private async Task <Subscription> ExecuteAsync(
            string id,
            OperationMessagePayload payload,
            MessageHandlingContext context)
        {
            var writer = context.Writer;

            _logger.LogDebug("Executing operation: {operationName} query: {query}",
                             payload.OperationName,
                             payload.Query);

            var result = await _executer.ExecuteAsync(
                payload.OperationName,
                payload.Query,
                payload.Variables?.ToInputs(),
                context,
                null // TODO: find later a better way to specify services
                ).ConfigureAwait(false);

            if (result.Errors != null && result.Errors.Any())
            {
                _logger.LogError("Execution errors: {errors}", ResultHelper.GetErrorString(result));
                await writer.SendAsync(new OperationMessage
                {
                    Type    = MessageType.GQL_ERROR,
                    Id      = id,
                    Payload = result
                }).ConfigureAwait(false);

                return(null);
            }

            // is sub
            if (result is SubscriptionExecutionResult subscriptionExecutionResult)
            {
                using (_logger.BeginScope("Subscribing to: {subscriptionId}", id))
                {
                    if (subscriptionExecutionResult.Streams?.Values.SingleOrDefault() == null)
                    {
                        _logger.LogError("Cannot subscribe as no result stream available");
                        await writer.SendAsync(new OperationMessage
                        {
                            Type    = MessageType.GQL_ERROR,
                            Id      = id,
                            Payload = result
                        }).ConfigureAwait(false);

                        return(null);
                    }

                    _logger.LogDebug("Creating subscription");
                    return(new Subscription(
                               id,
                               payload,
                               subscriptionExecutionResult,
                               writer,
                               sub => _subscriptions.TryRemove(id, out _),
                               _loggerFactory.CreateLogger <Subscription>()));
                }
            }

            //is query or mutation
            await writer.SendAsync(new OperationMessage
            {
                Type    = MessageType.GQL_DATA,
                Id      = id,
                Payload = result
            }).ConfigureAwait(false);

            await writer.SendAsync(new OperationMessage
            {
                Type = MessageType.GQL_COMPLETE,
                Id   = id
            }).ConfigureAwait(false);

            return(null);
        }
Example #9
0
        public async Task <ExecutionResult> GQLDotNet_Three_Fields()
        {
            var result = await _gqlDotNetExecutor.ExecuteAsync("", Queries.ThreeFields, null, null);

            if (result.Errors is { })
        private async Task <Subscription> ExecuteAsync(
            string id,
            OperationMessagePayload payload,
            IWriterPipeline writer)
        {
            _logger.LogDebug("Executing operation: {operationName} query: {query}",
                             payload.OperationName,
                             payload.Query);

            var result = await _executer.ExecuteAsync(
                payload.OperationName,
                payload.Query,
                payload.Variables);

            if (result.Errors != null && result.Errors.Any())
            {
                _logger.LogError("Execution errors: {errors}", ResultHelper.GetErrorString(result));
                await writer.SendAsync(new OperationMessage
                {
                    Type    = MessageType.GQL_ERROR,
                    Id      = id,
                    Payload = JObject.FromObject(result)
                });

                return(null);
            }

            // is sub
            if (result is SubscriptionExecutionResult subscriptionExecutionResult)
            {
                using (_logger.BeginScope("Subscribing to: {subscriptionId}", id))
                {
                    if (subscriptionExecutionResult.Streams?.Values.SingleOrDefault() == null)
                    {
                        _logger.LogError("Cannot subscribe as no result stream available");
                        await writer.SendAsync(new OperationMessage
                        {
                            Type    = MessageType.GQL_ERROR,
                            Id      = id,
                            Payload = JObject.FromObject(result)
                        });

                        return(null);
                    }

                    _logger.LogInformation("Creating subscription");
                    return(new Subscription(
                               id,
                               payload,
                               subscriptionExecutionResult,
                               writer,
                               sub => _subscriptions.TryRemove(id, out _),
                               _loggerFactory.CreateLogger <Subscription>()));
                }
            }

            //is query or mutation
            await writer.SendAsync(new OperationMessage
            {
                Type    = MessageType.GQL_DATA,
                Id      = id,
                Payload = JObject.FromObject(result)
            });

            await writer.SendAsync(new OperationMessage
            {
                Type = MessageType.GQL_COMPLETE,
                Id   = id
            });

            return(null);
        }