public GraphQLAzureFunctionsMiddlewareProxy(
            IRequestExecutorResolver graphQLExecutorResolver,
            IHttpResultSerializer graphQLResultSerializer,
            IHttpRequestParser graphQLRequestParser,
            NameString schemaName = default,
            GraphQLAzureFunctionsConfigOptions options = null
            )
        {
            //We support multiple schemas by allowing a name to be specified, but default to DefaultName if not.
            this.SchemaName = schemaName.HasValue ? schemaName : Schema.DefaultName;

            //Initialize the Server Options with defaults!
            this.Options = options ?? new GraphQLAzureFunctionsConfigOptions();

            //Validate Dependencies...
            this.ExecutorResolver = graphQLExecutorResolver ??
                                    throw new ArgumentNullException(nameof(graphQLExecutorResolver), GRAPHQL_MIDDLEWARE_INIT_ERROR);

            this.ResultSerializer = graphQLResultSerializer ??
                                    throw new ArgumentNullException(nameof(graphQLResultSerializer), GRAPHQL_MIDDLEWARE_INIT_ERROR);

            this.RequestParser = graphQLRequestParser ??
                                 throw new ArgumentNullException(nameof(graphQLRequestParser), GRAPHQL_MIDDLEWARE_INIT_ERROR);

            //The File Provider is initialized internally as an EmbeddedFileProvider
            this.FileProvider = GraphQLInitHelpers.CreateEmbeddedFileProvider();

            //Set the RoutePath; a dependency of all dynamic file serving Middleware!
            this.RoutePath = new PathString(Options.AzureFunctionsRoutePath);

            //Initialize the Primary Middleware (POST) as needed for references to GetExecutorAsync() for Error Handling, etc....
            //NOTE: This will also return the Middleware to be used as the primary reference.
            this.PrimaryMiddleware = ConfigureMiddlewareChainOfResponsibility();
        }
 public HttpGetSchemaMiddleware(
     HttpRequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     NameString schemaName)
     : base(next, executorResolver, resultSerializer, schemaName)
 {
 }
예제 #3
0
 public WebSocketSubscriptionMiddleware(
     RequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     NameString schemaName)
     : base(next, executorResolver, resultSerializer, schemaName)
 {
 }
예제 #4
0
 public RequestExecutorProxy(
     IRequestExecutorResolver executorResolver,
     NameString schemaName)
 {
     _executorResolver = executorResolver ??
                         throw new ArgumentNullException(nameof(executorResolver));
     _schemaName = schemaName.EnsureNotEmpty(nameof(schemaName));
     _executorResolver.RequestExecutorEvicted += EvictRequestExecutor;
 }
 /// <summary>
 /// Initializes a new instance of <see cref="DefaultInMemoryClientFactory"/>
 /// </summary>
 /// <param name="requestExecutorResolver">
 /// The <see cref="RequestExecutorResolver"/> that should be used to resolve the schemas
 /// </param>
 /// <param name="optionsMonitor">
 /// The options monitor for the factory options
 /// </param>
 public DefaultInMemoryClientFactory(
     IRequestExecutorResolver requestExecutorResolver,
     IOptionsMonitor <InMemoryClientFactoryOptions> optionsMonitor)
 {
     _requestExecutorResolver = requestExecutorResolver ??
                                throw new ArgumentNullException(nameof(optionsMonitor));
     _optionsMonitor = optionsMonitor ??
                       throw new ArgumentNullException(nameof(optionsMonitor));
 }
예제 #6
0
 public ToolOptionsFileMiddleware(
     HttpRequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     NameString schemaName,
     PathString matchUrl)
     : base(next, executorResolver, resultSerializer, schemaName)
 {
     _matchUrl = matchUrl;
 }
 public HttpMultipartMiddleware(
     HttpRequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     IHttpRequestParser requestParser,
     NameString schemaName,
     IOptions <FormOptions> formOptions)
     : base(next, executorResolver, resultSerializer, requestParser, schemaName)
 {
     _formOptions = formOptions.Value;
 }
예제 #8
0
 public HttpPostMiddleware(
     HttpRequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     IHttpRequestParser requestParser,
     NameString schemaName)
     : base(next, executorResolver, resultSerializer, schemaName)
 {
     _requestParser = requestParser ??
                      throw new ArgumentNullException(nameof(requestParser));
 }
 public ToolOptionsFileMiddleware(
     HttpRequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     NameString schemaName,
     PathString matchUrl)
     : base(next, executorResolver, resultSerializer, schemaName)
 {
     _contentTypeProvider = new FileExtensionContentTypeProvider();
     _matchUrl            = matchUrl;
 }
 public HttpGetSchemaMiddleware(
     HttpRequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     IServerDiagnosticEvents diagnosticEvents,
     NameString schemaName,
     MiddlewareRoutingType routing)
     : base(next, executorResolver, resultSerializer, schemaName)
 {
     _diagnosticEvents = diagnosticEvents ??
                         throw new ArgumentNullException(nameof(diagnosticEvents));
     _routing = routing;
 }
 public GraphQLAzureFunctionsExecutorProxyV11(
     IRequestExecutorResolver graphqlExecutorResolver,
     IHttpResultSerializer graphqlResultSerializer,
     IHttpRequestParser graphqlRequestParser,
     NameString schemaName = default
     )
 {
     this.AzureFunctionsMiddlewareProxy = new GraphQLAzureFunctionsMiddlewareProxy(
         graphqlExecutorResolver,
         graphqlResultSerializer,
         graphqlRequestParser,
         schemaName
         );
 }
예제 #12
0
 public HttpGetMiddleware(
     HttpRequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     IHttpRequestParser requestParser,
     IServerDiagnosticEvents diagnosticEvents,
     NameString schemaName)
     : base(next, executorResolver, resultSerializer, schemaName)
 {
     _requestParser = requestParser ??
                      throw new ArgumentNullException(nameof(requestParser));
     _diagnosticEvents = diagnosticEvents ??
                         throw new ArgumentNullException(nameof(diagnosticEvents));
 }
예제 #13
0
 public HttpPostMiddleware(
     HttpRequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     IRequestParser requestParser,
     NameString schemaName)
 {
     _next             = next;
     _executorResolver = executorResolver;
     _resultSerializer = resultSerializer;
     _requestParser    = requestParser;
     _schemaName       = schemaName;
     executorResolver.RequestExecutorEvicted += EvictRequestExecutor;
 }
예제 #14
0
        protected MiddlewareBase(
            RequestDelegate next,
            IRequestExecutorResolver executorResolver,
            IHttpResultSerializer resultSerializer,
            NameString schemaName)
        {
            _next = next ??
                    throw new ArgumentNullException(nameof(next));
            _executorResolver = executorResolver ??
                                throw new ArgumentNullException(nameof(executorResolver));
            _resultSerializer = resultSerializer ??
                                throw new ArgumentNullException(nameof(executorResolver));
            SchemaName = schemaName;

            executorResolver.RequestExecutorEvicted += EvictRequestExecutor;
        }
 public GraphQLAzureFunctionsExecutorProxyV11Plus(
     IRequestExecutorResolver graphQLExecutorResolver,
     IHttpResultSerializer graphQLResultSerializer,
     IHttpRequestParser graphQLRequestParser,
     NameString schemaName = default,
     GraphQLAzureFunctionsConfigOptions options = null
     )
 {
     this.AzureFunctionsMiddlewareProxy = new GraphQLAzureFunctionsMiddlewareProxy(
         graphQLExecutorResolver,
         graphQLResultSerializer,
         graphQLRequestParser,
         schemaName,
         options
         );
 }
예제 #16
0
 public HttpPostMiddleware(
     HttpRequestDelegate next,
     IRequestExecutorResolver executorResolver,
     IHttpResultSerializer resultSerializer,
     IHttpRequestParser requestParser,
     IServerDiagnosticEvents diagnosticEvents,
     NameString schemaName)
     : base(
         next,
         executorResolver,
         resultSerializer,
         requestParser,
         diagnosticEvents,
         schemaName)
 {
 }
예제 #17
0
        public ExecutorWarmupService(
            IRequestExecutorResolver executorResolver,
            IEnumerable <WarmupSchema> schemas)
        {
            if (executorResolver is null !)
            {
                throw new ArgumentNullException(nameof(executorResolver));
            }

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

            _executorResolver = executorResolver;
            _schemaNames      = new HashSet <NameString>(schemas.Select(t => t.SchemaName));
        }
예제 #18
0
        public GraphQLAzureFunctionsMiddlewareProxy(
            IRequestExecutorResolver graphqlExecutorResolver,
            IHttpResultSerializer graphqlResultSerializer,
            IHttpRequestParser graphqlRequestParser,
            NameString schemaName = default
            )
        {
            //We support multiple schemas by allowing a name to be specified, but default to DefaultName if not.
            this.SchemaName = schemaName.HasValue ? schemaName : Schema.DefaultName;

            //Validate Dependencies...
            this.ExecutorResolver = graphqlExecutorResolver ??
                                    throw new ArgumentNullException(nameof(graphqlExecutorResolver), GRAPHQL_MIDDLEWARE_INIT_ERROR);

            this.ResultSerializer = graphqlResultSerializer ??
                                    throw new ArgumentNullException(nameof(graphqlResultSerializer), GRAPHQL_MIDDLEWARE_INIT_ERROR);

            this.RequestParser = graphqlRequestParser ??
                                 throw new ArgumentNullException(nameof(graphqlRequestParser), GRAPHQL_MIDDLEWARE_INIT_ERROR);


            //BBernard - Initialize the middleware proxy and pipeline with support for both Http GET & POST processing...
            //NOTE: Middleware uses the Pipeline Pattern (similar to Chain Of Responsibility), therefore
            //  we adapt that here to manually build up the two key middleware handlers for Http Get & Http Post processing.
            var httpGetMiddlewareShim = new HttpGetMiddleware(
                (httpContext) => throw new HttpRequestException(
                    "GraphQL was unable to process the request, ensure that an Http POST or GET GraphQL request was sent as well-formed Json."
                    ),
                this.ExecutorResolver,
                this.ResultSerializer,
                this.RequestParser,
                this.SchemaName
                );

            ////NOTE: The normal use case for GraphQL is POST'ing of the query so we initialize it last in the chain/pipeline
            ////  so that it is the first to execute, and then fallback to Http Get if appropriate, finally throw
            ////  an exception if neither are supported by the current request.
            this.MiddlewareProxy = new HttpPostMiddleware(
                async(httpContext) => await httpGetMiddlewareShim.InvokeAsync(httpContext),
                this.ExecutorResolver,
                this.ResultSerializer,
                this.RequestParser,
                this.SchemaName
                );
        }
예제 #19
0
        protected MiddlewareBase(
            RequestDelegate next,
            IRequestExecutorResolver executorResolver,
            IHttpResultSerializer resultSerializer,
            NameString schemaName)
        {
            if (executorResolver == null)
            {
                throw new ArgumentNullException(nameof(executorResolver));
            }

            _next = next ??
                    throw new ArgumentNullException(nameof(next));
            _resultSerializer = resultSerializer ??
                                throw new ArgumentNullException(nameof(executorResolver));
            SchemaName    = schemaName;
            ExecutorProxy = new RequestExecutorProxy(executorResolver, schemaName);
        }
예제 #20
0
 public bool Evict([FromServices] IRequestExecutorResolver executorResolver, ISchema schema)
 {
     executorResolver.EvictRequestExecutor(schema.Name);
     return(true);
 }
        public async Task AutoMerge_HotReload_ClearOperationCaches()
        {
            // arrange
            using var cts = new CancellationTokenSource(20_000);
            NameString         configurationName  = "C" + Guid.NewGuid().ToString("N");
            var                schemaDefinitionV2 = FileResource.Open("AccountSchemaDefinition.json");
            IHttpClientFactory httpClientFactory  = CreateDefaultRemoteSchemas(configurationName);
            DocumentNode       document           = Utf8GraphQLParser.Parse("{ foo }");
            var                queryHash          = "abc";

            IDatabase database = _connection.GetDatabase();

            while (!cts.IsCancellationRequested)
            {
                if (await database.SetLengthAsync(configurationName.Value) == 4)
                {
                    break;
                }

                await Task.Delay(150, cts.Token);
            }

            ServiceProvider serviceProvider =
                new ServiceCollection()
                .AddSingleton(httpClientFactory)
                .AddGraphQL()
                .AddQueryType(d => d.Name("Query").Field("foo").Resolve("foo"))
                .AddRemoteSchemasFromRedis(configurationName, _ => _connection)
                .Services
                .BuildServiceProvider();

            IRequestExecutorResolver executorResolver =
                serviceProvider.GetRequiredService <IRequestExecutorResolver>();
            IDocumentCache documentCache =
                serviceProvider.GetRequiredService <IDocumentCache>();
            IPreparedOperationCache preparedOperationCache =
                serviceProvider.GetRequiredService <IPreparedOperationCache>();

            await executorResolver.GetRequestExecutorAsync(cancellationToken : cts.Token);

            var raised = false;

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

            Assert.False(documentCache.TryGetDocument(queryHash, out _));
            Assert.False(preparedOperationCache.TryGetOperation(queryHash, out _));

            IRequestExecutor requestExecutor =
                await executorResolver.GetRequestExecutorAsync(cancellationToken : cts.Token);

            await requestExecutor
            .ExecuteAsync(QueryRequestBuilder
                          .New()
                          .SetQuery(document)
                          .SetQueryHash(queryHash)
                          .Create(),
                          cts.Token);

            Assert.True(preparedOperationCache.TryGetOperation("_Default-1-abc", out _));

            // act
            await database.StringSetAsync($"{configurationName}.{_accounts}", schemaDefinitionV2);

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

            while (!cts.IsCancellationRequested)
            {
                if (raised)
                {
                    break;
                }

                await Task.Delay(150, cts.Token);
            }

            // assert
            Assert.True(documentCache.TryGetDocument(queryHash, out _));
            Assert.False(preparedOperationCache.TryGetOperation(queryHash, out _));
        }
예제 #22
0
 public void Constructor_NoExecutor_ThrowException()
 {
     // arrange
     IRequestExecutorResolver executorResolver = default !;