From c5f1e5f4dedba09831cdefb7daeeed64f15a2b91 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 16 Aug 2023 18:25:15 +0200 Subject: [PATCH] Add test case for gh-774 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-774 --- .../GraphQlObservationInstrumentation.java | 2 +- ...raphQlObservationInstrumentationTests.java | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java b/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java index c09de5ed..8d85d67a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java @@ -203,7 +203,7 @@ public class GraphQlObservationInstrumentation extends SimpleInstrumentation { } else { GraphQLContext localContext = dataFetcherLocalContext == null ? - GraphQLContext.getDefault() : dataFetcherLocalContext; + GraphQLContext.newContext().build() : GraphQLContext.newContext().of(dataFetcherLocalContext).build(); return DataFetcherResult.newResult() .data(value) .localContext(localContext.put(ObservationThreadLocalAccessor.KEY, dataFetcherObservation)) diff --git a/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java index c02fbe76..add2dd21 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java @@ -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 response = ResponseHelper.forResponse(responseMono); } + @Test + void shouldNotOverrideExistingLocalContext() { + + String document = """ + { + bookById(id: 1) { + author { + firstName, + lastName + } + } + } + """; + DataFetcher> bookDataFetcher = environment -> DataFetcherResult.newResult() + .data(BookSource.getBook(1L)) + .localContext(GraphQLContext.newContext().of("test", "value").build()) + .build(); + DataFetcher authorDataFetcher = environment -> BookSource.getAuthor(101L); + DataFetcher 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 responseMono = graphQlSetup + .queryFetcher("bookById", bookDataFetcher) + .dataFetcher("Book", "author", authorDataFetcher) + .dataFetcher("Author", "firstName", authorFirstNameDataFetcher) + .toGraphQlService() + .execute(request); + ResponseHelper.forResponse(responseMono); + } + }