-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Ensure reactive context is propagated (#512)
DefaultGraphQLInvocation and DefaultGraphQLExecutionInputCustomizer are updated to use Mono and Flux in their internal implementation in order to ensure that the Micronaut PropagationContext is carried appropriately through the invocation flow. Previous use of the bare io.micronaut.core.async.publisher.Publishers API in DefaultGraphQLExecutionInputCustomizer was causing the context not to be propagated as desired when including the Micrometer Context Propagation library. A test is added to verify the context propagation works as expected. Some additional cleanup is done throughout the test suite to reduce the scope of included Micronaut beans to the specific tests in order to make it easier to test different setups. * Avoid direct instantiation of DefaultApplicationContext Resolves #495
- Loading branch information
1 parent
e67a1f4
commit a2e6699
Showing
14 changed files
with
256 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
104
...l/src/test/groovy/io/micronaut/configuration/graphql/GraphQLContextPropagationSpec.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package io.micronaut.configuration.graphql | ||
|
||
import graphql.GraphQL | ||
import graphql.schema.DataFetcher | ||
import graphql.schema.DataFetchingEnvironment | ||
import graphql.schema.GraphQLSchema | ||
import graphql.schema.idl.RuntimeWiring | ||
import graphql.schema.idl.SchemaGenerator | ||
import graphql.schema.idl.SchemaParser | ||
import graphql.schema.idl.TypeDefinitionRegistry | ||
import io.micronaut.context.ApplicationContext | ||
import io.micronaut.context.annotation.Bean | ||
import io.micronaut.context.annotation.Factory | ||
import io.micronaut.context.annotation.Requires | ||
import io.micronaut.context.env.Environment | ||
import io.micronaut.core.annotation.Nullable | ||
import io.micronaut.core.io.ResourceResolver | ||
import io.micronaut.http.HttpResponse | ||
import io.micronaut.http.annotation.Body | ||
import io.micronaut.http.annotation.Get | ||
import io.micronaut.http.annotation.Post | ||
import io.micronaut.http.annotation.QueryValue | ||
import io.micronaut.http.client.annotation.Client | ||
import io.micronaut.http.context.ServerRequestContext | ||
import io.micronaut.runtime.server.EmbeddedServer | ||
import jakarta.inject.Singleton | ||
import spock.lang.AutoCleanup | ||
import spock.lang.Specification | ||
|
||
import java.net.http.HttpRequest | ||
|
||
class GraphQLContextPropagationSpec extends Specification { | ||
|
||
@AutoCleanup | ||
EmbeddedServer embeddedServer | ||
|
||
GraphQLClient graphQLClient | ||
|
||
def setup() { | ||
embeddedServer = ApplicationContext.run( | ||
EmbeddedServer, | ||
["spec.name": GraphQLContextPropagationSpec.simpleName]) | ||
graphQLClient = embeddedServer.applicationContext.getBean(GraphQLClient) | ||
} | ||
|
||
void "server request context is propagated to data fetcher"() { | ||
when: | ||
GraphQLResponseBody response = graphQLClient.hello("query { hello }") | ||
|
||
then: | ||
response | ||
response.getSpecification()["data"]["hello"] == "Hello World!" | ||
} | ||
|
||
@Client("/graphql") | ||
static interface GraphQLClient { | ||
|
||
@Get("{?query}") | ||
GraphQLResponseBody hello(@QueryValue String query) | ||
|
||
} | ||
|
||
@Factory | ||
static class GraphQLFactory { | ||
|
||
@Bean | ||
@Singleton | ||
@Requires(property = "spec.name", value = "GraphQLContextPropagationSpec") | ||
GraphQL graphQL(ResourceResolver resourceResolver, HelloDataFetcher helloDataFetcher) { | ||
|
||
SchemaParser schemaParser = new SchemaParser() | ||
SchemaGenerator schemaGenerator = new SchemaGenerator() | ||
|
||
TypeDefinitionRegistry typeRegistry = new TypeDefinitionRegistry() | ||
typeRegistry.merge(schemaParser.parse(new BufferedReader(new InputStreamReader( | ||
resourceResolver.getResourceAsStream("classpath:schema.graphqls").get())))) | ||
|
||
RuntimeWiring runtimeWiring = RuntimeWiring.newRuntimeWiring() | ||
.type("Query", typeWiring -> typeWiring | ||
.dataFetcher("hello", helloDataFetcher)) | ||
.build() | ||
|
||
GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring) | ||
|
||
return GraphQL.newGraphQL(graphQLSchema).build() | ||
} | ||
} | ||
|
||
@Singleton | ||
@Requires(property = "spec.name", value = "GraphQLContextPropagationSpec") | ||
static class HelloDataFetcher implements DataFetcher<String> { | ||
|
||
@Override | ||
String get(DataFetchingEnvironment env) { | ||
Optional<HttpRequest> request = ServerRequestContext.currentRequest() | ||
assert request.isPresent() | ||
String name = env.getArgument("name") | ||
if (name == null || name.trim().length() == 0) { | ||
name = "World" | ||
} | ||
return String.format("Hello %s!", name) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 0 additions & 23 deletions
23
graphql/src/test/groovy/io/micronaut/configuration/graphql/GraphQLFactory.groovy
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.