private static void VerifyRequestContents(IRequestExecutor executor, string queryString)
 {
     executor.Received()
         .ExecuteAsync(
             Arg.Is<IHttpRequest>(request =>
                 request.CanonicalUri.ToString().EndsWith(queryString)),
             Arg.Any<CancellationToken>());
 }
 internal static IInternalDataStore Create(IRequestExecutor requestExecutor = null, ICacheProvider cacheProvider = null, ILogger logger = null, IClient client = null)
 {
     return new DefaultDataStore(
         client: client ?? Substitute.For<IClient>(),
         requestExecutor: requestExecutor ?? Substitute.For<IRequestExecutor>(),
         baseUrl: BaseUrl,
         serializer: Serializers.Create().JsonNetSerializer().Build(),
         logger: logger ?? new NullLogger(),
         userAgentBuilder: new FakeUserAgentBuilder(),
         cacheProvider: cacheProvider ?? Caches.NewDisabledCacheProvider(),
         identityMapExpiration: TimeSpan.FromMinutes(10));
 }
        public StubRequestExecutor(string resourceJson, IClientApiKey clientApiKey = null)
        {
            this.resourceJson = resourceJson;
            this.fakeRequestExecutor = Substitute.For<IRequestExecutor>();

            // API Key
            this.fakeRequestExecutor.ApiKey.Returns(clientApiKey);

            // All GETs return 200 OK
            this.fakeRequestExecutor
                .ExecuteAsync(
                    Arg.Is<IHttpRequest>(req => req.Method == HttpMethod.Get), Arg.Any<CancellationToken>())
                .Returns(
                    Task.FromResult(new DefaultHttpResponse(200, "OK", new HttpHeaders(), resourceJson, "application/json", transportError: false) as IHttpResponse));
            this.fakeRequestExecutor
                .Execute(
                    Arg.Is<IHttpRequest>(req => req.Method == HttpMethod.Get))
                .Returns(new DefaultHttpResponse(200, "OK", new HttpHeaders(), resourceJson, "application/json", transportError: false));

            // All POSTs return 201 Created
            this.fakeRequestExecutor
                .ExecuteAsync(
                    Arg.Is<IHttpRequest>(req => req.Method == HttpMethod.Post), Arg.Any<CancellationToken>())
                .Returns(
                    Task.FromResult(new DefaultHttpResponse(201, "Created", new HttpHeaders(), resourceJson, "application/json", transportError: false) as IHttpResponse));
            this.fakeRequestExecutor
                .Execute(
                    Arg.Is<IHttpRequest>(req => req.Method == HttpMethod.Post))
                .Returns(new DefaultHttpResponse(201, "Created", new HttpHeaders(), resourceJson, "application/json", transportError: false));

            // All DELETEs return 204 No Content
            this.fakeRequestExecutor
                .ExecuteAsync(
                    Arg.Is<IHttpRequest>(req => req.Method == HttpMethod.Delete), Arg.Any<CancellationToken>())
                .Returns(
                    Task.FromResult(new DefaultHttpResponse(204, "No Content", new HttpHeaders(), null, null, transportError: false) as IHttpResponse));
            this.fakeRequestExecutor
                .Execute(
                    Arg.Is<IHttpRequest>(req => req.Method == HttpMethod.Delete))
                .Returns(new DefaultHttpResponse(204, "No Content", new HttpHeaders(), null, null, transportError: false));
        }
Exemple #4
0
    public async Task Create_ObjectEnum_OrderBy()
    {
        // arrange
        IRequestExecutor tester = _cache.CreateSchema <Bar, BarSortType>(_barEntities);

        // act
        IExecutionResult res1 = await tester.ExecuteAsync(
            QueryRequestBuilder.New()
            .SetQuery(
                "{ root(order: { foo: { barEnum: ASC}}) " +
                "{ foo{ barEnum}}}")
            .Create());

        IExecutionResult res2 = await tester.ExecuteAsync(
            QueryRequestBuilder.New()
            .SetQuery(
                "{ root(order: { foo: { barEnum: DESC}}) " +
                "{ foo{ barEnum}}}")
            .Create());

        // assert
        res1.MatchSqlSnapshot("ASC");
        res2.MatchSqlSnapshot("DESC");
    }
Exemple #5
0
        public async Task AutoMerge_Execute_Computed()
        {
            // arrange
            IHttpClientFactory httpClientFactory =
                Context.CreateDefaultRemoteSchemas();

            IRequestExecutor executor =
                await new ServiceCollection()
                .AddSingleton(httpClientFactory)
                .AddGraphQL()
                .AddRemoteSchema(Context.ContractSchema)
                .AddRemoteSchema(Context.CustomerSchema)
                .AddTypeExtensionsFromString(
                    @"extend type Customer {
                            foo: String @computed(dependantOn: [""id"", ""name""])
                        }")
                .MapField(
                    new FieldReference("Customer", "foo"),
                    next => context =>
            {
                var obj        = context.Parent <IReadOnlyDictionary <string, object> >();
                context.Result = obj["name"] + "_" + obj["id"];
                return(default);
            })
        public async Task MiddlewareConfig_MapWithClassFactory()
        {
            // arrange
            ISchema schema = Schema.Create(
                "type Query { a: String b: String }",
                c => c.Map(
                    new FieldReference("Query", "a"),
                    (services, next) => new TestFieldMiddleware(next))
                .Map(
                    new FieldReference("Query", "b"),
                    next => context =>
            {
                context.Result = "456";
                return(default(ValueTask));
            }));

            IRequestExecutor executor = schema.MakeExecutable();

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

            // assert
            result.ToJson().MatchSnapshot();
        }
Exemple #7
0
        public async Task Attribute_Nested_List_With_Field_Settings_Skip_2()
        {
            Snapshot.FullName();

            IRequestExecutor executor =
                await new ServiceCollection()
                .AddGraphQL()
                .AddQueryType <QueryAttr>()
                .Services
                .BuildServiceProvider()
                .GetRequestExecutorAsync();

            await executor
            .ExecuteAsync(@"
                {
                    nestedObjectList(first: 2) {
                        edges {
                            node {
                                bar
                            }
                            cursor
                        }
                        nodes {
                            bar
                        }
                        pageInfo {
                            hasNextPage
                            hasPreviousPage
                            startCursor
                            endCursor
                        }
                        totalCount
                    }
                }")
            .MatchSnapshotAsync();
        }
Exemple #8
0
        public async Task SubscribeToReview()
        {
            // arrange
            IRequestExecutor executor = await CreateExecutorAsync();

            // act
            var subscriptionResult =
                (ISubscriptionResult)await executor.ExecuteAsync(
                    "subscription { onReview(episode: NEW_HOPE) " +
                    "{ stars } }");

            // assert
            await executor.ExecuteAsync(@"
                mutation {
                    createReview(episode: NEW_HOPE,
                        review: { stars: 5 commentary: ""foo"" }) {
                        stars
                        commentary
                    }
                }");

            IReadOnlyQueryResult eventResult = null;

            using (var cts = new CancellationTokenSource(2000))
            {
                await foreach (IQueryResult queryResult in
                               subscriptionResult.ReadResultsAsync().WithCancellation(cts.Token))
                {
                    var item = (IReadOnlyQueryResult)queryResult;
                    eventResult = item;
                    break;
                }
            }

            eventResult?.MatchSnapshot();
        }
Exemple #9
0
        public async Task Input_Value_Null_As_Variable()
        {
            // arrange
            ISchema schema = SchemaBuilder.New()
                             .AddQueryType(d => d
                                           .Name("Query")
                                           .Field("foo")
                                           .Type <AnyType>()
                                           .Argument("input", a => a.Type <AnyType>())
                                           .Resolver(ctx => ctx.ArgumentValue <object>("input")))
                             .Create();

            IRequestExecutor executor = schema.MakeExecutable();

            // act
            IExecutionResult result = await executor.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery("query ($foo: Any) { foo(input: $foo) }")
                .SetVariableValue("foo", null)
                .Create());

            // assert
            result.ToJson().MatchSnapshot();
        }
Exemple #10
0
        public async Task Execute_Ok_StatusCode_With_Error_On_DownStream_Request()
        {
            // arrange
            IHttpClientFactory httpClientFactory = CreateDefaultRemoteSchemas();

            IRequestExecutor executor =
                await new ServiceCollection()
                .AddSingleton(httpClientFactory)
                .AddGraphQL()
                .AddQueryType(d => d.Name("Query"))
                .AddRemoteSchema(_accounts)
                .AddRemoteSchema(_inventory)
                .AddRemoteSchema(_products)
                .AddRemoteSchema(_reviews)
                .BuildRequestExecutorAsync();

            // act
            IExecutionResult result = await executor.ExecuteAsync(
                @"{
                    a: topProducts(first: 1) {
                        upc
                        error
                    }
                    b: topProducts(first: 2) {
                        upc
                        error
                    }
                }");

            // assert
            Assert.Collection(
                result.Errors !.Select(t => t.Path !.ToString()).OrderBy(t => t),
                t => Assert.Equal("/a[0]/error", t),
                t => Assert.Equal("/b[0]/error", t),
                t => Assert.Equal("/b[1]/error", t));
        }
Exemple #11
0
    public async Task Should_NotInitializeObject_When_ResultOfLeftJoinIsNull_TwoFields()
    {
        // arrange
        IRequestExecutor tester = _cache.CreateSchema(_barWithoutRelation, OnModelCreating);

        // act
        // assert
        IExecutionResult res1 = await tester.ExecuteAsync(
            QueryRequestBuilder.New()
            .SetQuery(
                @"
                        {
                            root {
                                id
                                foo {
                                    id
                                    barEnum
                                }
                            }
                        }")
            .Create());

        res1.MatchSqlSnapshot();
    }
        public async Task Simple_StringList_Default_Items()
        {
            Snapshot.FullName();

            IRequestExecutor executor = await CreateSchemaAsync();

            IExecutionResult result = await executor
                                      .ExecuteAsync(
                @"
                {
                    foos {
                        items {
                            bar
                        }
                        pageInfo {
                            hasNextPage
                            hasPreviousPage
                        }
                        totalCount
                    }
                }");

            result.MatchDocumentSnapshot();
        }
 public ConnectionFactory()
 {
     IRestSharpFactory restSharpFactory = new RestSharpFactory();
     IResponseVerifier responseVerifier = new ResponseVerifier();
     _requestExecutor = new RequestExecutor(restSharpFactory, responseVerifier);
 }
 public HandshakeClient(IRequestExecutor requestExecutor)
 {
     _requestExecutor = requestExecutor;
 }
 public ChannelClient(IRequestExecutor requestExecutor)
 {
     _requestExecutor = requestExecutor;
 }
        public static IRequestExecutorBuilder AddRemoteSchema(
            this IRequestExecutorBuilder builder,
            NameString schemaName,
            Func <IServiceProvider, CancellationToken, ValueTask <DocumentNode> > loadSchema,
            bool ignoreRootTypes = false)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (loadSchema is null)
            {
                throw new ArgumentNullException(nameof(loadSchema));
            }

            schemaName.EnsureNotEmpty(nameof(schemaName));

            // first we add a full GraphQL schema and executor that represents the remote schema.
            // This remote schema will be used by the stitching engine to execute queries against
            // this schema and also to lookup types in order correctly convert between scalars.
            builder
            .AddGraphQL(schemaName)
            .ConfigureSchemaServices(services =>
            {
                services.TryAddSingleton(
                    sp => new HttpRequestClient(
                        sp.GetApplicationService <IHttpClientFactory>(),
                        sp.GetRequiredService <IErrorHandler>(),
                        sp.GetRequiredService <IHttpStitchingRequestInterceptor>()));

                services.TryAddSingleton <
                    IHttpStitchingRequestInterceptor,
                    HttpStitchingRequestInterceptor>();
            })
            .ConfigureSchemaAsync(
                async(services, schemaBuilder, cancellationToken) =>
            {
                // No we need to load the schema document.
                DocumentNode document =
                    await loadSchema(services, cancellationToken)
                    .ConfigureAwait(false);

                document = document.RemoveBuiltInTypes();

                // The document is used to create a SDL-first schema ...
                schemaBuilder.AddDocument(document);

                // ... which will fail if any resolver is actually used ...
                // todo : how to bind resolvers
                schemaBuilder.Use(next => context => throw new NotSupportedException());
            })
            // ... instead we are using a special request pipeline that does everything like
            // the standard pipeline except the last middleware will not start the execution
            // algorithms but delegate the request via HTTP to the downstream schema.
            .UseHttpRequestPipeline();

            // Next, we will register a request executor proxy with the stitched schema,
            // that the stitching runtime will use to send requests to the schema representing
            // the downstream service.
            builder
            .ConfigureSchemaAsync(async(services, schemaBuilder, cancellationToken) =>
            {
                IInternalRequestExecutorResolver noLockExecutorResolver =
                    services.GetRequiredService <IInternalRequestExecutorResolver>();

                IRequestExecutor executor = await noLockExecutorResolver
                                            .GetRequestExecutorNoLockAsync(schemaName, cancellationToken)
                                            .ConfigureAwait(false);

                var autoProxy = AutoUpdateRequestExecutorProxy.Create(
                    new RequestExecutorProxy(
                        services.GetRequiredService <IRequestExecutorResolver>(),
                        schemaName),
                    executor);

                schemaBuilder
                .AddRemoteExecutor(schemaName, autoProxy)
                .TryAddSchemaInterceptor <StitchingSchemaInterceptor>()
                .TryAddTypeInterceptor <StitchingTypeInterceptor>();
            });

            // Last but not least, we will setup the stitching context which will
            // provide access to the remote executors which in turn use the just configured
            // request executor proxies to send requests to the downstream services.
            builder.Services.TryAddScoped <IStitchingContext, StitchingContext>();

            if (ignoreRootTypes)
            {
                builder.AddDocumentRewriter(new RemoveRootTypeRewriter(schemaName));
            }

            return(builder);
        }
Exemple #17
0
        public async Task Handle_Subscription_DataReceived_And_Completed()
        {
            // arrange
            var errorHandler = new Mock <IErrorHandler>();

            IServiceProvider services = new ServiceCollection()
                                        .AddGraphQL()
                                        .AddStarWarsTypes()
                                        .AddStarWarsRepositories()
                                        .AddInMemorySubscriptions()
                                        .Services
                                        .BuildServiceProvider();

            IRequestExecutor executor = await services
                                        .GetRequiredService <IRequestExecutorResolver>()
                                        .GetRequestExecutorAsync();

            var interceptor = new SocketSessionInterceptorMock();
            var connection  = new SocketConnectionMock {
                RequestServices = services
            };
            DocumentNode query = Utf8GraphQLParser.Parse(
                "subscription { onReview(episode: NEW_HOPE) { stars } }");
            var handler = new DataStartMessageHandler(
                executor,
                interceptor,
                errorHandler.Object,
                new NoopExecutionDiagnosticEvents());
            var message = new DataStartMessage("123", new GraphQLRequest(query));

            // act
            await handler.HandleAsync(
                connection,
                message,
                CancellationToken.None);

            // assert
            Assert.Empty(connection.SentMessages);
            Assert.NotEmpty(connection.Subscriptions);

            var stream =
                (IResponseStream)await executor.ExecuteAsync(
                    "subscription { onReview(episode: NEW_HOPE) { stars } }");

            await executor.ExecuteAsync(@"
                mutation {
                    createReview(episode:NEW_HOPE review:
                        {
                            commentary: ""foo""
                            stars: 5
                        }) {
                        stars
                    }
                }");

            using var cts = new CancellationTokenSource(15000);
            ConfiguredCancelableAsyncEnumerable <IQueryResult> .Enumerator enumerator =
                stream.ReadResultsAsync().WithCancellation(cts.Token).GetAsyncEnumerator();
            Assert.True(await enumerator.MoveNextAsync());

            await Task.Delay(2000, cts.Token);

            Assert.Collection(connection.SentMessages,
                              t =>
            {
                Assert.True(t.SequenceEqual(
                                new DataResultMessage(message.Id, enumerator.Current).Serialize()));
            });
        }
Exemple #18
0
 public Authenticator(IRequestExecutor requestExecutor, Settings settings)
 {
     this.requestExecutor = new RequestExecutionAdapter(requestExecutor);
     this.settings        = settings;
 }
Exemple #19
0
 public BasketController(IRequestExecutor requestExecutor, ISafeRunner safeRunner, IBasketService basketService)
 {
     _requestExecutor = requestExecutor;
     _safeRunner      = safeRunner;
     _basketService   = basketService;
 }
        private async Task HandleRequestAsync(
            HttpContext context,
            AllowedContentType contentType)
        {
            // first we need to get the request executor to be able to execute requests.
            IRequestExecutor requestExecutor = await GetExecutorAsync(context.RequestAborted);

            IHttpRequestInterceptor requestInterceptor = requestExecutor.GetRequestInterceptor();
            IErrorHandler           errorHandler       = requestExecutor.GetErrorHandler();

            HttpStatusCode?  statusCode = null;
            IExecutionResult?result;

            try
            {
                // next we parse the GraphQL request.
                IReadOnlyList <GraphQLRequest> requests =
                    await _requestParser.ReadJsonRequestAsync(
                        context.Request.Body, context.RequestAborted);

                switch (requests.Count)
                {
                // if the HTTP request body contains no GraphQL request structure the
                // whole request is invalid and we will create a GraphQL error response.
                case 0:
                {
                    statusCode = HttpStatusCode.BadRequest;
                    IError error = errorHandler.Handle(ErrorHelper.RequestHasNoElements());
                    result = QueryResultBuilder.CreateError(error);
                    break;
                }

                // if the HTTP request body contains a single GraphQL request and we do have
                // the batch operations query parameter specified we need to execute an
                // operation batch.
                //
                // An operation batch consists of a single GraphQL request document that
                // contains multiple operations. The batch operation query parameter
                // defines the order in which the operations shall be executed.
                case 1 when context.Request.Query.ContainsKey(_batchOperations):
                {
                    string operationNames = context.Request.Query[_batchOperations];

                    if (TryParseOperations(operationNames, out IReadOnlyList <string>?ops))
                    {
                        result = await ExecuteOperationBatchAsync(
                            context, requestExecutor, requestInterceptor, requests[0], ops);
                    }
                    else
                    {
                        IError error = errorHandler.Handle(ErrorHelper.InvalidRequest());
                        statusCode = HttpStatusCode.BadRequest;
                        result     = QueryResultBuilder.CreateError(error);
                    }
                    break;
                }

                // if the HTTP request body contains a single GraphQL request and
                // no batch query parameter is specified we need to execute a single
                // GraphQL request.
                //
                // Most GraphQL requests will be of this type where we want to execute
                // a single GraphQL query or mutation.
                case 1:
                {
                    result = await ExecuteSingleAsync(
                        context, requestExecutor, requestInterceptor, requests[0]);

                    break;
                }

                // if the HTTP request body contains more than one GraphQL request than
                // we need to execute a request batch where we need to execute multiple
                // fully specified GraphQL requests at once.
                default:
                    result = await ExecuteBatchAsync(
                        context, requestExecutor, requestInterceptor, requests);

                    break;
                }
            }
            catch (GraphQLRequestException ex)
            {
                // A GraphQL request exception is thrown if the HTTP request body couldn't be
                // parsed. In this case we will return HTTP status code 400 and return a
                // GraphQL error result.
                statusCode = HttpStatusCode.BadRequest;
                result     = QueryResultBuilder.CreateError(errorHandler.Handle(ex.Errors));
            }
            catch (Exception ex)
            {
                statusCode = HttpStatusCode.InternalServerError;
                IError error = errorHandler.CreateUnexpectedError(ex).Build();
                result = QueryResultBuilder.CreateError(error);
            }

            // in any case we will have a valid GraphQL result at this point that can be written
            // to the HTTP response stream.
            Debug.Assert(result is not null, "No GraphQL result was created.");
            await WriteResultAsync(context.Response, result, statusCode, context.RequestAborted);
        }
 public void ExecutorCreated(string name, IRequestExecutor executor)
 {
 }
 public ChatClient(IRequestExecutor requestExecutor)
 {
     _requestExecutor = requestExecutor;
 }
Exemple #23
0
 public HomeController(IRequestExecutor executor)
 {
     _requestExecutor    = executor;
     _bikeRequestBuilder = new BikeRequestBuilder();
     _itemsPerPage       = 6;
 }
        public async Task Create_Touches_Query()
        {
            // arrange
            IRequestExecutor tester = await CreateSchemaAsync <Foo, FooFilterType>(_fooEntities);

            // act
            // assert
            IExecutionResult res1 = await tester.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    @"{
                            root(where: {
                                bar: {
                                    touches: {
                                        geometry: {
                                            type: Polygon,
                                            coordinates: [
                                                [
                                                    [240 80],
                                                    [140 120],
                                                    [180 240],
                                                    [280 200],
                                                    [240 80]
                                                ]
                                            ]
                                        }
                                    }
                                }
                            }){
                                id
                            }
                        }")
                .Create());

            res1.MatchSqlSnapshot("true");

            IExecutionResult res2 = await tester.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    @"{
                            root(where: {
                                bar: {
                                    ntouches: {
                                        geometry: {
                                            type: Polygon,
                                            coordinates: [
                                                [
                                                    [240 80],
                                                    [140 120],
                                                    [180 240],
                                                    [280 200],
                                                    [240 80]
                                                ]
                                            ]
                                        }
                                    }
                                }
                            }){
                                id
                            }
                        }")
                .Create());

            res2.MatchSqlSnapshot("false");
        }
 public void ExecutorEvicted(string name, IRequestExecutor executor)
 {
 }
Exemple #26
0
 protected ARequest(string baseUrl, IRequestExecutor executor)
 {
     this.State       = RequestStates.Created;
     this._myExecutor = executor;
     this._SetBaseUrl(baseUrl);
 }
Exemple #27
0
        public async Task Array_Filter_On_Scalar_Types()
        {
            // arrange
            IServiceProvider services = new ServiceCollection()
                                        .AddSingleton <IMongoCollection <Foo> >(sp =>
            {
                IMongoDatabase database = _mongoResource.CreateDatabase();
                return(database.GetCollection <Foo>("col"));
            })
                                        .AddGraphQL()
                                        .AddQueryType <QueryType>()
                                        .BindRuntimeType <ObjectId, IdType>()
                                        .Services
                                        .BuildServiceProvider();

            IRequestExecutor executor =
                await services.GetRequiredService <IRequestExecutorResolver>()
                .GetRequestExecutorAsync();

            IMongoCollection <Foo> collection = services.GetRequiredService <IMongoCollection <Foo> >();

            await collection.InsertOneAsync(new Foo
            {
                BarCollection = new List <string> {
                    "a", "b", "c"
                },
                BazCollection = new List <Baz> {
                    new Baz {
                        Quux = "a"
                    }, new Baz {
                        Quux = "b"
                    }
                },
                Bars = new[] { "d", "e", "f" },
                Bazs = new[] { new Baz {
                                   Quux = "c"
                               }, new Baz {
                                   Quux = "d"
                               } },
                Quux = "abc"
            });

            ISchema schema = SchemaBuilder.New()
                             .AddQueryType <QueryType>()
                             .AddServices(services)
                             .BindClrType <ObjectId, IdType>()
                             .Create();

            IReadOnlyQueryRequest request = QueryRequestBuilder.New()
                                            .SetQuery(
                "{" +
                "foos(where: { bars_some: { element: \"e\" } }) { bars } " +
                "}")
                                            .Create();

            // act
            IExecutionResult result = await executor.ExecuteAsync(request);

            // assert
            result.MatchSnapshot();
        }
Exemple #28
0
        public async Task Create_Overlaps_Query()
        {
            // arrange
            IRequestExecutor tester = await CreateSchemaAsync <Foo, FooFilterType>(_fooEntities);

            // act
            // assert
            IExecutionResult res1 = await tester.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    @"{
                            root(where: {
                                bar: {
                                    overlaps: {
                                        geometry: {
                                            type: Polygon,
                                            coordinates: [
                                                [150 150],
                                                [270 150],
                                                [330 150],
                                                [250 70],
                                                [190 70],
                                                [70 70],
                                                [150 150]
                                            ]
                                        }
                                    }
                                }
                            }){
                                id
                            }
                        }")
                .Create());

            res1.MatchSqlSnapshot("true");

            IExecutionResult res2 = await tester.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    @"{
                            root(where: {
                                bar: {
                                    noverlaps: {
                                        geometry: {
                                            type: Polygon,
                                            coordinates: [
                                                [150 150],
                                                [270 150],
                                                [330 150],
                                                [250 70],
                                                [190 70],
                                                [70 70],
                                                [150 150]
                                            ]
                                        }
                                    }
                                }
                            }){
                                id
                            }
                        }")
                .Create());

            res2.MatchSqlSnapshot("false");
        }
Exemple #29
0
        public async Task AutoMerge_HotReload_Schema()
        {
            // arrange
            NameString         configurationName  = "C" + Guid.NewGuid().ToString("N");
            var                schemaDefinitionV2 = FileResource.Open("AccountSchemaDefinition.json");
            IHttpClientFactory httpClientFactory  = CreateDefaultRemoteSchemas(configurationName);

            IDatabase database = _connection.GetDatabase();

            for (var i = 0; i < 10; i++)
            {
                if (await database.SetLengthAsync(configurationName.Value) == 4)
                {
                    break;
                }

                await Task.Delay(150);
            }

            IRequestExecutorResolver executorResolver =
                new ServiceCollection()
                .AddSingleton(httpClientFactory)
                .AddGraphQL()
                .AddQueryType(d => d.Name("Query"))
                .AddRemoteSchemasFromRedis(configurationName, s => _connection)
                .Services
                .BuildServiceProvider()
                .GetRequiredService <IRequestExecutorResolver>();

            await executorResolver.GetRequestExecutorAsync();

            var raised = false;

            executorResolver.RequestExecutorEvicted += (sender, args) =>
            {
                if (args.Name.Equals(Schema.DefaultName))
                {
                    raised = true;
                }
            };

            // act
            Assert.False(raised, "eviction was raised before act.");
            await database.StringSetAsync($"{configurationName}.{_accounts}", schemaDefinitionV2);

            await _connection.GetSubscriber().PublishAsync(configurationName.Value, _accounts);

            for (var i = 0; i < 10; i++)
            {
                if (raised)
                {
                    break;
                }

                await Task.Delay(150);
            }

            // assert
            Assert.True(raised, "schema evicted.");
            IRequestExecutor executor = await executorResolver.GetRequestExecutorAsync();

            ObjectType type = executor.Schema.GetType <ObjectType>("User");

            Assert.True(type.Fields.ContainsField("foo"), "foo field exists.");
        }
 public RequestExecutorEvictedEventArgs(string name, IRequestExecutor evictedExecutor)
 {
     Name            = name;
     EvictedExecutor = evictedExecutor;
 }
Exemple #31
0
 public Authenticator(IRequestExecutor requestExecutor)
     : this(requestExecutor, new Settings())
 {
 }
        public async Task ExecuteExportObjectList()
        {
            // arrange
            Snapshot.FullName();

            IRequestExecutor executor = await CreateExecutorAsync(c => c
                                                                  .AddDocumentFromString(
                                                                      @"
                    type Query {
                        foo(f: [FooInput]) : [Foo]
                    }

                    type Foo {
                        bar: String!
                    }

                    input FooInput {
                        bar: String!
                    }")
                                                                  .AddResolver("Query", "foo", ctx =>
            {
                List <object> list = ctx.ArgumentValue <List <object> >("f");

                if (list is null)
                {
                    return(new List <object>
                    {
                        new Dictionary <string, object>
                        {
                            { "bar", "123" }
                        }
                    });
                }

                list.Add(new Dictionary <string, object>
                {
                    { "bar", "456" }
                });
                return(list);
            })
                                                                  .UseField(next => context =>
            {
                var o = context.Parent <object>();
                if (o is Dictionary <string, object> d &&
                    d.TryGetValue(context.ResponseName, out var v))
                {
                    context.Result = v;
                }
                return(next(context));
            })
                                                                  .AddExportDirectiveType());

            // act
            var batch = new List <IReadOnlyQueryRequest>
            {
                QueryRequestBuilder.New()
                .SetQuery(
                    @"{
                            foo @export(as: ""b"")
                            {
                                bar
                            }
                        }")
                .Create(),
                QueryRequestBuilder.New()
                .SetQuery(
                    @"{
                            foo(f: $b)
                            {
                                bar
                            }
                        }")
                .Create()
            };

            IBatchQueryResult batchResult = await executor.ExecuteBatchAsync(batch);

            // assert
            await batchResult.ToJsonAsync().MatchSnapshotAsync();
        }
        public async Task AutoMerge_Execute_Variables()
        {
            // arrange
            IHttpClientFactory httpClientFactory =
                Context.CreateDefaultRemoteSchemas();

            IRequestExecutor executor =
                await new ServiceCollection()
                .AddSingleton(httpClientFactory)
                .AddGraphQL()
                .AddRemoteSchema(Context.ContractSchema)
                .AddRemoteSchema(Context.CustomerSchema)
                .AddTypeExtensionsFromString(
                    @"extend type Customer {
                            contracts: [Contract!]
                                @delegate(
                                    schema: ""contract"",
                                    path: ""contracts(customerId:$fields:id)"")
                        }")
                .ModifyRequestOptions(o => o.IncludeExceptionDetails = true)
                .BuildRequestExecutorAsync();

            var variables = new Dictionary <string, object>
            {
                { "customerId", "Q3VzdG9tZXIKZDE=" },
                { "deep", "deep" },
                { "deeper", "deeper" }
            };

            // act
            IExecutionResult result = await executor.ExecuteAsync(
                @"query customer_query(
                    $customerId: ID!
                    $deep: String!
                    $deeper: String!
                    $deeperArray: String
                    $complex: ComplexInputType
                    $deeperInArray: String
                ) {
                    customer(id: $customerId) {
                        name
                        consultant {
                            name
                        }
                        complexArg(
                            arg: {
                                value: $deep
                                deeper: {
                                    value: ""CONSTANT""
                                    deeper: {
                                        value: $deeper
                                        deeperArray: [
                                            {
                                                value: ""CONSTANT_ARRAY"",
                                                deeper: {
                                                    value: $deeperInArray
                                                }
                                            }
                                        ]
                                    }
                                }
                                deeperArray: [
                                    {
                                        value: ""CONSTANT_ARRAY"",
                                        deeper: {
                                            value: $deeperArray
                                        }
                                    }
                                    $complex
                                ]
                            }
                        )
                        contracts {
                            id
                            ... on LifeInsuranceContract {
                                premium
                            }
                            ... on SomeOtherContract {
                                expiryDate
                            }
                        }
                    }
                }",
                variables);

            // assert
            result.MatchSnapshot();
        }
        public async Task GetItems_ObjectEqualsFilter_FirstItems_Is_Returned()
        {
            // arrange
            var serviceCollection     = new ServiceCollection();
            IServiceProvider services = new ServiceCollection()
                                        .AddSingleton <IMongoCollection <Model> >(sp =>
            {
                IMongoDatabase database = _mongoResource.CreateDatabase();

                IMongoCollection <Model> collection = database.GetCollection <Model>("col");
                collection.InsertMany(new[]
                {
                    new Model
                    {
                        Nested = null
                    },
                    new Model
                    {
                        Nested = new Model
                        {
                            Nested = new Model
                            {
                                Foo = "abc",
                                Bar = 1,
                                Baz = true
                            }
                        }
                    },
                    new Model
                    {
                        Nested = new Model
                        {
                            Nested = new Model
                            {
                                Foo = "def",
                                Bar = 2,
                                Baz = false
                            }
                        }
                    },
                });
                return(collection);
            })
                                        .AddGraphQL()
                                        .AddQueryType <QueryType>()
                                        .Services
                                        .BuildServiceProvider();

            IRequestExecutor executor =
                await services.GetRequiredService <IRequestExecutorResolver>()
                .GetRequestExecutorAsync();

            IReadOnlyQueryRequest request = QueryRequestBuilder.New()
                                            .SetQuery(
                "{ items(where: { nested:{ nested: { foo: \"abc\" " +
                "} } }) { nested { nested { foo } } } }")
                                            .Create();

            // act
            IExecutionResult result = await executor.ExecuteAsync(request);

            // assert
            result.MatchSnapshot();
        }
Exemple #35
0
        public static IRequestExecutorBuilder AddRemoteSchema(
            this IRequestExecutorBuilder builder,
            NameString schemaName,
            Func <IServiceProvider, CancellationToken, ValueTask <RemoteSchemaDefinition> > loadSchema,
            bool ignoreRootTypes = false)
        {
            if (builder is null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            if (loadSchema is null)
            {
                throw new ArgumentNullException(nameof(loadSchema));
            }

            schemaName.EnsureNotEmpty(nameof(schemaName));

            // first we add a full GraphQL schema and executor that represents the remote schema.
            // This remote schema will be used by the stitching engine to execute queries against
            // this schema and also to lookup types in order correctly convert between scalars.
            builder
            .AddGraphQL(schemaName)
            .ConfigureSchemaServices(services =>
            {
                services.TryAddSingleton(
                    sp => new HttpRequestClient(
                        sp.GetApplicationService <IHttpClientFactory>(),
                        sp.GetRequiredService <IErrorHandler>(),
                        sp.GetRequiredService <IHttpStitchingRequestInterceptor>()));

                services.TryAddSingleton <
                    IHttpStitchingRequestInterceptor,
                    HttpStitchingRequestInterceptor>();
            })
            .ConfigureSchemaAsync(
                async(services, schemaBuilder, cancellationToken) =>
            {
                // No we need to load the schema document.
                RemoteSchemaDefinition schemaDef =
                    await loadSchema(services, cancellationToken)
                    .ConfigureAwait(false);

                DocumentNode document = schemaDef.Document.RemoveBuiltInTypes();

                // We store the schema definition on the schema building context
                // and copy it to the schema once that is built.
                schemaBuilder
                .SetContextData(typeof(RemoteSchemaDefinition).FullName !, schemaDef)
                .TryAddTypeInterceptor <CopySchemaDefinitionTypeInterceptor>();

                // The document is used to create a SDL-first schema ...
                schemaBuilder.AddDocument(document);

                // ... which will fail if any resolver is actually used ...
                schemaBuilder.Use(next => context => throw new NotSupportedException());
            })
            // ... instead we are using a special request pipeline that does everything like
            // the standard pipeline except the last middleware will not start the execution
            // algorithms but delegate the request via HTTP to the downstream schema.
            .UseHttpRequestPipeline();

            // Next, we will register a request executor proxy with the stitched schema,
            // that the stitching runtime will use to send requests to the schema representing
            // the downstream service.
            builder
            .ConfigureSchemaAsync(async(services, schemaBuilder, cancellationToken) =>
            {
                IInternalRequestExecutorResolver noLockExecutorResolver =
                    services.GetRequiredService <IInternalRequestExecutorResolver>();

                IRequestExecutor executor = await noLockExecutorResolver
                                            .GetRequestExecutorNoLockAsync(schemaName, cancellationToken)
                                            .ConfigureAwait(false);

                var autoProxy = AutoUpdateRequestExecutorProxy.Create(
                    new RequestExecutorProxy(
                        services.GetRequiredService <IRequestExecutorResolver>(),
                        schemaName),
                    executor);

                schemaBuilder
                .AddRemoteExecutor(schemaName, autoProxy)
                .TryAddSchemaInterceptor <StitchingSchemaInterceptor>()
                .TryAddTypeInterceptor <StitchingTypeInterceptor>();

                var schemaDefinition =
                    (RemoteSchemaDefinition)autoProxy.Schema
                    .ContextData[typeof(RemoteSchemaDefinition).FullName !] !;

                var extensionsRewriter = new SchemaExtensionsRewriter();

                foreach (var extensionDocument in schemaDefinition.ExtensionDocuments)
                {
                    var doc = (DocumentNode)extensionsRewriter
                              .Rewrite(extensionDocument, schemaName.Value);

                    SchemaExtensionNode?schemaExtension =
                        doc.Definitions.OfType <SchemaExtensionNode>().FirstOrDefault();

                    if (schemaExtension is not null &&
                        schemaExtension.Directives.Count == 0 &&
                        schemaExtension.OperationTypes.Count == 0)
                    {
                        var definitions = doc.Definitions.ToList();
                        definitions.Remove(schemaExtension);
                        doc = doc.WithDefinitions(definitions);
                    }

                    schemaBuilder.AddTypeExtensions(doc);
                }

                schemaBuilder.AddTypeRewriter(
                    new RemoveFieldRewriter(
                        new FieldReference(
                            autoProxy.Schema.QueryType.Name,
                            SchemaDefinitionFieldNames.SchemaDefinitionField),
                        schemaName));

                schemaBuilder.AddDocumentRewriter(
                    new RemoveTypeRewriter(
                        SchemaDefinitionType.Names.SchemaDefinition,
                        schemaName));

                foreach (var schemaAction in extensionsRewriter.SchemaActions)
                {
                    switch (schemaAction.Name.Value)
                    {
                    case DirectiveNames.RemoveRootTypes:
                        schemaBuilder.AddDocumentRewriter(
                            new RemoveRootTypeRewriter(schemaName));
                        break;

                    case DirectiveNames.RemoveType:
                        schemaBuilder.AddDocumentRewriter(
                            new RemoveTypeRewriter(
                                GetArgumentValue(
                                    schemaAction,
                                    DirectiveFieldNames.RemoveType_TypeName),
                                schemaName));
                        break;

                    case DirectiveNames.RenameType:
                        schemaBuilder.AddTypeRewriter(
                            new RenameTypeRewriter(
                                GetArgumentValue(
                                    schemaAction,
                                    DirectiveFieldNames.RenameType_TypeName),
                                GetArgumentValue(
                                    schemaAction,
                                    DirectiveFieldNames.RenameType_NewTypeName),
                                schemaName));
                        break;

                    case DirectiveNames.RenameField:
                        schemaBuilder.AddTypeRewriter(
                            new RenameFieldRewriter(
                                new FieldReference(
                                    GetArgumentValue(
                                        schemaAction,
                                        DirectiveFieldNames.RenameField_TypeName),
                                    GetArgumentValue(
                                        schemaAction,
                                        DirectiveFieldNames.RenameField_FieldName)),
                                GetArgumentValue(
                                    schemaAction,
                                    DirectiveFieldNames.RenameField_NewFieldName),
                                schemaName));
                        break;
                    }
                }
            });
Exemple #36
0
        public async Task Create_ObjectString_OrderBy_TwoProperties()
        {
            // arrange
            IRequestExecutor tester = _cache.CreateSchema <Bar, BarSortType>(_barEntities);

            // act
            // assert
            IExecutionResult res1 = await tester.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    "{ root(order: { foo: { barBool: ASC, barShort: ASC }}) " +
                    "{ foo{ barBool barShort}}}")
                .Create());

            res1.MatchSnapshot("ASC");

            IExecutionResult res2 = await tester.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    @"
                        {
                            root(order: [
                                { foo: { barBool: ASC } },
                                { foo: { barShort: ASC } }]) {
                                foo {
                                    barBool
                                    barShort
                                }
                            }
                        }
                        ")
                .Create());

            res2.MatchSnapshot("ASC");

            IExecutionResult res3 = await tester.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    "{ root(order: { foo: { barBool: DESC, barShort: DESC}}) " +
                    "{ foo{ barBool barShort}}}")
                .Create());

            res3.MatchSnapshot("DESC");

            IExecutionResult res4 = await tester.ExecuteAsync(
                QueryRequestBuilder.New()
                .SetQuery(
                    @"
                        {
                            root(order: [
                                { foo: { barBool: DESC } },
                                { foo: { barShort: DESC } }]) {
                                foo {
                                    barBool
                                    barShort
                                }
                            }
                        }
                        ")
                .Create());

            res4.MatchSnapshot("DESC");
        }