Skip to content

Commit 98d39bc

Browse files
committed
Remove Context Propagation deprecated API usage
Prior to this commit, gh-676 fixed the local and global context inheritance in the `ContextDataFetcherDecorator` with a workaround. This commit undoes this workaround and uses the new Context Propagation API for this, effectively raising the requirement for version 1.0.3 and removing all deprecated APIs in the meantime. Closes gh-688
1 parent 610898c commit 98d39bc

10 files changed

+99
-42
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -26,6 +26,7 @@
2626

2727
import graphql.GraphQLContext;
2828
import io.micrometer.context.ContextSnapshot;
29+
import io.micrometer.context.ContextSnapshotFactory;
2930
import reactor.core.publisher.Mono;
3031

3132
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

@@ -122,13 +125,12 @@ private static Object invokeSuspendingFunction(Object bean, Method method, Objec
122125
}
123126

124127
@Nullable
125-
@SuppressWarnings("deprecation")
126128
private Object handleReturnValue(GraphQLContext graphQLContext, @Nullable Object result) {
127129
if (this.hasCallableReturnValue && result != null) {
128130
return CompletableFuture.supplyAsync(
129131
() -> {
130132
try {
131-
return ContextSnapshot.captureFrom(graphQLContext).wrap((Callable<?>) result).call();
133+
return SNAPSHOT_FACTORY.captureFrom(graphQLContext).wrap((Callable<?>) result).call();
132134
}
133135
catch (Exception ex) {
134136
throw new IllegalStateException(

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

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

5960
private final SubscriptionExceptionResolver subscriptionExceptionResolver;
6061

62+
private final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();
63+
6164
private ContextDataFetcherDecorator(
6265
DataFetcher<?> delegate, boolean subscription,
6366
SubscriptionExceptionResolver subscriptionExceptionResolver) {
@@ -70,21 +73,15 @@ private ContextDataFetcherDecorator(
7073
}
7174

7275
@Override
73-
@SuppressWarnings("deprecation")
7476
public Object get(DataFetchingEnvironment environment) throws Exception {
7577

76-
GraphQLContext context;
77-
// temporarily merge global and local graphql context until https://github.com/micrometer-metrics/context-propagation/pull/98
78+
ContextSnapshot snapshot;
7879
if (environment.getLocalContext() instanceof GraphQLContext localContext) {
79-
context = GraphQLContext.newContext()
80-
.of(environment.getGraphQlContext())
81-
.of(localContext)
82-
.build();
80+
snapshot = snapshotFactory.captureFrom(environment.getGraphQlContext(), localContext);
8381
}
8482
else {
85-
context = environment.getGraphQlContext();
83+
snapshot = snapshotFactory.captureFrom(environment.getGraphQlContext());
8684
}
87-
ContextSnapshot snapshot = ContextSnapshot.captureFrom(context);
8885
Object value = snapshot.wrap(() -> this.delegate.get(environment)).call();
8986

9087
if (this.subscription) {

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -21,7 +21,7 @@
2121

2222
import graphql.GraphQLError;
2323
import graphql.schema.DataFetchingEnvironment;
24-
import io.micrometer.context.ContextSnapshot;
24+
import io.micrometer.context.ContextSnapshotFactory;
2525
import io.micrometer.context.ThreadLocalAccessor;
2626
import org.apache.commons.logging.Log;
2727
import org.apache.commons.logging.LogFactory;
@@ -52,6 +52,8 @@ public abstract class DataFetcherExceptionResolverAdapter implements DataFetcher
5252

5353
protected final Log logger = LogFactory.getLog(getClass());
5454

55+
protected final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();
56+
5557
private boolean threadLocalContextAware;
5658

5759

@@ -93,13 +95,12 @@ public final Mono<List<GraphQLError>> resolveException(Throwable ex, DataFetchin
9395
}
9496

9597
@Nullable
96-
@SuppressWarnings("deprecation")
9798
private List<GraphQLError> resolveInternal(Throwable exception, DataFetchingEnvironment env) {
9899
if (!this.threadLocalContextAware) {
99100
return resolveToMultipleErrors(exception, env);
100101
}
101102
try {
102-
return ContextSnapshot.captureFrom(env.getGraphQlContext())
103+
return snapshotFactory.captureFrom(env.getGraphQlContext())
103104
.wrap(() -> resolveToMultipleErrors(exception, env))
104105
.call();
105106
}

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -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
*/
@@ -223,10 +227,9 @@ public DataLoaderOptions getOptions() {
223227
}
224228

225229
@Override
226-
@SuppressWarnings("deprecation")
227230
public CompletionStage<List<V>> load(List<K> keys, BatchLoaderEnvironment environment) {
228231
GraphQLContext graphQLContext = environment.getContext();
229-
ContextSnapshot snapshot = ContextSnapshot.captureFrom(graphQLContext);
232+
ContextSnapshot snapshot = SNAPSHOT_FACTORY.captureFrom(graphQLContext);
230233
try {
231234
return snapshot.wrap(() ->
232235
this.loader.apply(keys, environment)
@@ -272,10 +275,9 @@ public DataLoaderOptions getOptions() {
272275
}
273276

274277
@Override
275-
@SuppressWarnings("deprecation")
276278
public CompletionStage<Map<K, V>> load(Set<K> keys, BatchLoaderEnvironment environment) {
277279
GraphQLContext graphQLContext = environment.getContext();
278-
ContextSnapshot snapshot = ContextSnapshot.captureFrom(graphQLContext);
280+
ContextSnapshot snapshot = SNAPSHOT_FACTORY.captureFrom(graphQLContext);
279281
try {
280282
return snapshot.wrap(() ->
281283
this.loader.apply(keys, environment)

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -25,7 +25,7 @@
2525
import graphql.GraphQLContext;
2626
import graphql.execution.ExecutionIdProvider;
2727
import graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentationState;
28-
import io.micrometer.context.ContextSnapshot;
28+
import io.micrometer.context.ContextSnapshotFactory;
2929
import org.dataloader.DataLoaderRegistry;
3030
import reactor.core.publisher.Mono;
3131

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

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

5051
private final GraphQlSource graphQlSource;
5152

@@ -72,14 +73,13 @@ public void addDataLoaderRegistrar(DataLoaderRegistrar registrar) {
7273

7374

7475
@Override
75-
@SuppressWarnings("deprecation")
7676
public final Mono<ExecutionGraphQlResponse> execute(ExecutionGraphQlRequest request) {
7777
return Mono.deferContextual((contextView) -> {
7878
if (!this.isDefaultExecutionIdProvider && request.getExecutionId() == null) {
7979
request.configureExecutionInput(RESET_EXECUTION_ID_CONFIGURER);
8080
}
8181
ExecutionInput executionInput = request.toExecutionInput();
82-
ContextSnapshot.captureFrom(contextView).updateContext(executionInput.getGraphQLContext());
82+
snapshotFactory.captureFrom(contextView).updateContext(executionInput.getGraphQLContext());
8383
ExecutionInput updatedExecutionInput = registerDataLoaders(executionInput);
8484
return Mono.fromFuture(this.graphQlSource.graphQl().executeAsync(updatedExecutionInput))
8585
.map(result -> new DefaultExecutionGraphQlResponse(updatedExecutionInput, result));

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -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
/**
@@ -60,11 +63,10 @@ class ExceptionResolversExceptionHandler implements DataFetcherExceptionHandler
6063

6164

6265
@Override
63-
@SuppressWarnings("deprecation")
6466
public CompletableFuture<DataFetcherExceptionHandlerResult> handleException(DataFetcherExceptionHandlerParameters params) {
6567
Throwable exception = unwrapException(params);
6668
DataFetchingEnvironment env = params.getDataFetchingEnvironment();
67-
ContextSnapshot snapshot = ContextSnapshot.captureFrom(env.getGraphQlContext());
69+
ContextSnapshot snapshot = snapshotFactory.captureFrom(env.getGraphQlContext());
6870
try {
6971
return Flux.fromIterable(this.resolvers)
7072
.flatMap(resolver -> resolver.resolveException(exception, env))

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

Lines changed: 51 additions & 5 deletions
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-2024 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,13 +72,31 @@ private <V> void setValueInternal(Object value) {
7272
}
7373

7474
@Override
75-
@SuppressWarnings("deprecation")
75+
public void setValue() {
76+
this.delegate.setValue();
77+
}
78+
79+
@Override
80+
@Deprecated
7681
public void reset() {
7782
this.delegate.reset();
7883
}
7984

80-
81-
@SuppressWarnings("deprecation")
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+
}
99+
82100
private static class DelegateAccessor implements ThreadLocalAccessor<Object> {
83101

84102
@Override
@@ -97,14 +115,29 @@ public void setValue(Object value) {
97115
}
98116

99117
@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
100134
public void reset() {
101135
SecurityContextHolder.clearContext();
102136
}
103137

104138
}
105139

106140

107-
@SuppressWarnings("deprecation")
108141
private static class NoOpAccessor implements ThreadLocalAccessor<Object> {
109142

110143
@Override
@@ -122,6 +155,19 @@ public void setValue(Object value) {
122155
}
123156

124157
@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
125171
public void reset() {
126172
}
127173

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2022 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.
@@ -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

@@ -78,12 +81,12 @@ public boolean isThreadLocalContextAware() {
7881
}
7982

8083

81-
@SuppressWarnings({"unused", "try", "deprecation"})
84+
@SuppressWarnings({"unused", "try"})
8285
@Override
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);

0 commit comments

Comments
 (0)