public async Task ReceiveEvent_WithARegisteredClient_ClientRecievesEvent() { (var server, var socketClient, var apolloClient) = await this.CreateConnection(); // start the sub on the client var startMessage = new ApolloClientStartMessage() { Id = "abc", Payload = new GraphQueryData() { Query = "subscription { apolloSubscription { watchForPropObject { property1 } } }", }, }; await apolloClient.DispatchMessage(startMessage); var evt = new SubscriptionEvent() { Data = new TwoPropertyObject(), DataTypeName = SchemaExtensions.RetrieveFullyQualifiedDataObjectTypeName(typeof(TwoPropertyObject)), SchemaTypeName = SchemaExtensions.RetrieveFullyQualifiedSchemaTypeName(typeof(GraphSchema)), EventName = "[subscription]/ApolloSubscription/WatchForPropObject", }; var count = await server.ReceiveEvent(evt); Assert.AreEqual(1, count); socketClient.AssertApolloResponse(ApolloMessageType.DATA, "abc"); }
public async Task ReceiveEvent_OnStartedSubscription_YieldsDataMessage() { (var socketClient, var apolloClient) = await this.CreateConnection(); var startMessage = new ApolloClientStartMessage() { Id = "abc", Payload = new GraphQueryData() { Query = "subscription { apolloSubscription { watchForPropObject { property1 } } }", }, }; await apolloClient.DispatchMessage(startMessage); var route = new GraphFieldPath("[subscription]/ApolloSubscription/WatchForPropObject"); await apolloClient.ReceiveEvent(route, new TwoPropertyObject() { Property1 = "value1", Property2 = 33, }); socketClient.AssertApolloResponse( ApolloMessageType.DATA, "abc", @"{ ""data"" : { ""apolloSubscription"" : { ""watchForPropObject"" : { ""property1"" : ""value1"", } } } }"); }
public async Task ReceiveEvent_OnNonSubscribedEventNAme_YieldsNothing() { (var socketClient, var apolloClient) = await this.CreateConnection(); // start a real subscription so the client is tracking one var startMessage = new ApolloClientStartMessage() { Id = "abc", Payload = new GraphQueryData() { Query = "subscription { apolloSubscription { watchForPropObject { property1 } } }", }, }; await apolloClient.DispatchMessage(startMessage); // fire an event against a route not tracked, ensure the client skips it. var route = new GraphFieldPath("[subscription]/ApolloSubscription/WatchForPropObject_NotReal"); await apolloClient.ReceiveEvent(route, new TwoPropertyObject() { Property1 = "value1", Property2 = 33, }); Assert.AreEqual(0, socketClient.ResponseMessageCount); }
public async Task StartSubscription_ButMessageIsAQuery_YieldsDataMessage() { (var socketClient, var apolloClient) = await this.CreateConnection(); // use start message to send a query, not a subscription request // client should respond with expected data // then a complete var startMessage = new ApolloClientStartMessage() { Id = "abc", Payload = new GraphQueryData() { Query = "query { fastQuery { property1 } }", }, }; await apolloClient.DispatchMessage(startMessage); socketClient.AssertApolloResponse( ApolloMessageType.DATA, "abc", @"{ ""data"" : { ""fastQuery"" : { ""property1"" : ""bob"" } } }"); socketClient.AssertApolloResponse(ApolloMessageType.COMPLETE); }
/// <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); } }