Add test case for gh-761

This commit also ensures that a new local context is created, copying
the existing values. This avoids mutating the parent local context and
polluting it with local values.
This could cause unintended side effects on other child datafetchers.

Fixes gh-761
This commit is contained in:
Brian Clozel
2023-08-16 18:25:15 +02:00
parent 58bd58bef0
commit 94ba9fed8f
2 changed files with 37 additions and 1 deletions

View File

@@ -203,7 +203,7 @@ public class GraphQlObservationInstrumentation extends SimplePerformantInstrumen
}
else {
GraphQLContext localContext = dataFetcherLocalContext == null ?
GraphQLContext.getDefault() : dataFetcherLocalContext;
GraphQLContext.getDefault() : GraphQLContext.newContext().of(dataFetcherLocalContext).build();
return DataFetcherResult.newResult()
.data(value)
.localContext(localContext.put(ObservationThreadLocalAccessor.KEY, dataFetcherObservation))

View File

@@ -16,6 +16,7 @@
package org.springframework.graphql.observation;
import graphql.GraphQLContext;
import graphql.GraphqlErrorBuilder;
import graphql.execution.DataFetcherResult;
import graphql.schema.AsyncDataFetcher;
@@ -279,4 +280,39 @@ class GraphQlObservationInstrumentationTests {
ResponseHelper.forResponse(responseMono);
}
@Test
void shouldNotOverrideExistingLocalContext() {
String document = """
{
bookById(id: 1) {
author {
firstName,
lastName
}
}
}
""";
DataFetcher<DataFetcherResult<Object>> bookDataFetcher = environment -> DataFetcherResult.newResult()
.data(BookSource.getBook(1L))
.localContext(GraphQLContext.newContext().of("test", "value").build())
.build();
DataFetcher<Author> authorDataFetcher = environment -> BookSource.getAuthor(101L);
DataFetcher<String> authorFirstNameDataFetcher = environment -> {
GraphQLContext context = environment.getLocalContext();
String value = context.get("test");
assertThat(value).isEqualTo("value");
return BookSource.getAuthor(101L).getFirstName();
};
ExecutionGraphQlRequest request = TestExecutionRequest.forDocument(document);
Mono<ExecutionGraphQlResponse> responseMono = graphQlSetup
.queryFetcher("bookById", bookDataFetcher)
.dataFetcher("Book", "author", authorDataFetcher)
.dataFetcher("Author", "firstName", authorFirstNameDataFetcher)
.toGraphQlService()
.execute(request);
ResponseHelper.forResponse(responseMono);
}
}