/// <summary> /// Creates this query context instance that can be executed against the test server. /// </summary> /// <param name="subscriptionId">The subscription identifier to assign to the created sub.</param> /// <returns>GraphQueryContext.</returns> public virtual SubcriptionExecutionContext Build(string subscriptionId = null) { subscriptionId = subscriptionId ?? Guid.NewGuid().ToString(); var metaData = new MetaDataCollection(); // unchangable items about the request var request = new Mock <IGraphOperationRequest>(); // updateable items about the request var context = new SubcriptionExecutionContext( _client, this.OperationRequest, subscriptionId, _metrics, _eventLogger, metaData); foreach (var kvp in _sourceData) { var mockField = new Mock <IGraphField>(); mockField.Setup(x => x.FieldSource).Returns(GraphQL.AspNet.Internal.TypeTemplates.GraphFieldTemplateSource.Action); mockField.Setup(x => x.Route).Returns(kvp.Key); context.DefaultFieldSources.AddSource(mockField.Object, kvp.Value); } return(context); }
/// <summary> /// Parses the message contents to generate a valid client subscription and adds it to the watched /// set for this instance. /// </summary> /// <param name="message">The message with the subscription details.</param> private async Task ExecuteStartRequest(ApolloClientStartMessage message) { // ensure the id isnt already in use if (!_reservedMessageIds.ReserveMessageId(message.Id)) { await this .SendMessage(new ApolloServerErrorMessage( $"The message id {message.Id} is already reserved for an outstanding request and cannot " + "be processed against. Allow the in-progress request to complete or stop the associated subscription.", SubscriptionConstants.ErrorCodes.DUPLICATE_MESSAGE_ID, lastMessage : message, clientProvidedId : message.Id)) .ConfigureAwait(false); return; } var retainMessageId = false; var runtime = this.ServiceProvider.GetRequiredService(typeof(IGraphQLRuntime <TSchema>)) as IGraphQLRuntime <TSchema>; var request = runtime.CreateRequest(message.Payload); var metricsPackage = _enableMetrics ? runtime.CreateMetricsPackage() : null; var context = new SubcriptionExecutionContext( this, request, message.Id, metricsPackage); var result = await runtime .ExecuteRequest(context) .ConfigureAwait(false); if (context.IsSubscriptionOperation) { retainMessageId = await this .RegisterSubscriptionOrRespond(context.Subscription as ISubscription <TSchema>) .ConfigureAwait(false); } else { // not a subscription, just send back the generated response and close out the id ApolloMessage responseMessage; // report syntax errors as error messages // allow others to bubble into a fully reslt (per apollo spec) if (result.Messages.Count == 1 && result.Messages[0].Code == Constants.ErrorCodes.SYNTAX_ERROR) { responseMessage = new ApolloServerErrorMessage( result.Messages[0], message, message.Id); } else { responseMessage = new ApolloServerDataMessage(message.Id, result); } await this .SendMessage(responseMessage) .ConfigureAwait(false); await this .SendMessage(new ApolloServerCompleteMessage(message.Id)) .ConfigureAwait(false); } if (!retainMessageId) { _reservedMessageIds.ReleaseMessageId(message.Id); } }