From 7fc4df74a68d6525e5a4cde447310e94dad747f1 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Tue, 14 Mar 2023 08:17:02 +0000 Subject: [PATCH] Add request attributes to WebGraphQlRequest Closes gh-633 --- .../WebGraphQlHandlerGraphQlTransport.java | 12 ++++---- .../graphql/server/WebGraphQlRequest.java | 29 ++++++++++++++++--- .../server/WebSocketGraphQlRequest.java | 11 ++++--- .../server/webflux/GraphQlHttpHandler.java | 2 +- .../webflux/GraphQlWebSocketHandler.java | 2 +- .../server/webmvc/GraphQlHttpHandler.java | 2 +- .../webmvc/GraphQlWebSocketHandler.java | 4 +-- .../data/query/QuerydslDataFetcherTests.java | 2 +- .../QueryByExampleDataFetcherJpaTests.java | 2 +- ...QueryByExampleDataFetcherMongoDbTests.java | 2 +- ...xampleDataFetcherReactiveMongoDbTests.java | 2 +- ...PropagationWebGraphQlInterceptorTests.java | 3 +- .../server/WebGraphQlHandlerTests.java | 2 +- .../server/WebGraphQlInterceptorTests.java | 2 +- 14 files changed, 52 insertions(+), 25 deletions(-) diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlHandlerGraphQlTransport.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlHandlerGraphQlTransport.java index 373a02f3..5b9e14dc 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlHandlerGraphQlTransport.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlHandlerGraphQlTransport.java @@ -18,7 +18,7 @@ package org.springframework.graphql.test.tester; import java.net.URI; -import java.util.Map; +import java.util.Collections; import reactor.core.publisher.Mono; @@ -77,10 +77,12 @@ final class WebGraphQlHandlerGraphQlTransport extends AbstractDirectGraphQlTrans @Override protected Mono executeInternal(ExecutionGraphQlRequest executionRequest) { - String id = idGenerator.generateId().toString(); - Map body = executionRequest.toMap(); - WebGraphQlRequest webRequest = new WebGraphQlRequest(this.url, this.headers, null, body, id, null); - return this.graphQlHandler.handleRequest(webRequest).cast(ExecutionGraphQlResponse.class); + + WebGraphQlRequest request = new WebGraphQlRequest( + this.url, this.headers, null, Collections.emptyMap(), executionRequest.toMap(), + idGenerator.generateId().toString(), null); + + return this.graphQlHandler.handleRequest(request).cast(ExecutionGraphQlResponse.class); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/WebGraphQlRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/server/WebGraphQlRequest.java index d4966240..f8003562 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/WebGraphQlRequest.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/WebGraphQlRequest.java @@ -17,6 +17,7 @@ package org.springframework.graphql.server; import java.net.URI; +import java.util.Collections; import java.util.Locale; import java.util.Map; @@ -56,6 +57,8 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements private final MultiValueMap cookies; + private final Map attributes; + /** * Create an instance. @@ -63,14 +66,15 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements */ @Deprecated public WebGraphQlRequest(URI uri, HttpHeaders headers, Map body, String id, @Nullable Locale locale) { - this(uri, headers, null, body, id, locale); + this(uri, headers, null, Collections.emptyMap(), body, id, locale); } /** * Create an instance. * @param uri the URL for the HTTP request or WebSocket handshake * @param headers the HTTP request headers - * @param cookies the request cookies + * @param cookies the HTTP request cookies + * @param attributes request attributes * @param body the deserialized content of the GraphQL request * @param id an identifier for the GraphQL request * @param locale the locale from the HTTP request, if any @@ -78,7 +82,7 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements */ public WebGraphQlRequest( URI uri, HttpHeaders headers, @Nullable MultiValueMap cookies, - Map body, String id, @Nullable Locale locale) { + Map attributes, Map body, String id, @Nullable Locale locale) { super(getKey("query", body), getKey("operationName", body), getKey("variables", body), getKey("extensions", body), id, locale); @@ -88,7 +92,8 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements this.uri = UriComponentsBuilder.fromUri(uri).build(true); this.headers = headers; - this.cookies = (cookies != null ? cookies : EMPTY_COOKIES); + this.cookies = (cookies != null ? CollectionUtils.unmodifiableMultiValueMap(cookies) : EMPTY_COOKIES); + this.attributes = Collections.unmodifiableMap(attributes); } @SuppressWarnings("unchecked") @@ -114,4 +119,20 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements return this.headers; } + /** + * Return the cookies of the request of WebSocket handshake. + * @since 1.1.3 + */ + public MultiValueMap getCookies() { + return this.cookies; + } + + /** + * Return the request or WebSocket session attributes. + * @since 1.1.3 + */ + public Map getAttributes() { + return this.attributes; + } + } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketGraphQlRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketGraphQlRequest.java index bd4348f4..d3d1a388 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketGraphQlRequest.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketGraphQlRequest.java @@ -18,6 +18,7 @@ package org.springframework.graphql.server; import java.net.URI; +import java.util.Collections; import java.util.Locale; import java.util.Map; @@ -49,14 +50,15 @@ public class WebSocketGraphQlRequest extends WebGraphQlRequest { URI uri, HttpHeaders headers, Map body, String id, @Nullable Locale locale, WebSocketSessionInfo sessionInfo) { - this(uri, headers, null, body, id, locale, sessionInfo); + this(uri, headers, null, Collections.emptyMap(), body, id, locale, sessionInfo); } /** * Create an instance. * @param uri the URL for the HTTP request or WebSocket handshake * @param headers the HTTP request headers - * @param cookies the request cookies + * @param cookies the HTTP request cookies + * @param attributes session attributes * @param body the deserialized content of the GraphQL request * @param id the id from the GraphQL over WebSocket {@code "subscribe"} message * @param locale the locale from the HTTP request, if any @@ -65,9 +67,10 @@ public class WebSocketGraphQlRequest extends WebGraphQlRequest { */ public WebSocketGraphQlRequest( URI uri, HttpHeaders headers, @Nullable MultiValueMap cookies, - Map body, String id, @Nullable Locale locale, WebSocketSessionInfo sessionInfo) { + Map attributes, Map body, String id, @Nullable Locale locale, + WebSocketSessionInfo sessionInfo) { - super(uri, headers, cookies, body, id, locale); + super(uri, headers, cookies, attributes, body, id, locale); Assert.notNull(sessionInfo, "WebSocketSessionInfo is required"); this.sessionInfo = sessionInfo; } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlHttpHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlHttpHandler.java index 2828bb05..611efc1a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlHttpHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlHttpHandler.java @@ -75,7 +75,7 @@ public class GraphQlHttpHandler { .flatMap(body -> { WebGraphQlRequest graphQlRequest = new WebGraphQlRequest( serverRequest.uri(), serverRequest.headers().asHttpHeaders(), - serverRequest.cookies(), body, + serverRequest.cookies(), serverRequest.attributes(), body, serverRequest.exchange().getRequest().getId(), serverRequest.exchange().getLocaleContext().getLocale()); if (logger.isDebugEnabled()) { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandler.java index e1e90305..f6151fa7 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlWebSocketHandler.java @@ -149,7 +149,7 @@ public class GraphQlWebSocketHandler implements WebSocketHandler { } WebSocketGraphQlRequest request = new WebSocketGraphQlRequest( handshakeInfo.getUri(), handshakeInfo.getHeaders(), handshakeInfo.getCookies(), - payload, id, null, sessionInfo); + handshakeInfo.getAttributes(), payload, id, null, sessionInfo); if (logger.isDebugEnabled()) { logger.debug("Executing: " + request); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java index 3683c2b6..fb7c630d 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java @@ -90,7 +90,7 @@ public class GraphQlHttpHandler { WebGraphQlRequest graphQlRequest = new WebGraphQlRequest( serverRequest.uri(), serverRequest.headers().asHttpHeaders(), initCookies(serverRequest), - readBody(serverRequest), this.idGenerator.generateId().toString(), + serverRequest.attributes(), readBody(serverRequest), this.idGenerator.generateId().toString(), LocaleContextHolder.getLocale()); if (logger.isDebugEnabled()) { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandler.java index 92ca07ee..42b2eba3 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlWebSocketHandler.java @@ -203,8 +203,8 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub URI uri = session.getUri(); Assert.notNull(uri, "Expected handshake url"); HttpHeaders headers = session.getHandshakeHeaders(); - WebSocketGraphQlRequest request = - new WebSocketGraphQlRequest(uri, headers, null, payload, id, null, state.getSessionInfo()); + WebSocketGraphQlRequest request = new WebSocketGraphQlRequest( + uri, headers, null, session.getAttributes(), payload, id, null, state.getSessionInfo()); if (logger.isDebugEnabled()) { logger.debug("Executing: " + request); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/QuerydslDataFetcherTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/QuerydslDataFetcherTests.java index 15a0c52f..c000306e 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/QuerydslDataFetcherTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/QuerydslDataFetcherTests.java @@ -302,7 +302,7 @@ class QuerydslDataFetcherTests { private WebGraphQlRequest request(String query) { return new WebGraphQlRequest( - URI.create("/"), new HttpHeaders(), null, + URI.create("/"), new HttpHeaders(), null, Collections.emptyMap(), Collections.singletonMap("query", query), "1", Locale.ENGLISH); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/QueryByExampleDataFetcherJpaTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/QueryByExampleDataFetcherJpaTests.java index 116248b0..48f5b3c1 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/QueryByExampleDataFetcherJpaTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/QueryByExampleDataFetcherJpaTests.java @@ -188,7 +188,7 @@ class QueryByExampleDataFetcherJpaTests { private WebGraphQlRequest request(String query) { return new WebGraphQlRequest( - URI.create("/"), new HttpHeaders(), null, + URI.create("/"), new HttpHeaders(), null, Collections.emptyMap(), Collections.singletonMap("query", query), "1", null); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/QueryByExampleDataFetcherMongoDbTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/QueryByExampleDataFetcherMongoDbTests.java index 4c899318..2994ec75 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/QueryByExampleDataFetcherMongoDbTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/QueryByExampleDataFetcherMongoDbTests.java @@ -185,7 +185,7 @@ class QueryByExampleDataFetcherMongoDbTests { private WebGraphQlRequest request(String query) { return new WebGraphQlRequest( - URI.create("/"), new HttpHeaders(), null, + URI.create("/"), new HttpHeaders(), null, Collections.emptyMap(), Collections.singletonMap("query", query), "1", null); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/QueryByExampleDataFetcherReactiveMongoDbTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/QueryByExampleDataFetcherReactiveMongoDbTests.java index 7d6c9ca7..8ddba430 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/QueryByExampleDataFetcherReactiveMongoDbTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/QueryByExampleDataFetcherReactiveMongoDbTests.java @@ -157,7 +157,7 @@ class QueryByExampleDataFetcherReactiveMongoDbTests { private WebGraphQlRequest request(String query) { return new WebGraphQlRequest( - URI.create("/"), new HttpHeaders(), null, + URI.create("/"), new HttpHeaders(), null, Collections.emptyMap(), Collections.singletonMap("query", query), "1", null); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/observation/PropagationWebGraphQlInterceptorTests.java b/spring-graphql/src/test/java/org/springframework/graphql/observation/PropagationWebGraphQlInterceptorTests.java index 108de4f3..fafe47a2 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/observation/PropagationWebGraphQlInterceptorTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/observation/PropagationWebGraphQlInterceptorTests.java @@ -18,6 +18,7 @@ package org.springframework.graphql.observation; import java.net.URI; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -83,7 +84,7 @@ class PropagationWebGraphQlInterceptorTests { HttpHeaders httpHeaders = new HttpHeaders(); headers.forEach(httpHeaders::set); return new WebGraphQlRequest( - URI.create("https://example.org/graphql"), httpHeaders, null, + URI.create("https://example.org/graphql"), httpHeaders, null, Collections.emptyMap(), Map.of("query", "{ notUsed }"), "1", null); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/WebGraphQlHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/WebGraphQlHandlerTests.java index ec1f7047..ba2ceaa8 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/WebGraphQlHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/WebGraphQlHandlerTests.java @@ -42,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class WebGraphQlHandlerTests { private static final WebGraphQlRequest webInput = new WebGraphQlRequest( - URI.create("https://abc.org"), new HttpHeaders(), null, + URI.create("https://abc.org"), new HttpHeaders(), null, Collections.emptyMap(), Collections.singletonMap("query", "{ greeting }"), "1", null); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/WebGraphQlInterceptorTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/WebGraphQlInterceptorTests.java index 50cc1e33..19dcf9c8 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/WebGraphQlInterceptorTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/WebGraphQlInterceptorTests.java @@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class WebGraphQlInterceptorTests { private static final WebGraphQlRequest webRequest = new WebGraphQlRequest( - URI.create("http://abc.org"), new HttpHeaders(), null, + URI.create("http://abc.org"), new HttpHeaders(), null, Collections.emptyMap(), Collections.singletonMap("query", "{ notUsed }"), "1", null); @Test