Skip to content

Commit 94ba9fe

Browse files
committed
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
1 parent 58bd58b commit 94ba9fe

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ else if (result.getLocalContext() instanceof GraphQLContext) {
203203
}
204204
else {
205205
GraphQLContext localContext = dataFetcherLocalContext == null ?
206-
GraphQLContext.getDefault() : dataFetcherLocalContext;
206+
GraphQLContext.getDefault() : GraphQLContext.newContext().of(dataFetcherLocalContext).build();
207207
return DataFetcherResult.newResult()
208208
.data(value)
209209
.localContext(localContext.put(ObservationThreadLocalAccessor.KEY, dataFetcherObservation))

spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.graphql.observation;
1818

19+
import graphql.GraphQLContext;
1920
import graphql.GraphqlErrorBuilder;
2021
import graphql.execution.DataFetcherResult;
2122
import graphql.schema.AsyncDataFetcher;
@@ -279,4 +280,39 @@ void currentObservationSetInDataFetcherContext() {
279280
ResponseHelper.forResponse(responseMono);
280281
}
281282

283+
@Test
284+
void shouldNotOverrideExistingLocalContext() {
285+
286+
String document = """
287+
{
288+
bookById(id: 1) {
289+
author {
290+
firstName,
291+
lastName
292+
}
293+
}
294+
}
295+
""";
296+
DataFetcher<DataFetcherResult<Object>> bookDataFetcher = environment -> DataFetcherResult.newResult()
297+
.data(BookSource.getBook(1L))
298+
.localContext(GraphQLContext.newContext().of("test", "value").build())
299+
.build();
300+
DataFetcher<Author> authorDataFetcher = environment -> BookSource.getAuthor(101L);
301+
DataFetcher<String> authorFirstNameDataFetcher = environment -> {
302+
GraphQLContext context = environment.getLocalContext();
303+
String value = context.get("test");
304+
assertThat(value).isEqualTo("value");
305+
return BookSource.getAuthor(101L).getFirstName();
306+
};
307+
308+
ExecutionGraphQlRequest request = TestExecutionRequest.forDocument(document);
309+
Mono<ExecutionGraphQlResponse> responseMono = graphQlSetup
310+
.queryFetcher("bookById", bookDataFetcher)
311+
.dataFetcher("Book", "author", authorDataFetcher)
312+
.dataFetcher("Author", "firstName", authorFirstNameDataFetcher)
313+
.toGraphQlService()
314+
.execute(request);
315+
ResponseHelper.forResponse(responseMono);
316+
}
317+
282318
}

0 commit comments

Comments
 (0)