Skip to content

Commit

Permalink
Remove Context Propagation deprecated API usage
Browse files Browse the repository at this point in the history
Prior to this commit, spring-projectsgh-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 spring-projectsgh-688
  • Loading branch information
bclozel committed Feb 14, 2024
1 parent 12dffaf commit 6985d7d
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -26,6 +26,7 @@

import graphql.GraphQLContext;
import io.micrometer.context.ContextSnapshot;
import io.micrometer.context.ContextSnapshotFactory;
import reactor.core.publisher.Mono;

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

private static final Object NO_VALUE = new Object();

private static final ContextSnapshotFactory SNAPSHOT_FACTORY = ContextSnapshotFactory.builder().build();


private final boolean hasCallableReturnValue;

Expand Down Expand Up @@ -122,13 +125,12 @@ private static Object invokeSuspendingFunction(Object bean, Method method, Objec
}

@Nullable
@SuppressWarnings("deprecation")
private Object handleReturnValue(GraphQLContext graphQLContext, @Nullable Object result) {
if (this.hasCallableReturnValue && result != null) {
return CompletableFuture.supplyAsync(
() -> {
try {
return ContextSnapshot.captureFrom(graphQLContext).wrap((Callable<?>) result).call();
return SNAPSHOT_FACTORY.captureFrom(graphQLContext).wrap((Callable<?>) result).call();
}
catch (Exception ex) {
throw new IllegalStateException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import graphql.util.TraversalControl;
import graphql.util.TraverserContext;
import io.micrometer.context.ContextSnapshot;
import io.micrometer.context.ContextSnapshotFactory;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
Expand All @@ -58,6 +59,8 @@ final class ContextDataFetcherDecorator implements DataFetcher<Object> {

private final SubscriptionExceptionResolver subscriptionExceptionResolver;

private final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();

private ContextDataFetcherDecorator(
DataFetcher<?> delegate, boolean subscription,
SubscriptionExceptionResolver subscriptionExceptionResolver) {
Expand All @@ -70,21 +73,15 @@ private ContextDataFetcherDecorator(
}

@Override
@SuppressWarnings("deprecation")
public Object get(DataFetchingEnvironment environment) throws Exception {

GraphQLContext context;
// temporarily merge global and local graphql context until https://github.com/micrometer-metrics/context-propagation/pull/98
ContextSnapshot snapshot;
if (environment.getLocalContext() instanceof GraphQLContext localContext) {
context = GraphQLContext.newContext()
.of(environment.getGraphQlContext())
.of(localContext)
.build();
snapshot = snapshotFactory.captureFrom(environment.getGraphQlContext(), localContext);
}
else {
context = environment.getGraphQlContext();
snapshot = snapshotFactory.captureFrom(environment.getGraphQlContext());
}
ContextSnapshot snapshot = ContextSnapshot.captureFrom(context);
Object value = snapshot.wrap(() -> this.delegate.get(environment)).call();

if (this.subscription) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,7 +21,7 @@

import graphql.GraphQLError;
import graphql.schema.DataFetchingEnvironment;
import io.micrometer.context.ContextSnapshot;
import io.micrometer.context.ContextSnapshotFactory;
import io.micrometer.context.ThreadLocalAccessor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand Down Expand Up @@ -52,6 +52,8 @@ public abstract class DataFetcherExceptionResolverAdapter implements DataFetcher

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

protected final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();

private boolean threadLocalContextAware;


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

@Nullable
@SuppressWarnings("deprecation")
private List<GraphQLError> resolveInternal(Throwable exception, DataFetchingEnvironment env) {
if (!this.threadLocalContextAware) {
return resolveToMultipleErrors(exception, env);
}
try {
return ContextSnapshot.captureFrom(env.getGraphQlContext())
return snapshotFactory.captureFrom(env.getGraphQlContext())
.wrap(() -> resolveToMultipleErrors(exception, env))
.call();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,6 +27,7 @@

import graphql.GraphQLContext;
import io.micrometer.context.ContextSnapshot;
import io.micrometer.context.ContextSnapshotFactory;
import org.dataloader.BatchLoaderContextProvider;
import org.dataloader.BatchLoaderEnvironment;
import org.dataloader.BatchLoaderWithContext;
Expand All @@ -52,13 +53,16 @@
*/
public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry {

private static final ContextSnapshotFactory SNAPSHOT_FACTORY = ContextSnapshotFactory.builder().build();

private final List<ReactorBatchLoader<?,?>> loaders = new ArrayList<>();

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

private final Supplier<DataLoaderOptions> defaultOptionsSupplier;



/**
* Default constructor.
*/
Expand Down Expand Up @@ -223,10 +227,9 @@ public DataLoaderOptions getOptions() {
}

@Override
@SuppressWarnings("deprecation")
public CompletionStage<List<V>> load(List<K> keys, BatchLoaderEnvironment environment) {
GraphQLContext graphQLContext = environment.getContext();
ContextSnapshot snapshot = ContextSnapshot.captureFrom(graphQLContext);
ContextSnapshot snapshot = SNAPSHOT_FACTORY.captureFrom(graphQLContext);
try {
return snapshot.wrap(() ->
this.loader.apply(keys, environment)
Expand Down Expand Up @@ -272,10 +275,9 @@ public DataLoaderOptions getOptions() {
}

@Override
@SuppressWarnings("deprecation")
public CompletionStage<Map<K, V>> load(Set<K> keys, BatchLoaderEnvironment environment) {
GraphQLContext graphQLContext = environment.getContext();
ContextSnapshot snapshot = ContextSnapshot.captureFrom(graphQLContext);
ContextSnapshot snapshot = SNAPSHOT_FACTORY.captureFrom(graphQLContext);
try {
return snapshot.wrap(() ->
this.loader.apply(keys, environment)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,7 +25,7 @@
import graphql.GraphQLContext;
import graphql.execution.ExecutionIdProvider;
import graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentationState;
import io.micrometer.context.ContextSnapshot;
import io.micrometer.context.ContextSnapshotFactory;
import org.dataloader.DataLoaderRegistry;
import reactor.core.publisher.Mono;

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

private final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();

private final GraphQlSource graphQlSource;

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


@Override
@SuppressWarnings("deprecation")
public final Mono<ExecutionGraphQlResponse> execute(ExecutionGraphQlRequest request) {
return Mono.deferContextual((contextView) -> {
if (!this.isDefaultExecutionIdProvider && request.getExecutionId() == null) {
request.configureExecutionInput(RESET_EXECUTION_ID_CONFIGURER);
}
ExecutionInput executionInput = request.toExecutionInput();
ContextSnapshot.captureFrom(contextView).updateContext(executionInput.getGraphQLContext());
snapshotFactory.captureFrom(contextView).updateContext(executionInput.getGraphQLContext());
ExecutionInput updatedExecutionInput = registerDataLoaders(executionInput);
return Mono.fromFuture(this.graphQlSource.graphQl().executeAsync(updatedExecutionInput))
.map(result -> new DefaultExecutionGraphQlResponse(updatedExecutionInput, result));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -29,6 +29,7 @@
import graphql.execution.ExecutionId;
import graphql.schema.DataFetchingEnvironment;
import io.micrometer.context.ContextSnapshot;
import io.micrometer.context.ContextSnapshotFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Flux;
Expand All @@ -47,6 +48,8 @@ class ExceptionResolversExceptionHandler implements DataFetcherExceptionHandler

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

private final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();

private final List<DataFetcherExceptionResolver> resolvers;

/**
Expand All @@ -60,11 +63,10 @@ class ExceptionResolversExceptionHandler implements DataFetcherExceptionHandler


@Override
@SuppressWarnings("deprecation")
public CompletableFuture<DataFetcherExceptionHandlerResult> handleException(DataFetcherExceptionHandlerParameters params) {
Throwable exception = unwrapException(params);
DataFetchingEnvironment env = params.getDataFetchingEnvironment();
ContextSnapshot snapshot = ContextSnapshot.captureFrom(env.getGraphQlContext());
ContextSnapshot snapshot = snapshotFactory.captureFrom(env.getGraphQlContext());
try {
return Flux.fromIterable(this.resolvers)
.flatMap(resolver -> resolver.resolveException(exception, env))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -72,13 +72,31 @@ private <V> void setValueInternal(Object value) {
}

@Override
@SuppressWarnings("deprecation")
public void setValue() {
this.delegate.setValue();
}

@Override
@Deprecated
public void reset() {
this.delegate.reset();
}


@SuppressWarnings("deprecation")
@Override
public void restore(Object previousValue) {
restoreInternal(previousValue);
}

@SuppressWarnings("unchecked")
public <V> void restoreInternal(Object previousValue) {
((ThreadLocalAccessor<V>) this.delegate).restore((V) previousValue);
}

@Override
public void restore() {
this.delegate.restore();
}

private static class DelegateAccessor implements ThreadLocalAccessor<Object> {

@Override
Expand All @@ -97,14 +115,29 @@ public void setValue(Object value) {
}

@Override
public void setValue() {
SecurityContextHolder.clearContext();
}

@Override
public void restore(Object previousValue) {
SecurityContextHolder.setContext((SecurityContext) previousValue);
}

@Override
public void restore() {
SecurityContextHolder.clearContext();
}

@Override
@Deprecated
public void reset() {
SecurityContextHolder.clearContext();
}

}


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

@Override
Expand All @@ -122,6 +155,19 @@ public void setValue(Object value) {
}

@Override
public void setValue() {
}

@Override
public void restore(Object previousValue) {
}

@Override
public void restore() {
}

@Override
@Deprecated
public void reset() {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,7 @@

import graphql.GraphQLError;
import io.micrometer.context.ContextSnapshot;
import io.micrometer.context.ContextSnapshotFactory;
import io.micrometer.context.ThreadLocalAccessor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand Down Expand Up @@ -50,6 +51,8 @@ public abstract class SubscriptionExceptionResolverAdapter implements Subscripti

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

protected final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build();

private boolean threadLocalContextAware;


Expand Down Expand Up @@ -78,12 +81,12 @@ public boolean isThreadLocalContextAware() {
}


@SuppressWarnings({"unused", "try", "deprecation"})
@SuppressWarnings({"unused", "try"})
@Override
public final Mono<List<GraphQLError>> resolveException(Throwable exception) {
if (this.threadLocalContextAware) {
return Mono.deferContextual(contextView -> {
ContextSnapshot snapshot = ContextSnapshot.captureFrom(contextView);
ContextSnapshot snapshot = snapshotFactory.captureFrom(contextView);
try {
List<GraphQLError> errors = snapshot.wrap(() -> resolveToMultipleErrors(exception)).call();
return Mono.justOrEmpty(errors);
Expand Down
Loading

0 comments on commit 6985d7d

Please sign in to comment.