Remove built-in ThreadLocalAccessor
The ThreadLocalAccessor in 1.0 was intended as a temporary solution that is now replaced by a similar contract in the `io.micrometer:context-propagation` library. Unfortunately, there is no way to adapt one to the other, but it is trivial to implement the new contract and register it either with `ContextRegistry#getInstance` on startup or through the `ServiceLoader` mechanism. See gh-459
This commit is contained in:
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.execution;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Default implementation of a composite accessor that is returned from
|
||||
* {@link ThreadLocalAccessor#composite(List)}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
class CompositeThreadLocalAccessor implements ThreadLocalAccessor {
|
||||
|
||||
private final List<ThreadLocalAccessor> accessors;
|
||||
|
||||
CompositeThreadLocalAccessor(List<ThreadLocalAccessor> accessors) {
|
||||
this.accessors = new ArrayList<>(accessors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extractValues(Map<String, Object> container) {
|
||||
this.accessors.forEach((accessor) -> accessor.extractValues(container));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreValues(Map<String, Object> values) {
|
||||
this.accessors.forEach((accessor) -> accessor.restoreValues(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetValues(Map<String, Object> values) {
|
||||
this.accessors.forEach((accessor) -> accessor.resetValues(values));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.graphql.execution;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.micrometer.context.ThreadLocalAccessor;
|
||||
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
@@ -33,9 +31,7 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SecurityContextThreadLocalAccessor implements ThreadLocalAccessor<Object>,
|
||||
org.springframework.graphql.execution.ThreadLocalAccessor {
|
||||
public class SecurityContextThreadLocalAccessor implements ThreadLocalAccessor<Object> {
|
||||
|
||||
private final static boolean springSecurityPresent = ClassUtils.isPresent(
|
||||
"org.springframework.security.core.context.SecurityContext",
|
||||
@@ -81,27 +77,6 @@ public class SecurityContextThreadLocalAccessor implements ThreadLocalAccessor<O
|
||||
}
|
||||
|
||||
|
||||
// Temporary implementation of deprecated ThreadLocalAccessor while it is still used
|
||||
// in the Boot starter. If registered as such, it is ignored.
|
||||
|
||||
@Override
|
||||
public void extractValues(Map<String, Object> container) {
|
||||
container.put((String) key(), SecurityContextHolder.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreValues(Map<String, Object> values) {
|
||||
if (values.containsKey((String) key())) {
|
||||
SecurityContextHolder.setContext((SecurityContext) values.get((String) key()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetValues(Map<String, Object> values) {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
|
||||
private static class DelegateAccessor implements ThreadLocalAccessor<Object> {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.execution;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
|
||||
/**
|
||||
* Interface to be implemented to assist with the extraction of ThreadLocal
|
||||
* values at the start of GraphQL request execution, e.g. in the web layer.
|
||||
* Those values are saved in {@link graphql.ExecutionInput} and restored later
|
||||
* around the invocation of data fetchers and exception resolvers which may be
|
||||
* in a different thread.
|
||||
*
|
||||
* <p>Implementations of this interface are typically declared as beans in
|
||||
* Spring configuration and are invoked in order as defined in
|
||||
* {@link ObjectProvider#orderedStream()}.
|
||||
*
|
||||
* <p>Currently supported for GraphQL requests over HTTP and WebSocket in
|
||||
* Spring MVC applications.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 1.0.0
|
||||
* @deprecated as of 1.1.0 in favor of using
|
||||
* {@link io.micrometer.context.ThreadLocalAccessor} from the
|
||||
* {@code "io.micrometer:context-propagation"} library.
|
||||
* @see org.springframework.graphql.server.WebGraphQlHandler.Builder#threadLocalAccessor(ThreadLocalAccessor...)
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ThreadLocalAccessor {
|
||||
|
||||
/**
|
||||
* Extract ThreadLocal values and add them to the given Map, so they can be
|
||||
* saved and subsequently {@link #restoreValues(Map) restored} around the
|
||||
* invocation of data fetchers and exception resolvers.
|
||||
* @param container to add extracted ThreadLocal values to
|
||||
*/
|
||||
void extractValues(Map<String, Object> container);
|
||||
|
||||
/**
|
||||
* Restore ThreadLocal context by looking up previously
|
||||
* {@link #extractValues(Map) extracted} values.
|
||||
* @param values previously extracted saved ThreadLocal values
|
||||
*/
|
||||
void restoreValues(Map<String, Object> values);
|
||||
|
||||
/**
|
||||
* Reset ThreadLocal context for the given, previously
|
||||
* {@link #extractValues(Map) extracted} and then
|
||||
* {@link #restoreValues(Map) restored} values.
|
||||
* @param values previously extracted saved ThreadLocal values
|
||||
*/
|
||||
void resetValues(Map<String, Object> values);
|
||||
|
||||
/**
|
||||
* Create a composite accessor that applies all of the given ThreadLocal accessors.
|
||||
* @param accessors the accessors to apply
|
||||
* @return the composite accessor
|
||||
*/
|
||||
static ThreadLocalAccessor composite(List<ThreadLocalAccessor> accessors) {
|
||||
return new CompositeThreadLocalAccessor(accessors);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,16 +21,12 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import io.micrometer.context.ContextSnapshot;
|
||||
|
||||
import org.springframework.graphql.execution.SecurityContextThreadLocalAccessor;
|
||||
import org.springframework.graphql.execution.ThreadLocalAccessor;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlService;
|
||||
import org.springframework.graphql.server.WebGraphQlInterceptor.Chain;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
|
||||
/**
|
||||
@@ -38,7 +34,6 @@ import org.springframework.util.CollectionUtils;
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
class DefaultWebGraphQlHandlerBuilder implements WebGraphQlHandler.Builder {
|
||||
|
||||
private final ExecutionGraphQlService service;
|
||||
@@ -48,9 +43,6 @@ class DefaultWebGraphQlHandlerBuilder implements WebGraphQlHandler.Builder {
|
||||
@Nullable
|
||||
private WebSocketGraphQlInterceptor webSocketInterceptor;
|
||||
|
||||
@Nullable
|
||||
private List<ThreadLocalAccessor> accessors;
|
||||
|
||||
|
||||
DefaultWebGraphQlHandlerBuilder(ExecutionGraphQlService service) {
|
||||
Assert.notNull(service, "GraphQlService is required");
|
||||
@@ -75,30 +67,6 @@ class DefaultWebGraphQlHandlerBuilder implements WebGraphQlHandler.Builder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public WebGraphQlHandler.Builder threadLocalAccessor(ThreadLocalAccessor... accessors) {
|
||||
return threadLocalAccessors(Arrays.asList(accessors));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public WebGraphQlHandler.Builder threadLocalAccessors(List<ThreadLocalAccessor> accessors) {
|
||||
|
||||
// Filter out SecurityContextThreadLocalAccessor which is registered as a ThreadLocalAccessor
|
||||
// from the micrometer-metrics/context-propagatation library. This code can be removed when
|
||||
// SecurityContextThreadLocalAccessor no longer implements the deprecated ThreadLocalAccessor.
|
||||
accessors = accessors.stream()
|
||||
.filter(a -> !(a instanceof SecurityContextThreadLocalAccessor))
|
||||
.toList();
|
||||
|
||||
if (!CollectionUtils.isEmpty(accessors)) {
|
||||
this.accessors = (this.accessors != null) ? this.accessors : new ArrayList<>();
|
||||
this.accessors.addAll(accessors);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebGraphQlHandler build() {
|
||||
|
||||
@@ -117,12 +85,6 @@ class DefaultWebGraphQlHandlerBuilder implements WebGraphQlHandler.Builder {
|
||||
webSocketInterceptor : new WebSocketGraphQlInterceptor() {});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ThreadLocalAccessor getThreadLocalAccessor() {
|
||||
return (CollectionUtils.isEmpty(accessors) ? null : ThreadLocalAccessor.composite(accessors));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<WebGraphQlResponse> handleRequest(WebGraphQlRequest request) {
|
||||
ContextSnapshot snapshot = ContextSnapshot.capture();
|
||||
|
||||
@@ -21,8 +21,6 @@ import java.util.List;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlService;
|
||||
import org.springframework.graphql.execution.ThreadLocalAccessor;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
|
||||
/**
|
||||
@@ -41,15 +39,6 @@ public interface WebGraphQlHandler {
|
||||
*/
|
||||
WebSocketGraphQlInterceptor getWebSocketInterceptor();
|
||||
|
||||
/**
|
||||
* Return the composite {@link ThreadLocalAccessor} that the handler is
|
||||
* configured with.
|
||||
* @deprecated as of 1.1.0, together with {@link ThreadLocalAccessor}.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
ThreadLocalAccessor getThreadLocalAccessor();
|
||||
|
||||
/**
|
||||
* Execute the given request and return the response.
|
||||
* @param request the request to execute
|
||||
@@ -97,28 +86,6 @@ public interface WebGraphQlHandler {
|
||||
*/
|
||||
Builder interceptors(List<WebGraphQlInterceptor> interceptors);
|
||||
|
||||
/**
|
||||
* Configure accessors for ThreadLocal variables to use to extract
|
||||
* ThreadLocal values at the start of GraphQL execution in the web layer,
|
||||
* and have those saved, and restored around the invocation of data
|
||||
* fetchers and exception resolvers.
|
||||
* @param accessors the accessors to add
|
||||
* @return this builder
|
||||
* @deprecated as of 1.1.0 together with {@link ThreadLocalAccessor}.
|
||||
*/
|
||||
@Deprecated
|
||||
Builder threadLocalAccessor(ThreadLocalAccessor... accessors);
|
||||
|
||||
/**
|
||||
* Alternative to {@link #threadLocalAccessor(ThreadLocalAccessor...)} with a
|
||||
* List.
|
||||
* @param accessors the list of accessors to add
|
||||
* @return this builder
|
||||
* @deprecated as of 1.1.0 together with {@link ThreadLocalAccessor}.
|
||||
*/
|
||||
@Deprecated
|
||||
Builder threadLocalAccessors(List<ThreadLocalAccessor> accessors);
|
||||
|
||||
/**
|
||||
* Build the {@link WebGraphQlHandler} instance.
|
||||
* @return the built WebGraphQlHandler
|
||||
|
||||
@@ -35,12 +35,10 @@ import org.springframework.graphql.execution.DefaultExecutionGraphQlService;
|
||||
import org.springframework.graphql.execution.GraphQlSource;
|
||||
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
|
||||
import org.springframework.graphql.execution.SubscriptionExceptionResolver;
|
||||
import org.springframework.graphql.execution.ThreadLocalAccessor;
|
||||
import org.springframework.graphql.server.WebGraphQlHandler;
|
||||
import org.springframework.graphql.server.WebGraphQlInterceptor;
|
||||
import org.springframework.graphql.server.WebGraphQlSetup;
|
||||
import org.springframework.graphql.server.webflux.GraphQlHttpHandler;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Workflow for GraphQL tests setup that starts with {@link GraphQlSource.Builder}
|
||||
@@ -58,8 +56,6 @@ public class GraphQlSetup implements GraphQlServiceSetup {
|
||||
|
||||
private final List<WebGraphQlInterceptor> interceptors = new ArrayList<>();
|
||||
|
||||
private final List<ThreadLocalAccessor> accessors = new ArrayList<>();
|
||||
|
||||
|
||||
private GraphQlSetup(Resource... schemaResources) {
|
||||
this.graphQlSourceBuilder = GraphQlSource.schemaResourceBuilder().schemaResources(schemaResources);
|
||||
@@ -147,19 +143,10 @@ public class GraphQlSetup implements GraphQlServiceSetup {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebGraphQlSetup threadLocalAccessor(@Nullable ThreadLocalAccessor accessor) {
|
||||
if (accessor != null) {
|
||||
this.accessors.add(accessor);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public WebGraphQlHandler toWebGraphQlHandler() {
|
||||
ExecutionGraphQlService service = toGraphQlService();
|
||||
return WebGraphQlHandler.builder(service)
|
||||
.interceptors(this.interceptors)
|
||||
.threadLocalAccessors(this.accessors)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package org.springframework.graphql.server;
|
||||
|
||||
import org.springframework.graphql.execution.ThreadLocalAccessor;
|
||||
import org.springframework.graphql.server.webflux.GraphQlHttpHandler;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Workflow that results in the creation of a {@link WebGraphQlHandler} or
|
||||
@@ -29,8 +27,6 @@ public interface WebGraphQlSetup {
|
||||
|
||||
WebGraphQlSetup interceptor(WebGraphQlInterceptor... interceptors);
|
||||
|
||||
WebGraphQlSetup threadLocalAccessor(@Nullable ThreadLocalAccessor accessor);
|
||||
|
||||
WebGraphQlHandler toWebGraphQlHandler();
|
||||
|
||||
org.springframework.graphql.server.webmvc.GraphQlHttpHandler toHttpHandler();
|
||||
|
||||
Reference in New Issue
Block a user