Skip to content

Commit 48c1626

Browse files
committed
Upgrade to Context Propagation 1.0.3
Closes gh-716 Closes gh-718
1 parent c944d9b commit 48c1626

11 files changed

+90
-19
lines changed

platform/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ dependencies {
2525

2626
constraints {
2727
api("com.graphql-java:graphql-java:${graphQlJavaVersion}")
28-
api("io.micrometer:context-propagation:1.0.2")
28+
api("io.micrometer:context-propagation:1.0.3")
2929

3030
api("jakarta.annotation:jakarta.annotation-api:2.1.1")
3131
api("jakarta.servlet:jakarta.servlet-api:6.0.0")

spring-graphql/src/main/java/org/springframework/graphql/data/method/InvocableHandlerMethodSupport.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import graphql.GraphQLContext;
2929
import io.micrometer.context.ContextSnapshot;
30+
import io.micrometer.context.ContextSnapshotFactory;
3031
import reactor.core.publisher.Mono;
3132

3233
import org.springframework.core.CoroutinesUtils;
@@ -45,6 +46,8 @@ public abstract class InvocableHandlerMethodSupport extends HandlerMethod {
4546

4647
private static final Object NO_VALUE = new Object();
4748

49+
private static final ContextSnapshotFactory SNAPSHOT_FACTORY = ContextSnapshotFactory.builder().build();
50+
4851

4952
private final boolean hasCallableReturnValue;
5053

@@ -114,7 +117,7 @@ private Object handleReturnValue(GraphQLContext graphQLContext, @Nullable Object
114117
return CompletableFuture.supplyAsync(
115118
() -> {
116119
try {
117-
return ContextSnapshot.captureFrom(graphQLContext).wrap((Callable<?>) result).call();
120+
return SNAPSHOT_FACTORY.captureFrom(graphQLContext).wrap((Callable<?>) result).call();
118121
}
119122
catch (Exception ex) {
120123
throw new IllegalStateException(

spring-graphql/src/main/java/org/springframework/graphql/execution/ContextDataFetcherDecorator.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import graphql.util.TraversalControl;
3434
import graphql.util.TraverserContext;
3535
import io.micrometer.context.ContextSnapshot;
36+
import io.micrometer.context.ContextSnapshotFactory;
3637
import org.reactivestreams.Publisher;
3738
import reactor.core.publisher.Flux;
3839
import reactor.core.publisher.Mono;
@@ -59,6 +60,8 @@ final class ContextDataFetcherDecorator implements DataFetcher<Object> {
5960

6061
private final SubscriptionExceptionResolver subscriptionExceptionResolver;
6162

63+
private final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();
64+
6265
private ContextDataFetcherDecorator(
6366
DataFetcher<?> delegate, boolean subscription,
6467
SubscriptionExceptionResolver subscriptionExceptionResolver) {
@@ -73,18 +76,13 @@ private ContextDataFetcherDecorator(
7376
@Override
7477
public Object get(DataFetchingEnvironment environment) throws Exception {
7578

76-
GraphQLContext context;
77-
// temporarily merge global and local graphql context until https://github.com/micrometer-metrics/context-propagation/pull/98
79+
ContextSnapshot snapshot;
7880
if (environment.getLocalContext() instanceof GraphQLContext localContext) {
79-
context = GraphQLContext.newContext()
80-
.of(environment.getGraphQlContext())
81-
.of(localContext)
82-
.build();
81+
snapshot = snapshotFactory.captureFrom(environment.getGraphQlContext(), localContext);
8382
}
8483
else {
85-
context = environment.getGraphQlContext();
84+
snapshot = snapshotFactory.captureFrom(environment.getGraphQlContext());
8685
}
87-
ContextSnapshot snapshot = ContextSnapshot.captureFrom(context);
8886
Object value = snapshot.wrap(() -> this.delegate.get(environment)).call();
8987

9088
if (this.subscription) {

spring-graphql/src/main/java/org/springframework/graphql/execution/DataFetcherExceptionResolverAdapter.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import graphql.GraphQLError;
2323
import graphql.schema.DataFetchingEnvironment;
2424
import io.micrometer.context.ContextSnapshot;
25+
import io.micrometer.context.ContextSnapshotFactory;
2526
import io.micrometer.context.ThreadLocalAccessor;
2627
import org.apache.commons.logging.Log;
2728
import org.apache.commons.logging.LogFactory;
@@ -52,6 +53,8 @@ public abstract class DataFetcherExceptionResolverAdapter implements DataFetcher
5253

5354
protected final Log logger = LogFactory.getLog(getClass());
5455

56+
protected final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();
57+
5558
private boolean threadLocalContextAware;
5659

5760

@@ -98,7 +101,7 @@ private List<GraphQLError> resolveInternal(Throwable exception, DataFetchingEnvi
98101
return resolveToMultipleErrors(exception, env);
99102
}
100103
try {
101-
return ContextSnapshot.captureFrom(env.getGraphQlContext())
104+
return snapshotFactory.captureFrom(env.getGraphQlContext())
102105
.wrap(() -> resolveToMultipleErrors(exception, env))
103106
.call();
104107
}

spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistry.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import graphql.GraphQLContext;
2929
import io.micrometer.context.ContextSnapshot;
30+
import io.micrometer.context.ContextSnapshotFactory;
3031
import org.dataloader.BatchLoaderContextProvider;
3132
import org.dataloader.BatchLoaderEnvironment;
3233
import org.dataloader.BatchLoaderWithContext;
@@ -52,13 +53,16 @@
5253
*/
5354
public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry {
5455

56+
private static final ContextSnapshotFactory SNAPSHOT_FACTORY = ContextSnapshotFactory.builder().build();
57+
5558
private final List<ReactorBatchLoader<?,?>> loaders = new ArrayList<>();
5659

5760
private final List<ReactorMappedBatchLoader<?,?>> mappedLoaders = new ArrayList<>();
5861

5962
private final Supplier<DataLoaderOptions> defaultOptionsSupplier;
6063

6164

65+
6266
/**
6367
* Default constructor
6468
*/
@@ -230,7 +234,7 @@ public DataLoaderOptions getOptions() {
230234
@Override
231235
public CompletionStage<List<V>> load(List<K> keys, BatchLoaderEnvironment environment) {
232236
GraphQLContext graphQLContext = environment.getContext();
233-
ContextSnapshot snapshot = ContextSnapshot.captureFrom(graphQLContext);
237+
ContextSnapshot snapshot = SNAPSHOT_FACTORY.captureFrom(graphQLContext);
234238
try {
235239
return snapshot.wrap(() ->
236240
this.loader.apply(keys, environment)
@@ -280,7 +284,7 @@ public DataLoaderOptions getOptions() {
280284
@Override
281285
public CompletionStage<Map<K, V>> load(Set<K> keys, BatchLoaderEnvironment environment) {
282286
GraphQLContext graphQLContext = environment.getContext();
283-
ContextSnapshot snapshot = ContextSnapshot.captureFrom(graphQLContext);
287+
ContextSnapshot snapshot = SNAPSHOT_FACTORY.captureFrom(graphQLContext);
284288
try {
285289
return snapshot.wrap(() ->
286290
this.loader.apply(keys, environment)

spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultExecutionGraphQlService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import graphql.GraphQLContext;
2626
import graphql.execution.ExecutionIdProvider;
2727
import io.micrometer.context.ContextSnapshot;
28+
import io.micrometer.context.ContextSnapshotFactory;
2829
import org.dataloader.DataLoaderRegistry;
2930
import reactor.core.publisher.Mono;
3031

@@ -45,6 +46,7 @@ public class DefaultExecutionGraphQlService implements ExecutionGraphQlService {
4546
private static final BiFunction<ExecutionInput, ExecutionInput.Builder, ExecutionInput> RESET_EXECUTION_ID_CONFIGURER =
4647
(executionInput, builder) -> builder.executionId(null).build();
4748

49+
private final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();
4850

4951
private final GraphQlSource graphQlSource;
5052

@@ -77,7 +79,7 @@ public final Mono<ExecutionGraphQlResponse> execute(ExecutionGraphQlRequest requ
7779
request.configureExecutionInput(RESET_EXECUTION_ID_CONFIGURER);
7880
}
7981
ExecutionInput executionInput = request.toExecutionInput();
80-
ContextSnapshot.captureFrom(contextView).updateContext(executionInput.getGraphQLContext());
82+
snapshotFactory.captureFrom(contextView).updateContext(executionInput.getGraphQLContext());
8183
ExecutionInput updatedExecutionInput = registerDataLoaders(executionInput);
8284
return Mono.fromFuture(this.graphQlSource.graphQl().executeAsync(updatedExecutionInput))
8385
.map(result -> new DefaultExecutionGraphQlResponse(updatedExecutionInput, result));

spring-graphql/src/main/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandler.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import graphql.execution.ExecutionId;
3030
import graphql.schema.DataFetchingEnvironment;
3131
import io.micrometer.context.ContextSnapshot;
32+
import io.micrometer.context.ContextSnapshotFactory;
3233
import org.apache.commons.logging.Log;
3334
import org.apache.commons.logging.LogFactory;
3435
import reactor.core.publisher.Flux;
@@ -47,6 +48,8 @@ class ExceptionResolversExceptionHandler implements DataFetcherExceptionHandler
4748

4849
private static final Log logger = LogFactory.getLog(ExceptionResolversExceptionHandler.class);
4950

51+
private final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();
52+
5053
private final List<DataFetcherExceptionResolver> resolvers;
5154

5255
/**
@@ -70,7 +73,7 @@ public DataFetcherExceptionHandlerResult onException(DataFetcherExceptionHandler
7073
public CompletableFuture<DataFetcherExceptionHandlerResult> handleException(DataFetcherExceptionHandlerParameters params) {
7174
Throwable exception = unwrapException(params);
7275
DataFetchingEnvironment env = params.getDataFetchingEnvironment();
73-
ContextSnapshot snapshot = ContextSnapshot.captureFrom(env.getGraphQlContext());
76+
ContextSnapshot snapshot = snapshotFactory.captureFrom(env.getGraphQlContext());
7477
try {
7578
return Flux.fromIterable(this.resolvers)
7679
.flatMap(resolver -> resolver.resolveException(exception, env))

spring-graphql/src/main/java/org/springframework/graphql/execution/SecurityContextThreadLocalAccessor.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,10 +72,30 @@ private <V> void setValueInternal(Object value) {
7272
}
7373

7474
@Override
75+
public void setValue() {
76+
this.delegate.setValue();
77+
}
78+
79+
@Override
80+
@Deprecated
7581
public void reset() {
7682
this.delegate.reset();
7783
}
7884

85+
@Override
86+
public void restore(Object previousValue) {
87+
restoreInternal(previousValue);
88+
}
89+
90+
@SuppressWarnings("unchecked")
91+
public <V> void restoreInternal(Object previousValue) {
92+
((ThreadLocalAccessor<V>) this.delegate).restore((V) previousValue);
93+
}
94+
95+
@Override
96+
public void restore() {
97+
this.delegate.restore();
98+
}
7999

80100
private static class DelegateAccessor implements ThreadLocalAccessor<Object> {
81101

@@ -95,6 +115,22 @@ public void setValue(Object value) {
95115
}
96116

97117
@Override
118+
public void setValue() {
119+
SecurityContextHolder.clearContext();
120+
}
121+
122+
@Override
123+
public void restore(Object previousValue) {
124+
SecurityContextHolder.setContext((SecurityContext) previousValue);
125+
}
126+
127+
@Override
128+
public void restore() {
129+
SecurityContextHolder.clearContext();
130+
}
131+
132+
@Override
133+
@Deprecated
98134
public void reset() {
99135
SecurityContextHolder.clearContext();
100136
}
@@ -119,6 +155,19 @@ public void setValue(Object value) {
119155
}
120156

121157
@Override
158+
public void setValue() {
159+
}
160+
161+
@Override
162+
public void restore(Object previousValue) {
163+
}
164+
165+
@Override
166+
public void restore() {
167+
}
168+
169+
@Override
170+
@Deprecated
122171
public void reset() {
123172
}
124173

spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionExceptionResolverAdapter.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import graphql.GraphQLError;
2424
import io.micrometer.context.ContextSnapshot;
25+
import io.micrometer.context.ContextSnapshotFactory;
2526
import io.micrometer.context.ThreadLocalAccessor;
2627
import org.apache.commons.logging.Log;
2728
import org.apache.commons.logging.LogFactory;
@@ -50,6 +51,8 @@ public abstract class SubscriptionExceptionResolverAdapter implements Subscripti
5051

5152
protected final Log logger = LogFactory.getLog(getClass());
5253

54+
protected final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();
55+
5356
private boolean threadLocalContextAware;
5457

5558

@@ -83,7 +86,7 @@ public boolean isThreadLocalContextAware() {
8386
public final Mono<List<GraphQLError>> resolveException(Throwable exception) {
8487
if (this.threadLocalContextAware) {
8588
return Mono.deferContextual(contextView -> {
86-
ContextSnapshot snapshot = ContextSnapshot.captureFrom(contextView);
89+
ContextSnapshot snapshot = snapshotFactory.captureFrom(contextView);
8790
try {
8891
List<GraphQLError> errors = snapshot.wrap(() -> resolveToMultipleErrors(exception)).call();
8992
return Mono.justOrEmpty(errors);

spring-graphql/src/main/java/org/springframework/graphql/server/DefaultWebGraphQlHandlerBuilder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.List;
2222

2323
import io.micrometer.context.ContextSnapshot;
24+
import io.micrometer.context.ContextSnapshotFactory;
2425
import reactor.core.publisher.Mono;
2526

2627
import org.springframework.graphql.ExecutionGraphQlService;
@@ -70,6 +71,8 @@ public WebGraphQlHandler.Builder interceptors(List<WebGraphQlInterceptor> interc
7071
@Override
7172
public WebGraphQlHandler build() {
7273

74+
ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();
75+
7376
Chain endOfChain = request -> this.service.execute(request).map(WebGraphQlResponse::new);
7477

7578
Chain executionChain = this.interceptors.stream()
@@ -87,7 +90,7 @@ public WebSocketGraphQlInterceptor getWebSocketInterceptor() {
8790

8891
@Override
8992
public Mono<WebGraphQlResponse> handleRequest(WebGraphQlRequest request) {
90-
ContextSnapshot snapshot = ContextSnapshot.captureAll();
93+
ContextSnapshot snapshot = snapshotFactory.captureAll();
9194
return executionChain.next(request).contextWrite(snapshot::updateContext);
9295
}
9396
};

0 commit comments

Comments
 (0)