diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index cbedf431..c7338a65 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -18,16 +18,16 @@ ext { } dependencies { - checkstyle "io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}" + checkstyle("com.puppycrawl.tools:checkstyle:${checkstyle.toolVersion}") + checkstyle("io.spring.javaformat:spring-javaformat-checkstyle:${javaFormatVersion}") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}") implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${kotlinVersion}") implementation("io.spring.javaformat:spring-javaformat-gradle-plugin:${javaFormatVersion}") } checkstyle { - def archive = configurations.checkstyle.filter { it.name.startsWith("spring-javaformat-checkstyle")} - config = resources.text.fromArchiveEntry(archive, "io/spring/javaformat/checkstyle/checkstyle.xml") - toolVersion = 8.11 + toolVersion = "10.12.4" } gradlePlugin { diff --git a/buildSrc/gradle.properties b/buildSrc/gradle.properties index 9a7bd463..f9c62e7e 100644 --- a/buildSrc/gradle.properties +++ b/buildSrc/gradle.properties @@ -1 +1 @@ -javaFormatVersion=0.0.28 \ No newline at end of file +javaFormatVersion=0.0.41 \ No newline at end of file diff --git a/buildSrc/src/main/java/org/springframework/graphql/build/ConventionsPlugin.java b/buildSrc/src/main/java/org/springframework/graphql/build/ConventionsPlugin.java index 59da5043..28479254 100644 --- a/buildSrc/src/main/java/org/springframework/graphql/build/ConventionsPlugin.java +++ b/buildSrc/src/main/java/org/springframework/graphql/build/ConventionsPlugin.java @@ -23,6 +23,7 @@ import org.gradle.api.plugins.JavaBasePlugin; import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; import org.springframework.graphql.build.conventions.DeploymentConventions; +import org.springframework.graphql.build.conventions.FormattingConventions; import org.springframework.graphql.build.conventions.JavaConventions; import org.springframework.graphql.build.conventions.KotlinConventions; @@ -42,6 +43,7 @@ public class ConventionsPlugin implements Plugin { @Override public void apply(Project project) { + new FormattingConventions().apply(project); new JavaConventions().apply(project); new KotlinConventions().apply(project); new DeploymentConventions().apply(project); diff --git a/buildSrc/src/main/java/org/springframework/graphql/build/conventions/FormattingConventions.java b/buildSrc/src/main/java/org/springframework/graphql/build/conventions/FormattingConventions.java index 55471f46..30fb9b31 100644 --- a/buildSrc/src/main/java/org/springframework/graphql/build/conventions/FormattingConventions.java +++ b/buildSrc/src/main/java/org/springframework/graphql/build/conventions/FormattingConventions.java @@ -16,7 +16,6 @@ package org.springframework.graphql.build.conventions; -import io.spring.javaformat.gradle.FormatTask; import io.spring.javaformat.gradle.SpringJavaFormatPlugin; import org.gradle.api.Project; import org.gradle.api.artifacts.DependencySet; @@ -26,8 +25,7 @@ import org.gradle.api.plugins.quality.CheckstylePlugin; /** * Conventions that are applied in the presence of the {@link JavaBasePlugin}. When the - * plugin is applied, the {@link SpringJavaFormatPlugin Spring Java Format} and - * {@link CheckstylePlugin Checkstyle}. + * plugin is applied, {@link CheckstylePlugin Checkstyle} is applied and configured. * * @author Brian Clozel */ @@ -38,14 +36,14 @@ public class FormattingConventions { } private void applySpringJavaFormat(Project project) { - project.getPlugins().apply(SpringJavaFormatPlugin.class); - project.getTasks().withType(FormatTask.class, (formatTask) -> formatTask.setEncoding("UTF-8")); project.getPlugins().apply(CheckstylePlugin.class); CheckstyleExtension checkstyle = project.getExtensions().getByType(CheckstyleExtension.class); - checkstyle.setToolVersion("8.43"); + checkstyle.setToolVersion("10.12.4"); checkstyle.getConfigDirectory().set(project.getRootProject().file("src/checkstyle")); String version = SpringJavaFormatPlugin.class.getPackage().getImplementationVersion(); DependencySet checkstyleDependencies = project.getConfigurations().getByName("checkstyle").getDependencies(); + checkstyleDependencies + .add(project.getDependencies().create("com.puppycrawl.tools:checkstyle:" + checkstyle.getToolVersion())); checkstyleDependencies .add(project.getDependencies().create("io.spring.javaformat:spring-javaformat-checkstyle:" + version)); } diff --git a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graalvm/server/GraphQlConfiguration.java b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graalvm/server/GraphQlConfiguration.java index 7fe28e45..e5a46dce 100644 --- a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graalvm/server/GraphQlConfiguration.java +++ b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graalvm/server/GraphQlConfiguration.java @@ -31,8 +31,8 @@ public class GraphQlConfiguration { @Bean RuntimeWiringConfigurer customWiringConfigurer(BookRepository bookRepository) { // <1> DataFetcher dataFetcher = QuerydslDataFetcher.builder(bookRepository).single(); - return wiringBuilder -> wiringBuilder - .type("Query", builder -> builder.dataFetcher("book", dataFetcher)); // <2> + return (wiringBuilder) -> wiringBuilder + .type("Query", (builder) -> builder.dataFetcher("book", dataFetcher)); // <2> } } diff --git a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graphiql/configuration/GraphiQlConfiguration.java b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graphiql/configuration/GraphiQlConfiguration.java index 3ffb4e17..ce03e7e5 100644 --- a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graphiql/configuration/GraphiQlConfiguration.java +++ b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/graphiql/configuration/GraphiQlConfiguration.java @@ -28,13 +28,13 @@ import org.springframework.web.servlet.function.ServerResponse; @Configuration public class GraphiQlConfiguration { - @Bean - @Order(0) - public RouterFunction graphiQlRouterFunction() { - RouterFunctions.Builder builder = RouterFunctions.route(); - ClassPathResource graphiQlPage = new ClassPathResource("graphiql/index.html"); // <1> - GraphiQlHandler graphiQLHandler = new GraphiQlHandler("/graphql", "", graphiQlPage); // <2> - builder = builder.GET("/graphiql", graphiQLHandler::handleRequest); // <3> - return builder.build(); // <4> - } + @Bean + @Order(0) + public RouterFunction graphiQlRouterFunction() { + RouterFunctions.Builder builder = RouterFunctions.route(); + ClassPathResource graphiQlPage = new ClassPathResource("graphiql/index.html"); // <1> + GraphiQlHandler graphiQLHandler = new GraphiQlHandler("/graphql", "", graphiQlPage); // <2> + builder = builder.GET("/graphiql", graphiQLHandler::handleRequest); // <3> + return builder.build(); // <4> + } } diff --git a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/interception/web/RequestErrorInterceptor.java b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/interception/web/RequestErrorInterceptor.java index 07967ad2..6017da15 100644 --- a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/interception/web/RequestErrorInterceptor.java +++ b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/interception/web/RequestErrorInterceptor.java @@ -30,20 +30,20 @@ class RequestErrorInterceptor implements WebGraphQlInterceptor { @Override public Mono intercept(WebGraphQlRequest request, Chain chain) { - return chain.next(request).map(response -> { + return chain.next(request).map((response) -> { if (response.isValid()) { return response; // <1> } List errors = response.getErrors().stream() // <2> - .map(error -> { + .map((error) -> { GraphqlErrorBuilder builder = GraphqlErrorBuilder.newError(); // ... return builder.build(); }) .toList(); - return response.transform(builder -> builder.errors(errors).build()); // <3> + return response.transform((builder) -> builder.errors(errors).build()); // <3> }); } -} \ No newline at end of file +} diff --git a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/interception/web/ResponseHeaderInterceptor.java b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/interception/web/ResponseHeaderInterceptor.java index 0bd33c19..ab538387 100644 --- a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/interception/web/ResponseHeaderInterceptor.java +++ b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/interception/web/ResponseHeaderInterceptor.java @@ -33,7 +33,7 @@ class ResponseHeaderInterceptor implements WebGraphQlInterceptor { @Override public Mono intercept(WebGraphQlRequest request, Chain chain) { // <2> - return chain.next(request).doOnNext(response -> { + return chain.next(request).doOnNext((response) -> { String value = response.getExecutionInput().getGraphQLContext().get("cookieName"); ResponseCookie cookie = ResponseCookie.from("cookieName", value).build(); response.getResponseHeaders().add(HttpHeaders.SET_COOKIE, cookie.toString()); diff --git a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/transports/rsocket/GraphQlRSocketController.java b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/transports/rsocket/GraphQlRSocketController.java index 349da8c4..3801becf 100644 --- a/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/transports/rsocket/GraphQlRSocketController.java +++ b/spring-graphql-docs/src/main/java/org/springframework/graphql/docs/server/transports/rsocket/GraphQlRSocketController.java @@ -43,4 +43,4 @@ public class GraphQlRSocketController { public Flux> handleSubscription(Map payload) { return this.handler.handleSubscription(payload); } -} \ No newline at end of file +} diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/AbstractDirectGraphQlTransport.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/AbstractDirectGraphQlTransport.java index 359587f1..16f9d136 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/AbstractDirectGraphQlTransport.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/AbstractDirectGraphQlTransport.java @@ -41,7 +41,6 @@ import org.springframework.util.IdGenerator; * to a server-side GraphQL handler or service. * * @author Rossen Stoyanchev - * @since 1.0.0 */ abstract class AbstractDirectGraphQlTransport implements GraphQlTransport { @@ -56,7 +55,7 @@ abstract class AbstractDirectGraphQlTransport implements GraphQlTransport { @SuppressWarnings({"ConstantConditions", "unchecked"}) @Override public Flux executeSubscription(GraphQlRequest request) { - return executeInternal(toExecutionRequest(request)).flatMapMany(response -> { + return executeInternal(toExecutionRequest(request)).flatMapMany((response) -> { try { Object data = response.getData(); AssertionErrors.assertTrue("Not a Publisher: " + data, data instanceof Publisher); @@ -64,7 +63,7 @@ abstract class AbstractDirectGraphQlTransport implements GraphQlTransport { List errors = response.getErrors(); AssertionErrors.assertTrue("Subscription errors: " + errors, CollectionUtils.isEmpty(errors)); - return Flux.from((Publisher) data).map(executionResult -> + return Flux.from((Publisher) data).map((executionResult) -> new DefaultExecutionGraphQlResponse(response.getExecutionInput(), executionResult)); } catch (AssertionError ex) { diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/AbstractGraphQlTesterBuilder.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/AbstractGraphQlTesterBuilder.java index 287770ea..c79237e0 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/AbstractGraphQlTesterBuilder.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/AbstractGraphQlTesterBuilder.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.test.tester; import java.time.Duration; @@ -35,7 +36,6 @@ import org.springframework.graphql.ResponseError; import org.springframework.graphql.client.AbstractGraphQlClientBuilder; import org.springframework.graphql.client.GraphQlClient; import org.springframework.graphql.client.GraphQlTransport; -import org.springframework.graphql.support.CachingDocumentSource; import org.springframework.graphql.support.DocumentSource; import org.springframework.graphql.support.ResourceDocumentSource; import org.springframework.lang.Nullable; @@ -51,6 +51,7 @@ import org.springframework.util.ClassUtils; * agnostic {@code GraphQlTester}. A transport specific extension can then wrap * this default tester by extending {@link AbstractDelegatingGraphQlTester}. * + * @param the type of builder * @author Rossen Stoyanchev * @since 1.0.0 * @see AbstractDelegatingGraphQlTester @@ -86,7 +87,7 @@ public abstract class AbstractGraphQlTesterBuilder predicate) { - this.errorFilter = (this.errorFilter != null ? errorFilter.and(predicate) : predicate); + this.errorFilter = (this.errorFilter != null) ? this.errorFilter.and(predicate) : predicate; return self(); } @@ -115,6 +116,7 @@ public abstract class AbstractGraphQlTesterBuilder configurer) { this.jsonPathConfig = configurer.apply(this.jsonPathConfig); @@ -123,6 +125,7 @@ public abstract class AbstractGraphQlTesterBuilder> getBuilderInitializer() { - return builder -> { + return (builder) -> { if (this.errorFilter != null) { builder.errorFilter(this.errorFilter); } builder.documentSource(this.documentSource); - builder.configureJsonPathConfig(config -> this.jsonPathConfig); + builder.configureJsonPathConfig((config) -> this.jsonPathConfig); builder.responseTimeout(this.responseTimeout); }; } @@ -153,6 +156,7 @@ public abstract class AbstractGraphQlTesterBuilder defaultJsonProviderType; diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultExecutionGraphQlServiceTesterBuilder.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultExecutionGraphQlServiceTesterBuilder.java index c511687b..2f33956b 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultExecutionGraphQlServiceTesterBuilder.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultExecutionGraphQlServiceTesterBuilder.java @@ -37,7 +37,6 @@ import org.springframework.util.Assert; * wraps an {@code ExecutionGraphQlService}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultExecutionGraphQlServiceTesterBuilder extends AbstractGraphQlTesterBuilder @@ -95,7 +94,7 @@ final class DefaultExecutionGraphQlServiceTesterBuilder private void registerJsonPathMappingProvider() { if (this.encoder != null && this.decoder != null) { - configureJsonPathConfig(config -> { + configureJsonPathConfig((config) -> { EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider( Collections.singletonList(this.encoder), Collections.singletonList(this.decoder)); return config.mappingProvider(provider); @@ -111,7 +110,7 @@ final class DefaultExecutionGraphQlServiceTesterBuilder /** * Default {@link ExecutionGraphQlServiceTester} implementation. */ - private static class DefaultExecutionGraphQlServiceTester + private static final class DefaultExecutionGraphQlServiceTester extends AbstractDelegatingGraphQlTester implements ExecutionGraphQlServiceTester { private final GraphQlServiceGraphQlTransport transport; diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java index 882cd0a1..98d5bb8d 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java @@ -153,7 +153,7 @@ final class DefaultGraphQlTester implements GraphQlTester { @SuppressWarnings("ConstantConditions") @Override public Response execute() { - return transport.execute(request()).map(response -> mapResponse(response, request())).block(responseTimeout); + return DefaultGraphQlTester.this.transport.execute(request()).map((response) -> mapResponse(response, request())).block(DefaultGraphQlTester.this.responseTimeout); } @Override @@ -163,7 +163,7 @@ final class DefaultGraphQlTester implements GraphQlTester { @Override public Subscription executeSubscription() { - return () -> transport.executeSubscription(request()).map(result -> mapResponse(result, request())); + return () -> DefaultGraphQlTester.this.transport.executeSubscription(request()).map((result) -> mapResponse(result, request())); } private GraphQlRequest request() { @@ -171,7 +171,7 @@ final class DefaultGraphQlTester implements GraphQlTester { } private DefaultResponse mapResponse(GraphQlResponse response, GraphQlRequest request) { - return new DefaultResponse(response, errorFilter, assertDecorator(request), jsonPathConfig); + return new DefaultResponse(response, DefaultGraphQlTester.this.errorFilter, assertDecorator(request), DefaultGraphQlTester.this.jsonPathConfig); } private Consumer assertDecorator(GraphQlRequest request) { @@ -191,7 +191,7 @@ final class DefaultGraphQlTester implements GraphQlTester { /** * Container for GraphQL response data and errors along with convenience methods. */ - private final static class ResponseDelegate { + private static final class ResponseDelegate { private final DocumentContext jsonDoc; @@ -258,7 +258,7 @@ final class DefaultGraphQlTester implements GraphQlTester { } void consumeErrors(Consumer> consumer) { - filterErrors(error -> true); + filterErrors((error) -> true); consumer.accept(this.errors); } @@ -392,7 +392,7 @@ final class DefaultGraphQlTester implements GraphQlTester { this.delegate.doAssert(() -> { Object value = this.pathHelper.evaluateJsonPath(this.delegate.jsonContent()); AssertionErrors.assertNull( - "Expected null value at JSON path \"" + path + "\" but found " + value, value); + "Expected null value at JSON path \"" + this.path + "\" but found " + value, value); }); return this; } @@ -464,7 +464,7 @@ final class DefaultGraphQlTester implements GraphQlTester { } private static String joinPaths(@Nullable String basePath, String path) { - return (basePath != null ? basePath + "." + path : path); + return (basePath != null) ? basePath + "." + path : path; } @@ -476,7 +476,7 @@ final class DefaultGraphQlTester implements GraphQlTester { private final D entity; protected DefaultEntity(TypeRefAdapter typeAdapter) { - this.entity = delegate.read(jsonPath, typeAdapter); + this.entity = DefaultPath.this.delegate.read(DefaultPath.this.jsonPath, typeAdapter); } protected D getEntity() { @@ -484,57 +484,57 @@ final class DefaultGraphQlTester implements GraphQlTester { } protected void doAssert(Runnable task) { - delegate.doAssert(task); + DefaultPath.this.delegate.doAssert(task); } protected String getPath() { - return path; + return DefaultPath.this.path; } @Override public Path path(String path) { - return forPath(basePath, path, delegate); + return forPath(DefaultPath.this.basePath, path, DefaultPath.this.delegate); } @Override public Path path(String path, Consumer pathConsumer) { - return forNestedPath(basePath, path, delegate, pathConsumer); + return forNestedPath(DefaultPath.this.basePath, path, DefaultPath.this.delegate, pathConsumer); } @Override public T isEqualTo(Object expected) { - delegate.doAssert(() -> AssertionErrors.assertEquals(path, expected, this.entity)); + DefaultPath.this.delegate.doAssert(() -> AssertionErrors.assertEquals(DefaultPath.this.path, expected, this.entity)); return self(); } @Override public T isNotEqualTo(Object other) { - delegate.doAssert(() -> AssertionErrors.assertNotEquals(path, other, this.entity)); + DefaultPath.this.delegate.doAssert(() -> AssertionErrors.assertNotEquals(DefaultPath.this.path, other, this.entity)); return self(); } @Override public T isSameAs(Object expected) { - delegate.doAssert(() -> AssertionErrors.assertTrue(path, expected == this.entity)); + DefaultPath.this.delegate.doAssert(() -> AssertionErrors.assertTrue(DefaultPath.this.path, expected == this.entity)); return self(); } @Override public T isNotSameAs(Object other) { - delegate.doAssert(() -> AssertionErrors.assertTrue(path, other != this.entity)); + DefaultPath.this.delegate.doAssert(() -> AssertionErrors.assertTrue(DefaultPath.this.path, other != this.entity)); return self(); } @Override public T matches(Predicate predicate) { - delegate - .doAssert(() -> AssertionErrors.assertTrue(path, predicate.test(this.entity))); + DefaultPath.this.delegate + .doAssert(() -> AssertionErrors.assertTrue(DefaultPath.this.path, predicate.test(this.entity))); return self(); } @Override public T satisfies(Consumer consumer) { - delegate.doAssert(() -> consumer.accept(this.entity)); + DefaultPath.this.delegate.doAssert(() -> consumer.accept(this.entity)); return self(); } @@ -557,7 +557,7 @@ final class DefaultGraphQlTester implements GraphQlTester { private final class DefaultEntityList extends DefaultEntity, EntityList> implements EntityList { - public DefaultEntityList(TypeRefAdapter> typeAdapter) { + DefaultEntityList(TypeRefAdapter> typeAdapter) { super(typeAdapter); } diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultHttpGraphQlTesterBuilder.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultHttpGraphQlTesterBuilder.java index 88462f76..f3b1120c 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultHttpGraphQlTesterBuilder.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultHttpGraphQlTesterBuilder.java @@ -33,7 +33,6 @@ import org.springframework.web.util.UriComponentsBuilder; * {@link WebTestClient.Builder}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultHttpGraphQlTesterBuilder extends AbstractGraphQlTesterBuilder @@ -93,8 +92,8 @@ final class DefaultHttpGraphQlTesterBuilder } private void registerJsonPathMappingProvider() { - this.webTestClientBuilder.codecs(codecConfigurer -> - configureJsonPathConfig(config -> { + this.webTestClientBuilder.codecs((codecConfigurer) -> + configureJsonPathConfig((config) -> { EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(codecConfigurer); return config.mappingProvider(provider); })); @@ -105,7 +104,7 @@ final class DefaultHttpGraphQlTesterBuilder * Default {@link HttpGraphQlTester} that builds and uses a {@link WebTestClient} * for request execution. */ - private static class DefaultHttpGraphQlTester extends AbstractDelegatingGraphQlTester implements HttpGraphQlTester { + private static final class DefaultHttpGraphQlTester extends AbstractDelegatingGraphQlTester implements HttpGraphQlTester { private final WebTestClient webTestClient; diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultRSocketGraphQlTesterBuilder.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultRSocketGraphQlTesterBuilder.java index 878b2817..0c627c12 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultRSocketGraphQlTesterBuilder.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultRSocketGraphQlTesterBuilder.java @@ -113,9 +113,9 @@ public class DefaultRSocketGraphQlTesterBuilder } private void registerJsonPathMappingProvider() { - this.rsocketGraphQlClientBuilder.rsocketRequester(builder -> - builder.rsocketStrategies(strategiesBuilder -> - configureJsonPathConfig(config -> { + this.rsocketGraphQlClientBuilder.rsocketRequester((builder) -> + builder.rsocketStrategies((strategiesBuilder) -> + configureJsonPathConfig((config) -> { RSocketStrategies strategies = strategiesBuilder.build(); List> encoders = strategies.encoders(); List> decoders = strategies.decoders(); diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultTransportGraphQlTesterBuilder.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultTransportGraphQlTesterBuilder.java index 3b3bc457..9b0e02ba 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultTransportGraphQlTesterBuilder.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultTransportGraphQlTesterBuilder.java @@ -27,7 +27,6 @@ import org.springframework.util.Assert; * Default {@link GraphQlTester.Builder} with a given, externally prepared transport. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultTransportGraphQlTesterBuilder extends AbstractGraphQlTesterBuilder { @@ -50,7 +49,7 @@ final class DefaultTransportGraphQlTesterBuilder /** * {@link GraphQlTester} with a given transport. */ - private static class DefaultTransportGraphQlTester extends AbstractDelegatingGraphQlTester { + private static final class DefaultTransportGraphQlTester extends AbstractDelegatingGraphQlTester { private final GraphQlTransport transport; diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTesterBuilder.java similarity index 95% rename from spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTester.java rename to spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTesterBuilder.java index 7d4e8193..d54f9d5b 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTesterBuilder.java @@ -34,7 +34,6 @@ import org.springframework.web.util.DefaultUriBuilderFactory; * {@link WebGraphQlHandler} for request execution. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultWebGraphQlTesterBuilder extends AbstractGraphQlTesterBuilder @@ -104,7 +103,7 @@ final class DefaultWebGraphQlTesterBuilder } private void registerJsonPathMappingProvider() { - configureJsonPathConfig(jsonPathConfig -> { + configureJsonPathConfig((jsonPathConfig) -> { EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(this.codecConfigurer); return jsonPathConfig.mappingProvider(provider); }); @@ -114,7 +113,7 @@ final class DefaultWebGraphQlTesterBuilder /** * Default {@link WebGraphQlTester} implementation. */ - private static class DefaultWebGraphQlTester extends AbstractDelegatingGraphQlTester implements WebGraphQlTester { + private static final class DefaultWebGraphQlTester extends AbstractDelegatingGraphQlTester implements WebGraphQlTester { private final WebGraphQlHandlerGraphQlTransport transport; diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebSocketGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebSocketGraphQlTesterBuilder.java similarity index 94% rename from spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebSocketGraphQlTester.java rename to spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebSocketGraphQlTesterBuilder.java index dcc5467f..8a63390b 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebSocketGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebSocketGraphQlTesterBuilder.java @@ -34,7 +34,6 @@ import org.springframework.web.reactive.socket.client.WebSocketClient; * {@link WebSocketGraphQlClient.Builder}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultWebSocketGraphQlTesterBuilder extends AbstractGraphQlTesterBuilder @@ -108,8 +107,8 @@ final class DefaultWebSocketGraphQlTesterBuilder } private void registerJsonPathMappingProvider() { - this.graphQlClientBuilder.codecConfigurer(codecConfigurer -> { - configureJsonPathConfig(jsonPathConfig -> { + this.graphQlClientBuilder.codecConfigurer((codecConfigurer) -> { + configureJsonPathConfig((jsonPathConfig) -> { EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(codecConfigurer); return jsonPathConfig.mappingProvider(provider); }); @@ -120,7 +119,7 @@ final class DefaultWebSocketGraphQlTesterBuilder /** * Default {@link WebSocketGraphQlTester} implementation. */ - private static class DefaultWebSocketGraphQlTester extends AbstractDelegatingGraphQlTester implements WebSocketGraphQlTester { + private static final class DefaultWebSocketGraphQlTester extends AbstractDelegatingGraphQlTester implements WebSocketGraphQlTester { private final WebSocketGraphQlClient client; diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/EncoderDecoderMappingProvider.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/EncoderDecoderMappingProvider.java index 7458abc1..89103e01 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/EncoderDecoderMappingProvider.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/EncoderDecoderMappingProvider.java @@ -45,7 +45,6 @@ import org.springframework.util.MimeTypeUtils; * JSON Path {@link MappingProvider} that uses {@link Encoder} and {@link Decoder}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class EncoderDecoderMappingProvider implements MappingProvider { @@ -60,29 +59,29 @@ final class EncoderDecoderMappingProvider implements MappingProvider { /** * Create an instance with a {@link CodecConfigurer}. */ - public EncoderDecoderMappingProvider(CodecConfigurer configurer) { + EncoderDecoderMappingProvider(CodecConfigurer configurer) { this.encoder = findJsonEncoder(configurer); this.decoder = findJsonDecoder(configurer); } /** - * Create an instance with a List of encoders and decoders> + * Create an instance with a List of encoders and decoders. */ - public EncoderDecoderMappingProvider(List> encoders, List> decoders) { + EncoderDecoderMappingProvider(List> encoders, List> decoders) { this.encoder = findJsonEncoder(encoders); this.decoder = findJsonDecoder(decoders); } private static Encoder findJsonEncoder(CodecConfigurer configurer) { return findJsonEncoder(configurer.getWriters().stream() - .filter(writer -> writer instanceof EncoderHttpMessageWriter) - .map(writer -> ((EncoderHttpMessageWriter) writer).getEncoder())); + .filter((writer) -> writer instanceof EncoderHttpMessageWriter) + .map((writer) -> ((EncoderHttpMessageWriter) writer).getEncoder())); } private static Decoder findJsonDecoder(CodecConfigurer configurer) { return findJsonDecoder(configurer.getReaders().stream() - .filter(reader -> reader instanceof DecoderHttpMessageReader) - .map(reader -> ((DecoderHttpMessageReader) reader).getDecoder())); + .filter((reader) -> reader instanceof DecoderHttpMessageReader) + .map((reader) -> ((DecoderHttpMessageReader) reader).getDecoder())); } private static Encoder findJsonEncoder(List> encoders) { @@ -95,14 +94,14 @@ final class EncoderDecoderMappingProvider implements MappingProvider { private static Encoder findJsonEncoder(Stream> stream) { return stream - .filter(encoder -> encoder.canEncode(MAP_TYPE, MediaType.APPLICATION_JSON)) + .filter((encoder) -> encoder.canEncode(MAP_TYPE, MediaType.APPLICATION_JSON)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("No JSON Encoder")); } private static Decoder findJsonDecoder(Stream> decoderStream) { return decoderStream - .filter(decoder -> decoder.canDecode(MAP_TYPE, MediaType.APPLICATION_JSON)) + .filter((decoder) -> decoder.canDecode(MAP_TYPE, MediaType.APPLICATION_JSON)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("No JSON Decoder")); } diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/ExecutionGraphQlServiceTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/ExecutionGraphQlServiceTester.java index 1b530c9d..a864f330 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/ExecutionGraphQlServiceTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/ExecutionGraphQlServiceTester.java @@ -40,6 +40,7 @@ public interface ExecutionGraphQlServiceTester extends GraphQlTester { /** * Create a {@link ExecutionGraphQlServiceTester} instance. + * @param service the GraphQL service to use */ static ExecutionGraphQlServiceTester create(ExecutionGraphQlService service) { return builder(service).build(); @@ -47,6 +48,7 @@ public interface ExecutionGraphQlServiceTester extends GraphQlTester { /** * Return a builder for {@link ExecutionGraphQlServiceTester}. + * @param service the GraphQL service to use */ static ExecutionGraphQlServiceTester.Builder builder(ExecutionGraphQlService service) { return new DefaultExecutionGraphQlServiceTesterBuilder(service); @@ -55,12 +57,14 @@ public interface ExecutionGraphQlServiceTester extends GraphQlTester { /** * Default {@link ExecutionGraphQlServiceTester.Builder} implementation. + * @param the type of builder */ interface Builder> extends GraphQlTester.Builder { /** * Provide a {@code BiFunction} to help initialize the * {@link ExecutionInput} with. + * @param configurer the function that initializes the execution input * @since 1.1.2 * @see org.springframework.graphql.ExecutionGraphQlRequest#configureExecutionInput(BiFunction) */ @@ -69,12 +73,14 @@ public interface ExecutionGraphQlServiceTester extends GraphQlTester { /** * Configure the JSON encoder to use for mapping response data to * higher level objects. + * @param encoder the JSON encoder to use */ B encoder(Encoder encoder); /** * Configure the JSON decoder to use for mapping response data to * higher level objects. + * @param decoder the JSON decoder to use */ B decoder(Decoder decoder); diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlServiceGraphQlTransport.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlServiceGraphQlTransport.java index 5370e482..4f7915d0 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlServiceGraphQlTransport.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlServiceGraphQlTransport.java @@ -34,7 +34,6 @@ import org.springframework.util.Assert; * {@code GraphQlTransport} that calls directly a {@link ExecutionGraphQlService}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class GraphQlServiceGraphQlTransport extends AbstractDirectGraphQlTransport { @@ -53,11 +52,11 @@ final class GraphQlServiceGraphQlTransport extends AbstractDirectGraphQlTranspor } - public ExecutionGraphQlService getGraphQlService() { + ExecutionGraphQlService getGraphQlService() { return this.graphQlService; } - public List> getExecutionInputConfigurers() { + List> getExecutionInputConfigurers() { return this.executionInputConfigurers; } diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java index 124b55f6..4c09da83 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java @@ -66,6 +66,7 @@ public interface GraphQlTester { * Variant of {@link #document(String)} that uses the given key to resolve * the GraphQL document from a file with the help of the configured * {@link Builder#documentSource(DocumentSource) DocumentSource}. + * @param documentName the name of the document to send * @return spec for response assertions * @throws IllegalArgumentException if the documentName cannot be resolved * @throws AssertionError if the response status is not 200 (OK) @@ -94,6 +95,7 @@ public interface GraphQlTester { /** * A builder to create a {@link GraphQlTester} instance. + * @param the type of builder */ interface Builder> { @@ -111,6 +113,7 @@ public interface GraphQlTester { *

By default, this is set to {@link ResourceDocumentSource} with * classpath location {@code "graphql-test/"} and * {@link ResourceDocumentSource#FILE_EXTENSIONS} as extensions. + * @param contentLoader the document content loader */ B documentSource(DocumentSource contentLoader); @@ -130,6 +133,7 @@ public interface GraphQlTester { /** * Declare options to gather input for a GraphQL request and execute it. + * @param the type of request */ interface Request> { @@ -311,7 +315,7 @@ public interface GraphQlTester { } /** - * Contains a decoded entity and provides options to assert it + * Contains a decoded entity and provides options to assert it. * * @param the entity type * @param the {@code Entity} spec type @@ -320,6 +324,7 @@ public interface GraphQlTester { /** * Verify the decoded entity is equal to the given value. + * @param the {@code Entity} spec type * @param expected the expected value * @return the {@code Entity} spec for further assertions */ @@ -327,6 +332,7 @@ public interface GraphQlTester { /** * Verify the decoded entity is not equal to the given value. + * @param the {@code Entity} spec type * @param other the value to check against * @return the {@code Entity} spec for further assertions */ @@ -334,6 +340,7 @@ public interface GraphQlTester { /** * Verify the decoded entity is the same instance as the given value. + * @param the {@code Entity} spec type * @param expected the expected value * @return the {@code Entity} spec for further assertions */ @@ -341,6 +348,7 @@ public interface GraphQlTester { /** * Verify the decoded entity is not the same instance as the given value. + * @param the {@code Entity} spec type * @param other the value to check against * @return the {@code Entity} spec for further assertions */ @@ -348,6 +356,7 @@ public interface GraphQlTester { /** * Verify the decoded entity matches the given predicate. + * @param the {@code Entity} spec type * @param predicate the predicate to apply * @return the {@code Entity} spec for further assertions */ @@ -355,6 +364,7 @@ public interface GraphQlTester { /** * Verify the entity with the given {@link Consumer}. + * @param the {@code Entity} spec type * @param consumer the consumer to apply * @return the {@code Entity} spec for further assertions */ diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/HttpGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/HttpGraphQlTester.java index ae9a8b92..b50a674d 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/HttpGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/HttpGraphQlTester.java @@ -37,6 +37,7 @@ public interface HttpGraphQlTester extends WebGraphQlTester { /** * Create an {@link HttpGraphQlTester} that uses the given {@link WebTestClient}. + * @param webTestClient the {@code WebTestClient} to use */ static HttpGraphQlTester create(WebTestClient webTestClient) { return builder(webTestClient.mutate()).build(); @@ -45,6 +46,7 @@ public interface HttpGraphQlTester extends WebGraphQlTester { /** * Return a builder to initialize an {@link HttpGraphQlTester} by creating * the underlying {@link WebTestClient} through the given builder. + * @param webTestClientBuilder the {@code WebTestClient} builder to use */ static HttpGraphQlTester.Builder builder(WebTestClient.Builder webTestClientBuilder) { return new DefaultHttpGraphQlTesterBuilder(webTestClientBuilder); @@ -53,6 +55,7 @@ public interface HttpGraphQlTester extends WebGraphQlTester { /** * Builder for the GraphQL over HTTP tester. + * @param the type of builder */ interface Builder> extends WebGraphQlTester.Builder { @@ -60,6 +63,7 @@ public interface HttpGraphQlTester extends WebGraphQlTester { * Customize the {@code WebTestClient} to use. *

Note that some properties of {@code WebTestClient.Builder} like the * base URL, headers, and codecs can be customized through this builder. + * @param webClient a consumer that customizes the {@code WebClient} builder * @see #url(String) * @see #header(String, String...) * @see #codecConfigurer(Consumer) diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/RSocketGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/RSocketGraphQlTester.java index da6ceefa..ec2b89a7 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/RSocketGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/RSocketGraphQlTester.java @@ -64,6 +64,7 @@ public interface RSocketGraphQlTester extends GraphQlTester { /** * Start with a given {@link #builder()}. + * @param requesterBuilder the builder to use as a baseline */ static RSocketGraphQlTester.Builder builder(RSocketRequester.Builder requesterBuilder) { return new DefaultRSocketGraphQlTesterBuilder(requesterBuilder); @@ -72,6 +73,7 @@ public interface RSocketGraphQlTester extends GraphQlTester { /** * Builder for a GraphQL over RSocket tester. + * @param the type of builder */ interface Builder> extends GraphQlTester.Builder { @@ -119,11 +121,12 @@ public interface RSocketGraphQlTester extends GraphQlTester { *

Note that some properties of {@code RSocketRequester.Builder} like the * data MimeType, and the underlying RSocket transport can be customized * through this builder. + * @param requester a consumer that customizes the {@code RSocketRequester} through its builder + * @return the same builder instance * @see #dataMimeType(MimeType) * @see #tcp(String, int) * @see #webSocket(URI) * @see #clientTransport(ClientTransport) - * @return the same builder instance */ B rsocketRequester(Consumer requester); 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 06cc9749..b1e4bb18 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 @@ -35,7 +35,6 @@ import org.springframework.lang.Nullable; * {@code GraphQlTransport} that calls directly a {@link WebGraphQlHandler}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class WebGraphQlHandlerGraphQlTransport extends AbstractDirectGraphQlTransport { @@ -51,26 +50,26 @@ final class WebGraphQlHandlerGraphQlTransport extends AbstractDirectGraphQlTrans WebGraphQlHandlerGraphQlTransport( @Nullable URI url, HttpHeaders headers, WebGraphQlHandler handler, CodecConfigurer configurer) { - this.url = (url != null ? url : URI.create("")); + this.url = (url != null) ? url : URI.create(""); this.headers.addAll(headers); this.graphQlHandler = handler; this.codecConfigurer = configurer; } - public URI getUrl() { + URI getUrl() { return this.url; } - public HttpHeaders getHeaders() { + HttpHeaders getHeaders() { return this.headers; } - public WebGraphQlHandler getGraphQlHandler() { + WebGraphQlHandler getGraphQlHandler() { return this.graphQlHandler; } - public CodecConfigurer getCodecConfigurer() { + CodecConfigurer getCodecConfigurer() { return this.codecConfigurer; } diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlTester.java index 9c75221f..63dc0287 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlTester.java @@ -43,6 +43,7 @@ public interface WebGraphQlTester extends GraphQlTester { /** * Create a {@link WebGraphQlTester} instance. + * @param graphQlHandler the web GraphQL handler to be tested */ static WebGraphQlTester create(WebGraphQlHandler graphQlHandler) { return builder(graphQlHandler).build(); @@ -59,6 +60,7 @@ public interface WebGraphQlTester extends GraphQlTester { /** * Common builder for Web {@code GraphQlTester} extensions. + * @param the type of builder */ interface Builder> extends GraphQlTester.Builder { @@ -91,6 +93,7 @@ public interface WebGraphQlTester extends GraphQlTester { /** * Configure the underlying {@code CodecConfigurer} to use for all JSON * encoding and decoding needs. + * @param codecsConsumer a consumer that customizes the configured codecs */ B codecConfigurer(Consumer codecsConsumer); diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebSocketGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebSocketGraphQlTester.java index 93fdaaea..86eeed93 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebSocketGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebSocketGraphQlTester.java @@ -77,6 +77,7 @@ public interface WebSocketGraphQlTester extends WebGraphQlTester { /** * Builder for a GraphQL over WebSocket tester. + * @param the type of builder */ interface Builder> extends WebGraphQlTester.Builder { diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebTestClientTransport.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebTestClientTransport.java index 90469759..feef287a 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebTestClientTransport.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebTestClientTransport.java @@ -34,12 +34,11 @@ import org.springframework.util.Assert; * {@code GraphQlTransport} for GraphQL over HTTP via {@link WebTestClient}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class WebTestClientTransport implements GraphQlTransport { private static final ParameterizedTypeReference> MAP_TYPE = - new ParameterizedTypeReference>() {}; + new ParameterizedTypeReference>() { }; private final WebTestClient webTestClient; @@ -65,7 +64,7 @@ final class WebTestClientTransport implements GraphQlTransport { .returnResult() .getResponseBody(); - responseMap = (responseMap != null ? responseMap : Collections.emptyMap()); + responseMap = (responseMap != null) ? responseMap : Collections.emptyMap(); GraphQlResponse response = GraphQlTransport.createResponse(responseMap); return Mono.just(response); } diff --git a/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/GraphQlTesterTests.java b/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/GraphQlTesterTests.java index 20ec2061..3fc7fb76 100644 --- a/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/GraphQlTesterTests.java +++ b/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/GraphQlTesterTests.java @@ -139,7 +139,7 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport { assertThat(actual.getName()).isEqualTo("Luke Skywalker"); response.path("") - .entity(new ParameterizedTypeReference>() {}) + .entity(new ParameterizedTypeReference>() { }) .isEqualTo(Collections.singletonMap("me", luke)); assertThat(getActualRequestDocument()).contains(document); @@ -186,7 +186,7 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport { "Request: document='{me {name, friends}}'"); response.path("me.friends") - .entityList(new ParameterizedTypeReference() {}) + .entityList(new ParameterizedTypeReference() { }) .containsExactly(han, leia); assertThat(getActualRequestDocument()).contains(document); diff --git a/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/RSocketGraphQlTesterBuilderTests.java b/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/RSocketGraphQlTesterBuilderTests.java index 53d61550..48ae5d36 100644 --- a/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/RSocketGraphQlTesterBuilderTests.java +++ b/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/RSocketGraphQlTesterBuilderTests.java @@ -117,7 +117,7 @@ public class RSocketGraphQlTesterBuilderTests { assertThat(testDecoder.getLastValue()).isEqualTo(character); } - + private static class BuilderSetup { private final MockExecutionGraphQlService graphQlService = new MockExecutionGraphQlService(); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/GraphQlRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/GraphQlRequest.java index 84062e67..0e979209 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/GraphQlRequest.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/GraphQlRequest.java @@ -61,7 +61,7 @@ public interface GraphQlRequest { /** * Convert the request to a {@link Map} as defined in * GraphQL over HTTP and - * GraphQL over WebSocket: + * GraphQL over WebSocket. * * * diff --git a/spring-graphql/src/main/java/org/springframework/graphql/ResponseError.java b/spring-graphql/src/main/java/org/springframework/graphql/ResponseError.java index b30898ff..10297819 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/ResponseError.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/ResponseError.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-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. + * 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; import java.util.List; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/AbstractGraphQlClientBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/client/AbstractGraphQlClientBuilder.java index a5d1a1fd..9f414dea 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/AbstractGraphQlClientBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/AbstractGraphQlClientBuilder.java @@ -47,6 +47,7 @@ import org.springframework.util.ClassUtils; * agnostic {@code GraphQlClient}. A transport specific extension can then wrap * this default tester by extending {@link AbstractDelegatingGraphQlClient}. * + * @param the type of builder * @author Rossen Stoyanchev * @since 1.0.0 * @see AbstractDelegatingGraphQlClient @@ -123,6 +124,8 @@ public abstract class AbstractGraphQlClientBuilder encoder, Decoder decoder) { this.jsonEncoder = encoder; @@ -131,6 +134,7 @@ public abstract class AbstractGraphQlClientBuilder encoder) { this.jsonEncoder = encoder; @@ -146,6 +150,7 @@ public abstract class AbstractGraphQlClientBuilder decoder) { this.jsonDecoder = decoder; @@ -170,12 +175,13 @@ public abstract class AbstractGraphQlClientBuilder> getBuilderInitializer() { - return builder -> { - builder.interceptors(interceptorList -> interceptorList.addAll(interceptors)); - builder.documentSource(documentSource); + return (builder) -> { + builder.interceptors((interceptorList) -> interceptorList.addAll(this.interceptors)); + builder.documentSource(this.documentSource); builder.setJsonCodecs(getEncoder(), getDecoder()); }; } private Chain createExecuteChain(GraphQlTransport transport) { - Chain chain = request -> transport.execute(request) - .map(response -> new DefaultClientGraphQlResponse(request, response, getEncoder(), getDecoder())); + Chain chain = (request) -> transport.execute(request) + .map((response) -> new DefaultClientGraphQlResponse(request, response, getEncoder(), getDecoder())); return this.interceptors.stream() .reduce(GraphQlClientInterceptor::andThen) - .map(i -> (Chain) (request) -> i.intercept(request, chain)) + .map((i) -> (Chain) (request) -> i.intercept(request, chain)) .orElse(chain); } private SubscriptionChain createSubscriptionChain(GraphQlTransport transport) { - SubscriptionChain chain = request -> transport + SubscriptionChain chain = (request) -> transport .executeSubscription(request) - .map(response -> new DefaultClientGraphQlResponse(request, response, getEncoder(), getDecoder())); + .map((response) -> new DefaultClientGraphQlResponse(request, response, getEncoder(), getDecoder())); return this.interceptors.stream() .reduce(GraphQlClientInterceptor::andThen) - .map(i -> (SubscriptionChain) (request) -> i.interceptSubscription(request, chain)) + .map((i) -> (SubscriptionChain) (request) -> i.interceptSubscription(request, chain)) .orElse(chain); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/AbstractGraphQlClientSyncBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/client/AbstractGraphQlClientSyncBuilder.java index 5b7b85a9..42d74609 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/AbstractGraphQlClientSyncBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/AbstractGraphQlClientSyncBuilder.java @@ -49,6 +49,7 @@ import org.springframework.util.ClassUtils; * agnostic {@code GraphQlClient}. A transport specific extension can then wrap * this default tester by extending {@link AbstractDelegatingGraphQlClient}. * + * @param the type of builder * @author Rossen Stoyanchev * @since 1.3 * @see AbstractDelegatingGraphQlClient @@ -131,6 +132,7 @@ public abstract class AbstractGraphQlClientSyncBuilder converter) { this.jsonConverter = converter; @@ -140,12 +142,13 @@ public abstract class AbstractGraphQlClientSyncBuilder> getBuilderInitializer() { - return builder -> { - builder.interceptors(interceptorList -> interceptorList.addAll(interceptors)); - builder.documentSource(documentSource); + return (builder) -> { + builder.interceptors((interceptorList) -> interceptorList.addAll(this.interceptors)); + builder.documentSource(this.documentSource); builder.setJsonConverter(getJsonConverter()); }; } @@ -168,14 +171,14 @@ public abstract class AbstractGraphQlClientSyncBuilder encoder = HttpMessageConverterDelegate.asEncoder(getJsonConverter()); Decoder decoder = HttpMessageConverterDelegate.asDecoder(getJsonConverter()); - Chain chain = request -> { + Chain chain = (request) -> { GraphQlResponse response = transport.execute(request); return new DefaultClientGraphQlResponse(request, response, encoder, decoder); }; return this.interceptors.stream() .reduce(SyncGraphQlClientInterceptor::andThen) - .map(i -> (Chain) (request) -> i.intercept(request, chain)) + .map((i) -> (Chain) (request) -> i.intercept(request, chain)) .orElse(chain); } @@ -185,7 +188,7 @@ public abstract class AbstractGraphQlClientSyncBuilder initialize() { return new MappingJackson2HttpMessageConverter(); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/ClientGraphQlResponse.java b/spring-graphql/src/main/java/org/springframework/graphql/client/ClientGraphQlResponse.java index a43c29c2..0824975b 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/ClientGraphQlResponse.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/ClientGraphQlResponse.java @@ -32,10 +32,12 @@ public interface ClientGraphQlResponse extends GraphQlResponse { /** * {@inheritDoc} */ + @Override ClientResponseField field(String path); /** * Decode the full response map to the given target type. + * @param the target type * @param type the target class * @return the decoded value, or never {@code null} * @throws FieldAccessException if the response is not {@link #isValid() valid} @@ -44,7 +46,8 @@ public interface ClientGraphQlResponse extends GraphQlResponse { /** * Variant of {@link #toEntity(Class)} with a {@link ParameterizedTypeReference}. - * @param type the target type + * @param the target type + * @param type the target parameterized type * @return the decoded value, or never {@code null} * @throws FieldAccessException if the response is not {@link #isValid() valid} */ diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/ClientResponseField.java b/spring-graphql/src/main/java/org/springframework/graphql/client/ClientResponseField.java index 8d7ef9a9..66b5146d 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/ClientResponseField.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/ClientResponseField.java @@ -34,6 +34,7 @@ public interface ClientResponseField extends ResponseField { /** * Decode the field to an entity of the given type. + * @param the entity type * @param entityType the type to convert to * @return the decoded entity, or {@code null} if the field is {@code null} * but otherwise there are no errors @@ -46,12 +47,15 @@ public interface ClientResponseField extends ResponseField { /** * Variant of {@link #toEntity(Class)} with a {@link ParameterizedTypeReference}. + * @param the entity type + * @param entityType the type to convert to */ @Nullable D toEntity(ParameterizedTypeReference entityType); /** * Variant of {@link #toEntity(Class)} to decode to a list of entities. + * @param the entity type * @param elementType the type of elements in the list * @return the list of decoded entities, or an empty list if the field is * {@code null} but otherwise there are no errors @@ -61,15 +65,16 @@ public interface ClientResponseField extends ResponseField { */ List toEntityList(Class elementType); - /** - * Variant of {@link #toEntity(Class)} to decode to a list of entities. - * @param elementType the type of elements in the list - * @return the list of decoded entities, or an empty list if the field is - * {@code null} but otherwise there are no errors - * @throws FieldAccessException if the target field is {@code null} and the - * response is not {@link GraphQlResponse#isValid() valid} or the field has - * {@link ResponseField#getErrors() errors}. - */ + /** + * Variant of {@link #toEntity(Class)} to decode to a list of entities. + * @param the entity type + * @param elementType the type of elements in the list + * @return the list of decoded entities, or an empty list if the field is + * {@code null} but otherwise there are no errors + * @throws FieldAccessException if the target field is {@code null} and the + * response is not {@link GraphQlResponse#isValid() valid} or the field has + * {@link ResponseField#getErrors() errors}. + */ List toEntityList(ParameterizedTypeReference elementType); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/CodecDelegate.java b/spring-graphql/src/main/java/org/springframework/graphql/client/CodecDelegate.java index 6f433c78..841f1219 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/CodecDelegate.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/CodecDelegate.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.client; import java.util.List; @@ -37,7 +38,6 @@ import org.springframework.web.reactive.socket.WebSocketSession; * Helper class for encoding and decoding GraphQL messages. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class CodecDelegate { @@ -60,14 +60,14 @@ final class CodecDelegate { static Encoder findJsonEncoder(CodecConfigurer configurer) { return findJsonEncoder(configurer.getWriters().stream() - .filter(writer -> writer instanceof EncoderHttpMessageWriter) - .map(writer -> ((EncoderHttpMessageWriter) writer).getEncoder())); + .filter((writer) -> writer instanceof EncoderHttpMessageWriter) + .map((writer) -> ((EncoderHttpMessageWriter) writer).getEncoder())); } static Decoder findJsonDecoder(CodecConfigurer configurer) { return findJsonDecoder(configurer.getReaders().stream() - .filter(reader -> reader instanceof DecoderHttpMessageReader) - .map(reader -> ((DecoderHttpMessageReader) reader).getDecoder())); + .filter((reader) -> reader instanceof DecoderHttpMessageReader) + .map((reader) -> ((DecoderHttpMessageReader) reader).getDecoder())); } static Encoder findJsonEncoder(List> encoders) { @@ -80,26 +80,26 @@ final class CodecDelegate { private static Encoder findJsonEncoder(Stream> stream) { return stream - .filter(encoder -> encoder.canEncode(MESSAGE_TYPE, MediaType.APPLICATION_JSON)) + .filter((encoder) -> encoder.canEncode(MESSAGE_TYPE, MediaType.APPLICATION_JSON)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("No JSON Encoder")); } private static Decoder findJsonDecoder(Stream> decoderStream) { return decoderStream - .filter(decoder -> decoder.canDecode(MESSAGE_TYPE, MediaType.APPLICATION_JSON)) + .filter((decoder) -> decoder.canDecode(MESSAGE_TYPE, MediaType.APPLICATION_JSON)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("No JSON Decoder")); } - public CodecConfigurer getCodecConfigurer() { + CodecConfigurer getCodecConfigurer() { return this.codecConfigurer; } @SuppressWarnings("unchecked") - public WebSocketMessage encode(WebSocketSession session, GraphQlWebSocketMessage message) { + WebSocketMessage encode(WebSocketSession session, GraphQlWebSocketMessage message) { DataBuffer buffer = ((Encoder) this.encoder).encodeValue( (T) message, session.bufferFactory(), MESSAGE_TYPE, MimeTypeUtils.APPLICATION_JSON, null); @@ -108,7 +108,7 @@ final class CodecDelegate { } @SuppressWarnings("ConstantConditions") - public GraphQlWebSocketMessage decode(WebSocketMessage webSocketMessage) { + GraphQlWebSocketMessage decode(WebSocketMessage webSocketMessage) { DataBuffer buffer = DataBufferUtils.retain(webSocketMessage.getPayload()); return (GraphQlWebSocketMessage) this.decoder.decode(buffer, MESSAGE_TYPE, null, null); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlRequest.java index ad576e45..8f0e6c83 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlRequest.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlRequest.java @@ -27,7 +27,6 @@ import org.springframework.lang.Nullable; * Default implementation of {@link ClientGraphQlRequest}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultClientGraphQlRequest extends DefaultGraphQlRequest implements ClientGraphQlRequest { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlResponse.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlResponse.java index 18a5ad4c..90bb57cb 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlResponse.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientGraphQlResponse.java @@ -26,7 +26,6 @@ import org.springframework.graphql.GraphQlResponse; * Default implementation of {@link ClientGraphQlResponse}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultClientGraphQlResponse extends ResponseMapGraphQlResponse implements ClientGraphQlResponse { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientResponseField.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientResponseField.java index 8cd78707..870349a9 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientResponseField.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultClientResponseField.java @@ -40,7 +40,6 @@ import org.springframework.util.MimeTypeUtils; * support for decoding. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultClientResponseField implements ClientResponseField { @@ -88,13 +87,13 @@ final class DefaultClientResponseField implements ClientResponseField { @Override public List toEntityList(Class elementType) { List list = toEntity(ResolvableType.forClassWithGenerics(List.class, elementType)); - return (list != null ? list : Collections.emptyList()); + return (list != null) ? list : Collections.emptyList(); } @Override public List toEntityList(ParameterizedTypeReference elementType) { List list = toEntity(ResolvableType.forClassWithGenerics(List.class, ResolvableType.forType(elementType))); - return (list != null ? list : Collections.emptyList()); + return (list != null) ? list : Collections.emptyList(); } @SuppressWarnings("unchecked") diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultGraphQlClient.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultGraphQlClient.java index ac9a2d9f..489f323f 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultGraphQlClient.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultGraphQlClient.java @@ -36,7 +36,6 @@ import org.springframework.util.Assert; * Default, final {@link GraphQlClient} implementation for use with any transport. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultGraphQlClient implements GraphQlClient { @@ -63,7 +62,7 @@ final class DefaultGraphQlClient implements GraphQlClient { this.documentSource = documentSource; this.blockingChain = blockingChain; this.nonBlockingChain = adaptToNonBlockingChain(blockingChain, scheduler); - this.subscriptionChain = request -> Flux.error(new IllegalStateException("Subscriptions on supported")); + this.subscriptionChain = (request) -> Flux.error(new IllegalStateException("Subscriptions on supported")); this.blockingTimeout = blockingTimeout; } @@ -87,14 +86,14 @@ final class DefaultGraphQlClient implements GraphQlClient { private static GraphQlClientInterceptor.Chain adaptToNonBlockingChain( SyncGraphQlClientInterceptor.Chain blockingChain, Scheduler scheduler) { - return request -> Mono.fromCallable(() -> blockingChain.next(request)).subscribeOn(scheduler); + return (request) -> Mono.fromCallable(() -> blockingChain.next(request)).subscribeOn(scheduler); } @SuppressWarnings("DataFlowIssue") private static SyncGraphQlClientInterceptor.Chain adaptToBlockingChain( GraphQlClientInterceptor.Chain executeChain, @Nullable Duration blockingTimeout) { - return (request -> blockingTimeout != null ? + return ((request) -> (blockingTimeout != null) ? executeChain.next(request).block(blockingTimeout) : executeChain.next(request).block()); } @@ -203,28 +202,28 @@ final class DefaultGraphQlClient implements GraphQlClient { @Override public ClientGraphQlResponse executeSync() { Mono mono = initRequest(); - ClientGraphQlRequest request = (blockingTimeout != null ? mono.block(blockingTimeout) : mono.block()); - return blockingChain.next(request); + ClientGraphQlRequest request = (DefaultGraphQlClient.this.blockingTimeout != null) ? mono.block(DefaultGraphQlClient.this.blockingTimeout) : mono.block(); + return DefaultGraphQlClient.this.blockingChain.next(request); } @Override public Mono execute() { - return initRequest().flatMap(request -> nonBlockingChain.next(request) + return initRequest().flatMap((request) -> DefaultGraphQlClient.this.nonBlockingChain.next(request) .onErrorResume( - ex -> !(ex instanceof GraphQlClientException), - ex -> Mono.error(new GraphQlTransportException(ex, request)))); + (ex) -> !(ex instanceof GraphQlClientException), + (ex) -> Mono.error(new GraphQlTransportException(ex, request)))); } @Override public Flux executeSubscription() { - return initRequest().flatMapMany(request -> subscriptionChain.next(request) + return initRequest().flatMapMany((request) -> DefaultGraphQlClient.this.subscriptionChain.next(request) .onErrorResume( - ex -> !(ex instanceof GraphQlClientException), - ex -> Mono.error(new GraphQlTransportException(ex, request)))); + (ex) -> !(ex instanceof GraphQlClientException), + (ex) -> Mono.error(new GraphQlTransportException(ex, request)))); } private Mono initRequest() { - return this.documentMono.map(document -> new DefaultClientGraphQlRequest( + return this.documentMono.map((document) -> new DefaultClientGraphQlRequest( document, this.operationName, this.variables, this.extensions, this.attributes)); } @@ -252,7 +251,7 @@ final class DefaultGraphQlClient implements GraphQlClient { throw new FieldAccessException( ((DefaultClientGraphQlResponse) response).getRequest(), response, field); } - return (field.getValue() != null ? field : null); + return (field.getValue() != null) ? field : null; } } @@ -270,25 +269,25 @@ final class DefaultGraphQlClient implements GraphQlClient { @Override public D toEntity(Class entityType) { ClientResponseField field = getValidField(this.response); - return (field != null ? field.toEntity(entityType) : null); + return (field != null) ? field.toEntity(entityType) : null; } @Override public D toEntity(ParameterizedTypeReference entityType) { ClientResponseField field = getValidField(this.response); - return (field != null ? field.toEntity(entityType) : null); + return (field != null) ? field.toEntity(entityType) : null; } @Override public List toEntityList(Class elementType) { ClientResponseField field = getValidField(this.response); - return (field != null ? field.toEntityList(elementType) : Collections.emptyList()); + return (field != null) ? field.toEntityList(elementType) : Collections.emptyList(); } @Override public List toEntityList(ParameterizedTypeReference elementType) { ClientResponseField field = getValidField(this.response); - return (field != null ? field.toEntityList(elementType) : Collections.emptyList()); + return (field != null) ? field.toEntityList(elementType) : Collections.emptyList(); } } @@ -305,27 +304,27 @@ final class DefaultGraphQlClient implements GraphQlClient { @Override public Mono toEntity(Class entityType) { - return this.responseMono.mapNotNull(this::getValidField).mapNotNull(field -> field.toEntity(entityType)); + return this.responseMono.mapNotNull(this::getValidField).mapNotNull((field) -> field.toEntity(entityType)); } @Override public Mono toEntity(ParameterizedTypeReference entityType) { - return this.responseMono.mapNotNull(this::getValidField).mapNotNull(field -> field.toEntity(entityType)); + return this.responseMono.mapNotNull(this::getValidField).mapNotNull((field) -> field.toEntity(entityType)); } @Override public Mono> toEntityList(Class elementType) { - return this.responseMono.map(response -> { + return this.responseMono.map((response) -> { ClientResponseField field = getValidField(response); - return (field != null ? field.toEntityList(elementType) : Collections.emptyList()); + return (field != null) ? field.toEntityList(elementType) : Collections.emptyList(); }); } @Override public Mono> toEntityList(ParameterizedTypeReference elementType) { - return this.responseMono.map(response -> { + return this.responseMono.map((response) -> { ClientResponseField field = getValidField(response); - return (field != null ? field.toEntityList(elementType) : Collections.emptyList()); + return (field != null) ? field.toEntityList(elementType) : Collections.emptyList(); }); } @@ -343,27 +342,27 @@ final class DefaultGraphQlClient implements GraphQlClient { @Override public Flux toEntity(Class entityType) { - return this.responseFlux.mapNotNull(this::getValidField).mapNotNull(field -> field.toEntity(entityType)); + return this.responseFlux.mapNotNull(this::getValidField).mapNotNull((field) -> field.toEntity(entityType)); } @Override public Flux toEntity(ParameterizedTypeReference entityType) { - return this.responseFlux.mapNotNull(this::getValidField).mapNotNull(field -> field.toEntity(entityType)); + return this.responseFlux.mapNotNull(this::getValidField).mapNotNull((field) -> field.toEntity(entityType)); } @Override public Flux> toEntityList(Class elementType) { - return this.responseFlux.map(response -> { + return this.responseFlux.map((response) -> { ClientResponseField field = getValidField(response); - return (field != null ? field.toEntityList(elementType) : Collections.emptyList()); + return (field != null) ? field.toEntityList(elementType) : Collections.emptyList(); }); } @Override public Flux> toEntityList(ParameterizedTypeReference elementType) { - return this.responseFlux.map(response -> { + return this.responseFlux.map((response) -> { ClientResponseField field = getValidField(response); - return (field != null ? field.toEntityList(elementType) : Collections.emptyList()); + return (field != null) ? field.toEntityList(elementType) : Collections.emptyList(); }); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultHttpGraphQlClientBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultHttpGraphQlClientBuilder.java index f2e4f38d..7041fea4 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultHttpGraphQlClientBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultHttpGraphQlClientBuilder.java @@ -33,7 +33,6 @@ import org.springframework.web.util.UriComponentsBuilder; * around a {@link WebClient.Builder}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultHttpGraphQlClientBuilder extends AbstractGraphQlClientBuilder @@ -105,7 +104,7 @@ final class DefaultHttpGraphQlClientBuilder public HttpGraphQlClient build() { // Pass the codecs to the parent for response decoding - this.webClientBuilder.codecs(configurer -> + this.webClientBuilder.codecs((configurer) -> setJsonCodecs( CodecDelegate.findJsonEncoder(configurer), CodecDelegate.findJsonDecoder(configurer))); @@ -139,6 +138,7 @@ final class DefaultHttpGraphQlClientBuilder this.builderInitializer = builderInitializer; } + @Override public DefaultHttpGraphQlClientBuilder mutate() { DefaultHttpGraphQlClientBuilder builder = new DefaultHttpGraphQlClientBuilder(this.webClient); this.builderInitializer.accept(builder); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultRSocketGraphQlClientBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultRSocketGraphQlClientBuilder.java index 0dc645d4..68e6fe0a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultRSocketGraphQlClientBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultRSocketGraphQlClientBuilder.java @@ -41,7 +41,6 @@ import org.springframework.util.MimeTypeUtils; * a {@link RSocketRequester.Builder}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultRSocketGraphQlClientBuilder extends AbstractGraphQlClientBuilder @@ -134,9 +133,9 @@ final class DefaultRSocketGraphQlClientBuilder public RSocketGraphQlClient build() { // Pass the codecs to the parent for response decoding - this.requesterBuilder.rsocketStrategies(builder -> { - builder.decoders(decoders -> setJsonDecoder(CodecDelegate.findJsonDecoder(decoders))); - builder.encoders(encoders -> setJsonEncoder(CodecDelegate.findJsonEncoder(encoders))); + this.requesterBuilder.rsocketStrategies((builder) -> { + builder.decoders((decoders) -> setJsonDecoder(CodecDelegate.findJsonDecoder(decoders))); + builder.encoders((encoders) -> setJsonEncoder(CodecDelegate.findJsonEncoder(encoders))); }); RSocketRequester requester; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultSyncHttpGraphQlClientBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultSyncHttpGraphQlClientBuilder.java index df24f1b3..233ebd42 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultSyncHttpGraphQlClientBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultSyncHttpGraphQlClientBuilder.java @@ -34,7 +34,6 @@ import org.springframework.web.util.UriComponentsBuilder; * around a {@link RestClient.Builder}. * * @author Rossen Stoyanchev - * @since 1.3 */ final class DefaultSyncHttpGraphQlClientBuilder extends AbstractGraphQlClientSyncBuilder @@ -105,7 +104,7 @@ final class DefaultSyncHttpGraphQlClientBuilder @Override public HttpSyncGraphQlClient build() { - this.restClientBuilder.messageConverters(converters -> { + this.restClientBuilder.messageConverters((converters) -> { HttpMessageConverter converter = HttpMessageConverterDelegate.findJsonConverter(converters); setJsonConverter(converter); }); @@ -141,6 +140,7 @@ final class DefaultSyncHttpGraphQlClientBuilder this.builderInitializer = builderInitializer; } + @Override public DefaultSyncHttpGraphQlClientBuilder mutate() { DefaultSyncHttpGraphQlClientBuilder builder = new DefaultSyncHttpGraphQlClientBuilder(this.restClient); this.builderInitializer.accept(builder); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultTransportGraphQlClientBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultTransportGraphQlClientBuilder.java index 86d49925..29dc8113 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultTransportGraphQlClientBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultTransportGraphQlClientBuilder.java @@ -26,7 +26,6 @@ import org.springframework.util.Assert; * Default {@link GraphQlClient.Builder} with a given, externally, prepared transport. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultTransportGraphQlClientBuilder extends AbstractGraphQlClientBuilder { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultWebSocketGraphQlClientBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultWebSocketGraphQlClientBuilder.java index 90204385..7d303850 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultWebSocketGraphQlClientBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DefaultWebSocketGraphQlClientBuilder.java @@ -20,7 +20,6 @@ import java.net.URI; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; -import java.util.stream.Collectors; import reactor.core.publisher.Mono; @@ -37,7 +36,6 @@ import org.springframework.web.util.DefaultUriBuilderFactory; * {@code WebSocketGraphQlTransport}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class DefaultWebSocketGraphQlClientBuilder extends AbstractGraphQlClientBuilder @@ -130,14 +128,14 @@ final class DefaultWebSocketGraphQlClientBuilder private WebSocketGraphQlClientInterceptor getInterceptor() { List interceptors = getInterceptors().stream() - .filter(interceptor -> interceptor instanceof WebSocketGraphQlClientInterceptor) - .map(interceptor -> (WebSocketGraphQlClientInterceptor) interceptor) + .filter((interceptor) -> interceptor instanceof WebSocketGraphQlClientInterceptor) + .map((interceptor) -> (WebSocketGraphQlClientInterceptor) interceptor) .toList(); Assert.state(interceptors.size() <= 1, "Only a single interceptor of type WebSocketGraphQlClientInterceptor may be configured"); - return (!interceptors.isEmpty() ? interceptors.get(0) : new WebSocketGraphQlClientInterceptor() {}); + return (!interceptors.isEmpty() ? interceptors.get(0) : new WebSocketGraphQlClientInterceptor() { }); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/DgsGraphQlClient.java b/spring-graphql/src/main/java/org/springframework/graphql/client/DgsGraphQlClient.java index 730fd935..5a877a27 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/DgsGraphQlClient.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/DgsGraphQlClient.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.client; import java.util.HashMap; @@ -39,8 +40,8 @@ import org.springframework.util.Assert; * GraphQlClient client = ... ; * DgsGraphQlClient dgsClient = DgsGraphQlClient.create(client); * - * List books = dgsClient.request(new BooksGraphQLQuery()) - * .projection(new BooksProjectionRoot<>().id().name()) + * List<Book> books = dgsClient.request(new BooksGraphQLQuery()) + * .projection(new BooksProjectionRoot<>().id().name()) * .retrieveSync() * .toEntityList(Book.class); * @@ -67,6 +68,7 @@ public final class DgsGraphQlClient { /** * Start defining a GraphQL request for the given {@link GraphQLQuery}. + * @param query the GraphQL query */ public RequestSpec request(GraphQLQuery query) { return new RequestSpec(query); @@ -80,7 +82,7 @@ public final class DgsGraphQlClient { public static DgsGraphQlClient create(GraphQlClient client) { return new DgsGraphQlClient(client); } - + /** * Declare options to gather input for a GraphQL request and execute it. @@ -105,6 +107,7 @@ public final class DgsGraphQlClient { /** * Provide a {@link BaseProjectionNode} that defines the response selection set. + * @param projectionNode the response selection set * @return ths same builder instance */ public RequestSpec projection(BaseProjectionNode projectionNode) { @@ -114,20 +117,23 @@ public final class DgsGraphQlClient { /** * Configure {@link Coercing} for serialization of scalar types. + * @param scalarType the scalar type + * @param coercing the coercing function for this scalar * @return ths same builder instance */ public RequestSpec coercing(Class scalarType, Coercing coercing) { - this.coercingMap = (this.coercingMap != null ? this.coercingMap : new LinkedHashMap<>()); + this.coercingMap = (this.coercingMap != null) ? this.coercingMap : new LinkedHashMap<>(); this.coercingMap.put(scalarType, coercing); return this; } /** * Configure {@link Coercing} for serialization of scalar types. + * @param coercingMap the map of coercing function * @return ths same builder instance */ public RequestSpec coercing(Map, Coercing> coercingMap) { - this.coercingMap = (this.coercingMap != null ? this.coercingMap : new LinkedHashMap<>()); + this.coercingMap = (this.coercingMap != null) ? this.coercingMap : new LinkedHashMap<>(); this.coercingMap.putAll(coercingMap); return this; } @@ -136,10 +142,12 @@ public final class DgsGraphQlClient { * Set a client request attribute. *

This is purely for client side request processing, i.e. available * throughout the {@link GraphQlClientInterceptor} chain but not sent. + * @param name the attribute name + * @param value the attribute value * @return ths same builder instance */ public RequestSpec attribute(String name, Object value) { - this.attributes = (this.attributes != null ? this.attributes : new HashMap<>()); + this.attributes = (this.attributes != null) ? this.attributes : new HashMap<>(); this.attributes.put(name, value); return this; } @@ -147,10 +155,11 @@ public final class DgsGraphQlClient { /** * Manipulate the client request attributes. The map provided to the consumer * is "live", so the consumer can inspect and modify attributes accordingly. + * @param attributesConsumer the consumer that will manipulate request attributes * @return ths same builder instance */ public RequestSpec attributes(Consumer> attributesConsumer) { - this.attributes = (this.attributes != null ? this.attributes : new HashMap<>()); + this.attributes = (this.attributes != null) ? this.attributes : new HashMap<>(); attributesConsumer.accept(this.attributes); return this; } @@ -168,6 +177,7 @@ public final class DgsGraphQlClient { /** * Variant of {@link #executeSync()} with explicit path relative to the "data" key. + * @param path the JSON path relative to the "data" key */ public GraphQlClient.RetrieveSyncSpec retrieveSync(String path) { return initRequestSpec().retrieveSync(path); @@ -186,6 +196,7 @@ public final class DgsGraphQlClient { /** * Variant of {@link #retrieve()} with explicit path relative to the "data" key. + * @param path the JSON path relative to the "data" key */ public GraphQlClient.RetrieveSpec retrieve(String path) { return initRequestSpec().retrieve(path); @@ -237,15 +248,15 @@ public final class DgsGraphQlClient { Assert.state(this.projectionNode != null || this.coercingMap == null, "Coercing map provided without projection"); - GraphQLQueryRequest request = (this.coercingMap != null ? + GraphQLQueryRequest request = (this.coercingMap != null) ? new GraphQLQueryRequest(this.query, this.projectionNode, this.coercingMap) : - new GraphQLQueryRequest(this.query, this.projectionNode)); + new GraphQLQueryRequest(this.query, this.projectionNode); - String operationName = (this.query.getName() != null ? this.query.getName() : null); + String operationName = (this.query.getName() != null) ? this.query.getName() : null; - return graphQlClient.document(request.serialize()) + return DgsGraphQlClient.this.graphQlClient.document(request.serialize()) .operationName(operationName) - .attributes(map -> { + .attributes((map) -> { if (this.attributes != null) { map.putAll(this.attributes); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/FieldAccessException.java b/spring-graphql/src/main/java/org/springframework/graphql/client/FieldAccessException.java index 6bddc787..4c6cb60e 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/FieldAccessException.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/FieldAccessException.java @@ -38,6 +38,9 @@ public class FieldAccessException extends GraphQlClientException { /** * Constructor with the request and response, and the accessed field. + * @param request the client request + * @param response the client response + * @param field the accessed field that caused the error */ public FieldAccessException( ClientGraphQlRequest request, ClientGraphQlResponse response, ClientResponseField field) { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClient.java b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClient.java index 99a0b943..411bb082 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClient.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClient.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.client; import java.time.Duration; @@ -64,6 +65,7 @@ public interface GraphQlClient { * Variant of {@link #document(String)} that uses the given key to resolve * the GraphQL document from a file with the help of the configured * {@link Builder#documentSource(DocumentSource) DocumentSource}. + * @param name the document name * @throws IllegalArgumentException if the content could not be loaded */ RequestSpec documentName(String name); @@ -90,7 +92,7 @@ public interface GraphQlClient { /** * Base builder for creating and initializing a {@link GraphQlClient}. - * @since 1.3 + * @param the type of builder */ interface BaseBuilder> { @@ -100,6 +102,7 @@ public interface GraphQlClient { *

By default, this is set to {@link ResourceDocumentSource} with * classpath location {@code "graphql-documents/"} and * {@link ResourceDocumentSource#FILE_EXTENSIONS} as extensions. + * @param contentLoader the strategy for resolving documents by their names */ B documentSource(DocumentSource contentLoader); @@ -125,7 +128,7 @@ public interface GraphQlClient { /** * Builder to create a {@link GraphQlClient} instance with a * synchronous execution chain and transport. - * @since 1.3 + * @param the type of builder * @see SyncGraphQlTransport */ interface SyncBuilder> extends BaseBuilder { @@ -159,6 +162,7 @@ public interface GraphQlClient { /** * Builder to create a {@link GraphQlClient} with a non-blocking execution * chain and transport. + * @param the type of builder */ interface Builder> extends BaseBuilder { @@ -248,6 +252,7 @@ public interface GraphQlClient { *

 		 * client.document("..").executeSync()
 		 * 
+ * @param path the field path * @return a spec with decoding options * @throws FieldAccessException if the field has any field errors, * including errors at, above or below the field path. @@ -261,6 +266,7 @@ public interface GraphQlClient { *
 		 * client.document("..").execute().map(response -> ...)
 		 * 
+ * @param path the field path * @return a spec with decoding options * @throws FieldAccessException if the field has any field errors, * including errors at, above or below the field path. @@ -274,6 +280,7 @@ public interface GraphQlClient { *
 		 * client.document("..").executeSubscription().map(response -> ...)
 		 * 
+ * @param path the field path * @return a spec with decoding options */ RetrieveSubscriptionSpec retrieveSubscription(String path); @@ -318,12 +325,12 @@ public interface GraphQlClient { /** * Declares options to decode a field in a single response. - * @since 1.3 */ interface RetrieveSyncSpec { /** * Decode the field to an entity of the given type. + * @param the type to convert to * @param entityType the type to convert to * @return the entity or null if the field is {@code null} and has no errors. * @throws FieldAccessException in case of {@link ResponseField field @@ -335,18 +342,23 @@ public interface GraphQlClient { /** * Variant of {@link #toEntity(Class)} with a {@link ParameterizedTypeReference}. + * @param the type to convert to + * @param entityType the type to convert to */ @Nullable D toEntity(ParameterizedTypeReference entityType); /** * Variant of {@link #toEntity(Class)} to decode to a List of entities. + * @param the type to convert to * @param elementType the type of elements in the list */ List toEntityList(Class elementType); /** * Variant of {@link #toEntityList(Class)} with a {@link ParameterizedTypeReference}. + * @param the type to convert to + * @param elementType the type of elements in the list */ List toEntityList(ParameterizedTypeReference elementType); @@ -360,6 +372,7 @@ public interface GraphQlClient { /** * Decode the field to an entity of the given type. + * @param the type to convert to * @param entityType the type to convert to * @return {@code Mono} with the decoded entity; completes with * {@link FieldAccessException} in case of {@link ResponseField field @@ -371,17 +384,22 @@ public interface GraphQlClient { /** * Variant of {@link #toEntity(Class)} with a {@link ParameterizedTypeReference}. + * @param the entity type + * @param entityType the type to convert to */ Mono toEntity(ParameterizedTypeReference entityType); /** * Variant of {@link #toEntity(Class)} to decode to a List of entities. + * @param the type to convert to * @param elementType the type of elements in the list */ Mono> toEntityList(Class elementType); /** * Variant of {@link #toEntityList(Class)} with a {@link ParameterizedTypeReference}. + * @param the type to convert to + * @param elementType the type of elements in the list */ Mono> toEntityList(ParameterizedTypeReference elementType); @@ -395,6 +413,7 @@ public interface GraphQlClient { /** * Decode the field to an entity of the given type. + * @param the type to convert to * @param entityType the type to convert to * @return {@code Mono} with the decoded entity; completes with * {@link FieldAccessException} in case of {@link ResponseField field @@ -406,20 +425,25 @@ public interface GraphQlClient { /** * Variant of {@link #toEntity(Class)} with a {@link ParameterizedTypeReference}. + * @param the type to convert to + * @param entityType the type to convert to */ Flux toEntity(ParameterizedTypeReference entityType); /** * Variant of {@link #toEntity(Class)} to decode each response to a List of entities. + * @param the type to convert to * @param elementType the type of elements in the list */ Flux> toEntityList(Class elementType); /** * Variant of {@link #toEntity(Class)} to decode each response to a List of entities. + * @param the type to convert to + * @param elementType the type of elements in the list */ Flux> toEntityList(ParameterizedTypeReference elementType); } -} \ No newline at end of file +} diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClientException.java b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClientException.java index 543ad296..9cce8bce 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClientException.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClientException.java @@ -36,6 +36,9 @@ public class GraphQlClientException extends NestedRuntimeException { /** * Constructor with a message, optional cause, and the request details. + * @param message the exception message to use + * @param cause the original cause for the client exception + * @param request the request that failed */ public GraphQlClientException(String message, @Nullable Throwable cause, GraphQlRequest request) { super(message, cause); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClientInterceptor.java b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClientInterceptor.java index b6c246e1..162baa38 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClientInterceptor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlClientInterceptor.java @@ -67,13 +67,13 @@ public interface GraphQlClientInterceptor { @Override public Mono intercept(ClientGraphQlRequest request, Chain chain) { return GraphQlClientInterceptor.this.intercept( - request, nextRequest -> interceptor.intercept(nextRequest, chain)); + request, (nextRequest) -> interceptor.intercept(nextRequest, chain)); } @Override public Flux interceptSubscription(ClientGraphQlRequest request, SubscriptionChain chain) { return GraphQlClientInterceptor.this.interceptSubscription( - request, nextRequest -> interceptor.interceptSubscription(nextRequest, chain)); + request, (nextRequest) -> interceptor.interceptSubscription(nextRequest, chain)); } }; } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransport.java b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransport.java index 44b0a7a7..2afc67ed 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransport.java @@ -63,6 +63,7 @@ public interface GraphQlTransport { /** * Factory method to create {@link GraphQlResponse} from a GraphQL response * map for use in transport implementations. + * @param responseMap the GraphQL response map */ static GraphQlResponse createResponse(Map responseMap) { return new ResponseMapGraphQlResponse(responseMap); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransportException.java b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransportException.java index 8dca147e..e7f80067 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransportException.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/GraphQlTransportException.java @@ -32,6 +32,8 @@ public class GraphQlTransportException extends GraphQlClientException { /** * Constructor with a default message. + * @param cause the original cause of the transport error + * @param request the request that failed at the transport level */ public GraphQlTransportException(@Nullable Throwable cause, GraphQlRequest request) { super("GraphQlTransport error: " + cause.getMessage(), cause, request); @@ -39,6 +41,9 @@ public class GraphQlTransportException extends GraphQlClientException { /** * Constructor with a given message. + * @param message the exception message to use + * @param cause the original cause of the transport error + * @param request the request that failed at the transport level */ public GraphQlTransportException(String message, @Nullable Throwable cause, GraphQlRequest request) { super(message, cause, request); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlClient.java b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlClient.java index 72c6505c..82734771 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlClient.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlClient.java @@ -36,6 +36,7 @@ public interface HttpGraphQlClient extends WebGraphQlClient { /** * Create an {@link HttpGraphQlClient} that uses the given {@link WebClient}. + * @param webClient the {@code WebClient} to use for sending HTTP requests */ static HttpGraphQlClient create(WebClient webClient) { return builder(webClient.mutate()).build(); @@ -51,6 +52,7 @@ public interface HttpGraphQlClient extends WebGraphQlClient { /** * Variant of {@link #builder()} with a pre-configured {@code WebClient} * to mutate and customize further through the returned builder. + * @param webClient the {@code WebClient} to use for sending HTTP requests */ static Builder builder(WebClient webClient) { return builder(webClient.mutate()); @@ -59,6 +61,7 @@ public interface HttpGraphQlClient extends WebGraphQlClient { /** * Variant of {@link #builder()} with a pre-configured {@code WebClient} * to mutate and customize further through the returned builder. + * @param webClientBuilder the {@code WebClient.Builder} to use for building the HTTP client */ static Builder builder(WebClient.Builder webClientBuilder) { return new DefaultHttpGraphQlClientBuilder(webClientBuilder); @@ -67,6 +70,7 @@ public interface HttpGraphQlClient extends WebGraphQlClient { /** * Builder for the GraphQL over HTTP client. + * @param the builder type */ interface Builder> extends WebGraphQlClient.Builder { @@ -74,6 +78,7 @@ public interface HttpGraphQlClient extends WebGraphQlClient { * Customize the {@code WebClient} to use. *

Note that some properties of {@code WebClient.Builder} like the * base URL, headers, and codecs can be customized through this builder. + * @param webClient the function for customizing the {@code WebClient.Builder} that's used to build the HTTP client * @see #url(String) * @see #header(String, String...) * @see #codecConfigurer(Consumer) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlTransport.java b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlTransport.java index 2f11343a..c5bc7009 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlTransport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpGraphQlTransport.java @@ -39,15 +39,14 @@ import org.springframework.web.reactive.function.client.WebClient; * * @author Rossen Stoyanchev * @author Brian Clozel - * @since 1.0.0 */ final class HttpGraphQlTransport implements GraphQlTransport { private static final ParameterizedTypeReference> MAP_TYPE = - new ParameterizedTypeReference>() {}; + new ParameterizedTypeReference>() { }; private static final ParameterizedTypeReference>> SSE_TYPE = - new ParameterizedTypeReference>>() {}; + new ParameterizedTypeReference>>() { }; // To be removed in favor of Framework's MediaType.APPLICATION_GRAPHQL_RESPONSE private static final MediaType APPLICATION_GRAPHQL_RESPONSE = @@ -69,7 +68,7 @@ final class HttpGraphQlTransport implements GraphQlTransport { HttpHeaders headers = new HttpHeaders(); webClient.mutate().defaultHeaders(headers::putAll); MediaType contentType = headers.getContentType(); - return (contentType != null ? contentType : MediaType.APPLICATION_JSON); + return (contentType != null) ? contentType : MediaType.APPLICATION_JSON; } @@ -80,7 +79,7 @@ final class HttpGraphQlTransport implements GraphQlTransport { .contentType(this.contentType) .accept(MediaType.APPLICATION_JSON, APPLICATION_GRAPHQL_RESPONSE, MediaType.APPLICATION_GRAPHQL) .bodyValue(request.toMap()) - .attributes(attributes -> { + .attributes((attributes) -> { if (request instanceof ClientGraphQlRequest clientRequest) { attributes.putAll(clientRequest.getAttributes()); } @@ -96,15 +95,15 @@ final class HttpGraphQlTransport implements GraphQlTransport { .contentType(this.contentType) .accept(MediaType.TEXT_EVENT_STREAM) .bodyValue(request.toMap()) - .attributes(attributes -> { + .attributes((attributes) -> { if (request instanceof ClientGraphQlRequest clientRequest) { attributes.putAll(clientRequest.getAttributes()); } }) .retrieve() .bodyToFlux(SSE_TYPE) - .takeWhile(event -> "next".equals(event.event())) - .map(event -> new ResponseMapGraphQlResponse(event.data())); + .takeWhile((event) -> "next".equals(event.event())) + .map((event) -> new ResponseMapGraphQlResponse(event.data())); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpMessageConverterDelegate.java b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpMessageConverterDelegate.java index 3b5422f7..2952a90a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpMessageConverterDelegate.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpMessageConverterDelegate.java @@ -54,14 +54,17 @@ import org.springframework.util.MimeType; * for JSON and adapt it to {@link Encoder} and {@link Decoder}. * * @author Rossen Stoyanchev - * @since 1.3 */ final class HttpMessageConverterDelegate { + private HttpMessageConverterDelegate() { + + } + @SuppressWarnings("unchecked") static HttpMessageConverter findJsonConverter(List> converters) { return (HttpMessageConverter) converters.stream() - .filter(converter -> converter.canRead(Map.class, MediaType.APPLICATION_JSON)) + .filter((converter) -> converter.canRead(Map.class, MediaType.APPLICATION_JSON)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("No JSON HttpMessageConverter")); } @@ -79,14 +82,14 @@ final class HttpMessageConverterDelegate { if (mimeType instanceof MediaType mediaType) { return mediaType; } - return (mimeType != null ? new MediaType(mimeType) : null); + return (mimeType != null) ? new MediaType(mimeType) : null; } /** * Partial Encoder implementation to encode a single value through an HttpMessageConverter. */ - private static class HttpMessageConverterEncoder implements Encoder { + private static final class HttpMessageConverterEncoder implements Encoder { private final HttpMessageConverter converter; @@ -140,7 +143,7 @@ final class HttpMessageConverterDelegate { /** * Partial Decoder implementation to decode a single buffer through an HttpMessageConverter. */ - private static class HttpMessageConverterDecoder implements Decoder { + private static final class HttpMessageConverterDecoder implements Decoder { private final HttpMessageConverter converter; @@ -196,7 +199,7 @@ final class HttpMessageConverterDelegate { } - private static class HttpInputMessageAdapter extends ByteArrayInputStream implements HttpInputMessage { + private static final class HttpInputMessageAdapter extends ByteArrayInputStream implements HttpInputMessage { HttpInputMessageAdapter(DataBuffer buffer) { super(toBytes(buffer)); @@ -222,7 +225,7 @@ final class HttpMessageConverterDelegate { } - private static class HttpOutputMessageAdapter extends ByteArrayOutputStream implements HttpOutputMessage { + private static final class HttpOutputMessageAdapter extends ByteArrayOutputStream implements HttpOutputMessage { private static final HttpHeaders noOpHeaders = new HttpHeaders(); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpSyncGraphQlClient.java b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpSyncGraphQlClient.java index 9b08751d..74782e55 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpSyncGraphQlClient.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpSyncGraphQlClient.java @@ -42,6 +42,7 @@ public interface HttpSyncGraphQlClient extends GraphQlClient { /** * Create an {@link HttpSyncGraphQlClient} that uses the given {@link RestClient}. + * @param client the {@code RestClient} to use for HTTP requests */ static HttpSyncGraphQlClient create(RestClient client) { return builder(client.mutate()).build(); @@ -57,6 +58,7 @@ public interface HttpSyncGraphQlClient extends GraphQlClient { /** * Variant of {@link #builder()} with a pre-configured {@code RestClient} * to mutate and customize further through the returned builder. + * @param client the {@code RestClient} to use for HTTP requests */ static Builder builder(RestClient client) { return builder(client.mutate()); @@ -65,6 +67,7 @@ public interface HttpSyncGraphQlClient extends GraphQlClient { /** * Variant of {@link #builder()} with a pre-configured {@code RestClient} * to mutate and customize further through the returned builder. + * @param builder the {@code RestClient} builder to use for HTTP requests */ static Builder builder(RestClient.Builder builder) { return new DefaultSyncHttpGraphQlClientBuilder(builder); @@ -73,6 +76,7 @@ public interface HttpSyncGraphQlClient extends GraphQlClient { /** * Builder for the GraphQL over HTTP client with a blocking execution chain. + * @param the type of builder */ interface Builder> extends GraphQlClient.SyncBuilder { @@ -115,6 +119,7 @@ public interface HttpSyncGraphQlClient extends GraphQlClient { * Customize the underlying {@code RestClient}. *

Note that some properties of {@code RestClient.Builder} like the base URL, * headers, and message converters can be customized through this builder. + * @param builderConsumer a consumer that customizes the {@code RestClient}. * @see #url(String) * @see #header(String, String...) * @see #messageConverters(Consumer) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpSyncGraphQlTransport.java b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpSyncGraphQlTransport.java index 9cb4370a..df9d18be 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/HttpSyncGraphQlTransport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/HttpSyncGraphQlTransport.java @@ -32,11 +32,10 @@ import org.springframework.web.client.RestClient; * Transport for GraphQL over HTTP requests executed with {@link RestClient}. * * @author Rossen Stoyanchev - * @since 1.3 */ final class HttpSyncGraphQlTransport implements SyncGraphQlTransport { - private static final ParameterizedTypeReference> MAP_TYPE = new ParameterizedTypeReference<>() {}; + private static final ParameterizedTypeReference> MAP_TYPE = new ParameterizedTypeReference<>() { }; private final RestClient restClient; @@ -54,7 +53,7 @@ final class HttpSyncGraphQlTransport implements SyncGraphQlTransport { HttpHeaders headers = new HttpHeaders(); webClient.mutate().defaultHeaders(headers::putAll); MediaType contentType = headers.getContentType(); - return (contentType != null ? contentType : MediaType.APPLICATION_JSON); + return (contentType != null) ? contentType : MediaType.APPLICATION_JSON; } @@ -68,7 +67,7 @@ final class HttpSyncGraphQlTransport implements SyncGraphQlTransport { .retrieve() .body(MAP_TYPE); - return new ResponseMapGraphQlResponse(body != null ? body : Collections.emptyMap()); + return new ResponseMapGraphQlResponse((body != null) ? body : Collections.emptyMap()); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/RSocketGraphQlClient.java b/spring-graphql/src/main/java/org/springframework/graphql/client/RSocketGraphQlClient.java index 133975d8..72126cf2 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/RSocketGraphQlClient.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/RSocketGraphQlClient.java @@ -70,6 +70,7 @@ public interface RSocketGraphQlClient extends GraphQlClient { /** * Start with a given {@link #builder()}. + * @param requesterBuilder the existing request builder */ static Builder builder(RSocketRequester.Builder requesterBuilder) { return new DefaultRSocketGraphQlClientBuilder(requesterBuilder); @@ -78,6 +79,7 @@ public interface RSocketGraphQlClient extends GraphQlClient { /** * Builder for the GraphQL over HTTP client. + * @param the builder type */ interface Builder> extends GraphQlClient.Builder { @@ -146,11 +148,12 @@ public interface RSocketGraphQlClient extends GraphQlClient { *

Note that some properties of {@code RSocketRequester.Builder} like the * data MimeType, and the underlying RSocket transport can be customized * through this builder. + * @param requester the requester to be customized + * @return the same builder instance * @see #dataMimeType(MimeType) * @see #tcp(String, int) * @see #webSocket(URI) * @see #clientTransport(ClientTransport) - * @return the same builder instance */ B rsocketRequester(Consumer requester); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/RSocketGraphQlTransport.java b/spring-graphql/src/main/java/org/springframework/graphql/client/RSocketGraphQlTransport.java index 324c1fed..3d19b614 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/RSocketGraphQlTransport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/RSocketGraphQlTransport.java @@ -45,12 +45,11 @@ import org.springframework.util.Assert; * metadata extension. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class RSocketGraphQlTransport implements GraphQlTransport { private static final ParameterizedTypeReference> MAP_TYPE = - new ParameterizedTypeReference>() {}; + new ParameterizedTypeReference>() { }; private static final ResolvableType LIST_TYPE = ResolvableType.forClass(List.class); @@ -83,7 +82,7 @@ final class RSocketGraphQlTransport implements GraphQlTransport { public Flux executeSubscription(GraphQlRequest request) { return this.rsocketRequester.route(this.route).data(request.toMap()) .retrieveFlux(MAP_TYPE) - .onErrorResume(RejectedException.class, ex -> Flux.error(decodeErrors(request, ex))) + .onErrorResume(RejectedException.class, (ex) -> Flux.error(decodeErrors(request, ex))) .map(ResponseMapGraphQlResponse::new); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/ResponseMapGraphQlResponse.java b/spring-graphql/src/main/java/org/springframework/graphql/client/ResponseMapGraphQlResponse.java index 22f82976..f91ddf15 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/ResponseMapGraphQlResponse.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/ResponseMapGraphQlResponse.java @@ -36,7 +36,6 @@ import org.springframework.util.ObjectUtils; * {@link GraphQlResponse} that wraps a deserialized the GraphQL response map. * * @author Rossen Stoyanchev - * @since 1.0.0 */ class ResponseMapGraphQlResponse extends AbstractGraphQlResponse { @@ -60,7 +59,7 @@ class ResponseMapGraphQlResponse extends AbstractGraphQlResponse { @SuppressWarnings("unchecked") private static List wrapErrors(Map map) { List> errors = (List>) map.get("errors"); - errors = (errors != null ? errors : Collections.emptyList()); + errors = (errors != null) ? errors : Collections.emptyList(); return errors.stream().map(MapResponseError::new).collect(Collectors.toList()); } @@ -134,7 +133,7 @@ class ResponseMapGraphQlResponse extends AbstractGraphQlResponse { return Collections.emptyList(); } return locations.stream() - .map(m -> new SourceLocation(getInt(m, "line"), getInt(m, "column"), (String) m.get("sourceName"))) + .map((m) -> new SourceLocation(getInt(m, "line"), getInt(m, "column"), (String) m.get("sourceName"))) .collect(Collectors.toList()); } @@ -155,7 +154,7 @@ class ResponseMapGraphQlResponse extends AbstractGraphQlResponse { return ""; } return path.stream().reduce("", - (s, o) -> s + (o instanceof Integer ? "[" + o + "]" : (s.isEmpty() ? o : "." + o)), + (s, o) -> s + ((o instanceof Integer) ? "[" + o + "]" : (s.isEmpty() ? o : "." + o)), (s, s2) -> null); } @@ -163,7 +162,7 @@ class ResponseMapGraphQlResponse extends AbstractGraphQlResponse { @Override @Nullable public String getMessage() { - return (String) errorMap.get("message"); + return (String) this.errorMap.get("message"); } @Override diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/SubscriptionErrorException.java b/spring-graphql/src/main/java/org/springframework/graphql/client/SubscriptionErrorException.java index 775ad801..51a27baa 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/SubscriptionErrorException.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/SubscriptionErrorException.java @@ -38,6 +38,8 @@ public class SubscriptionErrorException extends GraphQlTransportException { /** * Constructor with the request details and the errors listed in the payload * of the {@code "errors"} message. + * @param request the request details + * @param errors the errors listed in the payload */ public SubscriptionErrorException(GraphQlRequest request, List errors) { super("GraphQL subscription completed with an \"error\" message, " + diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/SyncGraphQlClientInterceptor.java b/spring-graphql/src/main/java/org/springframework/graphql/client/SyncGraphQlClientInterceptor.java index b6d14441..fcdb344a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/SyncGraphQlClientInterceptor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/SyncGraphQlClientInterceptor.java @@ -50,7 +50,7 @@ public interface SyncGraphQlClientInterceptor { @Override public ClientGraphQlResponse intercept(ClientGraphQlRequest request, Chain chain) { return SyncGraphQlClientInterceptor.this.intercept( - request, nextRequest -> interceptor.intercept(nextRequest, chain)); + request, (nextRequest) -> interceptor.intercept(nextRequest, chain)); } }; } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/WebGraphQlClient.java b/spring-graphql/src/main/java/org/springframework/graphql/client/WebGraphQlClient.java index 81365e53..eb7bbb99 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/WebGraphQlClient.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/WebGraphQlClient.java @@ -39,6 +39,7 @@ public interface WebGraphQlClient extends GraphQlClient { /** * Base builder for GraphQL clients over a Web transport. + * @param the type of builder */ interface Builder> extends GraphQlClient.Builder { @@ -72,6 +73,7 @@ public interface WebGraphQlClient extends GraphQlClient { * Configure JSON encoders and decoders for use in the * {@link org.springframework.graphql.GraphQlResponse} to convert response * data to higher level objects. + * @param codecsConsumer a callback that customizes the configured codecs */ B codecConfigurer(Consumer codecsConsumer); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketDisconnectedException.java b/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketDisconnectedException.java index eb64ef8b..f04ac0b8 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketDisconnectedException.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketDisconnectedException.java @@ -35,6 +35,9 @@ public class WebSocketDisconnectedException extends GraphQlTransportException { /** * Constructor with an explanation about the closure, along with the request * details and the status used to close the WebSocket session. + * @param closeStatusMessage the message received when the connection was closed + * @param request the ongoing request when the connection was closed + * @param status the received close status */ public WebSocketDisconnectedException(String closeStatusMessage, GraphQlRequest request, CloseStatus status) { super(closeStatusMessage, null, request); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlClient.java b/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlClient.java index 2350ec0a..86dbbdf8 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlClient.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlClient.java @@ -85,6 +85,7 @@ public interface WebSocketGraphQlClient extends WebGraphQlClient { /** * Builder for a GraphQL over WebSocket client. + * @param the builder type */ interface Builder> extends WebGraphQlClient.Builder { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlTransport.java b/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlTransport.java index 9c5a93c2..ba191672 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlTransport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/client/WebSocketGraphQlTransport.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.client; import java.net.URI; @@ -50,7 +51,6 @@ import org.springframework.web.reactive.socket.client.WebSocketClient; * {@link GraphQlTransport} for GraphQL over WebSocket via {@link WebSocketClient}. * * @author Rossen Stoyanchev - * @since 1.0.0 * @see GraphQL over WebSocket protocol */ final class WebSocketGraphQlTransport implements GraphQlTransport { @@ -78,7 +78,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { Assert.notNull(interceptor, "WebSocketGraphQlClientInterceptor is required"); this.url = url; - this.headers.putAll(headers != null ? headers : HttpHeaders.EMPTY); + this.headers.putAll((headers != null) ? headers : HttpHeaders.EMPTY); this.webSocketClient = client; this.graphQlSessionHandler = new GraphQlSessionHandler(codecConfigurer, interceptor); @@ -100,7 +100,9 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { Mono sessionMono = handler.getGraphQlSession(); client.execute(uri, headers, handler) - .subscribe(aVoid -> {}, + .subscribe((aVoid) -> { + + }, handler::handleWebSocketSessionError, handler::handleWebSocketSessionClosed); @@ -109,19 +111,19 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { } - public URI getUrl() { + URI getUrl() { return this.url; } - public HttpHeaders getHeaders() { + HttpHeaders getHeaders() { return this.headers; } - public WebSocketClient getWebSocketClient() { + WebSocketClient getWebSocketClient() { return this.webSocketClient; } - public CodecConfigurer getCodecConfigurer() { + CodecConfigurer getCodecConfigurer() { return this.graphQlSessionHandler.getCodecConfigurer(); } @@ -132,7 +134,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { * @return {@code Mono} that completes when the WebSocket is connected and * ready to begin sending GraphQL requests */ - public Mono start() { + Mono start() { this.graphQlSessionHandler.setStopped(false); return this.graphQlSessionMono.then(); } @@ -145,19 +147,19 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { * call {@link #start()} to allow requests again. * @return {@code Mono} that completes when the underlying session is closed */ - public Mono stop() { + Mono stop() { this.graphQlSessionHandler.setStopped(true); - return this.graphQlSessionMono.flatMap(GraphQlSession::close).onErrorResume(ex -> Mono.empty()); + return this.graphQlSessionMono.flatMap(GraphQlSession::close).onErrorResume((ex) -> Mono.empty()); } @Override public Mono execute(GraphQlRequest request) { - return this.graphQlSessionMono.flatMap(session -> session.execute(request)); + return this.graphQlSessionMono.flatMap((session) -> session.execute(request)); } @Override public Flux executeSubscription(GraphQlRequest request) { - return this.graphQlSessionMono.flatMapMany(session -> session.executeSubscription(request)); + return this.graphQlSessionMono.flatMapMany((session) -> session.executeSubscription(request)); } @@ -189,7 +191,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { } - public CodecConfigurer getCodecConfigurer() { + CodecConfigurer getCodecConfigurer() { return this.codecDelegate.getCodecConfigurer(); } @@ -205,7 +207,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { * the "connection_init" and "connection_ack" messages are exchanged or * returns an error if it fails for any reason. */ - public Mono getGraphQlSession() { + Mono getGraphQlSession() { return this.graphQlSessionSink.asMono(); } @@ -213,14 +215,14 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { * When the handler is marked "stopped", i.e. set to {@code true}, new * requests are rejected. When set to {@code true} they are allowed. */ - public void setStopped(boolean stopped) { + void setStopped(boolean stopped) { this.stopped.set(stopped); } /** * Whether the handler is marked {@link #setStopped(boolean) "stopped"}. */ - public boolean isStopped() { + boolean isStopped() { return this.stopped.get(); } @@ -241,10 +243,10 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { Mono sendCompletion = session.send(connectionInitMono.concatWith(graphQlSession.getRequestFlux()) - .map(message -> this.codecDelegate.encode(session, message))); + .map((message) -> this.codecDelegate.encode(session, message))); Mono receiveCompletion = session.receive() - .flatMap(webSocketMessage -> { + .flatMap((webSocketMessage) -> { if (sessionNotInitialized()) { try { GraphQlWebSocketMessage message = this.codecDelegate.decode(webSocketMessage); @@ -301,14 +303,14 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { private void registerCloseStatusHandling(GraphQlSession graphQlSession, WebSocketSession session) { session.closeStatus() .defaultIfEmpty(CloseStatus.NO_STATUS_CODE) - .doOnNext(closeStatus -> { + .doOnNext((closeStatus) -> { String closeStatusMessage = initCloseStatusMessage(closeStatus, null, graphQlSession); if (logger.isDebugEnabled()) { logger.debug(closeStatusMessage); } graphQlSession.terminateRequests(closeStatusMessage, closeStatus); }) - .doOnError(cause -> { + .doOnError((cause) -> { CloseStatus closeStatus = CloseStatus.NO_STATUS_CODE; String closeStatusMessage = initCloseStatusMessage(closeStatus, cause, graphQlSession); if (logger.isErrorEnabled()) { @@ -347,7 +349,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { * with an error. The error is routed to subscribers of * {@link #getGraphQlSession()} which is necessary for connection issues. */ - public void handleWebSocketSessionError(Throwable ex) { + void handleWebSocketSessionError(Throwable ex) { if (logger.isDebugEnabled()) { logger.debug("Session handling error: " + ex.getMessage(), ex); @@ -364,7 +366,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { * This must be called from code that calls the {@code WebSocketClient} * when execution completes. */ - public void handleWebSocketSessionClosed() { + void handleWebSocketSessionClosed() { this.graphQlSessionSink = Sinks.unsafe().one(); } @@ -396,16 +398,16 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { /** * Return the {@code Flux} of GraphQL requests to send as WebSocket messages. */ - public Flux getRequestFlux() { + Flux getRequestFlux() { return this.requestSink.getRequestFlux(); } // Outbound messages - public Mono execute(GraphQlRequest request) { + Mono execute(GraphQlRequest request) { String id = String.valueOf(this.requestIndex.incrementAndGet()); - return Mono.create(sink -> { + return Mono.create((sink) -> { SingleResponseRequestState state = new SingleResponseRequestState(request, sink); this.requestStateMap.put(id, state); try { @@ -419,9 +421,9 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { }).doOnCancel(() -> this.requestStateMap.remove(id)); } - public Flux executeSubscription(GraphQlRequest request) { + Flux executeSubscription(GraphQlRequest request) { String id = String.valueOf(this.requestIndex.incrementAndGet()); - return Flux.create(sink -> { + return Flux.create((sink) -> { SubscriptionRequestState state = new SubscriptionRequestState(request, sink); this.requestStateMap.put(id, state); try { @@ -452,7 +454,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { } } - public void sendPong(@Nullable Map payload) { + void sendPong(@Nullable Map payload) { GraphQlWebSocketMessage message = GraphQlWebSocketMessage.pong(payload); this.requestSink.sendRequest(message); } @@ -463,7 +465,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { /** * Handle a "next" message and route to its recipient. */ - public void handleNext(GraphQlWebSocketMessage message) { + void handleNext(GraphQlWebSocketMessage message) { String id = message.getId(); RequestState requestState = this.requestStateMap.get(id); if (requestState == null) { @@ -486,7 +488,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { * Handle an "error" message, turning it into an {@link GraphQlResponse} * for single responses, or signaling an error for streams. */ - public void handleError(GraphQlWebSocketMessage message) { + void handleError(GraphQlWebSocketMessage message) { String id = message.getId(); RequestState requestState = this.requestStateMap.remove(id); if (requestState == null) { @@ -512,7 +514,7 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { /** * Handle a "complete" message. */ - public void handleComplete(GraphQlWebSocketMessage message) { + void handleComplete(GraphQlWebSocketMessage message) { String id = message.getId(); RequestState requestState = this.requestStateMap.remove(id); if (requestState == null) { @@ -528,22 +530,22 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { * Return a {@code Mono} that completes when the connection is closed * for any reason. */ - public Mono notifyWhenClosed() { + Mono notifyWhenClosed() { return this.connection.notifyWhenClosed(); } /** * Close the underlying connection. */ - public Mono close() { + Mono close() { return this.connection.close(CloseStatus.GOING_AWAY); } /** * Terminate and clean all in-progress requests with the given error. */ - public void terminateRequests(String message, CloseStatus status) { - this.requestStateMap.values().forEach(info -> info.emitDisconnectError(message, status)); + void terminateRequests(String message, CloseStatus status) { + this.requestStateMap.values().forEach((info) -> info.emitDisconnectError(message, status)); this.requestStateMap.clear(); } @@ -595,21 +597,21 @@ final class WebSocketGraphQlTransport implements GraphQlTransport { /** * Holds the request {@code Flux} and associated {@link FluxSink}. */ - private static class RequestSink { + private static final class RequestSink { @Nullable private FluxSink requestSink; - private final Flux requestFlux = Flux.create(sink -> { + private final Flux requestFlux = Flux.create((sink) -> { Assert.state(this.requestSink == null, "Expected single subscriber only for outbound messages"); this.requestSink = sink; }); - public Flux getRequestFlux() { + Flux getRequestFlux() { return this.requestFlux; } - public void sendRequest(GraphQlWebSocketMessage message) { + void sendRequest(GraphQlWebSocketMessage message) { Assert.state(this.requestSink != null, "Unexpected request before Flux is subscribed to"); this.requestSink.next(message); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/ArgumentValue.java b/spring-graphql/src/main/java/org/springframework/graphql/data/ArgumentValue.java index 7d35f9b1..b25f89c4 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/ArgumentValue.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/ArgumentValue.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data; @@ -39,8 +40,8 @@ import org.springframework.util.ObjectUtils; * object. * * - * @author Rossen Stoyanchev * @param the type of value contained + * @author Rossen Stoyanchev * @since 1.1.0 * @see Nullable vs Optional */ @@ -115,6 +116,7 @@ public final class ArgumentValue { /** * Static factory method for an argument value that was provided, even if * it was set to {@literal "null}. + * @param the type of value * @param value the value to hold in the instance */ public static ArgumentValue ofNullable(@Nullable T value) { @@ -123,6 +125,7 @@ public final class ArgumentValue { /** * Static factory method for an argument value that was omitted. + * @param the type of value */ @SuppressWarnings("unchecked") public static ArgumentValue omitted() { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java index e54efab2..72e64921 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlArgumentBinder.java @@ -139,7 +139,7 @@ public class GraphQlArgumentBinder { DataFetchingEnvironment environment, @Nullable String name, ResolvableType targetType) throws BindException { - Object rawValue = (name != null ? environment.getArgument(name) : environment.getArguments()); + Object rawValue = (name != null) ? environment.getArgument(name) : environment.getArguments(); boolean isOmitted = (name != null && !environment.getArguments().containsKey(name)); return bind(name, rawValue, isOmitted, targetType); @@ -148,6 +148,11 @@ public class GraphQlArgumentBinder { /** * Variant of {@link #bind(DataFetchingEnvironment, String, ResolvableType)} * with a pre-extracted raw value to bind from. + * @param name the name of an argument, or {@code null} to use the full map + * @param rawValue the raw argument value (Collection, Map, or scalar) + * @param isOmitted {@code true} if the argument was omitted from the input + * and {@code false} if it was provided, but possibly {@code null} + * @param targetType the type of Object to create * @since 1.3 */ @Nullable @@ -259,9 +264,9 @@ public class GraphQlArgumentBinder { Constructor constructor = BeanUtils.getResolvableConstructor(targetClass); - Object value = (constructor.getParameterCount() > 0 ? + Object value = (constructor.getParameterCount() > 0) ? bindMapToObjectViaConstructor(rawMap, constructor, targetType, bindingResult) : - bindMapToObjectViaSetters(rawMap, constructor, targetType, bindingResult)); + bindMapToObjectViaSetters(rawMap, constructor, targetType, bindingResult); bindingResult.popNestedPath(); @@ -373,7 +378,7 @@ public class GraphQlArgumentBinder { Object value = null; try { TypeConverter converter = - (this.typeConverter != null ? this.typeConverter : new SimpleTypeConverter()); + (this.typeConverter != null) ? this.typeConverter : new SimpleTypeConverter(); value = converter.convertIfNecessary( rawValue, (Class) clazz, new TypeDescriptor(type, null, null)); @@ -398,9 +403,9 @@ public class GraphQlArgumentBinder { } private static String initObjectName(ResolvableType targetType) { - return (targetType.getSource() instanceof MethodParameter methodParameter ? + return (targetType.getSource() instanceof MethodParameter methodParameter) ? Conventions.getVariableNameForParameter(methodParameter) : - ClassUtils.getShortNameAsProperty(targetType.resolve(Object.class))); + ClassUtils.getShortNameAsProperty(targetType.resolve(Object.class)); } @Override @@ -413,7 +418,7 @@ public class GraphQlArgumentBinder { return null; } - public void rejectArgumentValue( + void rejectArgumentValue( String field, @Nullable Object rawValue, String code, String defaultMessage) { addError(new FieldError( diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlRepository.java b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlRepository.java index bb47e4e5..59b60d59 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlRepository.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/GraphQlRepository.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntitiesDataFetcher.java b/spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntitiesDataFetcher.java index c1fe5298..252a64d3 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntitiesDataFetcher.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntitiesDataFetcher.java @@ -44,7 +44,6 @@ import org.springframework.lang.Nullable; * {@link EntityHandlerMethod}s. * * @author Rossen Stoyanchev - * @since 1.3 * @see com.apollographql.federation.graphqljava.SchemaTransformer#fetchEntities(DataFetcher) */ final class EntitiesDataFetcher implements DataFetcher>>> { @@ -54,7 +53,7 @@ final class EntitiesDataFetcher implements DataFetcher handlerMethods, HandlerDataFetcherExceptionResolver resolver) { this.handlerMethods = new LinkedHashMap<>(handlerMethods); @@ -90,15 +89,15 @@ final class EntitiesDataFetcher implements DataFetcher resolveException(ex, env, handlerMethod, index)); + .onErrorResume((ex) -> resolveException(ex, env, handlerMethod, index)); } private Mono resolveException( Throwable ex, DataFetchingEnvironment env, @Nullable EntityHandlerMethod handlerMethod, int index) { - Throwable theEx = (ex instanceof CompletionException ? ex.getCause() : ex); + Throwable theEx = (ex instanceof CompletionException) ? ex.getCause() : ex; DataFetchingEnvironment theEnv = new EntityDataFetchingEnvironment(env, index); - Object handler = (handlerMethod != null ? handlerMethod.getBean() : null); + Object handler = (handlerMethod != null) ? handlerMethod.getBean() : null; return this.exceptionResolver.resolveException(theEx, theEnv, handler) .map(ErrorContainer::new) @@ -108,8 +107,8 @@ final class EntitiesDataFetcher implements DataFetcher representation) { + static DataFetchingEnvironment wrap(DataFetchingEnvironment env, Map representation) { return new EntityDataFetchingEnvironment(env, representation); } @@ -75,7 +74,7 @@ final class EntityArgumentMethodArgumentResolver extends ArgumentMethodArgumentR this.representation = representation; } - public Map getRepresentation() { + Map getRepresentation() { return this.representation; } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntityHandlerMethod.java b/spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntityHandlerMethod.java index 1f457273..6eaaa625 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntityHandlerMethod.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/federation/EntityHandlerMethod.java @@ -32,11 +32,10 @@ import org.springframework.lang.Nullable; * Invokable controller method to fetch a federated entity. * * @author Rossen Stoyanchev - * @since 1.3 */ final class EntityHandlerMethod extends DataFetcherHandlerMethodSupport { - public EntityHandlerMethod( + EntityHandlerMethod( HandlerMethod handlerMethod, HandlerMethodArgumentResolverComposite resolvers, @Nullable Executor executor) { @@ -44,7 +43,7 @@ final class EntityHandlerMethod extends DataFetcherHandlerMethodSupport { } - public Mono getEntity( + Mono getEntity( DataFetchingEnvironment environment, Map representation, int index) { Object[] args; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/federation/FederationSchemaFactory.java b/spring-graphql/src/main/java/org/springframework/graphql/data/federation/FederationSchemaFactory.java index 0ecaac79..605f39d1 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/federation/FederationSchemaFactory.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/federation/FederationSchemaFactory.java @@ -75,6 +75,7 @@ public final class FederationSchemaFactory /** * Configure a resolver that helps to map Java to entity schema type names. *

By default this is {@link ClassNameTypeResolver}. + * @param typeResolver the custom type resolver to use * @see SchemaTransformer#resolveEntityType(TypeResolver) */ public void setTypeResolver(@Nullable TypeResolver typeResolver) { @@ -86,7 +87,7 @@ public final class FederationSchemaFactory public void afterPropertiesSet() { super.afterPropertiesSet(); - detectHandlerMethods().forEach(info -> + detectHandlerMethods().forEach((info) -> this.handlerMethods.put(info.typeName(), new EntityHandlerMethod(info.handlerMethod(), getArgumentResolvers(), getExecutor()))); @@ -149,6 +150,8 @@ public final class FederationSchemaFactory * Create {@link GraphQLSchema} via {@link SchemaTransformer}, setting up * the "_entities" {@link DataFetcher} and {@link TypeResolver} for federated types. *

Use this to supply a {@link SchemaResourceBuilder#schemaFactory(BiFunction) schemaFactory}. + * @param registry the existing type definition registry + * @param wiring the existing runtime wiring */ public GraphQLSchema createGraphQLSchema(TypeDefinitionRegistry registry, RuntimeWiring wiring) { return createSchemaTransformer(registry, wiring).build(); @@ -157,6 +160,8 @@ public final class FederationSchemaFactory /** * Alternative to {@link #createGraphQLSchema(TypeDefinitionRegistry, RuntimeWiring)} * that allows calling additional methods on {@link SchemaTransformer}. + * @param registry the existing type definition registry + * @param wiring the existing runtime wiring */ public SchemaTransformer createSchemaTransformer(TypeDefinitionRegistry registry, RuntimeWiring wiring) { Assert.state(this.typeResolver != null, "afterPropertiesSet not called"); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/federation/RepresentationException.java b/spring-graphql/src/main/java/org/springframework/graphql/data/federation/RepresentationException.java index 18a17501..dfe065d1 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/federation/RepresentationException.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/federation/RepresentationException.java @@ -55,7 +55,7 @@ public class RepresentationException extends RuntimeException { super(msg); this.representation = representation; this.handlerMethod = hm; - this.errorType = (representation.get("__typename") == null ? ErrorType.BAD_REQUEST : ErrorType.INTERNAL_ERROR); + this.errorType = (representation.get("__typename") == null) ? ErrorType.BAD_REQUEST : ErrorType.INTERNAL_ERROR; } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethod.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethod.java index 9a428f90..c493bdec 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethod.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethod.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method; import java.lang.annotation.Annotation; @@ -77,6 +78,8 @@ public class HandlerMethod { /** * Constructor with a handler instance and a method. + * @param bean the handler instance + * @param method the handler method */ public HandlerMethod(Object bean, Method method) { Assert.notNull(bean, "Bean is required"); @@ -94,6 +97,9 @@ public class HandlerMethod { * Constructor with a bean name for the handler along with a {@code BeanFactory} * to allow {@link #createWithResolvedBean() resolving} the handler instance * later. + * @param beanName the bean name + * @param beanFactory the bean factory to use for bean resolution + * @param method the handler method */ public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) { Assert.hasText(beanName, "Bean name is required"); @@ -115,6 +121,7 @@ public class HandlerMethod { /** * Copy constructor for use from subclasses that accept more arguments. + * @param handlerMethod the handler method */ protected HandlerMethod(HandlerMethod handlerMethod) { this(handlerMethod, handlerMethod.bean); @@ -191,6 +198,7 @@ public class HandlerMethod { /** * Return the actual return value type. + * @param returnValue the return value instance, can be {@code null} */ public MethodParameter getReturnValueType(@Nullable Object returnValue) { return new ReturnValueMethodParameter(returnValue); @@ -208,6 +216,7 @@ public class HandlerMethod { * if no annotation can be found on the given method itself. *

Also supports merged composed annotations with attribute * overrides as of Spring Framework 4.3. + * @param the annotation type * @param annotationType the type of annotation to introspect the method for * @return the annotation, or {@code null} if none found * @see AnnotatedElementUtils#findMergedAnnotation @@ -219,6 +228,7 @@ public class HandlerMethod { /** * Return whether the parameter is declared with the given annotation type. + * @param the annotation type * @param annotationType the annotation type to look for * @see AnnotatedElementUtils#hasAnnotation */ @@ -331,6 +341,9 @@ public class HandlerMethod { * processing time may be a JDK dynamic proxy (lazy initialization, prototype * beans, and others). Endpoint classes that require proxying should prefer * class-based proxy mechanisms. + * @param method the handler method + * @param targetBean the bean instance + * @param args the method arguments */ protected void assertTargetBean(Method method, Object targetBean, Object[] args) { Class methodDeclaringClass = method.getDeclaringClass(); @@ -347,9 +360,9 @@ public class HandlerMethod { protected String formatInvokeError(String text, Object[] args) { String formattedArgs = IntStream.range(0, args.length) - .mapToObj(i -> (args[i] != null ? + .mapToObj((i) -> (args[i] != null) ? "[" + i + "] [type=" + args[i].getClass().getName() + "] [value=" + args[i] + "]" : - "[" + i + "] [null]")) + "[" + i + "] [null]") .collect(Collectors.joining(",\n", " ", " ")); return text + "\n" + @@ -401,21 +414,7 @@ public class HandlerMethod { if (index < ifcAnns.length) { Annotation[] paramAnns = ifcAnns[index]; if (paramAnns.length > 0) { - List merged = new ArrayList<>(anns.length + paramAnns.length); - merged.addAll(Arrays.asList(anns)); - for (Annotation paramAnn : paramAnns) { - boolean existingType = false; - for (Annotation ann : anns) { - if (ann.annotationType() == paramAnn.annotationType()) { - existingType = true; - break; - } - } - if (!existingType) { - merged.add(adaptAnnotation(paramAnn)); - } - } - anns = merged.toArray(new Annotation[0]); + anns = mergeAnnotations(anns, paramAnns); } } } @@ -424,6 +423,25 @@ public class HandlerMethod { } return anns; } + + private Annotation[] mergeAnnotations(Annotation[] anns, Annotation[] paramAnns) { + List merged = new ArrayList<>(anns.length + paramAnns.length); + merged.addAll(Arrays.asList(anns)); + for (Annotation paramAnn : paramAnns) { + boolean existingType = false; + for (Annotation ann : anns) { + if (ann.annotationType() == paramAnn.annotationType()) { + existingType = true; + break; + } + } + if (!existingType) { + merged.add(adaptAnnotation(paramAnn)); + } + } + anns = merged.toArray(new Annotation[0]); + return anns; + } } @@ -435,7 +453,7 @@ public class HandlerMethod { @Nullable private final Object returnValue; - public ReturnValueMethodParameter(@Nullable Object returnValue) { + ReturnValueMethodParameter(@Nullable Object returnValue) { super(-1); this.returnValue = returnValue; } @@ -447,7 +465,7 @@ public class HandlerMethod { @Override public Class getParameterType() { - return (this.returnValue != null ? this.returnValue.getClass() : super.getParameterType()); + return (this.returnValue != null) ? this.returnValue.getClass() : super.getParameterType(); } @Override diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethodArgumentResolver.java index 6e948920..e4cd87ce 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethodArgumentResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method; import graphql.schema.DataFetchingEnvironment; @@ -35,20 +36,18 @@ public interface HandlerMethodArgumentResolver { /** * Whether this resolver supports the given {@link MethodParameter}. + * @param parameter the method parameter to check for support */ boolean supportsParameter(MethodParameter parameter); /** * Resolve a method parameter to a value. - * * @param parameter the method parameter to resolve. This parameter must * have previously checked via {@link #supportsParameter}. * @param environment the environment to use to resolve the value - * * @return the resolved value, which may be {@code null} if not resolved; * the value may also be a {@link reactor.core.publisher.Mono} if it * requires asynchronous resolution. - * * @throws Exception in case of errors with the preparation of argument values */ @Nullable diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethodArgumentResolverComposite.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethodArgumentResolverComposite.java index dd7fd899..b94addd1 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethodArgumentResolverComposite.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethodArgumentResolverComposite.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method; import java.util.ArrayList; @@ -43,6 +44,7 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu /** * Add the given {@link HandlerMethodArgumentResolver}. + * @param resolver the argument resolver */ public void addResolver(HandlerMethodArgumentResolver resolver) { this.argumentResolvers.add(resolver); @@ -84,10 +86,11 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu /** * Find a registered {@link HandlerMethodArgumentResolver} that supports * the given method parameter. + * @param parameter the method parameter */ @Nullable public HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { - return this.argumentResolverCache.computeIfAbsent(parameter, p -> { + return this.argumentResolverCache.computeIfAbsent(parameter, (p) -> { for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) { if (resolver.supportsParameter(parameter)) { return resolver; @@ -97,4 +100,4 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu }); } -} \ No newline at end of file +} diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/InvocableHandlerMethodSupport.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/InvocableHandlerMethodSupport.java index 9f6183a2..9a78e3cf 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/InvocableHandlerMethodSupport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/InvocableHandlerMethodSupport.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method; import java.lang.reflect.InvocationTargetException; @@ -25,7 +26,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import graphql.GraphQLContext; -import io.micrometer.context.ContextSnapshot; import io.micrometer.context.ContextSnapshotFactory; import reactor.core.publisher.Mono; @@ -72,6 +72,7 @@ public abstract class InvocableHandlerMethodSupport extends HandlerMethod { /** * Invoke the handler method with the given argument values. + * @param graphQLContext the GraphQL context for this data fetching operation * @param argValues the values to use to invoke the method * @return the value returned from the method or a {@code Mono} * if the invocation fails. @@ -92,7 +93,7 @@ public abstract class InvocableHandlerMethodSupport extends HandlerMethod { } catch (IllegalArgumentException ex) { assertTargetBean(method, getBean(), argValues); - String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument"); + String text = (ex.getMessage() != null) ? ex.getMessage() : "Illegal argument"; return Mono.error(new IllegalStateException(formatInvokeError(text, argValues), ex)); } catch (InvocationTargetException ex) { @@ -145,15 +146,16 @@ public abstract class InvocableHandlerMethodSupport extends HandlerMethod { /** * Use this method to resolve the arguments asynchronously. This is only * useful when at least one of the values is a {@link Mono} + * @param args the arguments to be resolved asynchronously */ @SuppressWarnings("unchecked") protected Mono toArgsMono(Object[] args) { List> monoList = new ArrayList<>(); for (Object arg : args) { - Mono argMono = (arg instanceof Mono ? (Mono) arg : Mono.justOrEmpty(arg)); + Mono argMono = ((arg instanceof Mono) ? (Mono) arg : Mono.justOrEmpty(arg)); monoList.add(argMono.defaultIfEmpty(NO_VALUE)); } - return Mono.zip(monoList, values -> { + return Mono.zip(monoList, (values) -> { for (int i = 0; i < values.length; i++) { if (values[i] == NO_VALUE) { values[i] = null; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/Argument.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/Argument.java index 6e378f82..2ee80cbf 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/Argument.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/Argument.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/Arguments.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/Arguments.java index 0fdd7bc2..d604020a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/Arguments.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/Arguments.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/BatchMapping.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/BatchMapping.java index c4ee2e85..4e695ab6 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/BatchMapping.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/BatchMapping.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/ContextValue.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/ContextValue.java index 0a2e1ef2..44357931 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/ContextValue.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/ContextValue.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/GraphQlExceptionHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/GraphQlExceptionHandler.java index 9ab606f8..377401b0 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/GraphQlExceptionHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/GraphQlExceptionHandler.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/LocalContextValue.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/LocalContextValue.java index 23bc1083..9e906c49 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/LocalContextValue.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/LocalContextValue.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/MutationMapping.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/MutationMapping.java index 727bed45..984e4b6c 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/MutationMapping.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/MutationMapping.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/QueryMapping.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/QueryMapping.java index 9abc721a..02a1bf53 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/QueryMapping.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/QueryMapping.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/SchemaMapping.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/SchemaMapping.java index dff610ec..fe0cf0d7 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/SchemaMapping.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/SchemaMapping.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/SubscriptionMapping.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/SubscriptionMapping.java index c862ae13..342a9e7f 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/SubscriptionMapping.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/SubscriptionMapping.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation; import java.lang.annotation.Documented; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurer.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurer.java index 7fa22069..7cbfdb38 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurer.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.annotation.Annotation; @@ -105,13 +106,13 @@ public class AnnotatedControllerConfigurer private static final ClassLoader classLoader = AnnotatedControllerConfigurer.class.getClassLoader(); - private final static boolean springDataPresent = ClassUtils.isPresent( + private static final boolean springDataPresent = ClassUtils.isPresent( "org.springframework.data.projection.SpelAwareProxyProjectionFactory", classLoader); - private final static boolean springSecurityPresent = ClassUtils.isPresent( + private static final boolean springSecurityPresent = ClassUtils.isPresent( "org.springframework.security.core.context.SecurityContext", classLoader); - private final static boolean beanValidationPresent = ClassUtils.isPresent( + private static final boolean beanValidationPresent = ClassUtils.isPresent( "jakarta.validation.executable.ExecutableValidator", classLoader); @@ -125,7 +126,6 @@ public class AnnotatedControllerConfigurer * Add a {@link HandlerMethodArgumentResolver} for custom controller method * arguments. Such custom resolvers are ordered after built-in resolvers * except for {@link SourceMethodArgumentResolver}, which is always last. - * * @param resolver the resolver to add. * @since 1.2.0 */ @@ -228,7 +228,7 @@ public class AnnotatedControllerConfigurer @Override public void configure(RuntimeWiring.Builder runtimeWiringBuilder) { - detectHandlerMethods().forEach(info -> { + detectHandlerMethods().forEach((info) -> { DataFetcher dataFetcher; if (!info.isBatchMapping()) { dataFetcher = new SchemaMappingDataFetcher( @@ -238,7 +238,7 @@ public class AnnotatedControllerConfigurer dataFetcher = registerBatchLoader(info); } FieldCoordinates coordinates = info.getCoordinates(); - runtimeWiringBuilder.type(coordinates.getTypeName(), typeBuilder -> + runtimeWiringBuilder.type(coordinates.getTypeName(), (typeBuilder) -> typeBuilder.dataFetcher(coordinates.getFieldName(), dataFetcher)); }); } @@ -322,7 +322,7 @@ public class AnnotatedControllerConfigurer BatchLoaderRegistry registry = obtainApplicationContext().getBean(BatchLoaderRegistry.class); BatchLoaderRegistry.RegistrationSpec registration = registry.forName(dataLoaderKey); if (info.getMaxBatchSize() > 0) { - registration.withOptions(options -> options.setMaxBatchSize(info.getMaxBatchSize())); + registration.withOptions((options) -> options.setMaxBatchSize(info.getMaxBatchSize())); } HandlerMethod handlerMethod = info.getHandlerMethod(); @@ -362,6 +362,7 @@ public class AnnotatedControllerConfigurer * Alternative to {@link #configure(RuntimeWiring.Builder)} that registers * data fetchers in a {@link GraphQLCodeRegistry.Builder}. This could be * used with programmatic creation of {@link graphql.schema.GraphQLSchema}. + * @param codeRegistryBuilder the code registry */ @SuppressWarnings("rawtypes") public void configure(GraphQLCodeRegistry.Builder codeRegistryBuilder) { @@ -408,7 +409,7 @@ public class AnnotatedControllerConfigurer this.argumentResolvers = argumentResolvers; this.methodValidationHelper = - (helper != null ? helper.getValidationHelperFor(info.getHandlerMethod()) : null); + (helper != null) ? helper.getValidationHelperFor(info.getHandlerMethod()) : null; this.exceptionResolver = exceptionResolver; @@ -429,12 +430,12 @@ public class AnnotatedControllerConfigurer @Override public Map getArguments() { - Predicate argumentPredicate = p -> + Predicate argumentPredicate = (p) -> (p.getParameterAnnotation(Argument.class) != null || p.getParameterType() == ArgumentValue.class); return Arrays.stream(this.mappingInfo.getHandlerMethod().getMethodParameters()) .filter(argumentPredicate) - .peek(p -> p.initParameterNameDiscovery(parameterNameDiscoverer)) + .peek((p) -> p.initParameterNameDiscovery(parameterNameDiscoverer)) .collect(Collectors.toMap( ArgumentMethodArgumentResolver::getArgumentName, ResolvableType::forMethodParameter)); @@ -443,7 +444,7 @@ public class AnnotatedControllerConfigurer /** * Return the {@link HandlerMethod} used to fetch data. */ - public HandlerMethod getHandlerMethod() { + HandlerMethod getHandlerMethod() { return this.mappingInfo.getHandlerMethod(); } @@ -469,13 +470,13 @@ public class AnnotatedControllerConfigurer DataFetchingEnvironment env, DataFetcherHandlerMethod handlerMethod, Object result) { if (this.subscription && result instanceof Publisher publisher) { - result = Flux.from(publisher).onErrorResume(ex -> handleSubscriptionError(ex, env, handlerMethod)); + result = Flux.from(publisher).onErrorResume((ex) -> handleSubscriptionError(ex, env, handlerMethod)); } else if (result instanceof Mono) { - result = ((Mono) result).onErrorResume(ex -> (Mono) handleException(ex, env, handlerMethod)); + result = ((Mono) result).onErrorResume((ex) -> (Mono) handleException(ex, env, handlerMethod)); } else if (result instanceof Flux) { - result = ((Flux) result).onErrorResume(ex -> (Mono) handleException(ex, env, handlerMethod)); + result = ((Flux) result).onErrorResume((ex) -> (Mono) handleException(ex, env, handlerMethod)); } return result; } @@ -484,7 +485,7 @@ public class AnnotatedControllerConfigurer Throwable ex, DataFetchingEnvironment env, DataFetcherHandlerMethod handlerMethod) { return this.exceptionResolver.resolveException(ex, env, handlerMethod.getBean()) - .map(errors -> DataFetcherResult.newResult().errors(errors).build()) + .map((errors) -> DataFetcherResult.newResult().errors(errors).build()) .switchIfEmpty(Mono.error(ex)); } @@ -493,7 +494,7 @@ public class AnnotatedControllerConfigurer Throwable ex, DataFetchingEnvironment env, DataFetcherHandlerMethod handlerMethod) { return (Publisher) this.exceptionResolver.resolveException(ex, env, handlerMethod.getBean()) - .flatMap(errors -> Mono.error(new SubscriptionPublisherException(errors, ex))) + .flatMap((errors) -> Mono.error(new SubscriptionPublisherException(errors, ex))) .switchIfEmpty(Mono.error(ex)); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerDetectionSupport.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerDetectionSupport.java index 9fada65c..60075a4a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerDetectionSupport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerDetectionSupport.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.reflect.Method; @@ -54,13 +55,13 @@ import org.springframework.util.ClassUtils; * Convenient base for classes that find annotated controller method with argument * values resolved from a {@link graphql.schema.DataFetchingEnvironment}. * + * @param the type of mapping info prepared from a controller method * @author Rossen Stoyanchev * @since 1.3 - * @param the type of mapping info prepared from a controller method */ public abstract class AnnotatedControllerDetectionSupport implements ApplicationContextAware, InitializingBean { - protected final static boolean springSecurityPresent = ClassUtils.isPresent( + protected static final boolean springSecurityPresent = ClassUtils.isPresent( "org.springframework.security.core.context.SecurityContext", AnnotatedControllerDetectionSupport.class.getClassLoader()); @@ -102,6 +103,7 @@ public abstract class AnnotatedControllerDetectionSupport implements Applicat * that assists in binding GraphQL arguments onto * {@link org.springframework.graphql.data.method.annotation.Argument @Argument} * annotated method parameters. + * @param registrar the formatter registrar */ public void addFormatterRegistrar(FormatterRegistrar registrar) { registrar.registerFormatters(this.conversionService); @@ -116,6 +118,7 @@ public abstract class AnnotatedControllerDetectionSupport implements Applicat * {@link org.springframework.graphql.data.method.annotation.Argument @Argument} * should falls back to direct field access in case the target object does * not use accessor methods. + * @param fallBackOnDirectFieldAccess whether binding should fall back on direct field access * @since 1.2.0 */ public void setFallBackOnDirectFieldAccess(boolean fallBackOnDirectFieldAccess) { @@ -133,11 +136,9 @@ public abstract class AnnotatedControllerDetectionSupport implements Applicat * exceptions from non-controller {@link DataFetcher}s since exceptions from * {@code @SchemaMapping} controller methods are handled automatically at * the point of invocation. - * * @return a resolver instance that can be plugged into * {@link org.springframework.graphql.execution.GraphQlSource.Builder#exceptionResolvers(List) * GraphQlSource.Builder} - * * @since 1.2.0 */ public HandlerDataFetcherExceptionResolver getExceptionResolver() { @@ -214,15 +215,15 @@ public abstract class AnnotatedControllerDetectionSupport implements Applicat } catch (Throwable ex) { // An unresolvable bean type, probably from a lazy bean - let's ignore it. - if (logger.isTraceEnabled()) { - logger.trace("Could not resolve type for bean '" + beanName + "'", ex); + if (this.logger.isTraceEnabled()) { + this.logger.trace("Could not resolve type for bean '" + beanName + "'", ex); } } if (beanType == null || !AnnotatedElementUtils.hasAnnotation(beanType, Controller.class)) { continue; } Class beanClass = context.getType(beanName); - findHandlerMethods(beanName, beanClass).forEach(info -> registerHandlerMethod(info, results)); + findHandlerMethods(beanName, beanClass).forEach((info) -> registerHandlerMethod(info, results)); } return results; } @@ -240,8 +241,8 @@ public abstract class AnnotatedControllerDetectionSupport implements Applicat Collection mappingInfos = map.values(); - if (logger.isTraceEnabled() && !mappingInfos.isEmpty()) { - logger.trace(formatMappings(userClass, mappingInfos)); + if (this.logger.isTraceEnabled() && !mappingInfos.isEmpty()) { + this.logger.trace(formatMappings(userClass, mappingInfos)); } return mappingInfos; @@ -252,10 +253,10 @@ public abstract class AnnotatedControllerDetectionSupport implements Applicat private String formatMappings(Class handlerType, Collection infos) { String formattedType = Arrays.stream(ClassUtils.getPackageName(handlerType).split("\\.")) - .map(p -> p.substring(0, 1)) + .map((p) -> p.substring(0, 1)) .collect(Collectors.joining(".", "", "." + handlerType.getSimpleName())); return infos.stream() - .map(info -> { + .map((info) -> { Method method = getHandlerMethod(info).getMethod(); String methodParameters = Arrays.stream(method.getGenericParameterTypes()) .map(Type::getTypeName) @@ -268,7 +269,7 @@ public abstract class AnnotatedControllerDetectionSupport implements Applicat private void registerHandlerMethod(M info, Set results) { Assert.state(this.exceptionResolver != null, "afterPropertiesSet not called"); HandlerMethod handlerMethod = getHandlerMethod(info); - M existing = results.stream().filter(o -> o.equals(info)).findFirst().orElse(null); + M existing = results.stream().filter((o) -> o.equals(info)).findFirst().orElse(null); if (existing != null && !getHandlerMethod(existing).equals(handlerMethod)) { throw new IllegalStateException( "Ambiguous mapping. Cannot map '" + handlerMethod.getBean() + "' method \n" + @@ -281,9 +282,9 @@ public abstract class AnnotatedControllerDetectionSupport implements Applicat protected HandlerMethod createHandlerMethod(Method originalMethod, Object handler, Class handlerType) { Method method = AopUtils.selectInvocableMethod(originalMethod, handlerType); - return (handler instanceof String beanName ? + return (handler instanceof String beanName) ? new HandlerMethod(beanName, obtainApplicationContext().getAutowireCapableBeanFactory(), method) : - new HandlerMethod(handler, method)); + new HandlerMethod(handler, method); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolver.java index 006ac950..be9d444e 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.reflect.Method; @@ -72,7 +73,6 @@ import org.springframework.web.method.ControllerAdviceBean; * * @author Rossen Stoyanchev * @author Brian Clozel - * @since 1.2.0 */ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherExceptionResolver { @@ -98,9 +98,9 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx * are validated to ensure they are within a range of supported types. * @param controllerType the controller type to register */ - public void registerController(Class controllerType) { + void registerController(Class controllerType) { this.controllerCache.computeIfAbsent( - controllerType, type -> new MethodResolver(findExceptionHandlers(controllerType))); + controllerType, (type) -> new MethodResolver(findExceptionHandlers(controllerType))); } /** @@ -110,7 +110,7 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx * for use at runtime. * @param context the context to look into */ - public void registerControllerAdvice(ApplicationContext context) { + void registerControllerAdvice(ApplicationContext context) { Map detectedControllerAdvice = new HashMap<>(); for (ControllerAdviceBean bean : ControllerAdviceBean.findAnnotatedBeans(context)) { Class beanType = bean.getBeanType(); @@ -121,9 +121,8 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx } } } - detectedControllerAdvice.keySet().stream().sorted(OrderComparator.INSTANCE).forEach(bean -> { - this.controllerAdviceCache.put(bean, detectedControllerAdvice.get(bean)); - }); + detectedControllerAdvice.keySet().stream().sorted(OrderComparator.INSTANCE) + .forEach((bean) -> this.controllerAdviceCache.put(bean, detectedControllerAdvice.get(bean))); if (logger.isDebugEnabled()) { logger.debug("@GraphQlException methods in ControllerAdvice beans: " + (this.controllerAdviceCache.isEmpty() ? "none" : this.controllerAdviceCache.size())); @@ -134,7 +133,7 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx private static Map, Method> findExceptionHandlers(Class handlerType) { Map handlerMap = MethodIntrospector.selectMethods( - handlerType, (MethodIntrospector.MetadataLookup) method -> + handlerType, (MethodIntrospector.MetadataLookup) (method) -> AnnotatedElementUtils.findMergedAnnotation(method, GraphQlExceptionHandler.class)); Map, Method> mappings = new HashMap<>(handlerMap.size()); @@ -230,7 +229,7 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx while (exToExpose != null) { exceptions.add(exToExpose); Throwable cause = exToExpose.getCause(); - exToExpose = (cause != exToExpose ? cause : null); + exToExpose = (cause != exToExpose) ? cause : null; } Object[] arguments = new Object[exceptions.size() + 1]; exceptions.toArray(arguments); // efficient arraycopy call in ArrayList @@ -278,7 +277,7 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx * @return the exception handler to use, or {@code null} if no match */ @Nullable - public MethodHolder resolveMethod(Throwable exception) { + MethodHolder resolveMethod(Throwable exception) { MethodHolder method = resolveMethodByExceptionType(exception.getClass()); if (method == null) { Throwable cause = exception.getCause(); @@ -296,7 +295,7 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx method = getMappedMethod(exceptionType); this.resolvedExceptionCache.put(exceptionType, method); } - return (method != NO_MATCH ? method : null); + return (method != NO_MATCH) ? method : null; } private MethodHolder getMappedMethod(Class exceptionType) { @@ -342,11 +341,11 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx this.adapter = ReturnValueAdapter.createFor(this.returnType); } - public Method getMethod() { + Method getMethod() { return this.method; } - public Mono> adapt(@Nullable Object result, Throwable ex) { + Mono> adapt(@Nullable Object result, Throwable ex) { return this.adapter.adapt(result, this.returnType, ex); } @@ -421,24 +420,24 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx } - /** Adapter for void */ + /* Adapter for void */ ReturnValueAdapter forVoid = (result, returnType, ex) -> Mono.just(Collections.emptyList()); - /** Adapter for a single GraphQLError */ + /* Adapter for a single GraphQLError */ ReturnValueAdapter forSingleError = (result, returnType, ex) -> - (result == null ? - Mono.empty() : - Mono.just(Collections.singletonList((GraphQLError) result))); + (result != null) ? + Mono.just(Collections.singletonList((GraphQLError) result)) : + Mono.empty(); - /** Adapter for a collection of GraphQLError's */ + /* Adapter for a collection of GraphQLError's */ ReturnValueAdapter forCollection = (result, returnType, ex) -> - (result == null ? - Mono.empty() : - Mono.just((result instanceof List ? + (result != null) ? + Mono.just((result instanceof List) ? (List) result : - new ArrayList<>((Collection) result)))); + new ArrayList<>((Collection) result)) : + Mono.empty(); - /** Adapter for Object */ + /* Adapter for Object */ ReturnValueAdapter forObject = (result, returnType, ex) -> { if (result == null) { return Mono.empty(); @@ -458,15 +457,15 @@ final class AnnotatedControllerExceptionResolver implements HandlerDataFetcherEx } }; - /** Adapter for {@code Mono} */ + /* Adapter for {@code Mono} */ ReturnValueAdapter forMonoVoid = (result, returnType, ex) -> - (result == null ? Mono.empty() : Mono.just(Collections.emptyList())); + (result != null) ? Mono.just(Collections.emptyList()) : Mono.empty(); - /** Adapter for a {@code Mono} wrapping any of the other synchronous return value types */ + /* Adapter for a {@code Mono} wrapping any of the other synchronous return value types */ ReturnValueAdapter forMono = (result, returnType, ex) -> - (result == null ? - Mono.empty() : - ((Mono) result).flatMap(o -> forObject.adapt(o, returnType, ex)).switchIfEmpty(Mono.error(ex))); + (result != null) ? + ((Mono) result).flatMap((o) -> forObject.adapt(o, returnType, ex)).switchIfEmpty(Mono.error(ex)) : + Mono.empty(); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolver.java index 4ff10edb..fbb3c407 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import graphql.schema.DataFetchingEnvironment; @@ -83,6 +84,9 @@ public class ArgumentMethodArgumentResolver implements HandlerMethodArgumentReso /** * Perform the binding with the configured {@link #getArgumentBinder() binder}. + * @param environment for access to the arguments + * @param name the name of an argument, or {@code null} to use the full map + * @param targetType the type of Object to create * @since 1.3 */ @Nullable diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentValueValueExtractor.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentValueValueExtractor.java index f2f71c74..bf8eb572 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentValueValueExtractor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentValueValueExtractor.java @@ -19,22 +19,24 @@ package org.springframework.graphql.data.method.annotation.support; import jakarta.validation.valueextraction.ExtractedValue; import jakarta.validation.valueextraction.UnwrapByDefault; import jakarta.validation.valueextraction.ValueExtractor; + import org.springframework.graphql.data.ArgumentValue; /** * {@link ValueExtractor} that enables {@code @Valid} with {@link ArgumentValue}, * and helps to extract the value from it. * + * @author Rossen Stoyanchev * @since 1.2.2 */ @UnwrapByDefault public final class ArgumentValueValueExtractor implements ValueExtractor> { - @Override - public void extractValues(ArgumentValue argumentValue, ValueReceiver receiver) { - if (!argumentValue.isOmitted()) { - receiver.value(null, argumentValue.value()); - } - } + @Override + public void extractValues(ArgumentValue argumentValue, ValueReceiver receiver) { + if (!argumentValue.isOmitted()) { + receiver.value(null, argumentValue.value()); + } + } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentsMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentsMethodArgumentResolver.java index 4b4bfa6c..3291fb8c 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentsMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ArgumentsMethodArgumentResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import graphql.schema.DataFetchingEnvironment; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AuthenticationPrincipalArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AuthenticationPrincipalArgumentResolver.java index 08d39a38..6a077057 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AuthenticationPrincipalArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AuthenticationPrincipalArgumentResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.annotation.Annotation; @@ -97,7 +98,7 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg @Override public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment environment) throws Exception { return getCurrentAuthentication(parameter) - .mapNotNull(auth -> resolvePrincipal(parameter, auth.getPrincipal())) + .mapNotNull((auth) -> resolvePrincipal(parameter, auth.getPrincipal())) .transform((argument) -> isPublisherOrMono(parameter) ? Mono.just(argument) : argument); } @@ -109,7 +110,7 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg @SuppressWarnings("unchecked") private Mono getCurrentAuthentication(MethodParameter parameter) { Object value = PrincipalMethodArgumentResolver.resolveAuthentication(parameter); - return (value instanceof Authentication auth ? Mono.just(auth) : (Mono) value); + return (value instanceof Authentication auth) ? Mono.just(auth) : (Mono) value; } @Nullable diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/BatchLoaderHandlerMethod.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/BatchLoaderHandlerMethod.java index 0a255542..34f30922 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/BatchLoaderHandlerMethod.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/BatchLoaderHandlerMethod.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.security.Principal; @@ -50,7 +51,7 @@ import org.springframework.util.ClassUtils; */ public class BatchLoaderHandlerMethod extends InvocableHandlerMethodSupport { - private final static boolean springSecurityPresent = ClassUtils.isPresent( + private static final boolean springSecurityPresent = ClassUtils.isPresent( "org.springframework.security.core.context.SecurityContext", AnnotatedControllerConfigurer.class.getClassLoader()); @@ -66,7 +67,6 @@ public class BatchLoaderHandlerMethod extends InvocableHandlerMethodSupport { /** * Invoke the underlying batch loader method with a collection of keys to * return a Map of key-value pairs. - * * @param keys the keys for which to load values * @param environment the environment available to batch loaders * @param the type of keys in the map @@ -80,7 +80,7 @@ public class BatchLoaderHandlerMethod extends InvocableHandlerMethodSupport { Object result = doInvoke(environment.getContext(), args); return toMonoMap(result); } - return toArgsMono(args).flatMap(argValues -> { + return toArgsMono(args).flatMap((argValues) -> { Object result = doInvoke(environment.getContext(), argValues); return toMonoMap(result); }); @@ -89,7 +89,6 @@ public class BatchLoaderHandlerMethod extends InvocableHandlerMethodSupport { /** * Invoke the underlying batch loader method with a collection of input keys * to return a collection of matching values. - * * @param keys the keys for which to load values * @param environment the environment available to batch loaders * @param the type of values returned @@ -101,7 +100,7 @@ public class BatchLoaderHandlerMethod extends InvocableHandlerMethodSupport { Object result = doInvoke(environment.getContext(), args); return toFlux(result); } - return toArgsMono(args).flatMapMany(resolvedArgs -> { + return toArgsMono(args).flatMapMany((resolvedArgs) -> { Object result = doInvoke(environment.getContext(), resolvedArgs); return toFlux(result); }); @@ -164,7 +163,7 @@ public class BatchLoaderHandlerMethod extends InvocableHandlerMethodSupport { } private boolean doesNotHaveAsyncArgs(Object[] args) { - return Arrays.stream(args).noneMatch(arg -> arg instanceof Mono); + return Arrays.stream(args).noneMatch((arg) -> arg instanceof Mono); } @SuppressWarnings("unchecked") @@ -176,7 +175,7 @@ public class BatchLoaderHandlerMethod extends InvocableHandlerMethodSupport { return (Mono>) result; } else if (result instanceof CompletableFuture) { - return Mono.fromFuture((CompletableFuture>) result); + return Mono.fromFuture((CompletableFuture>) result); } return Mono.error(new IllegalStateException("Unexpected return value: " + result)); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ContextValueMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ContextValueMethodArgumentResolver.java index 1335c00f..1537dff9 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ContextValueMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ContextValueMethodArgumentResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.annotation.Annotation; @@ -72,7 +73,7 @@ public class ContextValueMethodArgumentResolver implements HandlerMethodArgument @Nullable GraphQLContext graphQlContext) { Class parameterType = parameter.getParameterType(); - Object value = (graphQlContext != null ? graphQlContext.get(contextValueName) : null); + Object value = (graphQlContext != null) ? graphQlContext.get(contextValueName) : null; boolean isOptional = parameterType.equals(Optional.class); boolean isMono = parameterType.equals(Mono.class); @@ -85,14 +86,14 @@ public class ContextValueMethodArgumentResolver implements HandlerMethodArgument if (value == null) { value = Mono.empty(); } - else if (!( value instanceof Mono)) { + else if (!(value instanceof Mono)) { value = Mono.just(value); } return Mono.just(value); } if (isOptional) { - return (value instanceof Optional ? value : Optional.ofNullable(value)); + return (value instanceof Optional) ? value : Optional.ofNullable(value); } return value; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ContinuationHandlerMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ContinuationHandlerMethodArgumentResolver.java index 51613f45..903e5666 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ContinuationHandlerMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ContinuationHandlerMethodArgumentResolver.java @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import graphql.schema.DataFetchingEnvironment; + import org.springframework.core.MethodParameter; import org.springframework.graphql.data.method.HandlerMethodArgumentResolver; @@ -27,14 +29,14 @@ import org.springframework.graphql.data.method.HandlerMethodArgumentResolver; */ public class ContinuationHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { - @Override - public boolean supportsParameter(MethodParameter parameter) { - return "kotlin.coroutines.Continuation".equals(parameter.getParameterType().getName()); - } + @Override + public boolean supportsParameter(MethodParameter parameter) { + return "kotlin.coroutines.Continuation".equals(parameter.getParameterType().getName()); + } - @Override - public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment environment) { - return null; - } + @Override + public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment environment) { + return null; + } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethod.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethod.java index c7806f96..c6840d1b 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethod.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethod.java @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.Arrays; +import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.function.BiConsumer; @@ -49,6 +51,7 @@ public class DataFetcherHandlerMethod extends DataFetcherHandlerMethodSupport { * @param handlerMethod the handler method * @param resolvers the argument resolvers * @param validationHelper to apply bean validation with + * @param executor an {@link Executor} to use for {@link Callable} return values * @param subscription whether the field being fetched is of subscription type */ public DataFetcherHandlerMethod( @@ -58,7 +61,7 @@ public class DataFetcherHandlerMethod extends DataFetcherHandlerMethodSupport { super(handlerMethod, resolvers, executor); Assert.isTrue(!resolvers.getResolvers().isEmpty(), "No argument resolvers"); - this.validationHelper = (validationHelper != null ? validationHelper : (controller, args) -> {}); + this.validationHelper = (validationHelper != null) ? validationHelper : (controller, args) -> { }; this.subscription = subscription; } @@ -72,9 +75,7 @@ public class DataFetcherHandlerMethod extends DataFetcherHandlerMethodSupport { * The {@code providedArgs} parameter however may supply argument values to * be used directly, i.e. without argument resolution. Provided argument * values are checked before argument resolvers. - * * @param environment the environment to resolve arguments from - * * @return the raw value returned by the invoked method, possibly a * {@code Mono} in case a method argument requires asynchronous resolution; * {@code Mono} is returned if invocation fails. @@ -87,6 +88,8 @@ public class DataFetcherHandlerMethod extends DataFetcherHandlerMethodSupport { /** * Variant of {@link #invoke(DataFetchingEnvironment)} that also accepts * "given" arguments, which are matched by type. + * @param environment the data fetching environment + * @param providedArgs additional arguments to be matched by their type * @since 1.2.0 */ @Nullable @@ -99,17 +102,17 @@ public class DataFetcherHandlerMethod extends DataFetcherHandlerMethodSupport { return Mono.error(ex); } - if (Arrays.stream(args).noneMatch(arg -> arg instanceof Mono)) { + if (Arrays.stream(args).noneMatch((arg) -> arg instanceof Mono)) { return validateAndInvoke(args, environment); } return this.subscription ? - toArgsMono(args).flatMapMany(argValues -> { + toArgsMono(args).flatMapMany((argValues) -> { Object result = validateAndInvoke(argValues, environment); Assert.state(result instanceof Publisher, "Expected a Publisher from a Subscription response"); return Flux.from((Publisher) result); }) : - toArgsMono(args).flatMap(argValues -> { + toArgsMono(args).flatMap((argValues) -> { Object result = validateAndInvoke(argValues, environment); if (result instanceof Mono mono) { return mono; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethodSupport.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethodSupport.java index 10be0587..a0acbc55 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethodSupport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethodSupport.java @@ -66,6 +66,8 @@ public class DataFetcherHandlerMethodSupport extends InvocableHandlerMethodSuppo /** * Get the method argument values for the current request, checking the provided * argument values and falling back to the configured argument resolvers. + * @param environment the data fetching environment to resolve arguments from + * @param providedArgs the arguments provided directly */ protected Object[] getMethodArgumentValues( DataFetchingEnvironment environment, Object... providedArgs) throws Exception { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherMappingInfo.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherMappingInfo.java index 8551a478..6c236574 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherMappingInfo.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetcherMappingInfo.java @@ -84,11 +84,6 @@ public final class DataFetcherMappingInfo { return this.handlerMethod; } - @Override - public int hashCode() { - return getCoordinates().hashCode() * 31; - } - @Override public boolean equals(@Nullable Object other) { if (this == other) { @@ -100,6 +95,11 @@ public final class DataFetcherMappingInfo { return (this.coordinates.equals(otherInfo.coordinates)); } + @Override + public int hashCode() { + return getCoordinates().hashCode() * 31; + } + @Override public String toString() { return this.coordinates + " -> " + getHandlerMethod(); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentMethodArgumentResolver.java index 9d7313f3..577a9e4c 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentMethodArgumentResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.Locale; @@ -27,7 +28,7 @@ import org.springframework.graphql.data.method.HandlerMethodArgumentResolver; /** * Resolver for {@link DataFetchingEnvironment} and related values that can be - * accessed through the {@link DataFetchingEnvironment} such as: + * accessed through the {@link DataFetchingEnvironment}. This includes: *
    *
  • {@link GraphQLContext} *
  • {@link DataFetchingFieldSelectionSet} diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataLoaderMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataLoaderMethodArgumentResolver.java index a23f5aa6..02d2155e 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataLoaderMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/DataLoaderMethodArgumentResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.reflect.ParameterizedType; @@ -41,7 +42,7 @@ import org.springframework.util.Assert; * @since 1.0.0 */ public class DataLoaderMethodArgumentResolver implements HandlerMethodArgumentResolver { - + @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterType().equals(DataLoader.class); @@ -80,8 +81,8 @@ public class DataLoaderMethodArgumentResolver implements HandlerMethodArgumentRe ParameterizedType parameterizedType = (ParameterizedType) genericType; if (parameterizedType.getActualTypeArguments().length == 2) { Type valueType = parameterizedType.getActualTypeArguments()[1]; - return (valueType instanceof Class ? - (Class) valueType : ResolvableType.forType(valueType).resolve()); + return (valueType instanceof Class) ? + (Class) valueType : ResolvableType.forType(valueType).resolve(); } } return null; @@ -92,7 +93,7 @@ public class DataLoaderMethodArgumentResolver implements HandlerMethodArgumentRe @Nullable Class valueType, @Nullable String parameterName) { String message = "Cannot resolve DataLoader for parameter" + - (parameterName != null ? " '" + parameterName + "'" : "[" + parameter.getParameterIndex() + "]" ) + + ((parameterName != null) ? " '" + parameterName + "'" : "[" + parameter.getParameterIndex() + "]") + " in method " + parameter.getMethod().toGenericString() + ". "; if (valueType == null) { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/HandlerDataFetcherExceptionResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/HandlerDataFetcherExceptionResolver.java index 2709e546..e36bc876 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/HandlerDataFetcherExceptionResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/HandlerDataFetcherExceptionResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.List; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/LocalContextValueMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/LocalContextValueMethodArgumentResolver.java index 26e6bcc3..5915bdc9 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/LocalContextValueMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/LocalContextValueMethodArgumentResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import graphql.GraphQLContext; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/PrincipalMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/PrincipalMethodArgumentResolver.java index eb989c90..101c96d8 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/PrincipalMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/PrincipalMethodArgumentResolver.java @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.security.Principal; import graphql.schema.DataFetchingEnvironment; +import reactor.core.publisher.Mono; import org.springframework.core.MethodParameter; import org.springframework.graphql.data.method.HandlerMethodArgumentResolver; @@ -26,7 +28,6 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.ReactiveSecurityContextHolder; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; -import reactor.core.publisher.Mono; /** * Resolver to obtain {@link Principal} from Spring Security context via diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ProjectedPayloadMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ProjectedPayloadMethodArgumentResolver.java index 223347f4..628f7a30 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ProjectedPayloadMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ProjectedPayloadMethodArgumentResolver.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; @@ -75,7 +76,7 @@ public class ProjectedPayloadMethodArgumentResolver implements HandlerMethodArgu Assert.notNull(applicationContext, "ApplicationContext must not be null"); this.projectionFactory.setBeanFactory(applicationContext); ClassLoader classLoader = applicationContext.getClassLoader(); - if(classLoader != null) { + if (classLoader != null) { this.projectionFactory.setBeanClassLoader(classLoader); } } @@ -98,8 +99,8 @@ public class ProjectedPayloadMethodArgumentResolver implements HandlerMethodArgu private static Class getTargetType(MethodParameter parameter) { Class type = parameter.getParameterType(); - return (type.equals(Optional.class) || type.equals(ArgumentValue.class) ? - parameter.nested().getNestedParameterType() : parameter.getParameterType()); + return (type.equals(Optional.class) || type.equals(ArgumentValue.class)) ? + parameter.nested().getNestedParameterType() : parameter.getParameterType(); } @Override @@ -117,15 +118,15 @@ public class ProjectedPayloadMethodArgumentResolver implements HandlerMethodArgu } Map arguments = environment.getArguments(); - Object rawValue = (name != null ? arguments.get(name) : arguments); - Object value = (rawValue != null ? createProjection(targetType, rawValue) : null); + Object rawValue = (name != null) ? arguments.get(name) : arguments; + Object value = (rawValue != null) ? createProjection(targetType, rawValue) : null; if (isOptional) { return Optional.ofNullable(value); } else if (isArgumentValue) { - return (name != null && arguments.containsKey(name) ? - ArgumentValue.ofNullable(value) : ArgumentValue.omitted()); + return (name != null && arguments.containsKey(name)) ? + ArgumentValue.ofNullable(value) : ArgumentValue.omitted(); } else { return value; @@ -140,7 +141,7 @@ public class ProjectedPayloadMethodArgumentResolver implements HandlerMethodArgu * or the map of arguments * @return the created project instance */ - protected Object createProjection(Class targetType, Object rawValue){ + protected Object createProjection(Class targetType, Object rawValue) { return this.projectionFactory.createProjection(targetType, rawValue); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingBeanFactoryInitializationAotProcessor.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingBeanFactoryInitializationAotProcessor.java index bc4676b9..397e9daa 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingBeanFactoryInitializationAotProcessor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingBeanFactoryInitializationAotProcessor.java @@ -54,8 +54,6 @@ import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; import org.springframework.web.bind.annotation.ControllerAdvice; -import static org.springframework.core.annotation.MergedAnnotations.SearchStrategy.TYPE_HIERARCHY; - /** * {@link BeanFactoryInitializationAotProcessor} implementation for registering * runtime hints discoverable through GraphQL controllers, such as: @@ -80,11 +78,10 @@ import static org.springframework.core.annotation.MergedAnnotations.SearchStrate * * @author Brian Clozel * @see org.springframework.graphql.data.method.HandlerMethodArgumentResolver - * @since 1.1.0 */ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryInitializationAotProcessor { - private final static boolean springDataPresent = ClassUtils.isPresent( + private static final boolean springDataPresent = ClassUtils.isPresent( "org.springframework.data.projection.SpelAwareProxyProjectionFactory", SchemaMappingBeanFactoryInitializationAotProcessor.class.getClassLoader()); @@ -94,8 +91,8 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI List> controllers = new ArrayList<>(); List> controllerAdvices = new ArrayList<>(); Arrays.stream(beanFactory.getBeanDefinitionNames()) - .map(beanName -> RegisteredBean.of(beanFactory, beanName).getBeanClass()) - .forEach(beanClass -> { + .map((beanName) -> RegisteredBean.of(beanFactory, beanName).getBeanClass()) + .forEach((beanClass) -> { if (isController(beanClass)) { controllers.add(beanClass); } @@ -107,11 +104,11 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI } private boolean isController(AnnotatedElement element) { - return MergedAnnotations.from(element, TYPE_HIERARCHY).isPresent(Controller.class); + return MergedAnnotations.from(element, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).isPresent(Controller.class); } private boolean isControllerAdvice(AnnotatedElement element) { - return MergedAnnotations.from(element, TYPE_HIERARCHY).isPresent(ControllerAdvice.class); + return MergedAnnotations.from(element, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).isPresent(ControllerAdvice.class); } @@ -124,7 +121,7 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI private final HandlerMethodArgumentResolverComposite argumentResolvers; - public SchemaMappingBeanFactoryInitializationAotContribution(List> controllers, List> controllerAdvices) { + SchemaMappingBeanFactoryInitializationAotContribution(List> controllers, List> controllerAdvices) { this.controllers = controllers; this.controllerAdvices = controllerAdvices; this.argumentResolvers = createArgumentResolvers(); @@ -141,19 +138,19 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI public void applyTo(GenerationContext context, BeanFactoryInitializationCode initializationCode) { RuntimeHints runtimeHints = context.getRuntimeHints(); registerSpringDataSpelSupport(runtimeHints); - this.controllers.forEach(controller -> { + this.controllers.forEach((controller) -> { runtimeHints.reflection().registerType(controller, MemberCategory.INTROSPECT_DECLARED_METHODS); ReflectionUtils.doWithMethods(controller, - method -> processSchemaMappingMethod(runtimeHints, method), + (method) -> processSchemaMappingMethod(runtimeHints, method), this::isGraphQlHandlerMethod); ReflectionUtils.doWithMethods(controller, - method -> processExceptionHandlerMethod(runtimeHints, method), + (method) -> processExceptionHandlerMethod(runtimeHints, method), this::isExceptionHandlerMethod); }); - this.controllerAdvices.forEach(controllerAdvice -> { + this.controllerAdvices.forEach((controllerAdvice) -> { runtimeHints.reflection().registerType(controllerAdvice, MemberCategory.INTROSPECT_DECLARED_METHODS); ReflectionUtils.doWithMethods(controllerAdvice, - method -> processExceptionHandlerMethod(runtimeHints, method), + (method) -> processExceptionHandlerMethod(runtimeHints, method), this::isExceptionHandlerMethod); }); } @@ -163,18 +160,18 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI runtimeHints.reflection() .registerType(SpelAwareProxyProjectionFactory.class) .registerType(TypeReference.of("org.springframework.data.projection.SpelEvaluatingMethodInterceptor$TargetWrapper"), - builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + (builder) -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.INVOKE_PUBLIC_METHODS)); } } private boolean isGraphQlHandlerMethod(AnnotatedElement element) { - MergedAnnotations annotations = MergedAnnotations.from(element, TYPE_HIERARCHY); + MergedAnnotations annotations = MergedAnnotations.from(element, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY); return annotations.isPresent(SchemaMapping.class) || annotations.isPresent(BatchMapping.class); } private boolean isExceptionHandlerMethod(AnnotatedElement element) { - return MergedAnnotations.from(element, TYPE_HIERARCHY).isPresent(GraphQlExceptionHandler.class); + return MergedAnnotations.from(element, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).isPresent(GraphQlExceptionHandler.class); } private void processSchemaMappingMethod(RuntimeHints runtimeHints, Method method) { @@ -229,7 +226,7 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI } - private static class NoHintsRequired implements MethodParameterRuntimeHintsRegistrar { + private static final class NoHintsRequired implements MethodParameterRuntimeHintsRegistrar { @Override public void apply(RuntimeHints runtimeHints) { @@ -242,14 +239,14 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI private final MethodParameter methodParameter; - public ArgumentBindingHints(MethodParameter methodParameter) { + ArgumentBindingHints(MethodParameter methodParameter) { this.methodParameter = methodParameter; } @Override public void apply(RuntimeHints runtimeHints) { Type parameterType = this.methodParameter.getGenericParameterType(); - if (ArgumentValue.class.isAssignableFrom(methodParameter.getParameterType())) { + if (ArgumentValue.class.isAssignableFrom(this.methodParameter.getParameterType())) { parameterType = this.methodParameter.nested().getNestedGenericParameterType(); } bindingRegistrar.registerReflectionHints(runtimeHints.reflection(), parameterType); @@ -261,7 +258,7 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI private final MethodParameter methodParameter; - public DataLoaderHints(MethodParameter methodParameter) { + DataLoaderHints(MethodParameter methodParameter) { this.methodParameter = methodParameter; } @@ -277,7 +274,7 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI private final MethodParameter methodParameter; - public ProjectedPayloadHints(MethodParameter methodParameter) { + ProjectedPayloadHints(MethodParameter methodParameter) { this.methodParameter = methodParameter; } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolver.java index 851ce1b4..30d9e2c7 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SortMethodArgumentResolver.java @@ -57,11 +57,11 @@ public class SortMethodArgumentResolver implements HandlerMethodArgumentResolver Sort sort = this.sortStrategy.extract(environment); if (parameter.isOptional()) { - sort = (sort == Sort.unsorted() ? null : sort); + sort = (sort == Sort.unsorted()) ? null : sort; return Optional.ofNullable(sort); } - return (sort != null ? sort : Sort.unsorted()); + return (sort != null) ? sort : Sort.unsorted(); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SourceMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SourceMethodArgumentResolver.java index 83c0be24..b5fdbea0 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SourceMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SourceMethodArgumentResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.net.URI; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolver.java index e39ef21b..949b39b9 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SubrangeMethodArgumentResolver.java @@ -30,6 +30,7 @@ import org.springframework.util.Assert; * Resolver for a method argument of type {@link Subrange} initialized * from "first", "last", "before", and "after" GraphQL arguments. * + * @param

    the type of position in the subrange * @author Rossen Stoyanchev * @since 1.2.0 */ @@ -62,12 +63,15 @@ public class SubrangeMethodArgumentResolver

    implements HandlerMethodArgumentR forward = false; } } - P pos = (cursor != null ? this.cursorStrategy.fromCursor(cursor) : null); + P pos = (cursor != null) ? this.cursorStrategy.fromCursor(cursor) : null; return createSubrange(pos, count, forward); } /** * Allows subclasses to create an extension of {@link Subrange}. + * @param pos the position in the subrange + * @param count the number of elements in the subrange + * @param forward whether the scroll direction is forward or backward from this position */ protected Subrange

    createSubrange(@Nullable P pos, @Nullable Integer count, boolean forward) { return new Subrange<>(pos, count, forward); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ValidationHelper.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ValidationHelper.java index ea189963..778eb614 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ValidationHelper.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/ValidationHelper.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.annotation.Annotation; @@ -43,9 +44,8 @@ import org.springframework.validation.beanvalidation.SpringValidatorAdapter; * requires bean validation. * * @author Rossen Stoyanchev - * @since 1.2.0 */ -class ValidationHelper { +final class ValidationHelper { private final Validator validator; @@ -62,7 +62,7 @@ class ValidationHelper { * {@link Validated}, {@link Valid}, or {@link Constraint} annotations. */ @Nullable - public BiConsumer getValidationHelperFor(HandlerMethod handlerMethod) { + BiConsumer getValidationHelperFor(HandlerMethod handlerMethod) { boolean requiresMethodValidation = false; Class[] methodValidationGroups = null; @@ -88,18 +88,18 @@ class ValidationHelper { } else if (annot.annotationType().equals(Validated.class)) { Class[] groups = ((Validated) annot).value(); - parameterValidator = (parameterValidator != null ? + parameterValidator = (parameterValidator != null) ? parameterValidator.andThen(new MethodParameterValidator(i, groups)) : - new MethodParameterValidator(i, groups)); + new MethodParameterValidator(i, groups); } } } - BiConsumer result = (requiresMethodValidation ? - new HandlerMethodValidator(handlerMethod, methodValidationGroups) : null); + BiConsumer result = (requiresMethodValidation) ? + new HandlerMethodValidator(handlerMethod, methodValidationGroups) : null; if (parameterValidator != null) { - return (result != null ? result.andThen(parameterValidator) : parameterValidator); + return (result != null) ? result.andThen(parameterValidator) : parameterValidator; } return result; @@ -120,7 +120,7 @@ class ValidationHelper { * {@link Validator} bean declared, or {@code null} otherwise. */ @Nullable - public static ValidationHelper createIfValidatorPresent(ApplicationContext context) { + static ValidationHelper createIfValidatorPresent(ApplicationContext context) { Validator validator = context.getBeanProvider(Validator.class).getIfAvailable(); if (validator instanceof LocalValidatorFactoryBean) { validator = ((LocalValidatorFactoryBean) validator).getValidator(); @@ -128,13 +128,13 @@ class ValidationHelper { else if (validator instanceof SpringValidatorAdapter) { validator = validator.unwrap(Validator.class); } - return (validator != null ? create(validator) : null); + return (validator != null) ? create(validator) : null; } /** * Factory method with a given {@link Validator} instance. */ - public static ValidationHelper create(Validator validator) { + static ValidationHelper create(Validator validator) { return new ValidationHelper(validator); } @@ -151,7 +151,7 @@ class ValidationHelper { HandlerMethodValidator(HandlerMethod handlerMethod, @Nullable Class[] validationGroups) { Assert.notNull(handlerMethod, "HandlerMethod is required"); this.method = handlerMethod.getMethod(); - this.validationGroups = (validationGroups != null ? validationGroups : new Class[] {}); + this.validationGroups = (validationGroups != null) ? validationGroups : new Class[] {}; } @Override @@ -181,7 +181,7 @@ class ValidationHelper { MethodParameterValidator(int index, @Nullable Class[] validationGroups) { this.index = index; - this.validationGroups = (validationGroups != null ? validationGroups : new Class[] {}); + this.validationGroups = (validationGroups != null) ? validationGroups : new Class[] {}; } @Override diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/package-info.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/package-info.java index 9c464ed1..fea82553 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/package-info.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/package-info.java @@ -1,3 +1,19 @@ +/* + * Copyright 2020-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. + * 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. + */ + /** * Resolvers for method parameters of annotated handler methods. */ diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Base64CursorEncoder.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Base64CursorEncoder.java index 333874ba..f201e011 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Base64CursorEncoder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Base64CursorEncoder.java @@ -28,7 +28,6 @@ import java.util.Base64; *

    To create an instance, use {@link CursorEncoder#base64()}. * * @author Rossen Stoyanchev - * @since 1.2.0 */ final class Base64CursorEncoder implements CursorEncoder { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/CompositeConnectionAdapter.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/CompositeConnectionAdapter.java index 06e05e74..4c79a3b8 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/CompositeConnectionAdapter.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/CompositeConnectionAdapter.java @@ -27,7 +27,6 @@ import org.springframework.util.Assert; * the first one that supports a given Object container type, and delegates to it. * * @author Rossen Stoyanchev - * @since 1.2.0 */ final class CompositeConnectionAdapter implements ConnectionAdapter { @@ -45,18 +44,22 @@ final class CompositeConnectionAdapter implements ConnectionAdapter { return (getAdapter(containerType) != null); } + @Override public Collection getContent(Object container) { return getRequiredAdapter(container).getContent(container); } + @Override public boolean hasPrevious(Object container) { return getRequiredAdapter(container).hasPrevious(container); } + @Override public boolean hasNext(Object container) { return getRequiredAdapter(container).hasNext(container); } + @Override public String cursorAt(Object container, int index) { return getRequiredAdapter(container).cursorAt(container, index); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionAdapter.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionAdapter.java index e332261d..f5e7f6f6 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionAdapter.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionAdapter.java @@ -30,26 +30,33 @@ public interface ConnectionAdapter { /** * Whether the adapter supports the given Object container type. + * @param containerType the container type to check for support */ boolean supports(Class containerType); /** * Return the contained items as a List. + * @param the type of objects in the collection + * @param container the container of elements */ Collection getContent(Object container); /** * Whether there are more pages before this one. + * @param container the container of elements */ boolean hasPrevious(Object container); /** * Whether there are more pages after this one. + * @param container the container of elements */ boolean hasNext(Object container); /** * Return a cursor for the item at the given index. + * @param container the container of elements + * @param index the index of an element in the container */ String cursorAt(Object container, int index); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionAdapterSupport.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionAdapterSupport.java index 752d90bb..7fa4886d 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionAdapterSupport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionAdapterSupport.java @@ -22,6 +22,7 @@ import org.springframework.util.Assert; * Convenient base class for implementations of * {@link org.springframework.graphql.data.pagination.ConnectionAdapter}. * + * @param

    the position type * @author Rossen Stoyanchev * @since 1.2.0 */ @@ -32,6 +33,7 @@ public class ConnectionAdapterSupport

    { /** * Constructor with a {@link CursorStrategy} to use. + * @param cursorStrategy the cursor strategy to use */ protected ConnectionAdapterSupport(CursorStrategy

    cursorStrategy) { Assert.notNull(cursorStrategy, "CursorStrategy is required"); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitor.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitor.java index e1a64139..3644510a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/ConnectionFieldTypeVisitor.java @@ -145,7 +145,7 @@ public final class ConnectionFieldTypeVisitor extends GraphQLTypeVisitorStub { @Nullable private static GraphQLObjectType getAsObjectType(@Nullable GraphQLFieldDefinition field) { - return (getType(field) instanceof GraphQLObjectType type ? type : null); + return (getType(field) instanceof GraphQLObjectType type) ? type : null; } @Nullable @@ -164,7 +164,7 @@ public final class ConnectionFieldTypeVisitor extends GraphQLTypeVisitorStub { return null; } GraphQLOutputType type = field.getType(); - return (type instanceof GraphQLNonNull nonNullType ? nonNullType.getWrappedType() : type); + return (type instanceof GraphQLNonNull nonNullType) ? nonNullType.getWrappedType() : type; } @@ -185,7 +185,7 @@ public final class ConnectionFieldTypeVisitor extends GraphQLTypeVisitorStub { */ private record ConnectionDataFetcher(DataFetcher delegate, ConnectionAdapter adapter) implements DataFetcher { - private final static Connection EMPTY_CONNECTION = + private static final Connection EMPTY_CONNECTION = new DefaultConnection<>(Collections.emptyList(), new DefaultPageInfo(null, null, false, false)); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/CursorStrategy.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/CursorStrategy.java index 6691560f..e1805a46 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/CursorStrategy.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/CursorStrategy.java @@ -24,6 +24,7 @@ package org.springframework.graphql.data.pagination; * {@link #withEncoder(CursorStrategy, CursorEncoder)} to further encode and * decode cursor Strings to make them opaque for clients. * + * @param

    the type of position * @author Rossen Stoyanchev * @since 1.2.0 */ @@ -31,6 +32,7 @@ public interface CursorStrategy

    { /** * Whether the strategy supports the given type of position Object. + * @param targetType the type of position to be checked */ boolean supports(Class targetType); @@ -52,6 +54,9 @@ public interface CursorStrategy

    { /** * Decorate the given {@code CursorStrategy} with encoding and decoding * that makes the String cursor opaque to clients. + * @param the type of position for the given strategy + * @param strategy the cursor strategy to decorate + * @param encoder strategy for encoding the cursor */ static EncodingCursorStrategy withEncoder(CursorStrategy strategy, CursorEncoder encoder) { return new EncodingCursorStrategy<>(strategy, encoder); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/EncodingCursorStrategy.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/EncodingCursorStrategy.java index 0f7b9fb9..071260a4 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/EncodingCursorStrategy.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/EncodingCursorStrategy.java @@ -25,6 +25,7 @@ import org.springframework.util.Assert; *

    To create an instance, use * {@link CursorStrategy#withEncoder(CursorStrategy, CursorEncoder)}. * + * @param the type of position * @author Rossen Stoyanchev * @since 1.2.0 */ diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/NoOpCursorEncoder.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/NoOpCursorEncoder.java index 2be8a430..dff4000c 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/NoOpCursorEncoder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/NoOpCursorEncoder.java @@ -22,7 +22,6 @@ package org.springframework.graphql.data.pagination; *

    To create an instance, use {@link CursorEncoder#noOpEncoder()}. * * @author Rossen Stoyanchev - * @since 1.2.0 */ final class NoOpCursorEncoder implements CursorEncoder { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Subrange.java b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Subrange.java index abd98724..bf390fd0 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Subrange.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/pagination/Subrange.java @@ -26,6 +26,7 @@ import org.springframework.lang.Nullable; * Container for parameters that limit result elements to a subrange including a * relative position, number of elements, and direction. * + * @param

    the type of position in the entire collection * @author Rossen Stoyanchev * @since 1.2.0 */ @@ -41,10 +42,13 @@ public class Subrange

    { /** * Constructor with the relative position, count, and direction. + * @param position the position in the entire collection + * @param count the number of elements in the subrange + * @param forward whether the subrange is forward or backward from ths position */ public Subrange(@Nullable P position, @Nullable Integer count, boolean forward) { this.position = Optional.ofNullable(position); - this.count = (count != null ? OptionalInt.of(count) : OptionalInt.empty()); + this.count = (count != null) ? OptionalInt.of(count) : OptionalInt.empty(); this.forward = forward; } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/AbstractSortStrategy.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/AbstractSortStrategy.java index 35890390..ad182c30 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/AbstractSortStrategy.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/AbstractSortStrategy.java @@ -41,7 +41,7 @@ public abstract class AbstractSortStrategy implements SortStrategy { List properties = getProperties(environment); if (!ObjectUtils.isEmpty(properties)) { Sort.Direction direction = getDirection(environment); - direction = (direction != null ? direction : Sort.DEFAULT_DIRECTION); + direction = (direction != null) ? direction : Sort.DEFAULT_DIRECTION; List sortOrders = new ArrayList<>(properties.size()); for (String property : properties) { sortOrders.add(new Sort.Order(direction, property)); @@ -53,11 +53,13 @@ public abstract class AbstractSortStrategy implements SortStrategy { /** * Return the sort properties to use, or an empty list if there are none. + * @param environment the data fetching environment for this operation */ protected abstract List getProperties(DataFetchingEnvironment environment); /** * Return the sort direction to use, or {@code null}. + * @param environment the data fetching environment for this operation */ @Nullable protected abstract Sort.Direction getDirection(DataFetchingEnvironment environment); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/AutoRegistrationRuntimeWiringConfigurer.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/AutoRegistrationRuntimeWiringConfigurer.java index 0f2fe3dd..b551ab40 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/AutoRegistrationRuntimeWiringConfigurer.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/AutoRegistrationRuntimeWiringConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.query; import java.util.List; @@ -42,11 +43,10 @@ import org.springframework.util.Assert; * already have registrations. * * @author Rossen Stoyanchev - * @since 1.0.0 */ class AutoRegistrationRuntimeWiringConfigurer implements RuntimeWiringConfigurer { - private final static Log logger = LogFactory.getLog(AutoRegistrationRuntimeWiringConfigurer.class); + private static final Log logger = LogFactory.getLog(AutoRegistrationRuntimeWiringConfigurer.class); private final Map dataFetcherFactories; @@ -107,7 +107,7 @@ class AutoRegistrationRuntimeWiringConfigurer implements RuntimeWiringConfigurer @Override public boolean providesDataFetcher(FieldWiringEnvironment environment) { - if (dataFetcherFactories.isEmpty()) { + if (AutoRegistrationRuntimeWiringConfigurer.this.dataFetcherFactories.isEmpty()) { return false; } @@ -118,7 +118,7 @@ class AutoRegistrationRuntimeWiringConfigurer implements RuntimeWiringConfigurer String outputTypeName = getOutputTypeName(environment); boolean result = (outputTypeName != null && - dataFetcherFactories.containsKey(outputTypeName) && + AutoRegistrationRuntimeWiringConfigurer.this.dataFetcherFactories.containsKey(outputTypeName) && !hasDataFetcherFor(environment.getFieldDefinition())); if (!result) { @@ -150,7 +150,7 @@ class AutoRegistrationRuntimeWiringConfigurer implements RuntimeWiringConfigurer } private GraphQLType removeNonNullWrapper(GraphQLType outputType) { - return (outputType instanceof GraphQLNonNull wrapper ? wrapper.getWrappedType() : outputType); + return (outputType instanceof GraphQLNonNull wrapper) ? wrapper.getWrappedType() : outputType; } private boolean isConnectionType(GraphQLType type) { @@ -162,7 +162,7 @@ class AutoRegistrationRuntimeWiringConfigurer implements RuntimeWiringConfigurer private boolean hasDataFetcherFor(FieldDefinition fieldDefinition) { if (this.existingQueryDataFetcherPredicate == null) { Map map = this.builder.build().getDataFetcherForType("Query"); - this.existingQueryDataFetcherPredicate = fieldName -> map.get(fieldName) != null; + this.existingQueryDataFetcherPredicate = (fieldName) -> map.get(fieldName) != null; } return this.existingQueryDataFetcherPredicate.test(fieldDefinition.getName()); } @@ -171,7 +171,7 @@ class AutoRegistrationRuntimeWiringConfigurer implements RuntimeWiringConfigurer if (logger.isTraceEnabled()) { String query = environment.getFieldDefinition().getName(); logger.trace((match ? "Matched" : "Skipped") + - " output typeName " + (typeName != null ? "'" + typeName + "'" : "null") + + " output typeName " + ((typeName != null) ? "'" + typeName + "'" : "null") + " for query '" + query + "'"); } } @@ -182,12 +182,12 @@ class AutoRegistrationRuntimeWiringConfigurer implements RuntimeWiringConfigurer String outputTypeName = getOutputTypeName(environment); logTraceMessage(environment, outputTypeName, true); - DataFetcherFactory factory = dataFetcherFactories.get(outputTypeName); + DataFetcherFactory factory = AutoRegistrationRuntimeWiringConfigurer.this.dataFetcherFactories.get(outputTypeName); Assert.notNull(factory, "Expected DataFetcher factory for typeName '" + outputTypeName + "'"); GraphQLType type = removeNonNullWrapper(environment.getFieldType()); return (isConnectionType(type) ? factory.scrollable() : - (type instanceof GraphQLList ? factory.many() : factory.single())); + (type instanceof GraphQLList) ? factory.many() : factory.single()); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/JsonKeysetCursorStrategy.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/JsonKeysetCursorStrategy.java index a8437ca6..75aff66f 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/JsonKeysetCursorStrategy.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/JsonKeysetCursorStrategy.java @@ -86,6 +86,7 @@ public final class JsonKeysetCursorStrategy implements CursorStrategy fromCursor(String cursor) { DataBuffer buffer = this.bufferFactory.wrap(cursor.getBytes(StandardCharsets.UTF_8)); Map map = ((Decoder>) this.decoder).decode(buffer, MAP_TYPE, null, null); - return (map != null ? map : Collections.emptyMap()); + return (map != null) ? map : Collections.emptyMap(); } @@ -136,9 +137,9 @@ public final class JsonKeysetCursorStrategy implements CursorStrategy propertyPaths; @@ -54,9 +53,9 @@ class PropertySelection { /** - * @return the property paths as list. + * Return the property paths as list. */ - public List toList() { + List toList() { return this.propertyPaths.stream().map(PropertyPath::toDotPath).toList(); } @@ -64,14 +63,13 @@ class PropertySelection { /** * Create a property selection for the given {@link TypeInformation type} and * {@link DataFetchingFieldSelectionSet}. - * * @param typeInfo the type to inspect * @param selectionSet the field selection to apply * @return a property selection holding all selectable property paths. */ - public static PropertySelection create(TypeInformation typeInfo, DataFetchingFieldSelectionSet selectionSet) { + static PropertySelection create(TypeInformation typeInfo, DataFetchingFieldSelectionSet selectionSet) { FieldSelection selection = new DataFetchingFieldSelection(selectionSet); - List paths = getPropertyPaths(typeInfo, selection, path -> PropertyPath.from(path, typeInfo)); + List paths = getPropertyPaths(typeInfo, selection, (path) -> PropertyPath.from(path, typeInfo)); return new PropertySelection(paths); } @@ -111,8 +109,8 @@ class PropertySelection { private static boolean isConnectionEdges(SelectedField selectedField) { return selectedField.getName().equals("edges") && - selectedField.getParentField().getType() instanceof GraphQLNamedOutputType namedType && - namedType.getName().endsWith("Connection"); + selectedField.getParentField().getType() instanceof GraphQLNamedOutputType namedType && + namedType.getName().endsWith("Connection"); } private static boolean isConnectionEdgeNode(SelectedField selectedField) { @@ -141,13 +139,12 @@ class PropertySelection { interface FieldSelection extends Iterable { /** - * @return {@code true} if the field selection is empty + * Return {@code true} if the field selection is empty. */ boolean isEmpty(); /** * Obtain the field selection (nested fields) for a given {@code field}. - * * @param field the field for which nested fields should be obtained * @return the field selection. Can be empty. */ @@ -174,7 +171,7 @@ class PropertySelection { @Override public boolean isEmpty() { - return selectedFields.isEmpty(); + return this.selectedFields.isEmpty(); } @Override @@ -183,14 +180,14 @@ class PropertySelection { for (SelectedField selectedField : this.allFields) { if (field.equals(selectedField.getParentField())) { - selectedFields = (selectedFields != null ? selectedFields : new ArrayList<>()); + selectedFields = (selectedFields != null) ? selectedFields : new ArrayList<>(); selectedFields.add(selectedField); } } - return (selectedFields != null ? + return (selectedFields != null) ? new DataFetchingFieldSelection(selectedFields, this.allFields) : - EmptyFieldSelection.INSTANCE); + EmptyFieldSelection.INSTANCE; } @Override diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/QueryByExampleDataFetcher.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/QueryByExampleDataFetcher.java index 36d5f5ae..434cfce5 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/QueryByExampleDataFetcher.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/QueryByExampleDataFetcher.java @@ -100,7 +100,7 @@ import org.springframework.validation.BindException; */ public abstract class QueryByExampleDataFetcher { - private final static Log logger = LogFactory.getLog(QueryByExampleDataFetcher.class); + private static final Log logger = LogFactory.getLog(QueryByExampleDataFetcher.class); private final TypeInformation domainType; @@ -146,7 +146,7 @@ public abstract class QueryByExampleDataFetcher { List definedArguments = environment.getFieldDefinition().getArguments(); if (definedArguments.size() == 1) { String name = definedArguments.get(0).getName(); - if (arguments.get(name) instanceof Map) { + if (arguments.get(name) instanceof Map) { return name; } } @@ -201,6 +201,8 @@ public abstract class QueryByExampleDataFetcher { * without a {@code CursorStrategy} and default {@link ScrollSubrange}. * For default values, see the respective methods on {@link Builder} and * {@link ReactiveBuilder}. + * @param executors repositories to consider for registration + * @param reactiveExecutors reactive repositories to consider for registration */ public static RuntimeWiringConfigurer autoRegistrationConfigurer( List> executors, @@ -217,7 +219,6 @@ public abstract class QueryByExampleDataFetcher { * *

    Note: This applies only to top-level queries and * repositories annotated with {@link GraphQlRepository @GraphQlRepository}. - * * @param executors repositories to consider for registration * @param reactiveExecutors reactive repositories to consider for registration * @param cursorStrategy for decoding cursors in pagination requests; @@ -296,7 +297,7 @@ public abstract class QueryByExampleDataFetcher { @SuppressWarnings({"unchecked", "rawtypes"}) private static Builder customize(QueryByExampleExecutor executor, Builder builder) { - if(executor instanceof QueryByExampleBuilderCustomizer customizer){ + if (executor instanceof QueryByExampleBuilderCustomizer customizer) { return customizer.customize(builder); } return builder; @@ -304,7 +305,7 @@ public abstract class QueryByExampleDataFetcher { @SuppressWarnings({"unchecked", "rawtypes"}) private static ReactiveBuilder customize(ReactiveQueryByExampleExecutor executor, ReactiveBuilder builder) { - if(executor instanceof ReactiveQueryByExampleBuilderCustomizer customizer){ + if (executor instanceof ReactiveQueryByExampleBuilderCustomizer customizer) { return customizer.customize(builder); } return builder; @@ -362,6 +363,7 @@ public abstract class QueryByExampleDataFetcher { * into the target {@code projectionType}. Projection types can be * either interfaces with property getters to expose or regular classes * outside the entity type hierarchy for DTO projections. + * @param

    the projection type * @param projectionType projection type * @return a new {@link Builder} instance with all previously * configured options and {@code projectionType} applied @@ -395,6 +397,8 @@ public abstract class QueryByExampleDataFetcher { * from the beginning, or {@link KeysetScrollPosition#reverse()} the same * to go back from the end. *

    By default a count of 20 and {@link ScrollPosition#offset()} are used. + * @param defaultCount the default count of elements in the subrange + * @param defaultPosition function that returns a default {@code ScrollPosition} * @since 1.2.5 */ public Builder defaultScrollSubrange( @@ -409,6 +413,7 @@ public abstract class QueryByExampleDataFetcher { * not specify a cursor and/or a count of items. *

    By default, this is {@link OffsetScrollPosition#offset()} with a * count of 20. + * @param defaultSubrange the default scroll subrange * @return a new {@link Builder} instance with all previously configured * options and {@code Sort} applied * @deprecated in favor of {@link #defaultScrollSubrange(int, Function)} @@ -418,8 +423,8 @@ public abstract class QueryByExampleDataFetcher { public Builder defaultScrollSubrange(@Nullable ScrollSubrange defaultSubrange) { return new Builder<>(this.executor, this.domainType, this.resultType, this.cursorStrategy, - (defaultSubrange != null ? defaultSubrange.count().getAsInt() : null), - (defaultSubrange != null ? forward -> defaultSubrange.position().get() : null), + (defaultSubrange != null) ? defaultSubrange.count().getAsInt() : null, + (defaultSubrange != null) ? (forward) -> defaultSubrange.position().get() : null, this.sort); } @@ -457,9 +462,9 @@ public abstract class QueryByExampleDataFetcher { public DataFetcher> scrollable() { return new ScrollableEntityFetcher<>( this.executor, this.domainType, this.resultType, - (this.cursorStrategy != null ? this.cursorStrategy : RepositoryUtils.defaultCursorStrategy()), - (this.defaultScrollCount != null ? this.defaultScrollCount : RepositoryUtils.defaultScrollCount()), - (this.defaultScrollPosition != null ? this.defaultScrollPosition : RepositoryUtils.defaultScrollPosition()), + (this.cursorStrategy != null) ? this.cursorStrategy : RepositoryUtils.defaultCursorStrategy(), + (this.defaultScrollCount != null) ? this.defaultScrollCount : RepositoryUtils.defaultScrollCount(), + (this.defaultScrollPosition != null) ? this.defaultScrollPosition : RepositoryUtils.defaultScrollPosition(), this.sort); } @@ -472,7 +477,7 @@ public abstract class QueryByExampleDataFetcher { * Auto-registration}, which detects if a repository implements this * interface and applies it accordingly. * - * @param + * @param the domain type * @since 1.1.1 */ public interface QueryByExampleBuilderCustomizer { @@ -538,13 +543,14 @@ public abstract class QueryByExampleDataFetcher { * into the target {@code projectionType}. Projection types can be * either interfaces with property getters to expose or regular classes * outside the entity type hierarchy for DTO projections. + * @param

    projection type * @param projectionType projection type * @return a new {@link ReactiveBuilder} instance with all previously * configured options and {@code projectionType} applied */ public

    ReactiveBuilder projectAs(Class

    projectionType) { Assert.notNull(projectionType, "Projection type must not be null"); - return new ReactiveBuilder<>(this.executor, this.domainType, + return new ReactiveBuilder<>(this.executor, this.domainType, projectionType, this.cursorStrategy, this.defaultScrollCount, this.defaultScrollPosition, this.sort); } @@ -571,6 +577,8 @@ public abstract class QueryByExampleDataFetcher { * from the beginning, or {@link KeysetScrollPosition#reverse()} the same * to go back from the end. *

    By default a count of 20 and {@link ScrollPosition#offset()} are used. + * @param defaultCount the default count of elements in the subrange + * @param defaultPosition function that returns a default {@code ScrollPosition} * @since 1.2.5 */ public ReactiveBuilder defaultScrollSubrange( @@ -585,6 +593,7 @@ public abstract class QueryByExampleDataFetcher { * not specify a cursor and/or a count of items. *

    By default, this is {@link OffsetScrollPosition#offset()} with a * count of 20. + * @param defaultSubrange the default scroll subrange * @return a new {@link Builder} instance with all previously configured * options and {@code Sort} applied * @deprecated in favor of {@link #defaultScrollSubrange(int, Function)} @@ -594,8 +603,8 @@ public abstract class QueryByExampleDataFetcher { public ReactiveBuilder defaultScrollSubrange(@Nullable ScrollSubrange defaultSubrange) { return new ReactiveBuilder<>(this.executor, this.domainType, this.resultType, this.cursorStrategy, - (defaultSubrange != null ? defaultSubrange.count().getAsInt() : null), - (defaultSubrange != null ? forward -> defaultSubrange.position().get() : null), + (defaultSubrange != null) ? defaultSubrange.count().getAsInt() : null, + (defaultSubrange != null) ? (forward) -> defaultSubrange.position().get() : null, this.sort); } @@ -633,9 +642,9 @@ public abstract class QueryByExampleDataFetcher { public DataFetcher>> scrollable() { return new ReactiveScrollableEntityFetcher<>( this.executor, this.domainType, this.resultType, - (this.cursorStrategy != null ? this.cursorStrategy : RepositoryUtils.defaultCursorStrategy()), - (this.defaultScrollCount != null ? this.defaultScrollCount : RepositoryUtils.defaultScrollCount()), - (this.defaultScrollPosition != null ? this.defaultScrollPosition : RepositoryUtils.defaultScrollPosition()), + (this.cursorStrategy != null) ? this.cursorStrategy : RepositoryUtils.defaultCursorStrategy(), + (this.defaultScrollCount != null) ? this.defaultScrollCount : RepositoryUtils.defaultScrollCount(), + (this.defaultScrollPosition != null) ? this.defaultScrollPosition : RepositoryUtils.defaultScrollPosition(), this.sort); } @@ -647,8 +656,7 @@ public abstract class QueryByExampleDataFetcher { *

    This is supported by {@link #autoRegistrationConfigurer(List, List) * Auto-registration}, which detects if a repository implements this * interface and applies it accordingly. - * - * @param + * @param the domain type * @since 1.1.1 */ public interface ReactiveQueryByExampleBuilderCustomizer { @@ -688,7 +696,7 @@ public abstract class QueryByExampleDataFetcher { @Override @SuppressWarnings({"ConstantConditions", "unchecked"}) public R get(DataFetchingEnvironment env) throws BindException { - return this.executor.findBy(buildExample(env), query -> { + return this.executor.findBy(buildExample(env), (query) -> { FluentQuery.FetchableFluentQuery queryToUse = (FluentQuery.FetchableFluentQuery) query; if (this.sort.isSorted()) { @@ -737,7 +745,7 @@ public abstract class QueryByExampleDataFetcher { @Override @SuppressWarnings("unchecked") public Iterable get(DataFetchingEnvironment env) throws BindException { - return this.executor.findBy(buildExample(env), query -> { + return this.executor.findBy(buildExample(env), (query) -> { FluentQuery.FetchableFluentQuery queryToUse = (FluentQuery.FetchableFluentQuery) query; if (this.sort.isSorted()) { @@ -834,7 +842,7 @@ public abstract class QueryByExampleDataFetcher { @Override @SuppressWarnings("unchecked") public Mono get(DataFetchingEnvironment env) throws BindException { - return this.executor.findBy(buildExample(env), query -> { + return this.executor.findBy(buildExample(env), (query) -> { FluentQuery.ReactiveFluentQuery queryToUse = (FluentQuery.ReactiveFluentQuery) query; if (this.sort.isSorted()) { @@ -882,7 +890,7 @@ public abstract class QueryByExampleDataFetcher { @Override @SuppressWarnings("unchecked") public Flux get(DataFetchingEnvironment env) throws BindException { - return this.executor.findBy(buildExample(env), query -> { + return this.executor.findBy(buildExample(env), (query) -> { FluentQuery.ReactiveFluentQuery queryToUse = (FluentQuery.ReactiveFluentQuery) query; if (this.sort.isSorted()) { @@ -949,7 +957,7 @@ public abstract class QueryByExampleDataFetcher { @Override @SuppressWarnings("unchecked") public Mono> get(DataFetchingEnvironment env) throws BindException { - return this.executor.findBy(buildExample(env), query -> { + return this.executor.findBy(buildExample(env), (query) -> { FluentQuery.ReactiveFluentQuery queryToUse = (FluentQuery.ReactiveFluentQuery) query; if (this.sort.isSorted()) { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/QuerydslDataFetcher.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/QuerydslDataFetcher.java index ed233d8e..53a84f4f 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/QuerydslDataFetcher.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/QuerydslDataFetcher.java @@ -106,7 +106,7 @@ import org.springframework.util.MultiValueMap; */ public abstract class QuerydslDataFetcher { - private final static Log logger = LogFactory.getLog(QueryByExampleDataFetcher.class); + private static final Log logger = LogFactory.getLog(QueryByExampleDataFetcher.class); private static final QuerydslPredicateBuilder BUILDER = new QuerydslPredicateBuilder( DefaultConversionService.getSharedInstance(), SimpleEntityPathResolver.INSTANCE); @@ -152,7 +152,7 @@ public abstract class QuerydslDataFetcher { for (Map.Entry entry : getArgumentValues(environment).entrySet()) { Object value = entry.getValue(); - List values = (value instanceof List ? (List) value : Collections.singletonList(value)); + List values = (value instanceof List) ? (List) value : Collections.singletonList(value); parameters.put(entry.getKey(), values); } @@ -224,6 +224,8 @@ public abstract class QuerydslDataFetcher { * without a {@code CursorStrategy} and default {@link ScrollSubrange}. * For default values, see the respective methods on {@link Builder} and * {@link ReactiveBuilder}. + * @param executors repositories to consider for registration + * @param reactiveExecutors reactive repositories to consider for registration */ public static RuntimeWiringConfigurer autoRegistrationConfigurer( List> executors, @@ -243,7 +245,6 @@ public abstract class QuerydslDataFetcher { * If a repository is also an instance of {@link QuerydslBinderCustomizer}, * this is transparently detected and applied through the * {@code QuerydslDataFetcher} builder methods. - * * @param executors repositories to consider for registration * @param reactiveExecutors reactive repositories to consider for registration * @param cursorStrategy for decoding cursors in pagination requests; @@ -327,7 +328,7 @@ public abstract class QuerydslDataFetcher { @SuppressWarnings({"unchecked", "rawtypes"}) private static Builder customize(QuerydslPredicateExecutor executor, Builder builder) { - if(executor instanceof QuerydslBuilderCustomizer customizer){ + if (executor instanceof QuerydslBuilderCustomizer customizer) { return customizer.customize(builder); } return builder; @@ -335,7 +336,7 @@ public abstract class QuerydslDataFetcher { @SuppressWarnings({"unchecked", "rawtypes"}) private static ReactiveBuilder customize(ReactiveQuerydslPredicateExecutor executor, ReactiveBuilder builder) { - if(executor instanceof ReactiveQuerydslBuilderCustomizer customizer){ + if (executor instanceof ReactiveQuerydslBuilderCustomizer customizer) { return customizer.customize(builder); } return builder; @@ -343,9 +344,9 @@ public abstract class QuerydslDataFetcher { @SuppressWarnings("rawtypes") private static QuerydslBinderCustomizer customizer(Object executor) { - return (executor instanceof QuerydslBinderCustomizer ? + return (executor instanceof QuerydslBinderCustomizer) ? (QuerydslBinderCustomizer>) executor : - NO_OP_BINDER_CUSTOMIZER); + NO_OP_BINDER_CUSTOMIZER; } @@ -403,6 +404,7 @@ public abstract class QuerydslDataFetcher { * into the target {@code projectionType}. Projection types can be * either interfaces with property getters to expose or regular classes * outside the entity type hierarchy for DTO projections. + * @param

    the type of projection * @param projectionType projection type * @return a new {@link Builder} instance with all previously * configured options and {@code projectionType} applied @@ -438,6 +440,8 @@ public abstract class QuerydslDataFetcher { * from the beginning, or {@link KeysetScrollPosition#reverse()} the same * to go back from the end. *

    By default a count of 20 and {@link ScrollPosition#offset()} are used. + * @param defaultCount the default element count in the subrange + * @param defaultPosition the default scroll position * @since 1.2.5 */ public Builder defaultScrollSubrange( @@ -451,6 +455,7 @@ public abstract class QuerydslDataFetcher { * Configure a {@link ScrollSubrange} to use when a paginated request does * not specify a cursor and/or a count of items. *

    By default, this is {@link OffsetScrollPosition#offset()} with a count of 20. + * @param defaultSubrange the default scroll subrange * @return a new {@link Builder} instance * @since 1.2.0 * @deprecated in favor of {@link #defaultScrollSubrange(int, Function)} @@ -459,8 +464,8 @@ public abstract class QuerydslDataFetcher { @Deprecated(since = "1.2.5", forRemoval = true) public Builder defaultScrollSubrange(@Nullable ScrollSubrange defaultSubrange) { return new Builder<>(this.executor, this.domainType, this.resultType, this.cursorStrategy, - (defaultSubrange != null ? defaultSubrange.count().getAsInt() : null), - (defaultSubrange != null ? forward -> defaultSubrange.position().get() : null), + (defaultSubrange != null) ? defaultSubrange.count().getAsInt() : null, + (defaultSubrange != null) ? (forward) -> defaultSubrange.position().get() : null, this.sort, this.customizer); } @@ -474,7 +479,7 @@ public abstract class QuerydslDataFetcher { Assert.notNull(sort, "Sort must not be null"); return new Builder<>(this.executor, this.domainType, this.resultType, this.cursorStrategy, this.defaultScrollCount, this.defaultScrollPosition, - sort, customizer); + sort, this.customizer); } /** @@ -484,7 +489,6 @@ public abstract class QuerydslDataFetcher { * itself, this is automatically detected and applied during * {@link #autoRegistrationConfigurer(List, List) auto-registration}. * For manual registration, you will need to use this method to apply it. - * * @param customizer to customize the binding of the GraphQL request to * Querydsl Predicate * @return a new {@link Builder} instance with all previously configured @@ -521,9 +525,9 @@ public abstract class QuerydslDataFetcher { public DataFetcher> scrollable() { return new ScrollableEntityFetcher<>( this.executor, this.domainType, this.resultType, - (this.cursorStrategy != null ? this.cursorStrategy : RepositoryUtils.defaultCursorStrategy()), - (this.defaultScrollCount != null ? this.defaultScrollCount : RepositoryUtils.defaultScrollCount()), - (this.defaultScrollPosition != null ? this.defaultScrollPosition : RepositoryUtils.defaultScrollPosition()), + (this.cursorStrategy != null) ? this.cursorStrategy : RepositoryUtils.defaultCursorStrategy(), + (this.defaultScrollCount != null) ? this.defaultScrollCount : RepositoryUtils.defaultScrollCount(), + (this.defaultScrollPosition != null) ? this.defaultScrollPosition : RepositoryUtils.defaultScrollPosition(), this.sort, this.customizer); } @@ -532,12 +536,12 @@ public abstract class QuerydslDataFetcher { /** * Callback interface that can be used to customize QuerydslDataFetcher - * {@link Builder} to change its configuration. + * {@link Builder} to change its configuration. *

    This is supported by {@link #autoRegistrationConfigurer(List, List) * Auto-registration}, which detects if a repository implements this * interface and applies it accordingly. * - * @param + * @param the domain type * @since 1.1.1 */ public interface QuerydslBuilderCustomizer { @@ -606,6 +610,7 @@ public abstract class QuerydslDataFetcher { * into the target {@code projectionType}. Projection types can be * either interfaces with property getters to expose or regular classes * outside the entity type hierarchy for DTO projections. + * @param

    projection type * @param projectionType projection type * @return a new {@link Builder} instance with all previously * configured options and {@code projectionType} applied @@ -641,6 +646,8 @@ public abstract class QuerydslDataFetcher { * from the beginning, or {@link KeysetScrollPosition#reverse()} the same * to go back from the end. *

    By default a count of 20 and {@link ScrollPosition#offset()} are used. + * @param defaultCount the default element count in the subrange + * @param defaultPosition function that returns the default scroll position * @since 1.2.5 */ public ReactiveBuilder defaultScrollSubrange( @@ -654,6 +661,7 @@ public abstract class QuerydslDataFetcher { * Configure a {@link ScrollSubrange} to use when a paginated request does * not specify a cursor and/or a count of items. *

    By default, this is {@link OffsetScrollPosition#offset()} with a count of 20. + * @param defaultSubrange the default scroll subrange * @return a new {@link Builder} instance * @since 1.2.0 * @deprecated in favor of {@link #defaultScrollSubrange(int, Function)} @@ -663,8 +671,8 @@ public abstract class QuerydslDataFetcher { public ReactiveBuilder defaultScrollSubrange(@Nullable ScrollSubrange defaultSubrange) { return new ReactiveBuilder<>(this.executor, this.domainType, this.resultType, this.cursorStrategy, - (defaultSubrange != null ? defaultSubrange.count().getAsInt() : null), - (defaultSubrange != null ? forward -> defaultSubrange.position().get() : null), + (defaultSubrange != null) ? defaultSubrange.count().getAsInt() : null, + (defaultSubrange != null) ? (forward) -> defaultSubrange.position().get() : null, this.sort, this.customizer); } @@ -688,7 +696,6 @@ public abstract class QuerydslDataFetcher { * itself, this is automatically detected and applied during * {@link #autoRegistrationConfigurer(List, List) auto-registration}. * For manual registration, you will need to use this method to apply it. - * * @param customizer to customize the GraphQL query to Querydsl * Predicate binding with * @return a new {@link Builder} instance with all previously configured @@ -725,9 +732,9 @@ public abstract class QuerydslDataFetcher { public DataFetcher>> scrollable() { return new ReactiveScrollableEntityFetcher<>( this.executor, this.domainType, this.resultType, - (this.cursorStrategy != null ? this.cursorStrategy : RepositoryUtils.defaultCursorStrategy()), - (this.defaultScrollCount != null ? this.defaultScrollCount : RepositoryUtils.defaultScrollCount()), - (this.defaultScrollPosition != null ? this.defaultScrollPosition : RepositoryUtils.defaultScrollPosition()), + (this.cursorStrategy != null) ? this.cursorStrategy : RepositoryUtils.defaultCursorStrategy(), + (this.defaultScrollCount != null) ? this.defaultScrollCount : RepositoryUtils.defaultScrollCount(), + (this.defaultScrollPosition != null) ? this.defaultScrollPosition : RepositoryUtils.defaultScrollPosition(), this.sort, this.customizer); } @@ -740,8 +747,7 @@ public abstract class QuerydslDataFetcher { *

    This is supported by {@link #autoRegistrationConfigurer(List, List) * Auto-registration}, which detects if a repository implements this * interface and applies it accordingly. - * - * @param + * @param the domain type * @since 1.1.1 */ public interface ReactiveQuerydslBuilderCustomizer { @@ -783,15 +789,15 @@ public abstract class QuerydslDataFetcher { @Override @SuppressWarnings({"ConstantConditions", "unchecked"}) public R get(DataFetchingEnvironment env) { - return this.executor.findBy(buildPredicate(env), query -> { + return this.executor.findBy(buildPredicate(env), (query) -> { FetchableFluentQuery queryToUse = (FetchableFluentQuery) query; - if (this.sort.isSorted()){ + if (this.sort.isSorted()) { queryToUse = queryToUse.sortBy(this.sort); } Class resultType = this.resultType; - if (requiresProjection(resultType)){ + if (requiresProjection(resultType)) { queryToUse = queryToUse.as(resultType); } else { @@ -833,14 +839,14 @@ public abstract class QuerydslDataFetcher { @Override @SuppressWarnings("unchecked") public Iterable get(DataFetchingEnvironment env) { - return this.executor.findBy(buildPredicate(env), query -> { + return this.executor.findBy(buildPredicate(env), (query) -> { FetchableFluentQuery queryToUse = (FetchableFluentQuery) query; - if (this.sort.isSorted()){ + if (this.sort.isSorted()) { queryToUse = queryToUse.sortBy(this.sort); } - if (requiresProjection(this.resultType)){ + if (requiresProjection(this.resultType)) { queryToUse = queryToUse.as(this.resultType); } else { @@ -926,14 +932,14 @@ public abstract class QuerydslDataFetcher { @Override @SuppressWarnings("unchecked") public Mono get(DataFetchingEnvironment env) { - return this.executor.findBy(buildPredicate(env), query -> { + return this.executor.findBy(buildPredicate(env), (query) -> { FluentQuery.ReactiveFluentQuery queryToUse = (FluentQuery.ReactiveFluentQuery) query; - if (this.sort.isSorted()){ + if (this.sort.isSorted()) { queryToUse = queryToUse.sortBy(this.sort); } - if (requiresProjection(this.resultType)){ + if (requiresProjection(this.resultType)) { queryToUse = queryToUse.as(this.resultType); } else { @@ -976,14 +982,14 @@ public abstract class QuerydslDataFetcher { @Override @SuppressWarnings("unchecked") public Flux get(DataFetchingEnvironment env) { - return this.executor.findBy(buildPredicate(env), query -> { + return this.executor.findBy(buildPredicate(env), (query) -> { FluentQuery.ReactiveFluentQuery queryToUse = (FluentQuery.ReactiveFluentQuery) query; - if (this.sort.isSorted()){ + if (this.sort.isSorted()) { queryToUse = queryToUse.sortBy(this.sort); } - if (requiresProjection(this.resultType)){ + if (requiresProjection(this.resultType)) { queryToUse = queryToUse.as(this.resultType); } else { @@ -1046,14 +1052,14 @@ public abstract class QuerydslDataFetcher { @Override @SuppressWarnings("unchecked") public Mono> get(DataFetchingEnvironment env) { - return this.executor.findBy(buildPredicate(env), query -> { + return this.executor.findBy(buildPredicate(env), (query) -> { FluentQuery.ReactiveFluentQuery queryToUse = (FluentQuery.ReactiveFluentQuery) query; - if (this.sort.isSorted()){ + if (this.sort.isSorted()) { queryToUse = queryToUse.sortBy(this.sort); } - if (requiresProjection(this.resultType)){ + if (requiresProjection(this.resultType)) { queryToUse = queryToUse.as(this.resultType); } else { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/RepositoryUtils.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/RepositoryUtils.java index 4c18a242..b99c2434 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/RepositoryUtils.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/RepositoryUtils.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.query; import java.lang.reflect.Type; @@ -40,16 +41,19 @@ import org.springframework.util.StringUtils; * * @author Rossen Stoyanchev * @author Oliver Drotbohm - * @since 1.0.0 */ -class RepositoryUtils { +final class RepositoryUtils { + + private RepositoryUtils() { + + } @SuppressWarnings("unchecked") - public static Class getDomainType(Object executor) { + static Class getDomainType(Object executor) { return (Class) getRepositoryMetadata(executor).getDomainType(); } - public static RepositoryMetadata getRepositoryMetadata(Object executor) { + static RepositoryMetadata getRepositoryMetadata(Object executor) { Assert.isInstanceOf(Repository.class, executor); Type[] genericInterfaces = executor.getClass().getGenericInterfaces(); @@ -68,7 +72,7 @@ class RepositoryUtils { } @Nullable - public static String getGraphQlTypeName(Object repository) { + static String getGraphQlTypeName(Object repository) { GraphQlRepository annotation = AnnotatedElementUtils.findMergedAnnotation(repository.getClass(), GraphQlRepository.class); @@ -81,19 +85,19 @@ class RepositoryUtils { } - public static CursorStrategy defaultCursorStrategy() { + static CursorStrategy defaultCursorStrategy() { return CursorStrategy.withEncoder(new ScrollPositionCursorStrategy(), CursorEncoder.base64()); } - public static int defaultScrollCount() { + static int defaultScrollCount() { return 20; } - public static Function defaultScrollPosition() { - return forward -> ScrollPosition.offset(); + static Function defaultScrollPosition() { + return (forward) -> ScrollPosition.offset(); } - public static ScrollSubrange getScrollSubrange( + static ScrollSubrange getScrollSubrange( DataFetchingEnvironment env, CursorStrategy cursorStrategy) { boolean forward = true; @@ -106,7 +110,7 @@ class RepositoryUtils { forward = false; } } - ScrollPosition pos = (cursor != null ? cursorStrategy.fromCursor(cursor) : null); + ScrollPosition pos = (cursor != null) ? cursorStrategy.fromCursor(cursor) : null; return ScrollSubrange.create(pos, count, forward); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollPositionCursorStrategy.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollPositionCursorStrategy.java index 55c87735..52893894 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollPositionCursorStrategy.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollPositionCursorStrategy.java @@ -51,6 +51,7 @@ public final class ScrollPositionCursorStrategy implements CursorStrategy> keysetCursorStrategy) { Assert.notNull(keysetCursorStrategy, "'keysetCursorStrategy' is required"); @@ -80,7 +81,7 @@ public final class ScrollPositionCursorStrategy implements CursorStrategy 0 ? index : 0); + return ScrollPosition.offset((index > 0) ? index : 0); } else if (cursor.startsWith(KEYSET_PREFIX)) { Map keys = this.keysetCursorStrategy.fromCursor(cursor.substring(2)); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollSubrange.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollSubrange.java index 8507becd..488bf2f1 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollSubrange.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/ScrollSubrange.java @@ -49,6 +49,9 @@ public final class ScrollSubrange extends Subrange { /** * Public constructor. + * @param pos the reference position, or {@code null} if not specified + * @param count how many to return, or {@code null} if not specified + * @param forward whether scroll forward (true) or backward (false) * @deprecated in favor of {@link #create}, to be removed in 1.3. */ @Deprecated(since = "1.2.4", forRemoval = true) @@ -111,7 +114,7 @@ public final class ScrollSubrange extends Subrange { } else { // Advance back by 1 at least to item before position - int advanceCount = (count != null ? count : 1); + int advanceCount = (count != null) ? count : 1; if (position.getOffset() >= advanceCount) { position = position.advanceBy(-advanceCount); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/SliceConnectionAdapter.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/SliceConnectionAdapter.java index 07dbf2c0..2f91a747 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/SliceConnectionAdapter.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/SliceConnectionAdapter.java @@ -38,6 +38,7 @@ public final class SliceConnectionAdapter /** * Constructor with the {@link CursorStrategy} to use to encode the * {@code ScrollPosition} of page items. + * @param strategy the cursor strategy to use */ public SliceConnectionAdapter(CursorStrategy strategy) { super(strategy); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/query/SortStrategy.java b/spring-graphql/src/main/java/org/springframework/graphql/data/query/SortStrategy.java index 52746cf8..1ed2e69c 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/query/SortStrategy.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/query/SortStrategy.java @@ -32,6 +32,7 @@ public interface SortStrategy { /** * Return a {@link Sort} instance by extracting the sort information from * GraphQL arguments, or {@link Sort#unsorted()} otherwise. + * @param environment the data fetching environment */ Sort extract(DataFetchingEnvironment environment); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/AbstractGraphQlSourceBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/AbstractGraphQlSourceBuilder.java index 535513cb..8c418900 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/AbstractGraphQlSourceBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/AbstractGraphQlSourceBuilder.java @@ -38,6 +38,7 @@ import org.springframework.lang.Nullable; * Implementation of {@link GraphQlSource.Builder} that leaves it to subclasses * to initialize {@link GraphQLSchema}. * + * @param the builder type * @author Rossen Stoyanchev * @author Brian Clozel * @since 1.0.0 @@ -90,8 +91,8 @@ public abstract class AbstractGraphQlSourceBuilder configurer) { - this.graphQlConfigurer = (this.graphQlConfigurer != null ? - this.graphQlConfigurer.andThen(configurer) : configurer); + this.graphQlConfigurer = (this.graphQlConfigurer != null) ? + this.graphQlConfigurer.andThen(configurer) : configurer; return self(); } @@ -147,13 +148,14 @@ public abstract class AbstractGraphQlSourceBuilder builder.codeRegistry(outputCodeRegistry)); + return schema.transformWithoutTypes((builder) -> builder.codeRegistry(outputCodeRegistry)); } /** * Protected method to apply the * {@link #configureGraphQl(Consumer) configured graphQlConfigurer}'s. * Subclasses can use this to customize {@link GraphQL.Builder} further. + * @param builder the builder to be customized * @since 1.2.5 */ protected void applyGraphQlConfigurers(GraphQL.Builder builder) { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/BatchLoaderRegistry.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/BatchLoaderRegistry.java index 2c92f4aa..a7ad92fe 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/BatchLoaderRegistry.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/BatchLoaderRegistry.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.List; @@ -55,7 +56,6 @@ public interface BatchLoaderRegistry extends DataLoaderRegistrar { * {@code @SchemaMapping} handler methods can transparenly locate and * inject a {@code DataLoader} argument based on the generic type * {@code }. - * * @param keyType the type of keys that will be used as input * @param valueType the type of value that will be returned as output * @param the key type @@ -71,7 +71,6 @@ public interface BatchLoaderRegistry extends DataLoaderRegistrar { *

    Note: when this method is used, the parameter name * of a {@code DataLoader} argument in a {@code @SchemaMapping} handler * method needs to match the name given here. - * * @param name the name to use to register a {@code DataLoader} * @param the type of keys that will be used as input * @param the type of values that will be used as output diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/ClassNameTypeResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/ClassNameTypeResolver.java index afa7b4e5..1d694432 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/ClassNameTypeResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/ClassNameTypeResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.LinkedHashMap; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/CompositeSubscriptionExceptionResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/CompositeSubscriptionExceptionResolver.java index 87f7a3a0..1c240cda 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/CompositeSubscriptionExceptionResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/CompositeSubscriptionExceptionResolver.java @@ -38,44 +38,43 @@ import org.springframework.util.Assert; * * @author Mykyta Ivchenko * @author Rossen Stoyanchev - * @since 1.0.1 */ class CompositeSubscriptionExceptionResolver implements SubscriptionExceptionResolver { - private static final Log logger = LogFactory.getLog(CompositeSubscriptionExceptionResolver.class); + private static final Log logger = LogFactory.getLog(CompositeSubscriptionExceptionResolver.class); - private final List resolvers; + private final List resolvers; - CompositeSubscriptionExceptionResolver(List resolvers) { - Assert.notNull(resolvers, "'resolvers' is required"); - this.resolvers = resolvers; - } + CompositeSubscriptionExceptionResolver(List resolvers) { + Assert.notNull(resolvers, "'resolvers' is required"); + this.resolvers = resolvers; + } - @Override - public Mono> resolveException(Throwable exception) { - return Flux.fromIterable(this.resolvers) - .flatMap(resolver -> resolver.resolveException(exception)) - .next() - .onErrorResume(error -> Mono.just(handleResolverException(error, exception))) - .defaultIfEmpty(createDefaultError()); - } + @Override + public Mono> resolveException(Throwable exception) { + return Flux.fromIterable(this.resolvers) + .flatMap((resolver) -> resolver.resolveException(exception)) + .next() + .onErrorResume((error) -> Mono.just(handleResolverException(error, exception))) + .defaultIfEmpty(createDefaultError()); + } - private List handleResolverException( - Throwable resolverException, Throwable originalException) { + private List handleResolverException( + Throwable resolverException, Throwable originalException) { - if (logger.isWarnEnabled()) { - logger.warn("Failure while resolving " + originalException.getClass().getName(), resolverException); - } - return createDefaultError(); - } + if (logger.isWarnEnabled()) { + logger.warn("Failure while resolving " + originalException.getClass().getName(), resolverException); + } + return createDefaultError(); + } - private List createDefaultError() { - return Collections.singletonList(GraphqlErrorBuilder.newError() - .message("Subscription error") - .errorType(ErrorType.INTERNAL_ERROR) - .build()); - } + private List createDefaultError() { + return Collections.singletonList(GraphqlErrorBuilder.newError() + .message("Subscription error") + .errorType(ErrorType.INTERNAL_ERROR) + .build()); + } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurer.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurer.java index fc9ae6ae..d2e33bf0 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurer.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.Collection; @@ -67,7 +68,7 @@ public class ConnectionTypeDefinitionConfigurer implements TypeDefinitionConfigu .fieldDefinition(initFieldDefinition("endCursor", STRING_TYPE)) .build()); - typeNames.forEach(typeName -> { + typeNames.forEach((typeName) -> { String connectionTypeName = typeName + "Connection"; String edgeTypeName = typeName + "Edge"; @@ -90,19 +91,19 @@ public class ConnectionTypeDefinitionConfigurer implements TypeDefinitionConfigu return Stream.concat( registry.types().values().stream(), registry.objectTypeExtensions().values().stream().flatMap(Collection::stream)) - .filter(definition -> definition instanceof ImplementingTypeDefinition) - .flatMap(definition -> { + .filter((definition) -> definition instanceof ImplementingTypeDefinition) + .flatMap((definition) -> { ImplementingTypeDefinition typeDefinition = (ImplementingTypeDefinition) definition; return typeDefinition.getFieldDefinitions().stream() - .map(fieldDefinition -> { + .map((fieldDefinition) -> { Type type = fieldDefinition.getType(); - return (type instanceof NonNullType ? ((NonNullType) type).getType() : type); + return (type instanceof NonNullType) ? ((NonNullType) type).getType() : type; }) - .filter(type -> type instanceof TypeName) - .map(type -> ((TypeName) type).getName()) - .filter(name -> name.endsWith("Connection")) - .filter(name -> registry.getType(name).isEmpty()) - .map(name -> name.substring(0, name.length() - "Connection".length())); + .filter((type) -> type instanceof TypeName) + .map((type) -> ((TypeName) type).getName()) + .filter((name) -> name.endsWith("Connection")) + .filter((name) -> registry.getType(name).isEmpty()) + .map((name) -> name.substring(0, name.length() - "Connection".length())); }) .collect(Collectors.toCollection(LinkedHashSet::new)); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/ContextDataFetcherDecorator.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/ContextDataFetcherDecorator.java index a18ec49e..db0e7472 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/ContextDataFetcherDecorator.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/ContextDataFetcherDecorator.java @@ -77,22 +77,22 @@ final class ContextDataFetcherDecorator implements DataFetcher { ContextSnapshot snapshot; if (environment.getLocalContext() instanceof GraphQLContext localContext) { - snapshot = snapshotFactory.captureFrom(environment.getGraphQlContext(), localContext); + snapshot = this.snapshotFactory.captureFrom(environment.getGraphQlContext(), localContext); } else { - snapshot = snapshotFactory.captureFrom(environment.getGraphQlContext()); + snapshot = this.snapshotFactory.captureFrom(environment.getGraphQlContext()); } Object value = snapshot.wrap(() -> this.delegate.get(environment)).call(); if (this.subscription) { Assert.state(value instanceof Publisher, "Expected Publisher for a subscription"); - Flux flux = Flux.from((Publisher) value).onErrorResume(exception -> { + Flux flux = Flux.from((Publisher) value).onErrorResume((exception) -> { // Already handled, e.g. controller methods? if (exception instanceof SubscriptionPublisherException) { return Mono.error(exception); } return this.subscriptionExceptionResolver.resolveException(exception) - .flatMap(errors -> Mono.error(new SubscriptionPublisherException(errors, exception))); + .flatMap((errors) -> Mono.error(new SubscriptionPublisherException(errors, exception))); }); return flux.contextWrite(snapshot::updateContext); } @@ -121,7 +121,7 @@ final class ContextDataFetcherDecorator implements DataFetcher { /** * Type visitor to apply {@link ContextDataFetcherDecorator}. */ - private static class ContextTypeVisitor extends GraphQLTypeVisitorStub { + private static final class ContextTypeVisitor extends GraphQLTypeVisitorStub { private final SubscriptionExceptionResolver exceptionResolver; @@ -142,7 +142,7 @@ final class ContextDataFetcherDecorator implements DataFetcher { if (applyDecorator(dataFetcher)) { boolean handlesSubscription = visitorHelper.isSubscriptionType(parent); - dataFetcher = new ContextDataFetcherDecorator(dataFetcher, handlesSubscription, exceptionResolver); + dataFetcher = new ContextDataFetcherDecorator(dataFetcher, handlesSubscription, this.exceptionResolver); codeRegistry.dataFetcher(fieldCoordinates, dataFetcher); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/DataFetcherExceptionResolverAdapter.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/DataFetcherExceptionResolverAdapter.java index 67b7fae9..07f1c27a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/DataFetcherExceptionResolverAdapter.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/DataFetcherExceptionResolverAdapter.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.Collections; @@ -100,12 +101,12 @@ public abstract class DataFetcherExceptionResolverAdapter implements DataFetcher return resolveToMultipleErrors(exception, env); } try { - return snapshotFactory.captureFrom(env.getGraphQlContext()) + return this.snapshotFactory.captureFrom(env.getGraphQlContext()) .wrap(() -> resolveToMultipleErrors(exception, env)) .call(); } catch (Exception ex2) { - logger.warn("Failed to resolve " + exception, ex2); + this.logger.warn("Failed to resolve " + exception, ex2); return null; } } @@ -119,7 +120,7 @@ public abstract class DataFetcherExceptionResolverAdapter implements DataFetcher @Nullable protected List resolveToMultipleErrors(Throwable ex, DataFetchingEnvironment env) { GraphQLError error = resolveToSingleError(ex, env); - return (error != null ? Collections.singletonList(error) : null); + return (error != null) ? Collections.singletonList(error) : null; } /** diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/DataLoaderRegistrar.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/DataLoaderRegistrar.java index fae2ed82..52557fff 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/DataLoaderRegistrar.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/DataLoaderRegistrar.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import graphql.ExecutionInput; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistry.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistry.java index 9aabac37..1c204dfe 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistry.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistry.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.ArrayList; @@ -55,9 +56,9 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry { private static final ContextSnapshotFactory SNAPSHOT_FACTORY = ContextSnapshotFactory.builder().build(); - private final List> loaders = new ArrayList<>(); + private final List> loaders = new ArrayList<>(); - private final List> mappedLoaders = new ArrayList<>(); + private final List> mappedLoaders = new ArrayList<>(); private final Supplier defaultOptionsSupplier; @@ -73,6 +74,7 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry { /** * Constructor with a default {@link DataLoaderOptions} supplier to use as * a starting point for batch loader registrations. + * @param defaultOptionsSupplier a supplier for default dataloader options * @since 1.1.0 */ public DefaultBatchLoaderRegistry(Supplier defaultOptionsSupplier) { @@ -130,11 +132,11 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry { @Nullable private Consumer optionsConsumer; - public DefaultRegistrationSpec(Class valueType) { + DefaultRegistrationSpec(Class valueType) { this.valueType = valueType; } - public DefaultRegistrationSpec(String name) { + DefaultRegistrationSpec(String name) { this.name = name; this.valueType = null; } @@ -147,8 +149,8 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry { @Override public RegistrationSpec withOptions(Consumer optionsConsumer) { - this.optionsConsumer = (this.optionsConsumer != null ? - this.optionsConsumer.andThen(optionsConsumer) : optionsConsumer); + this.optionsConsumer = (this.optionsConsumer != null) ? + this.optionsConsumer.andThen(optionsConsumer) : optionsConsumer; return this; } @@ -181,7 +183,7 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry { private Supplier initOptionsSupplier() { Supplier optionsSupplier = () -> - new DataLoaderOptions(this.options != null ? + new DataLoaderOptions((this.options != null) ? this.options : DefaultBatchLoaderRegistry.this.defaultOptionsSupplier.get()); if (this.optionsConsumer == null) { @@ -201,7 +203,7 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry { * {@link BatchLoaderWithContext} that delegates to a {@link Flux} batch * loading function and exposes Reactor context to it. */ - private static class ReactorBatchLoader implements BatchLoaderWithContext { + private static final class ReactorBatchLoader implements BatchLoaderWithContext { private final String name; @@ -218,11 +220,11 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry { this.optionsSupplier = optionsSupplier; } - public String getName() { + String getName() { return this.name; } - public DataLoaderOptions getOptions() { + DataLoaderOptions getOptions() { return this.optionsSupplier.get(); } @@ -249,7 +251,7 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry { * {@link MappedBatchLoaderWithContext} that delegates to a {@link Mono} * batch loading function and exposes Reactor context to it. */ - private static class ReactorMappedBatchLoader implements MappedBatchLoaderWithContext { + private static final class ReactorMappedBatchLoader implements MappedBatchLoaderWithContext { private final String name; @@ -266,11 +268,11 @@ public class DefaultBatchLoaderRegistry implements BatchLoaderRegistry { this.optionsSupplier = optionsSupplier; } - public String getName() { + String getName() { return this.name; } - public DataLoaderOptions getOptions() { + DataLoaderOptions getOptions() { return this.optionsSupplier.get(); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultExecutionGraphQlService.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultExecutionGraphQlService.java index 49dd8568..b88ba2e0 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultExecutionGraphQlService.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultExecutionGraphQlService.java @@ -90,13 +90,13 @@ public class DefaultExecutionGraphQlService implements ExecutionGraphQlService { ExecutionInput executionInput = request.toExecutionInput(); - snapshotFactory.captureFrom(contextView).updateContext(executionInput.getGraphQLContext()); + this.snapshotFactory.captureFrom(contextView).updateContext(executionInput.getGraphQLContext()); ExecutionInput updatedExecutionInput = (this.hasDataLoaderRegistrations ? registerDataLoaders(executionInput) : executionInput); return Mono.fromFuture(this.graphQlSource.graphQl().executeAsync(updatedExecutionInput)) - .map(result -> new DefaultExecutionGraphQlResponse(updatedExecutionInput, result)); + .map((result) -> new DefaultExecutionGraphQlResponse(updatedExecutionInput, result)); }); } @@ -106,7 +106,7 @@ public class DefaultExecutionGraphQlService implements ExecutionGraphQlService { if (existingRegistry == EmptyDataLoaderRegistryInstance.EMPTY_DATALOADER_REGISTRY) { DataLoaderRegistry newRegistry = DataLoaderRegistry.newRegistry().build(); applyDataLoaderRegistrars(newRegistry, graphQLContext); - executionInput = executionInput.transform(builder -> builder.dataLoaderRegistry(newRegistry)); + executionInput = executionInput.transform((builder) -> builder.dataLoaderRegistry(newRegistry)); } else { applyDataLoaderRegistrars(existingRegistry, graphQLContext); @@ -115,7 +115,7 @@ public class DefaultExecutionGraphQlService implements ExecutionGraphQlService { } private void applyDataLoaderRegistrars(DataLoaderRegistry registry, GraphQLContext graphQLContext) { - this.dataLoaderRegistrars.forEach(registrar -> registrar.registerDataLoaders(registry, graphQLContext)); + this.dataLoaderRegistrars.forEach((registrar) -> registrar.registerDataLoaders(registry, graphQLContext)); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilder.java index 3edf152a..ce77b884 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilder.java @@ -52,7 +52,6 @@ import org.springframework.util.Assert; * * @author Rossen Stoyanchev * @author Brian Clozel - * @since 1.0.0 */ final class DefaultSchemaResourceGraphQlSourceBuilder extends AbstractGraphQlSourceBuilder @@ -76,7 +75,7 @@ final class DefaultSchemaResourceGraphQlSourceBuilder @Nullable private Consumer schemaReportConsumer; - private Consumer inspectorInitializerConsumer = initializer -> {}; + private Consumer inspectorInitializerConsumer = (initializer) -> { }; @Nullable private Consumer schemaReportRunner; @@ -152,7 +151,7 @@ final class DefaultSchemaResourceGraphQlSourceBuilder RuntimeWiring runtimeWiring = initRuntimeWiring(); TypeResolver typeResolver = initTypeResolver(); - registry.types().values().forEach(def -> { + registry.types().values().forEach((def) -> { if (def instanceof UnionTypeDefinition || def instanceof InterfaceTypeDefinition) { runtimeWiring.getTypeResolvers().putIfAbsent(def.getName(), typeResolver); } @@ -162,7 +161,7 @@ final class DefaultSchemaResourceGraphQlSourceBuilder // visitors may transform the schema, for example to add Connection types. if (this.schemaReportConsumer != null) { - this.schemaReportRunner = schema -> { + this.schemaReportRunner = (schema) -> { SchemaMappingInspector.Initializer initializer = SchemaMappingInspector.initializer(); if (this.typeResolver instanceof ClassNameTypeResolver cntr) { initializer.classResolver(SchemaMappingInspector.ClassResolver.fromClassNameTypeResolver(cntr)); @@ -173,9 +172,9 @@ final class DefaultSchemaResourceGraphQlSourceBuilder }; } - return (this.schemaFactory != null ? + return (this.schemaFactory != null) ? this.schemaFactory.apply(registry, runtimeWiring) : - new SchemaGenerator().makeExecutableSchema(registry, runtimeWiring)); + new SchemaGenerator().makeExecutableSchema(registry, runtimeWiring); } private TypeDefinitionRegistry parse(Resource schemaResource) { @@ -196,14 +195,14 @@ final class DefaultSchemaResourceGraphQlSourceBuilder private RuntimeWiring initRuntimeWiring() { RuntimeWiring.Builder builder = RuntimeWiring.newRuntimeWiring(); - this.runtimeWiringConfigurers.forEach(configurer -> configurer.configure(builder)); + this.runtimeWiringConfigurers.forEach((configurer) -> configurer.configure(builder)); List factories = new ArrayList<>(); WiringFactory factory = builder.build().getWiringFactory(); if (!factory.getClass().equals(NoopWiringFactory.class)) { factories.add(factory); } - this.runtimeWiringConfigurers.forEach(configurer -> configurer.configure(builder, factories)); + this.runtimeWiringConfigurers.forEach((configurer) -> configurer.configure(builder, factories)); if (!factories.isEmpty()) { builder.wiringFactory(new CombinedWiringFactory(factories)); } @@ -212,7 +211,7 @@ final class DefaultSchemaResourceGraphQlSourceBuilder } private TypeResolver initTypeResolver() { - return (this.typeResolver != null ? this.typeResolver : new ClassNameTypeResolver()); + return (this.typeResolver != null) ? this.typeResolver : new ClassNameTypeResolver(); } @Override diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultTypeVisitorHelper.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultTypeVisitorHelper.java index 76b4ea0c..46c1a5ec 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultTypeVisitorHelper.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/DefaultTypeVisitorHelper.java @@ -27,7 +27,6 @@ import org.springframework.lang.Nullable; * against {@link GraphQLSchema}. * * @author Rossen Stoyanchev - * @since 1.2.1 */ final class DefaultTypeVisitorHelper implements TypeVisitorHelper { @@ -36,11 +35,11 @@ final class DefaultTypeVisitorHelper implements TypeVisitorHelper { /** - * Package private constructor + * Package private constructor. */ DefaultTypeVisitorHelper(GraphQLSchema schema) { GraphQLObjectType subscriptionType = schema.getSubscriptionType(); - this.subscriptionTypeName = (subscriptionType != null ? subscriptionType.getName() : null); + this.subscriptionTypeName = (subscriptionType != null) ? subscriptionType.getName() : null; } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandler.java index b0af67fc..e5dd044d 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandler.java @@ -42,7 +42,6 @@ import org.springframework.util.Assert; * in a sequence until one returns a list of {@link GraphQLError}'s. * * @author Rossen Stoyanchev - * @since 1.0.0 */ class ExceptionResolversExceptionHandler implements DataFetcherExceptionHandler { @@ -66,14 +65,14 @@ class ExceptionResolversExceptionHandler implements DataFetcherExceptionHandler public CompletableFuture handleException(DataFetcherExceptionHandlerParameters params) { Throwable exception = unwrapException(params); DataFetchingEnvironment env = params.getDataFetchingEnvironment(); - ContextSnapshot snapshot = snapshotFactory.captureFrom(env.getGraphQlContext()); + ContextSnapshot snapshot = this.snapshotFactory.captureFrom(env.getGraphQlContext()); try { return Flux.fromIterable(this.resolvers) - .flatMap(resolver -> resolver.resolveException(exception, env)) - .map(errors -> DataFetcherExceptionHandlerResult.newResult().errors(errors).build()) + .flatMap((resolver) -> resolver.resolveException(exception, env)) + .map((errors) -> DataFetcherExceptionHandlerResult.newResult().errors(errors).build()) .next() - .doOnNext(result -> logResolvedException(exception, result)) - .onErrorResume(resolverEx -> Mono.just(handleResolverError(resolverEx, exception, env))) + .doOnNext((result) -> logResolvedException(exception, result)) + .onErrorResume((resolverEx) -> Mono.just(handleResolverError(resolverEx, exception, env))) .switchIfEmpty(Mono.fromCallable(() -> createInternalError(exception, env))) .contextWrite(snapshot::updateContext) .toFuture(); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/ExternalSchemaGraphQlSourceBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/ExternalSchemaGraphQlSourceBuilder.java index e4170a95..95b2e0c8 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/ExternalSchemaGraphQlSourceBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/ExternalSchemaGraphQlSourceBuilder.java @@ -27,7 +27,6 @@ import org.springframework.util.Assert; * {@link GraphQLSchema}. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class ExternalSchemaGraphQlSourceBuilder extends AbstractGraphQlSourceBuilder @@ -36,7 +35,7 @@ final class ExternalSchemaGraphQlSourceBuilder private final GraphQLSchema schema; - public ExternalSchemaGraphQlSourceBuilder(GraphQLSchema schema) { + ExternalSchemaGraphQlSourceBuilder(GraphQLSchema schema) { Assert.notNull(schema, "GraphQLSchema is required"); this.schema = schema; } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlContextAccessor.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlContextAccessor.java index 3e8c1736..575af5d4 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlContextAccessor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlContextAccessor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; @@ -39,7 +40,7 @@ public class GraphQlContextAccessor implements ContextAccessor keyPredicate, Map readValues) { - context.stream().forEach(entry -> { + context.stream().forEach((entry) -> { if (keyPredicate.test(entry.getKey())) { readValues.put(entry.getKey(), entry.getValue()); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlSource.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlSource.java index b9d18b45..5d98775c 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlSource.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/GraphQlSource.java @@ -69,6 +69,7 @@ public interface GraphQlSource { /** * Return a {@link GraphQlSource} builder that uses an externally prepared * {@link GraphQLSchema}. + * @param schema the GraphQL schema */ static Builder builder(GraphQLSchema schema) { return new ExternalSchemaGraphQlSourceBuilder(schema); @@ -79,6 +80,7 @@ public interface GraphQlSource { /** * Common configuration options for all {@link GraphQlSource} builders, * independent of how {@link GraphQLSchema} is created. + * @param the builder type */ interface Builder> { @@ -125,8 +127,8 @@ public interface GraphQlSource { * {@link #typeVisitors(List)} if it's not necessary to change the schema. * @param typeVisitors the type visitors to register * @return the current builder - * @see graphql.schema.SchemaTransformer#transformSchema(GraphQLSchema, GraphQLTypeVisitor) * @since 1.1.0 + * @see graphql.schema.SchemaTransformer#transformSchema(GraphQLSchema, GraphQLTypeVisitor) */ B typeVisitorsToTransformSchema(List typeVisitors); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/ReactiveSecurityDataFetcherExceptionResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/ReactiveSecurityDataFetcherExceptionResolver.java index b5033664..7f539a50 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/ReactiveSecurityDataFetcherExceptionResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/ReactiveSecurityDataFetcherExceptionResolver.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.Collections; @@ -62,7 +63,7 @@ public class ReactiveSecurityDataFetcherExceptionResolver implements DataFetcher } if (ex instanceof AccessDeniedException) { return ReactiveSecurityContextHolder.getContext() - .map(context -> Collections.singletonList( + .map((context) -> Collections.singletonList( SecurityExceptionResolverUtils.resolveAccessDenied(environment, this.trustResolver, context))) .switchIfEmpty(Mono.fromCallable(() -> Collections.singletonList( SecurityExceptionResolverUtils.resolveUnauthorized(environment)))); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/RuntimeWiringConfigurer.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/RuntimeWiringConfigurer.java index e45ce931..23b568a6 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/RuntimeWiringConfigurer.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/RuntimeWiringConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.List; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/SchemaMappingInspector.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/SchemaMappingInspector.java index 111ba47d..f067c6d0 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/SchemaMappingInspector.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/SchemaMappingInspector.java @@ -76,7 +76,7 @@ import org.springframework.util.MultiValueMap; * @since 1.2.0 */ @SuppressWarnings("rawtypes") -public class SchemaMappingInspector { +public final class SchemaMappingInspector { private static final Log logger = LogFactory.getLog(SchemaMappingInspector.class); @@ -191,7 +191,7 @@ public class SchemaMappingInspector { private void checkField( GraphQLFieldsContainer parent, GraphQLFieldDefinition field, ResolvableType resolvableType) { - TypePair typePair = TypePair.resolveTypePair(parent, field, resolvableType, schema); + TypePair typePair = TypePair.resolveTypePair(parent, field, resolvableType, this.schema); if (addAndCheckIfAlreadyInspected(typePair.outputType())) { return; @@ -239,7 +239,7 @@ public class SchemaMappingInspector { private PropertyDescriptor getProperty(ResolvableType resolvableType, String fieldName) { try { Class clazz = resolvableType.resolve(); - return (clazz != null ? BeanUtils.getPropertyDescriptor(clazz, fieldName) : null); + return (clazz != null) ? BeanUtils.getPropertyDescriptor(clazz, fieldName) : null; } catch (BeansException ex) { throw new IllegalStateException( @@ -264,7 +264,7 @@ public class SchemaMappingInspector { } private static String typeNameToString(GraphQLType type) { - return (type instanceof GraphQLNamedType namedType ? namedType.getName() : type.toString()); + return (type instanceof GraphQLNamedType namedType) ? namedType.getName() : type.toString(); } private void checkDataFetcherRegistrations() { @@ -291,6 +291,8 @@ public class SchemaMappingInspector { /** * Variant of {@link #inspect(GraphQLSchema, RuntimeWiring)} with a map of * {@code DataFetcher} registrations. + * @param schema the schema to inspect + * @param fetchers the map of {@code DataFetcher} registrations * @since 1.2.5 */ public static SchemaReport inspect(GraphQLSchema schema, Map> fetchers) { @@ -361,6 +363,7 @@ public class SchemaMappingInspector { /** * Create a resolver by re-using the explicit, reverse mappings of * {@link ClassNameTypeResolver}. + * @param resolver the type resolver using class names */ static ClassResolver fromClassNameTypeResolver(ClassNameTypeResolver resolver) { MappingClassResolver mappingResolver = new MappingClassResolver(); @@ -380,7 +383,7 @@ public class SchemaMappingInspector { private final List classResolvers = new ArrayList<>(); - public DefaultInitializer() { + DefaultInitializer() { this.classResolvers.add((objectType, interfaceOrUnionType) -> Collections.emptyList()); } @@ -407,11 +410,11 @@ public class SchemaMappingInspector { /** * ClassResolver with explicit mappings. */ - private static class MappingClassResolver implements ClassResolver { + private static final class MappingClassResolver implements ClassResolver { private final MultiValueMap> map = new LinkedMultiValueMap<>(); - public void addMapping(String typeName, Class clazz) { + void addMapping(String typeName, Class clazz) { this.map.add(typeName, clazz); } @@ -433,18 +436,18 @@ public class SchemaMappingInspector { private final MultiValueMap classPrefixes = new LinkedMultiValueMap<>(); - public ReflectionClassResolver(Function classNameFunction) { + ReflectionClassResolver(Function classNameFunction) { this.classNameFunction = classNameFunction; } - public void addClassPrefix(String interfaceOrUnionTypeName, String classPrefix) { + void addClassPrefix(String interfaceOrUnionTypeName, String classPrefix) { this.classPrefixes.add(interfaceOrUnionTypeName, classPrefix); } @Override public List> resolveClass(GraphQLObjectType objectType, GraphQLNamedOutputType interfaceOrUnion) { String className = this.classNameFunction.apply(objectType); - for (String prefix : classPrefixes.getOrDefault(interfaceOrUnion.getName(), Collections.emptyList())) { + for (String prefix : this.classPrefixes.getOrDefault(interfaceOrUnion.getName(), Collections.emptyList())) { try { Class clazz = Class.forName(prefix + className); return Collections.singletonList(clazz); @@ -464,7 +467,7 @@ public class SchemaMappingInspector { */ private static class InterfaceUnionLookup { - private final static Predicate PACKAGE_PREDICATE = name -> !name.startsWith("java."); + private static final Predicate PACKAGE_PREDICATE = (name) -> !name.startsWith("java."); private static final LinkedMultiValueMap EMPTY_MULTI_VALUE_MAP = new LinkedMultiValueMap<>(0); @@ -547,7 +550,7 @@ public class SchemaMappingInspector { for (ResolvableType resolvableType : resolvableTypes) { String name = interfaceOrUnionType.getName(); - this.mappings.computeIfAbsent(name, n -> new LinkedMultiValueMap<>()).add(objectType, resolvableType); + this.mappings.computeIfAbsent(name, (n) -> new LinkedMultiValueMap<>()).add(objectType, resolvableType); } } @@ -557,7 +560,7 @@ public class SchemaMappingInspector { * @return {@code MultiValueMap} with one or more pairs, possibly one * pair with {@link ResolvableType#NONE}. */ - public MultiValueMap resolveInterface(GraphQLInterfaceType interfaceType) { + MultiValueMap resolveInterface(GraphQLInterfaceType interfaceType) { return this.mappings.getOrDefault(interfaceType.getName(), EMPTY_MULTI_VALUE_MAP); } @@ -567,7 +570,7 @@ public class SchemaMappingInspector { * @return {@code MultiValueMap} with one or more pairs, possibly one * pair with {@link ResolvableType#NONE}. */ - public MultiValueMap resolveUnion(GraphQLUnionType unionType) { + MultiValueMap resolveUnion(GraphQLUnionType unionType) { return this.mappings.getOrDefault(unionType.getName(), EMPTY_MULTI_VALUE_MAP); } @@ -586,12 +589,16 @@ public class SchemaMappingInspector { * Convenience variant of * {@link #resolveTypePair(GraphQLType, GraphQLFieldDefinition, ResolvableType, GraphQLSchema)} * with a {@link DataFetcher} to extract the return type from. + * @param parent the parent type of the field + * @param field the field + * @param fetcher the data fetcher associated with this field + * @param schema the GraphQL schema */ public static TypePair resolveTypePair( GraphQLType parent, GraphQLFieldDefinition field, DataFetcher fetcher, GraphQLSchema schema) { return resolveTypePair(parent, field, - fetcher instanceof SelfDescribingDataFetcher sd ? sd.getReturnType() : ResolvableType.NONE, + (fetcher instanceof SelfDescribingDataFetcher sd) ? sd.getReturnType() : ResolvableType.NONE, schema); } @@ -626,7 +633,7 @@ public class SchemaMappingInspector { } private static GraphQLType unwrapIfNonNull(GraphQLType type) { - return (type instanceof GraphQLNonNull graphQLNonNull ? graphQLNonNull.getWrappedType() : type); + return (type instanceof GraphQLNonNull graphQLNonNull) ? graphQLNonNull.getWrappedType() : type; } private static boolean isPaginatedType(GraphQLType type) { @@ -697,7 +704,7 @@ public class SchemaMappingInspector { /** * Helps to build a {@link SchemaReport}. */ - private class ReportBuilder { + private final class ReportBuilder { private final List unmappedFields = new ArrayList<>(); @@ -707,23 +714,23 @@ public class SchemaMappingInspector { private final List skippedTypes = new ArrayList<>(); - public void unmappedField(FieldCoordinates coordinates) { + void unmappedField(FieldCoordinates coordinates) { this.unmappedFields.add(coordinates); } - public void unmappedRegistration(FieldCoordinates coordinates, DataFetcher dataFetcher) { + void unmappedRegistration(FieldCoordinates coordinates, DataFetcher dataFetcher) { this.unmappedRegistrations.put(coordinates, dataFetcher); } - public void unmappedArgument(DataFetcher dataFetcher, List arguments) { + void unmappedArgument(DataFetcher dataFetcher, List arguments) { this.unmappedArguments.put(dataFetcher, arguments); } - public void skippedType(GraphQLType type, FieldCoordinates coordinates) { + void skippedType(GraphQLType type, FieldCoordinates coordinates) { this.skippedTypes.add(new DefaultSkippedType(type, coordinates)); } - public SchemaReport build() { + SchemaReport build() { return new DefaultSchemaReport( this.unmappedFields, this.unmappedRegistrations, this.unmappedArguments, this.skippedTypes); } @@ -744,7 +751,7 @@ public class SchemaMappingInspector { private final List skippedTypes; - public DefaultSchemaReport( + DefaultSchemaReport( List unmappedFields, Map> unmappedRegistrations, MultiValueMap, String> unmappedArguments, List skippedTypes) { @@ -798,8 +805,8 @@ public class SchemaMappingInspector { private String formatUnmappedFields() { MultiValueMap map = new LinkedMultiValueMap<>(); - this.unmappedFields.forEach(coordinates -> { - List fields = map.computeIfAbsent(coordinates.getTypeName(), s -> new ArrayList<>()); + this.unmappedFields.forEach((coordinates) -> { + List fields = map.computeIfAbsent(coordinates.getTypeName(), (s) -> new ArrayList<>()); fields.add(coordinates.getFieldName()); }); return map.toString(); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/SchemaReport.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/SchemaReport.java index 95eed633..6ef0f1c3 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/SchemaReport.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/SchemaReport.java @@ -79,6 +79,7 @@ public interface SchemaReport { /** * Return the {@code DataFetcher} for the given field coordinates, if registered. + * @param coordinates the field coordinates */ @Nullable DataFetcher dataFetcher(FieldCoordinates coordinates); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/SecurityContextThreadLocalAccessor.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/SecurityContextThreadLocalAccessor.java index 4da0eedf..81ff664d 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/SecurityContextThreadLocalAccessor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/SecurityContextThreadLocalAccessor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import io.micrometer.context.ThreadLocalAccessor; @@ -33,7 +34,7 @@ import org.springframework.util.ClassUtils; */ public class SecurityContextThreadLocalAccessor implements ThreadLocalAccessor { - private final static boolean springSecurityPresent = ClassUtils.isPresent( + private static final boolean springSecurityPresent = ClassUtils.isPresent( "org.springframework.security.core.context.SecurityContext", SecurityContextThreadLocalAccessor.class.getClassLoader()); @@ -77,7 +78,7 @@ public class SecurityContextThreadLocalAccessor implements ThreadLocalAccessor { + private static final class DelegateAccessor implements ThreadLocalAccessor { @Override public Object key() { @@ -130,7 +131,7 @@ public class SecurityContextThreadLocalAccessor implements ThreadLocalAccessor { + private static final class NoOpAccessor implements ThreadLocalAccessor { @Override public Object key() { @@ -167,7 +168,7 @@ public class SecurityContextThreadLocalAccessor implements ThreadLocalAccessor the type of data returned by the {@code DataFetcher} * @author Brian Clozel * @author Rossen Stoyanchev * @since 1.2.0 diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionExceptionResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionExceptionResolver.java index 4fd441a2..44b80837 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionExceptionResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionExceptionResolver.java @@ -44,35 +44,35 @@ import reactor.core.publisher.Mono; @FunctionalInterface public interface SubscriptionExceptionResolver { - /** - * Resolve the given exception to a list of {@link GraphQLError}'s to be - * sent in an error message to the client. - * @param exception the exception from the Publisher - * @return a {@code Mono} with the GraphQL errors to send to the client; - * if the {@code Mono} completes with an empty List, the exception is resolved - * without any errors to send; if the {@code Mono} completes empty, without - * emitting a List, the exception remains unresolved, and that allows other - * resolvers to resolve it. - */ - Mono> resolveException(Throwable exception); + /** + * Resolve the given exception to a list of {@link GraphQLError}'s to be + * sent in an error message to the client. + * @param exception the exception from the Publisher + * @return a {@code Mono} with the GraphQL errors to send to the client; + * if the {@code Mono} completes with an empty List, the exception is resolved + * without any errors to send; if the {@code Mono} completes empty, without + * emitting a List, the exception remains unresolved, and that allows other + * resolvers to resolve it. + */ + Mono> resolveException(Throwable exception); - /** - * Factory method to create a {@link SubscriptionExceptionResolver} to - * resolve an exception to a single GraphQL error. Effectively, a shortcut - * for creating {@link SubscriptionExceptionResolverAdapter} and overriding - * its {@code resolveToSingleError} method. - * @param resolver the resolver function to map the exception - * @return the created instance - */ - static SubscriptionExceptionResolverAdapter forSingleError(Function resolver) { - return new SubscriptionExceptionResolverAdapter() { + /** + * Factory method to create a {@link SubscriptionExceptionResolver} to + * resolve an exception to a single GraphQL error. Effectively, a shortcut + * for creating {@link SubscriptionExceptionResolverAdapter} and overriding + * its {@code resolveToSingleError} method. + * @param resolver the resolver function to map the exception + * @return the created instance + */ + static SubscriptionExceptionResolverAdapter forSingleError(Function resolver) { + return new SubscriptionExceptionResolverAdapter() { - @Override - protected GraphQLError resolveToSingleError(Throwable ex) { - return resolver.apply(ex); - } - }; - } + @Override + protected GraphQLError resolveToSingleError(Throwable ex) { + return resolver.apply(ex); + } + }; + } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionExceptionResolverAdapter.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionExceptionResolverAdapter.java index 03d4f9ac..37f2078d 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionExceptionResolverAdapter.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionExceptionResolverAdapter.java @@ -49,78 +49,78 @@ import org.springframework.lang.Nullable; */ public abstract class SubscriptionExceptionResolverAdapter implements SubscriptionExceptionResolver { - protected final Log logger = LogFactory.getLog(getClass()); + protected final Log logger = LogFactory.getLog(getClass()); - protected final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build(); + protected final ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build(); - private boolean threadLocalContextAware; + private boolean threadLocalContextAware; - /** - * Subclasses can set this to indicate that ThreadLocal context from the - * transport handler (e.g. HTTP handler) should be restored when resolving - * exceptions. - *

    Note: This property is applicable only if transports - * use ThreadLocal's' (e.g. Spring MVC) and if a {@link ThreadLocalAccessor} - * is registered to extract ThreadLocal values of interest. There is no - * impact from setting this property otherwise. - *

    By default this is set to "false" in which case there is no attempt - * to propagate ThreadLocal context. - * @param threadLocalContextAware whether this resolver needs access to - * ThreadLocal context or not. - */ - public void setThreadLocalContextAware(boolean threadLocalContextAware) { - this.threadLocalContextAware = threadLocalContextAware; - } + /** + * Subclasses can set this to indicate that ThreadLocal context from the + * transport handler (e.g. HTTP handler) should be restored when resolving + * exceptions. + *

    Note: This property is applicable only if transports + * use ThreadLocal's' (e.g. Spring MVC) and if a {@link ThreadLocalAccessor} + * is registered to extract ThreadLocal values of interest. There is no + * impact from setting this property otherwise. + *

    By default this is set to "false" in which case there is no attempt + * to propagate ThreadLocal context. + * @param threadLocalContextAware whether this resolver needs access to + * ThreadLocal context or not. + */ + public void setThreadLocalContextAware(boolean threadLocalContextAware) { + this.threadLocalContextAware = threadLocalContextAware; + } - /** - * Whether ThreadLocal context needs to be restored for this resolver. - */ - public boolean isThreadLocalContextAware() { - return this.threadLocalContextAware; - } + /** + * Whether ThreadLocal context needs to be restored for this resolver. + */ + public boolean isThreadLocalContextAware() { + return this.threadLocalContextAware; + } - @SuppressWarnings({"unused", "try"}) - @Override - public final Mono> resolveException(Throwable exception) { - if (this.threadLocalContextAware) { - return Mono.deferContextual(contextView -> { - ContextSnapshot snapshot = snapshotFactory.captureFrom(contextView); - try { - List errors = snapshot.wrap(() -> resolveToMultipleErrors(exception)).call(); - return Mono.justOrEmpty(errors); - } - catch (Exception ex2) { - logger.warn("Failed to resolve " + exception, ex2); - return Mono.empty(); - } - }); - } - else { - return Mono.justOrEmpty(resolveToMultipleErrors(exception)); - } - } + @SuppressWarnings({"unused", "try"}) + @Override + public final Mono> resolveException(Throwable exception) { + if (this.threadLocalContextAware) { + return Mono.deferContextual((contextView) -> { + ContextSnapshot snapshot = this.snapshotFactory.captureFrom(contextView); + try { + List errors = snapshot.wrap(() -> resolveToMultipleErrors(exception)).call(); + return Mono.justOrEmpty(errors); + } + catch (Exception ex2) { + this.logger.warn("Failed to resolve " + exception, ex2); + return Mono.empty(); + } + }); + } + else { + return Mono.justOrEmpty(resolveToMultipleErrors(exception)); + } + } - /** - * Override this method to resolve the Exception to multiple GraphQL errors. - * @param exception the exception to resolve - * @return the resolved errors or {@code null} if unresolved - */ - @Nullable - protected List resolveToMultipleErrors(Throwable exception) { - GraphQLError error = resolveToSingleError(exception); - return (error != null ? Collections.singletonList(error) : null); - } + /** + * Override this method to resolve the Exception to multiple GraphQL errors. + * @param exception the exception to resolve + * @return the resolved errors or {@code null} if unresolved + */ + @Nullable + protected List resolveToMultipleErrors(Throwable exception) { + GraphQLError error = resolveToSingleError(exception); + return (error != null) ? Collections.singletonList(error) : null; + } - /** - * Override this method to resolve the Exception to a single GraphQL error. - * @param exception the exception to resolve - * @return the resolved error or {@code null} if unresolved - */ - @Nullable - protected GraphQLError resolveToSingleError(Throwable exception) { - return null; - } + /** + * Override this method to resolve the Exception to a single GraphQL error. + * @param exception the exception to resolve + * @return the resolved error or {@code null} if unresolved + */ + @Nullable + protected GraphQLError resolveToSingleError(Throwable exception) { + return null; + } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionPublisherException.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionPublisherException.java index 82ad10fb..851f7d9b 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionPublisherException.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/SubscriptionPublisherException.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.List; @@ -37,26 +38,28 @@ import org.springframework.core.NestedRuntimeException; @SuppressWarnings("serial") public final class SubscriptionPublisherException extends NestedRuntimeException { - private final List errors; + private final List errors; - /** - * Constructor with the resolved GraphQL errors and the original exception - * from the GraphQL subscription {@link org.reactivestreams.Publisher}. - */ - public SubscriptionPublisherException(List errors, Throwable cause) { - super("GraphQL subscription ended with error(s): " + errors, cause); - this.errors = errors; - } + /** + * Constructor with the resolved GraphQL errors and the original exception + * from the GraphQL subscription {@link org.reactivestreams.Publisher}. + * @param errors the list of resolved GraphQL errors + * @param cause the original exception + */ + public SubscriptionPublisherException(List errors, Throwable cause) { + super("GraphQL subscription ended with error(s): " + errors, cause); + this.errors = errors; + } - /** - * Return the GraphQL errors the exception was resolved to by the configured - * {@link SubscriptionExceptionResolver}'s. These errors can be included in - * an error message to be sent to the client by the underlying transport. - */ - public List getErrors() { - return this.errors; - } + /** + * Return the GraphQL errors the exception was resolved to by the configured + * {@link SubscriptionExceptionResolver}'s. These errors can be included in + * an error message to be sent to the client by the underlying transport. + */ + public List getErrors() { + return this.errors; + } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeDefinitionConfigurer.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeDefinitionConfigurer.java index 96d0387a..7e78718e 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeDefinitionConfigurer.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeDefinitionConfigurer.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import graphql.schema.GraphQLSchema; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeVisitorHelper.java b/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeVisitorHelper.java index e75ade9c..b02be750 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeVisitorHelper.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/execution/TypeVisitorHelper.java @@ -33,12 +33,14 @@ public interface TypeVisitorHelper { /** * Whether the given type is the subscription type. + * @param type the GraphQL type to check */ boolean isSubscriptionType(GraphQLNamedType type); /** * Create an instance with the given {@link GraphQLSchema}. + * @param schema the GraphQL schema to use */ static TypeVisitorHelper create(GraphQLSchema schema) { return new DefaultTypeVisitorHelper(schema); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/observation/DefaultDataFetcherObservationConvention.java b/spring-graphql/src/main/java/org/springframework/graphql/observation/DefaultDataFetcherObservationConvention.java index c994e8a8..1c46b7a4 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/observation/DefaultDataFetcherObservationConvention.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/observation/DefaultDataFetcherObservationConvention.java @@ -66,7 +66,8 @@ public class DefaultDataFetcherObservationConvention implements DataFetcherObser protected KeyValue outcome(DataFetcherObservationContext context) { if (context.getError() != null) { return OUTCOME_ERROR; - } return OUTCOME_SUCCESS; + } + return OUTCOME_SUCCESS; } protected KeyValue fieldName(DataFetcherObservationContext context) { @@ -76,7 +77,8 @@ public class DefaultDataFetcherObservationConvention implements DataFetcherObser protected KeyValue errorType(DataFetcherObservationContext context) { if (context.getError() != null) { return KeyValue.of(DataFetcherLowCardinalityKeyNames.ERROR_TYPE, context.getError().getClass().getSimpleName()); - } return ERROR_TYPE_NONE; + } + return ERROR_TYPE_NONE; } @Override diff --git a/spring-graphql/src/main/java/org/springframework/graphql/observation/ExecutionRequestObservationContext.java b/spring-graphql/src/main/java/org/springframework/graphql/observation/ExecutionRequestObservationContext.java index 044468cd..919b90bf 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/observation/ExecutionRequestObservationContext.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/observation/ExecutionRequestObservationContext.java @@ -19,6 +19,7 @@ package org.springframework.graphql.observation; import graphql.ExecutionInput; import graphql.ExecutionResult; import io.micrometer.observation.Observation; + import org.springframework.lang.Nullable; /** @@ -30,58 +31,58 @@ import org.springframework.lang.Nullable; */ public class ExecutionRequestObservationContext extends Observation.Context { - private final ExecutionInput executionInput; + private final ExecutionInput executionInput; - @Nullable - private ExecutionResult executionResult; + @Nullable + private ExecutionResult executionResult; - public ExecutionRequestObservationContext(ExecutionInput executionInput) { - this.executionInput = executionInput; - } + public ExecutionRequestObservationContext(ExecutionInput executionInput) { + this.executionInput = executionInput; + } - /** - * Return the {@link ExecutionInput input} for the request execution. - * @since 1.1.4 - */ - public ExecutionInput getExecutionInput() { - return this.executionInput; - } + /** + * Return the {@link ExecutionInput input} for the request execution. + * @since 1.1.4 + */ + public ExecutionInput getExecutionInput() { + return this.executionInput; + } - /** - * Return the {@link ExecutionInput input} for the request execution. - * @deprecated since 1.1.4 in favor of {@link #getExecutionInput()} - */ - @Deprecated(since = "1.1.4", forRemoval = true) - public ExecutionInput getCarrier() { - return this.executionInput; - } + /** + * Return the {@link ExecutionInput input} for the request execution. + * @deprecated since 1.1.4 in favor of {@link #getExecutionInput()} + */ + @Deprecated(since = "1.1.4", forRemoval = true) + public ExecutionInput getCarrier() { + return this.executionInput; + } - /** - * Return the {@link ExecutionResult result} for the request execution. - * @since 1.1.4 - */ - @Nullable - public ExecutionResult getExecutionResult() { - return this.executionResult; - } + /** + * Return the {@link ExecutionResult result} for the request execution. + * @since 1.1.4 + */ + @Nullable + public ExecutionResult getExecutionResult() { + return this.executionResult; + } - /** - * Set the {@link ExecutionResult result} for the request execution. - * @param executionResult the execution result - * @since 1.1.4 - */ - public void setExecutionResult(ExecutionResult executionResult) { - this.executionResult = executionResult; - } + /** + * Set the {@link ExecutionResult result} for the request execution. + * @param executionResult the execution result + * @since 1.1.4 + */ + public void setExecutionResult(ExecutionResult executionResult) { + this.executionResult = executionResult; + } - /** - * Return the {@link ExecutionResult result} for the request execution. - * @deprecated since 1.1.4 in favor of {@link #getExecutionResult()} - */ - @Nullable - @Deprecated(since = "1.1.4", forRemoval = true) - public ExecutionResult getResponse() { - return this.executionResult; - } + /** + * Return the {@link ExecutionResult result} for the request execution. + * @deprecated since 1.1.4 in favor of {@link #getExecutionResult()} + */ + @Nullable + @Deprecated(since = "1.1.4", forRemoval = true) + public ExecutionResult getResponse() { + return this.executionResult; + } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationDocumentation.java b/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationDocumentation.java index ed66dca3..3d512a48 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationDocumentation.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationDocumentation.java @@ -140,7 +140,7 @@ public enum GraphQlObservationDocumentation implements ObservationDocumentation }, /** - * Class name of the data fetching error + * Class name of the data fetching error. */ ERROR_TYPE { @Override diff --git a/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java b/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java index 65a4af6a..bdcba5ba 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/observation/GraphQlObservationInstrumentation.java @@ -16,6 +16,10 @@ package org.springframework.graphql.observation; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.CompletionStage; + import graphql.ExecutionResult; import graphql.GraphQLContext; import graphql.execution.instrumentation.InstrumentationContext; @@ -31,11 +35,8 @@ import graphql.schema.DataFetchingEnvironmentImpl; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; import io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor; -import org.springframework.lang.Nullable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.CompletionStage; +import org.springframework.lang.Nullable; /** * {@link graphql.execution.instrumentation.Instrumentation} that creates @@ -113,7 +114,7 @@ public class GraphQlObservationInstrumentation extends SimplePerformantInstrumen @Override public void onCompleted(ExecutionResult result, Throwable exc) { observationContext.setExecutionResult(result); - result.getErrors().forEach(graphQLError -> { + result.getErrors().forEach((graphQLError) -> { Observation.Event event = Observation.Event.of(graphQLError.getErrorType().toString(), graphQLError.getMessage()); requestObservation.event(event); }); @@ -156,7 +157,8 @@ public class GraphQlObservationInstrumentation extends SimplePerformantInstrumen dataFetcherObservation.error(error.getCause()); dataFetcherObservation.stop(); throw completionException; - } else { + } + else { dataFetcherObservation.error(error); dataFetcherObservation.stop(); throw new CompletionException(error); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/DefaultWebGraphQlHandlerBuilder.java b/spring-graphql/src/main/java/org/springframework/graphql/server/DefaultWebGraphQlHandlerBuilder.java index d5107ce6..e00f57d6 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/DefaultWebGraphQlHandlerBuilder.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/DefaultWebGraphQlHandlerBuilder.java @@ -59,7 +59,7 @@ class DefaultWebGraphQlHandlerBuilder implements WebGraphQlHandler.Builder { @Override public WebGraphQlHandler.Builder interceptors(List interceptors) { this.interceptors.addAll(interceptors); - interceptors.forEach(interceptor -> { + interceptors.forEach((interceptor) -> { if (interceptor instanceof WebSocketGraphQlInterceptor) { Assert.isNull(this.webSocketInterceptor, "There can be at most 1 WebSocketInterceptor"); this.webSocketInterceptor = (WebSocketGraphQlInterceptor) interceptor; @@ -73,19 +73,19 @@ class DefaultWebGraphQlHandlerBuilder implements WebGraphQlHandler.Builder { ContextSnapshotFactory snapshotFactory = ContextSnapshotFactory.builder().build(); - Chain endOfChain = request -> this.service.execute(request).map(WebGraphQlResponse::new); + Chain endOfChain = (request) -> this.service.execute(request).map(WebGraphQlResponse::new); Chain executionChain = this.interceptors.stream() .reduce(WebGraphQlInterceptor::andThen) - .map(interceptor -> interceptor.apply(endOfChain)) + .map((interceptor) -> interceptor.apply(endOfChain)) .orElse(endOfChain); return new WebGraphQlHandler() { @Override public WebSocketGraphQlInterceptor getWebSocketInterceptor() { - return (webSocketInterceptor != null ? - webSocketInterceptor : new WebSocketGraphQlInterceptor() {}); + return (DefaultWebGraphQlHandlerBuilder.this.webSocketInterceptor != null) ? + DefaultWebGraphQlHandlerBuilder.this.webSocketInterceptor : new WebSocketGraphQlInterceptor() { }; } @Override diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/GraphQlRSocketHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/GraphQlRSocketHandler.java index 9f0fc9e8..ba129388 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/GraphQlRSocketHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/GraphQlRSocketHandler.java @@ -61,12 +61,12 @@ import org.springframework.util.MimeTypeUtils; * } * * @MessageMapping("graphql") - * public Mono> handle(Map payload) { + * public Mono<Map<String, Object>> handle(Map<String, Object> payload) { * return this.handler.handle(payload); * } * * @MessageMapping("graphql") - * public Flux> handleSubscription(Map payload) { + * public Flux<Map<String, Object>> handleSubscription(Map<String, Object> payload) { * return this.handler.handleSubscription(payload); * } * } @@ -107,17 +107,18 @@ public class GraphQlRSocketHandler { } private static Chain initChain(ExecutionGraphQlService service, List interceptors) { - Chain endOfChain = request -> service.execute(request).map(RSocketGraphQlResponse::new); + Chain endOfChain = (request) -> service.execute(request).map(RSocketGraphQlResponse::new); return interceptors.isEmpty() ? endOfChain : interceptors.stream() .reduce(RSocketGraphQlInterceptor::andThen) - .map(interceptor -> interceptor.apply(endOfChain)) + .map((interceptor) -> interceptor.apply(endOfChain)) .orElse(endOfChain); } /** * Handle a {@code Request-Response} interaction. For queries and mutations. + * @param payload the decoded GraphQL request payload */ public Mono> handle(Map payload) { return handleInternal(payload).map(ExecutionGraphQlResponse::toMap); @@ -125,10 +126,11 @@ public class GraphQlRSocketHandler { /** * Handle a {@code Request-Stream} interaction. For subscriptions. + * @param payload the decoded GraphQL request payload */ public Flux> handleSubscription(Map payload) { return handleInternal(payload) - .flatMapMany(response -> { + .flatMapMany((response) -> { if (response.getData() instanceof Publisher) { Publisher publisher = response.getData(); return Flux.from(publisher).map(ExecutionResult::toSpecification); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/RSocketGraphQlInterceptor.java b/spring-graphql/src/main/java/org/springframework/graphql/server/RSocketGraphQlInterceptor.java index cdfeb9e0..f159eefa 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/RSocketGraphQlInterceptor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/RSocketGraphQlInterceptor.java @@ -53,7 +53,7 @@ public interface RSocketGraphQlInterceptor { * @return a new interceptor that chains the two */ default RSocketGraphQlInterceptor andThen(RSocketGraphQlInterceptor nextInterceptor) { - return (request, chain) -> intercept(request, nextRequest -> nextInterceptor.intercept(nextRequest, chain)); + return (request, chain) -> intercept(request, (nextRequest) -> nextInterceptor.intercept(nextRequest, chain)); } /** @@ -62,7 +62,7 @@ public interface RSocketGraphQlInterceptor { * @return a new chain instance */ default Chain apply(Chain chain) { - return request -> intercept(request, chain); + return (request) -> intercept(request, chain); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/WebGraphQlInterceptor.java b/spring-graphql/src/main/java/org/springframework/graphql/server/WebGraphQlInterceptor.java index eb6c43ec..2e7dd331 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/WebGraphQlInterceptor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/WebGraphQlInterceptor.java @@ -59,7 +59,7 @@ public interface WebGraphQlInterceptor { * @return a new interceptor that chains the two */ default WebGraphQlInterceptor andThen(WebGraphQlInterceptor nextInterceptor) { - return (request, chain) -> intercept(request, nextRequest -> { + return (request, chain) -> intercept(request, (nextRequest) -> { if (request instanceof WebSocketGraphQlRequest) { Assert.isTrue(nextRequest instanceof WebSocketGraphQlRequest, "Expected WebSocketGraphQlRequest but was: " + nextRequest.getClass().getName()); @@ -74,7 +74,7 @@ public interface WebGraphQlInterceptor { * @return a new chain instance */ default Chain apply(Chain chain) { - return request -> intercept(request, chain); + return (request) -> intercept(request, chain); } 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 ffa938ee..43aca472 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 @@ -83,6 +83,13 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements /** * Variant of {@link #WebGraphQlRequest(URI, HttpHeaders, MultiValueMap, Map, GraphQlRequest, String, Locale)} * with a Map for the request body. + * @param uri the URL for the HTTP request or WebSocket handshake + * @param headers the HTTP request headers + * @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 * @since 1.1.3 */ public WebGraphQlRequest( @@ -122,6 +129,11 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements /** * Create an instance. + * @param uri the URL for the HTTP request or WebSocket handshake + * @param headers the HTTP request headers + * @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 * @deprecated as of 1.1.3 in favor of * {@link #WebGraphQlRequest(URI, HttpHeaders, MultiValueMap, Map, GraphQlRequest, String, Locale)} */ @@ -143,7 +155,7 @@ public class WebGraphQlRequest extends DefaultExecutionGraphQlRequest implements this.uri = UriComponentsBuilder.fromUri(uri).build(true); this.headers = headers; - this.cookies = (cookies != null ? CollectionUtils.unmodifiableMultiValueMap(cookies) : EMPTY_COOKIES); + this.cookies = (cookies != null) ? CollectionUtils.unmodifiableMultiValueMap(cookies) : EMPTY_COOKIES; this.attributes = Collections.unmodifiableMap(attributes); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketGraphQlInterceptor.java b/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketGraphQlInterceptor.java index def46297..11c5ddfe 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketGraphQlInterceptor.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketGraphQlInterceptor.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.server; import java.util.Map; 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 1ee4ef26..00a7a578 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 @@ -43,6 +43,12 @@ public class WebSocketGraphQlRequest extends WebGraphQlRequest { /** * Create an instance. + * @param uri the URL for the HTTP request or WebSocket handshake + * @param headers the HTTP request headers + * @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 + * @param sessionInfo the WebSocket session id * @deprecated as of 1.1.3 in favor of the constructor with cookies */ @Deprecated(since = "1.1.3", forRemoval = true) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketSessionInfo.java b/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketSessionInfo.java index 01eeda4e..4290a5cc 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketSessionInfo.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/WebSocketSessionInfo.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.server; import java.net.InetSocketAddress; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/support/GraphQlWebSocketMessage.java b/spring-graphql/src/main/java/org/springframework/graphql/server/support/GraphQlWebSocketMessage.java index 0eabbfb7..33a0f58c 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/support/GraphQlWebSocketMessage.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/support/GraphQlWebSocketMessage.java @@ -97,6 +97,7 @@ public class GraphQlWebSocketMessage { /** * Return the payload. For a deserialized message, this is typically a * {@code Map} or {@code List} for an {@code "error"} message. + * @param

    teh payload type */ @SuppressWarnings("unchecked") public

    P getPayload() { @@ -120,14 +121,6 @@ public class GraphQlWebSocketMessage { } - @Override - public int hashCode() { - int hashCode = (this.type != null ? this.type.hashCode() : 0); - hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.id); - hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.payload); - return hashCode; - } - @Override public boolean equals(Object o) { if (!(o instanceof GraphQlWebSocketMessage)) { @@ -139,12 +132,20 @@ public class GraphQlWebSocketMessage { (ObjectUtils.nullSafeEquals(getPayload(), other.getPayload()))); } + @Override + public int hashCode() { + int hashCode = (this.type != null) ? this.type.hashCode() : 0; + hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.id); + hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.payload); + return hashCode; + } + @Override public String toString() { return "GraphQlWebSocketMessage[" + - (this.id != null ? "id=\"" + this.id + "\"" + ", " : "") + + ((this.id != null) ? "id=\"" + this.id + "\"" + ", " : "") + "type=\"" + this.type + "\"" + - (this.payload != null ? ", payload=" + this.payload : "") + "]"; + ((this.payload != null) ? ", payload=" + this.payload : "") + "]"; } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/support/GraphQlWebSocketMessageType.java b/spring-graphql/src/main/java/org/springframework/graphql/server/support/GraphQlWebSocketMessageType.java index d5a89724..841eb562 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/support/GraphQlWebSocketMessageType.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/support/GraphQlWebSocketMessageType.java @@ -26,20 +26,44 @@ package org.springframework.graphql.server.support; */ public enum GraphQlWebSocketMessageType { + /** + * Indicates that the client wants to establish a connection within the existing socket. + */ CONNECTION_INIT("connection_init", false), + /** + * Expected response to the {@link #CONNECTION_INIT} message from the client acknowledging a successful connection with the server. + */ CONNECTION_ACK("connection_ack", false), + /** + * Useful for detecting failed connections, displaying latency metrics or other types of network probing. + */ PING("ping", false), + /** + * The response to the {@link #PING} message. Must be sent as soon as the {@link #PING} message is received. + */ PONG("pong", false), + /** + * Requests an operation specified in the message payload. + */ SUBSCRIBE("subscribe", true), + /** + * Operation execution result(s) from the source stream created by the binding {@link #SUBSCRIBE} message. + */ NEXT("next", true), + /** + * Operation execution error(s) in response to the {@link #SUBSCRIBE} message. + */ ERROR("error", true), + /** + * Indicates that the requested operation execution has completed. + */ COMPLETE("complete", false), /** diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/support/SerializableGraphQlRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/server/support/SerializableGraphQlRequest.java index d73fb3bc..1e9878ba 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/support/SerializableGraphQlRequest.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/support/SerializableGraphQlRequest.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.server.support; import java.util.Map; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/AbstractGraphQlHttpHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/AbstractGraphQlHttpHandler.java index a7df7d23..1d528460 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/AbstractGraphQlHttpHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/AbstractGraphQlHttpHandler.java @@ -31,30 +31,29 @@ import org.springframework.web.reactive.function.server.ServerRequest; * Abstract class for GraphQL Handler implementations using the HTTP transport. * * @author Brian Clozel - * @since 1.3.0 */ class AbstractGraphQlHttpHandler { - protected final WebGraphQlHandler graphQlHandler; + protected final WebGraphQlHandler graphQlHandler; - @Nullable - protected final HttpCodecDelegate codecDelegate; + @Nullable + protected final HttpCodecDelegate codecDelegate; - public AbstractGraphQlHttpHandler(WebGraphQlHandler graphQlHandler, @Nullable HttpCodecDelegate codecDelegate) { - Assert.notNull(graphQlHandler, "WebGraphQlHandler is required"); - this.graphQlHandler = graphQlHandler; - this.codecDelegate = codecDelegate; - } + AbstractGraphQlHttpHandler(WebGraphQlHandler graphQlHandler, @Nullable HttpCodecDelegate codecDelegate) { + Assert.notNull(graphQlHandler, "WebGraphQlHandler is required"); + this.graphQlHandler = graphQlHandler; + this.codecDelegate = codecDelegate; + } - protected Mono readRequest(ServerRequest serverRequest) { - if (this.codecDelegate != null) { - MediaType contentType = serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON); - return this.codecDelegate.decode(serverRequest.bodyToFlux(DataBuffer.class), contentType); - } - else { - return serverRequest.bodyToMono(SerializableGraphQlRequest.class); - } - } + protected Mono readRequest(ServerRequest serverRequest) { + if (this.codecDelegate != null) { + MediaType contentType = serverRequest.headers().contentType().orElse(MediaType.APPLICATION_JSON); + return this.codecDelegate.decode(serverRequest.bodyToFlux(DataBuffer.class), contentType); + } + else { + return serverRequest.bodyToMono(SerializableGraphQlRequest.class); + } + } } 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 ca533420..a186da1b 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 @@ -71,7 +71,7 @@ public class GraphQlHttpHandler extends AbstractGraphQlHttpHandler { */ public Mono handleRequest(ServerRequest serverRequest) { return readRequest(serverRequest) - .flatMap(body -> { + .flatMap((body) -> { WebGraphQlRequest graphQlRequest = new WebGraphQlRequest( serverRequest.uri(), serverRequest.headers().asHttpHeaders(), serverRequest.cookies(), serverRequest.attributes(), body, @@ -82,12 +82,12 @@ public class GraphQlHttpHandler extends AbstractGraphQlHttpHandler { } return this.graphQlHandler.handleRequest(graphQlRequest); }) - .flatMap(response -> { + .flatMap((response) -> { if (logger.isDebugEnabled()) { logger.debug("Execution complete"); } ServerResponse.BodyBuilder builder = ServerResponse.ok(); - builder.headers(headers -> headers.putAll(response.getResponseHeaders())); + builder.headers((headers) -> headers.putAll(response.getResponseHeaders())); builder.contentType(selectResponseMediaType(serverRequest)); if (this.codecDelegate != null) { return builder.bodyValue(this.codecDelegate.encode(response)); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlRequestPredicates.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlRequestPredicates.java index f41159c3..28fd69e4 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlRequestPredicates.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlRequestPredicates.java @@ -42,126 +42,129 @@ import org.springframework.web.util.pattern.PathPatternParser; * @author Brian Clozel * @since 1.3.0 */ -public class GraphQlRequestPredicates { +public final class GraphQlRequestPredicates { - private static final Log logger = LogFactory.getLog(GraphQlRequestPredicates.class); + private static final Log logger = LogFactory.getLog(GraphQlRequestPredicates.class); - /** - * Create a {@link RequestPredicate predicate} that matches GraphQL HTTP requests for the configured path. - * - * @param path the path on which the GraphQL HTTP endpoint is mapped - * @see GraphQlHttpHandler - */ - public static RequestPredicate graphQlHttp(String path) { - return new GraphQlHttpRequestPredicate(path, MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL_RESPONSE); - } + private GraphQlRequestPredicates() { - /** - * Create a {@link RequestPredicate predicate} that matches GraphQL SSE over HTTP requests for the configured path. - * - * @param path the path on which the GraphQL SSE endpoint is mapped - * @see GraphQlSseHandler - */ - public static RequestPredicate graphQlSse(String path) { - return new GraphQlHttpRequestPredicate(path, MediaType.TEXT_EVENT_STREAM); - } + } - private static class GraphQlHttpRequestPredicate implements RequestPredicate { + /** + * Create a {@link RequestPredicate predicate} that matches GraphQL HTTP requests for the configured path. + * @param path the path on which the GraphQL HTTP endpoint is mapped + * @see GraphQlHttpHandler + */ + public static RequestPredicate graphQlHttp(String path) { + return new GraphQlHttpRequestPredicate(path, MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL_RESPONSE); + } - private final PathPattern pattern; + /** + * Create a {@link RequestPredicate predicate} that matches GraphQL SSE over HTTP requests for the configured path. + * @param path the path on which the GraphQL SSE endpoint is mapped + * @see GraphQlSseHandler + */ + public static RequestPredicate graphQlSse(String path) { + return new GraphQlHttpRequestPredicate(path, MediaType.TEXT_EVENT_STREAM); + } - private final List acceptedMediaTypes; + private static class GraphQlHttpRequestPredicate implements RequestPredicate { + + private final PathPattern pattern; + + private final List acceptedMediaTypes; - GraphQlHttpRequestPredicate(String path, MediaType... accepted) { - Assert.notNull(path, "'path' must not be null"); - Assert.notEmpty(accepted, "'accepted' must not be empty"); - PathPatternParser parser = PathPatternParser.defaultInstance; - path = parser.initFullPathPattern(path); - this.pattern = parser.parse(path); - this.acceptedMediaTypes = Arrays.asList(accepted); - } + GraphQlHttpRequestPredicate(String path, MediaType... accepted) { + Assert.notNull(path, "'path' must not be null"); + Assert.notEmpty(accepted, "'accepted' must not be empty"); + PathPatternParser parser = PathPatternParser.defaultInstance; + path = parser.initFullPathPattern(path); + this.pattern = parser.parse(path); + this.acceptedMediaTypes = Arrays.asList(accepted); + } - @Override - public boolean test(ServerRequest request) { - return methodMatch(request, HttpMethod.POST) - && contentTypeMatch(request, MediaType.APPLICATION_JSON) - && acceptMatch(request, this.acceptedMediaTypes) - && pathMatch(request, this.pattern); - } - } + @Override + public boolean test(ServerRequest request) { + return methodMatch(request, HttpMethod.POST) + && contentTypeMatch(request, MediaType.APPLICATION_JSON) + && acceptMatch(request, this.acceptedMediaTypes) + && pathMatch(request, this.pattern); + } - private static boolean methodMatch(ServerRequest request, HttpMethod expected) { - HttpMethod actual = resolveMethod(request); - boolean methodMatch = expected.equals(actual); - traceMatch("Method", expected, actual, methodMatch); - return methodMatch; - } + private static boolean methodMatch(ServerRequest request, HttpMethod expected) { + HttpMethod actual = resolveMethod(request); + boolean methodMatch = expected.equals(actual); + traceMatch("Method", expected, actual, methodMatch); + return methodMatch; + } - private static HttpMethod resolveMethod(ServerRequest request) { - if (CorsUtils.isPreFlightRequest(request.exchange().getRequest())) { - String accessControlRequestMethod = - request.headers().firstHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD); - if (accessControlRequestMethod != null) { - return HttpMethod.valueOf(accessControlRequestMethod); - } - } - return request.method(); - } + private static HttpMethod resolveMethod(ServerRequest request) { + if (CorsUtils.isPreFlightRequest(request.exchange().getRequest())) { + String accessControlRequestMethod = + request.headers().firstHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD); + if (accessControlRequestMethod != null) { + return HttpMethod.valueOf(accessControlRequestMethod); + } + } + return request.method(); + } - private static boolean contentTypeMatch(ServerRequest request, MediaType expected) { - if (CorsUtils.isPreFlightRequest(request.exchange().getRequest())) { - return true; - } - ServerRequest.Headers headers = request.headers(); - MediaType actual = headers.contentType().orElse(MediaType.APPLICATION_OCTET_STREAM); - boolean contentTypeMatch = expected.includes(actual); - traceMatch("Content-Type", expected, actual, contentTypeMatch); - return contentTypeMatch; - } + private static boolean contentTypeMatch(ServerRequest request, MediaType expected) { + if (CorsUtils.isPreFlightRequest(request.exchange().getRequest())) { + return true; + } + ServerRequest.Headers headers = request.headers(); + MediaType actual = headers.contentType().orElse(MediaType.APPLICATION_OCTET_STREAM); + boolean contentTypeMatch = expected.includes(actual); + traceMatch("Content-Type", expected, actual, contentTypeMatch); + return contentTypeMatch; + } - private static boolean acceptMatch(ServerRequest request, List expected) { - if (CorsUtils.isPreFlightRequest(request.exchange().getRequest())) { - return true; - } - ServerRequest.Headers headers = request.headers(); - List acceptedMediaTypes = acceptedMediaTypes(headers); - boolean match = false; - outer: - for (MediaType acceptedMediaType : acceptedMediaTypes) { - for (MediaType mediaType : expected) { - if (acceptedMediaType.isCompatibleWith(mediaType)) { - match = true; - break outer; - } - } - } - traceMatch("Accept", expected, acceptedMediaTypes, match); - return match; - } + private static boolean acceptMatch(ServerRequest request, List expected) { + if (CorsUtils.isPreFlightRequest(request.exchange().getRequest())) { + return true; + } + ServerRequest.Headers headers = request.headers(); + List acceptedMediaTypes = acceptedMediaTypes(headers); + boolean match = false; + outer: + for (MediaType acceptedMediaType : acceptedMediaTypes) { + for (MediaType mediaType : expected) { + if (acceptedMediaType.isCompatibleWith(mediaType)) { + match = true; + break outer; + } + } + } + traceMatch("Accept", expected, acceptedMediaTypes, match); + return match; + } - private static List acceptedMediaTypes(ServerRequest.Headers headers) { - List acceptedMediaTypes = headers.accept(); - if (acceptedMediaTypes.isEmpty()) { - acceptedMediaTypes = Collections.singletonList(MediaType.ALL); - } else { - MimeTypeUtils.sortBySpecificity(acceptedMediaTypes); - } - return acceptedMediaTypes; - } + private static List acceptedMediaTypes(ServerRequest.Headers headers) { + List acceptedMediaTypes = headers.accept(); + if (acceptedMediaTypes.isEmpty()) { + acceptedMediaTypes = Collections.singletonList(MediaType.ALL); + } + else { + MimeTypeUtils.sortBySpecificity(acceptedMediaTypes); + } + return acceptedMediaTypes; + } - private static boolean pathMatch(ServerRequest request, PathPattern pattern) { - PathContainer pathContainer = request.requestPath().pathWithinApplication(); - boolean pathMatch = pattern.matches(pathContainer); - traceMatch("Pattern", pattern.getPatternString(), request.path(), pathMatch); - return pathMatch; - } + private static boolean pathMatch(ServerRequest request, PathPattern pattern) { + PathContainer pathContainer = request.requestPath().pathWithinApplication(); + boolean pathMatch = pattern.matches(pathContainer); + traceMatch("Pattern", pattern.getPatternString(), request.path(), pathMatch); + return pathMatch; + } - private static void traceMatch(String prefix, Object desired, @Nullable Object actual, boolean match) { - if (logger.isTraceEnabled()) { - logger.trace(String.format("%s \"%s\" %s against value \"%s\"", - prefix, desired, match ? "matches" : "does not match", actual)); - } - } + private static void traceMatch(String prefix, Object desired, @Nullable Object actual, boolean match) { + if (logger.isTraceEnabled()) { + logger.trace(String.format("%s \"%s\" %s against value \"%s\"", + prefix, desired, match ? "matches" : "does not match", actual)); + } + } + } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlSseHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlSseHandler.java index 83cae32b..4a2f7d26 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlSseHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlSseHandler.java @@ -50,64 +50,63 @@ import org.springframework.web.reactive.function.server.ServerResponse; */ public class GraphQlSseHandler extends AbstractGraphQlHttpHandler { - private static final Log logger = LogFactory.getLog(GraphQlSseHandler.class); + private static final Log logger = LogFactory.getLog(GraphQlSseHandler.class); - private static final Mono>> COMPLETE_EVENT = Mono.just(ServerSentEvent.>builder(Collections.emptyMap()).event("complete").build()); + private static final Mono>> COMPLETE_EVENT = Mono.just(ServerSentEvent.>builder(Collections.emptyMap()).event("complete").build()); - public GraphQlSseHandler(WebGraphQlHandler graphQlHandler) { - super(graphQlHandler, null); - } + public GraphQlSseHandler(WebGraphQlHandler graphQlHandler) { + super(graphQlHandler, null); + } - /** - * Handle GraphQL requests over HTTP using the Server-Sent Events protocol. - * - * @param serverRequest the incoming HTTP request - * @return the HTTP response - */ - @SuppressWarnings("unchecked") - public Mono handleRequest(ServerRequest serverRequest) { - Flux>> data = readRequest(serverRequest) - .flatMap(body -> { - WebGraphQlRequest graphQlRequest = new WebGraphQlRequest( - serverRequest.uri(), serverRequest.headers().asHttpHeaders(), - serverRequest.cookies(), serverRequest.attributes(), body, - serverRequest.exchange().getRequest().getId(), - serverRequest.exchange().getLocaleContext().getLocale()); - if (logger.isDebugEnabled()) { - logger.debug("Executing: " + graphQlRequest); - } - return this.graphQlHandler.handleRequest(graphQlRequest); - }) - .flatMapMany(response -> { - if (logger.isDebugEnabled()) { - logger.debug("Execution result ready" - + (!CollectionUtils.isEmpty(response.getErrors()) ? " with errors: " + response.getErrors() : "") - + "."); - } - if (response.getData() instanceof Publisher) { - // Subscription - return Flux.from((Publisher) response.getData()).map(ExecutionResult::toSpecification); - } - if (logger.isDebugEnabled()) { - logger.debug("Only subscriptions are supported, DataFetcher must return a Publisher type"); - } - // Single response (query or mutation) are not supported - String errorMessage = "SSE transport only supports Subscription operations"; - GraphQLError unsupportedOperationError = GraphQLError.newError().errorType(ErrorType.OperationNotSupported) - .message(errorMessage).build(); - return Flux.error(new SubscriptionPublisherException(Collections.singletonList(unsupportedOperationError), - new IllegalArgumentException(errorMessage))); - }) - .onErrorResume(SubscriptionPublisherException.class, exc -> { - ExecutionResult errorResult = ExecutionResult.newExecutionResult().errors(exc.getErrors()).build(); - return Flux.just(errorResult.toSpecification()); - }) - .map(event -> ServerSentEvent.builder(event).event("next").build()); + /** + * Handle GraphQL requests over HTTP using the Server-Sent Events protocol. + * @param serverRequest the incoming HTTP request + * @return the HTTP response + */ + @SuppressWarnings("unchecked") + public Mono handleRequest(ServerRequest serverRequest) { + Flux>> data = readRequest(serverRequest) + .flatMap((body) -> { + WebGraphQlRequest graphQlRequest = new WebGraphQlRequest( + serverRequest.uri(), serverRequest.headers().asHttpHeaders(), + serverRequest.cookies(), serverRequest.attributes(), body, + serverRequest.exchange().getRequest().getId(), + serverRequest.exchange().getLocaleContext().getLocale()); + if (logger.isDebugEnabled()) { + logger.debug("Executing: " + graphQlRequest); + } + return this.graphQlHandler.handleRequest(graphQlRequest); + }) + .flatMapMany((response) -> { + if (logger.isDebugEnabled()) { + logger.debug("Execution result ready" + + (!CollectionUtils.isEmpty(response.getErrors()) ? " with errors: " + response.getErrors() : "") + + "."); + } + if (response.getData() instanceof Publisher) { + // Subscription + return Flux.from((Publisher) response.getData()).map(ExecutionResult::toSpecification); + } + if (logger.isDebugEnabled()) { + logger.debug("Only subscriptions are supported, DataFetcher must return a Publisher type"); + } + // Single response (query or mutation) are not supported + String errorMessage = "SSE transport only supports Subscription operations"; + GraphQLError unsupportedOperationError = GraphQLError.newError().errorType(ErrorType.OperationNotSupported) + .message(errorMessage).build(); + return Flux.error(new SubscriptionPublisherException(Collections.singletonList(unsupportedOperationError), + new IllegalArgumentException(errorMessage))); + }) + .onErrorResume(SubscriptionPublisherException.class, (exc) -> { + ExecutionResult errorResult = ExecutionResult.newExecutionResult().errors(exc.getErrors()).build(); + return Flux.just(errorResult.toSpecification()); + }) + .map((event) -> ServerSentEvent.builder(event).event("next").build()); - Flux>> body = data.concatWith(COMPLETE_EVENT); - return ServerResponse.ok().contentType(MediaType.TEXT_EVENT_STREAM).body(BodyInserters.fromServerSentEvents(body)) - .onErrorResume(Throwable.class, exc -> ServerResponse.badRequest().build()); - } + Flux>> body = data.concatWith(COMPLETE_EVENT); + return ServerResponse.ok().contentType(MediaType.TEXT_EVENT_STREAM).body(BodyInserters.fromServerSentEvents(body)) + .onErrorResume(Throwable.class, (exc) -> ServerResponse.badRequest().build()); + } } 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 68c7778c..b76f6761 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 @@ -126,17 +126,17 @@ public class GraphQlWebSocketHandler implements WebSocketHandler { .subscribe(); session.closeStatus() - .doOnSuccess(closeStatus -> { + .doOnSuccess((closeStatus) -> { Map connectionInitPayload = connectionInitPayloadRef.get(); if (connectionInitPayload == null) { return; } - int statusCode = (closeStatus != null ? closeStatus.getCode() : 1005); + int statusCode = (closeStatus != null) ? closeStatus.getCode() : 1005; this.webSocketInterceptor.handleConnectionClosed(sessionInfo, statusCode, connectionInitPayload); }) .subscribe(); - return session.send(session.receive().flatMap(webSocketMessage -> { + return session.send(session.receive().flatMap((webSocketMessage) -> { GraphQlWebSocketMessage message = this.webSocketCodecDelegate.decode(webSocketMessage); String id = message.getId(); Map payload = message.getPayload(); @@ -155,7 +155,7 @@ public class GraphQlWebSocketHandler implements WebSocketHandler { logger.debug("Executing: " + request); } return this.graphQlHandler.handleRequest(request) - .flatMapMany(response -> handleResponse(session, id, subscriptions, response)) + .flatMapMany((response) -> handleResponse(session, id, subscriptions, response)) .doOnTerminate(() -> subscriptions.remove(id)); } case PING -> { @@ -178,9 +178,9 @@ public class GraphQlWebSocketHandler implements WebSocketHandler { } return this.webSocketInterceptor.handleConnectionInitialization(sessionInfo, payload) .defaultIfEmpty(Collections.emptyMap()) - .map(ackPayload -> this.webSocketCodecDelegate.encodeConnectionAck(session, ackPayload)) + .map((ackPayload) -> this.webSocketCodecDelegate.encodeConnectionAck(session, ackPayload)) .flux() - .onErrorResume(ex -> GraphQlStatus.close(session, GraphQlStatus.UNAUTHORIZED_STATUS)); + .onErrorResume((ex) -> GraphQlStatus.close(session, GraphQlStatus.UNAUTHORIZED_STATUS)); } default -> { return GraphQlStatus.close(session, GraphQlStatus.INVALID_MESSAGE_STATUS); @@ -218,9 +218,9 @@ public class GraphQlWebSocketHandler implements WebSocketHandler { } return responseFlux - .map(responseMap -> this.webSocketCodecDelegate.encodeNext(session, id, responseMap)) + .map((responseMap) -> this.webSocketCodecDelegate.encodeNext(session, id, responseMap)) .concatWith(Mono.fromCallable(() -> this.webSocketCodecDelegate.encodeComplete(session, id))) - .onErrorResume(ex -> { + .onErrorResume((ex) -> { if (ex instanceof SubscriptionExistsException) { CloseStatus status = new CloseStatus(4409, "Subscriber for " + id + " already exists"); return GraphQlStatus.close(session, status); @@ -230,7 +230,7 @@ public class GraphQlWebSocketHandler implements WebSocketHandler { } - private static class GraphQlStatus { + private static final class GraphQlStatus { static final CloseStatus INVALID_MESSAGE_STATUS = new CloseStatus(4400, "Invalid message"); @@ -247,7 +247,7 @@ public class GraphQlWebSocketHandler implements WebSocketHandler { } - private static class WebFluxSessionInfo implements WebSocketSessionInfo { + private static final class WebFluxSessionInfo implements WebSocketSessionInfo { private final WebSocketSession session; @@ -288,7 +288,7 @@ public class GraphQlWebSocketHandler implements WebSocketHandler { @SuppressWarnings("serial") - private static class SubscriptionExistsException extends RuntimeException { + private static final class SubscriptionExistsException extends RuntimeException { } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphiQlHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphiQlHandler.java index 913fe5f2..e1195f9b 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphiQlHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphiQlHandler.java @@ -70,6 +70,7 @@ public class GraphiQlHandler { /** * Render the GraphiQL page as "text/html", or if the "path" query parameter * is missing, add it and redirect back to the same URL. + * @param request the HTTP server request */ public Mono handleRequest(ServerRequest request) { return (request.queryParam("path").isPresent() ? diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/HttpCodecDelegate.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/HttpCodecDelegate.java index 4e4b975d..9d588efc 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/HttpCodecDelegate.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/HttpCodecDelegate.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.server.webflux; import java.util.Map; @@ -39,7 +40,6 @@ import org.springframework.util.MimeTypeUtils; * * @author Rossen Stoyanchev * @author Brian Clozel - * @since 1.3.0 */ final class HttpCodecDelegate { @@ -77,13 +77,13 @@ final class HttpCodecDelegate { @SuppressWarnings("unchecked") - public DataBuffer encode(GraphQlResponse response) { + DataBuffer encode(GraphQlResponse response) { return ((Encoder>) this.encoder) .encodeValue(response.toMap(), DefaultDataBufferFactory.sharedInstance, RESPONSE_TYPE, MimeTypeUtils.APPLICATION_JSON, null); } @SuppressWarnings("unchecked") - public Mono decode(Publisher inputStream, MediaType contentType) { + Mono decode(Publisher inputStream, MediaType contentType) { return (Mono) this.decoder.decodeToMono(inputStream, REQUEST_TYPE, contentType, null); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/SchemaHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/SchemaHandler.java index 0c8c5c47..2c14cf5d 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/SchemaHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/SchemaHandler.java @@ -29,6 +29,7 @@ import org.springframework.web.reactive.function.server.ServerResponse; * {@link graphql.schema.GraphQLSchema} printed via {@link SchemaPrinter}. * * @author Rossen Stoyanchev + * @since 1.0.0 */ public class SchemaHandler { @@ -45,7 +46,7 @@ public class SchemaHandler { public Mono handleRequest(ServerRequest request) { return ServerResponse.ok() .contentType(MediaType.TEXT_PLAIN) - .bodyValue(this.printer.print(graphQlSource.schema())); + .bodyValue(this.printer.print(this.graphQlSource.schema())); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/WebSocketCodecDelegate.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/WebSocketCodecDelegate.java index 0643ac4b..206b5d15 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/WebSocketCodecDelegate.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/WebSocketCodecDelegate.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.server.webflux; import java.util.Collections; @@ -43,7 +44,6 @@ import org.springframework.web.reactive.socket.WebSocketSession; * Helper class for encoding and decoding GraphQL messages in WebSocket transport. * * @author Rossen Stoyanchev - * @since 1.0.0 */ final class WebSocketCodecDelegate { @@ -79,7 +79,7 @@ final class WebSocketCodecDelegate { @SuppressWarnings("unchecked") - public WebSocketMessage encode(WebSocketSession session, GraphQlWebSocketMessage message) { + WebSocketMessage encode(WebSocketSession session, GraphQlWebSocketMessage message) { DataBuffer buffer = ((Encoder) this.encoder).encodeValue( (T) message, session.bufferFactory(), MESSAGE_TYPE, MimeTypeUtils.APPLICATION_JSON, null); @@ -88,20 +88,20 @@ final class WebSocketCodecDelegate { } @SuppressWarnings("ConstantConditions") - public GraphQlWebSocketMessage decode(WebSocketMessage webSocketMessage) { + GraphQlWebSocketMessage decode(WebSocketMessage webSocketMessage) { DataBuffer buffer = DataBufferUtils.retain(webSocketMessage.getPayload()); return (GraphQlWebSocketMessage) this.decoder.decode(buffer, MESSAGE_TYPE, null, null); } - public WebSocketMessage encodeConnectionAck(WebSocketSession session, Object ackPayload) { + WebSocketMessage encodeConnectionAck(WebSocketSession session, Object ackPayload) { return encode(session, GraphQlWebSocketMessage.connectionAck(ackPayload)); } - public WebSocketMessage encodeNext(WebSocketSession session, String id, Map responseMap) { + WebSocketMessage encodeNext(WebSocketSession session, String id, Map responseMap) { return encode(session, GraphQlWebSocketMessage.next(id, responseMap)); } - public WebSocketMessage encodeError(WebSocketSession session, String id, Throwable ex) { + WebSocketMessage encodeError(WebSocketSession session, String id, Throwable ex) { List errors = ((ex instanceof SubscriptionPublisherException) ? ((SubscriptionPublisherException) ex).getErrors() : Collections.singletonList(GraphqlErrorBuilder.newError() @@ -111,7 +111,7 @@ final class WebSocketCodecDelegate { return encode(session, GraphQlWebSocketMessage.error(id, errors)); } - public WebSocketMessage encodeComplete(WebSocketSession session, String id) { + WebSocketMessage encodeComplete(WebSocketSession session, String id) { return encode(session, GraphQlWebSocketMessage.complete(id)); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/AbstractGraphQlHttpHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/AbstractGraphQlHttpHandler.java index 638573a3..bb68c712 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/AbstractGraphQlHttpHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/AbstractGraphQlHttpHandler.java @@ -20,7 +20,6 @@ import java.io.IOException; import jakarta.servlet.ServletException; import jakarta.servlet.http.Cookie; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -45,53 +44,52 @@ import org.springframework.web.servlet.function.ServerRequest; * Abstract class for GraphQL Handler implementations using the HTTP transport. * * @author Brian Clozel - * @since 1.3.0 */ abstract class AbstractGraphQlHttpHandler { - protected final Log logger = LogFactory.getLog(getClass()); + protected final Log logger = LogFactory.getLog(getClass()); - protected final IdGenerator idGenerator = new AlternativeJdkIdGenerator(); + protected final IdGenerator idGenerator = new AlternativeJdkIdGenerator(); - protected final WebGraphQlHandler graphQlHandler; + protected final WebGraphQlHandler graphQlHandler; - @Nullable - protected final HttpMessageConverter messageConverter; + @Nullable + protected final HttpMessageConverter messageConverter; - @SuppressWarnings("unchecked") - AbstractGraphQlHttpHandler(WebGraphQlHandler graphQlHandler, @Nullable HttpMessageConverter messageConverter) { - Assert.notNull(graphQlHandler, "WebGraphQlHandler is required"); - this.graphQlHandler = graphQlHandler; - this.messageConverter = (HttpMessageConverter) messageConverter; - } + @SuppressWarnings("unchecked") + AbstractGraphQlHttpHandler(WebGraphQlHandler graphQlHandler, @Nullable HttpMessageConverter messageConverter) { + Assert.notNull(graphQlHandler, "WebGraphQlHandler is required"); + this.graphQlHandler = graphQlHandler; + this.messageConverter = (HttpMessageConverter) messageConverter; + } - protected static MultiValueMap initCookies(ServerRequest serverRequest) { - MultiValueMap source = serverRequest.cookies(); - MultiValueMap target = new LinkedMultiValueMap<>(source.size()); - source.values().forEach(cookieList -> cookieList.forEach(cookie -> { - HttpCookie httpCookie = new HttpCookie(cookie.getName(), cookie.getValue()); - target.add(cookie.getName(), httpCookie); - })); - return target; - } + protected static MultiValueMap initCookies(ServerRequest serverRequest) { + MultiValueMap source = serverRequest.cookies(); + MultiValueMap target = new LinkedMultiValueMap<>(source.size()); + source.values().forEach((cookieList) -> cookieList.forEach((cookie) -> { + HttpCookie httpCookie = new HttpCookie(cookie.getName(), cookie.getValue()); + target.add(cookie.getName(), httpCookie); + })); + return target; + } - protected GraphQlRequest readBody(ServerRequest request) throws ServletException { - try { - if (this.messageConverter != null) { - MediaType contentType = request.headers().contentType().orElse(MediaType.APPLICATION_JSON); - if (this.messageConverter.canRead(SerializableGraphQlRequest.class, contentType)) { - return (GraphQlRequest) this.messageConverter.read(SerializableGraphQlRequest.class, - new ServletServerHttpRequest(request.servletRequest())); - } - throw new HttpMediaTypeNotSupportedException(contentType, this.messageConverter.getSupportedMediaTypes(), request.method()); - } - else { - return request.body(SerializableGraphQlRequest.class); - } - } - catch (IOException ex) { - throw new ServerWebInputException("I/O error while reading request body", null, ex); - } - } + protected GraphQlRequest readBody(ServerRequest request) throws ServletException { + try { + if (this.messageConverter != null) { + MediaType contentType = request.headers().contentType().orElse(MediaType.APPLICATION_JSON); + if (this.messageConverter.canRead(SerializableGraphQlRequest.class, contentType)) { + return (GraphQlRequest) this.messageConverter.read(SerializableGraphQlRequest.class, + new ServletServerHttpRequest(request.servletRequest())); + } + throw new HttpMediaTypeNotSupportedException(contentType, this.messageConverter.getSupportedMediaTypes(), request.method()); + } + else { + return request.body(SerializableGraphQlRequest.class); + } + } + catch (IOException ex) { + throw new ServerWebInputException("I/O error while reading request body", null, ex); + } + } } 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 9ba20349..d05fc456 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 @@ -44,7 +44,7 @@ import org.springframework.web.servlet.function.ServerResponse; * @author Brian Clozel * @since 1.0.0 */ -public class GraphQlHttpHandler extends AbstractGraphQlHttpHandler{ +public class GraphQlHttpHandler extends AbstractGraphQlHttpHandler { @SuppressWarnings("removal") private static final List SUPPORTED_MEDIA_TYPES = @@ -89,13 +89,13 @@ public class GraphQlHttpHandler extends AbstractGraphQlHttpHandler{ } CompletableFuture future = this.graphQlHandler.handleRequest(graphQlRequest) - .map(response -> { + .map((response) -> { if (logger.isDebugEnabled()) { logger.debug("Execution complete"); } MediaType contentType = selectResponseMediaType(serverRequest); ServerResponse.BodyBuilder builder = ServerResponse.ok(); - builder.headers(headers -> headers.putAll(response.getResponseHeaders())); + builder.headers((headers) -> headers.putAll(response.getResponseHeaders())); builder.contentType(contentType); if (this.messageConverter != null) { @@ -133,15 +133,15 @@ public class GraphQlHttpHandler extends AbstractGraphQlHttpHandler{ private ServerResponse.HeadersBuilder.WriteFunction writeFunction(MediaType contentType, GraphQlResponse response) { return (servletRequest, servletResponse) -> { - if (messageConverter != null) { - ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(servletResponse); - messageConverter.write(response.toMap(), contentType, httpResponse); + if (messageConverter != null) { + ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(servletResponse); + messageConverter.write(response.toMap(), contentType, httpResponse); return null; - } + } else { throw new HttpMediaTypeNotSupportedException(contentType, SUPPORTED_MEDIA_TYPES, HttpMethod.POST); } - }; + }; } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlRequestPredicates.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlRequestPredicates.java index e5f5103b..96e6bcbb 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlRequestPredicates.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlRequestPredicates.java @@ -42,126 +42,129 @@ import org.springframework.web.util.pattern.PathPatternParser; * @author Brian Clozel * @since 1.3.0 */ -public class GraphQlRequestPredicates { +public final class GraphQlRequestPredicates { - private static final Log logger = LogFactory.getLog(GraphQlRequestPredicates.class); + private static final Log logger = LogFactory.getLog(GraphQlRequestPredicates.class); - /** - * Create a {@link RequestPredicate predicate} that matches GraphQL HTTP requests for the configured path. - * - * @param path the path on which the GraphQL HTTP endpoint is mapped - * @see GraphQlHttpHandler - */ - public static RequestPredicate graphQlHttp(String path) { - return new GraphQlHttpRequestPredicate(path, MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL_RESPONSE); - } + private GraphQlRequestPredicates() { - /** - * Create a {@link RequestPredicate predicate} that matches GraphQL SSE over HTTP requests for the configured path. - * - * @param path the path on which the GraphQL SSE endpoint is mapped - * @see GraphQlSseHandler - */ - public static RequestPredicate graphQlSse(String path) { - return new GraphQlHttpRequestPredicate(path, MediaType.TEXT_EVENT_STREAM); - } + } - private static class GraphQlHttpRequestPredicate implements RequestPredicate { + /** + * Create a {@link RequestPredicate predicate} that matches GraphQL HTTP requests for the configured path. + * @param path the path on which the GraphQL HTTP endpoint is mapped + * @see GraphQlHttpHandler + */ + public static RequestPredicate graphQlHttp(String path) { + return new GraphQlHttpRequestPredicate(path, MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL_RESPONSE); + } - private final PathPattern pattern; + /** + * Create a {@link RequestPredicate predicate} that matches GraphQL SSE over HTTP requests for the configured path. + * @param path the path on which the GraphQL SSE endpoint is mapped + * @see GraphQlSseHandler + */ + public static RequestPredicate graphQlSse(String path) { + return new GraphQlHttpRequestPredicate(path, MediaType.TEXT_EVENT_STREAM); + } - private final List acceptedMediaTypes; + private static class GraphQlHttpRequestPredicate implements RequestPredicate { + + private final PathPattern pattern; + + private final List acceptedMediaTypes; - GraphQlHttpRequestPredicate(String path, MediaType... accepted) { - Assert.notNull(path, "'path' must not be null"); - Assert.notEmpty(accepted, "'accepted' must not be empty"); - PathPatternParser parser = PathPatternParser.defaultInstance; - path = parser.initFullPathPattern(path); - this.pattern = parser.parse(path); - this.acceptedMediaTypes = Arrays.asList(accepted); - } + GraphQlHttpRequestPredicate(String path, MediaType... accepted) { + Assert.notNull(path, "'path' must not be null"); + Assert.notEmpty(accepted, "'accepted' must not be empty"); + PathPatternParser parser = PathPatternParser.defaultInstance; + path = parser.initFullPathPattern(path); + this.pattern = parser.parse(path); + this.acceptedMediaTypes = Arrays.asList(accepted); + } - @Override - public boolean test(ServerRequest request) { - return methodMatch(request, HttpMethod.POST) - && contentTypeMatch(request, MediaType.APPLICATION_JSON) - && acceptMatch(request, this.acceptedMediaTypes) - && pathMatch(request, this.pattern); - } - } + @Override + public boolean test(ServerRequest request) { + return methodMatch(request, HttpMethod.POST) + && contentTypeMatch(request, MediaType.APPLICATION_JSON) + && acceptMatch(request, this.acceptedMediaTypes) + && pathMatch(request, this.pattern); + } - private static boolean methodMatch(ServerRequest request, HttpMethod expected) { - HttpMethod actual = resolveMethod(request); - boolean methodMatch = expected.equals(actual); - traceMatch("Method", expected, actual, methodMatch); - return methodMatch; - } + private static boolean methodMatch(ServerRequest request, HttpMethod expected) { + HttpMethod actual = resolveMethod(request); + boolean methodMatch = expected.equals(actual); + traceMatch("Method", expected, actual, methodMatch); + return methodMatch; + } - private static HttpMethod resolveMethod(ServerRequest request) { - if (CorsUtils.isPreFlightRequest(request.servletRequest())) { - String accessControlRequestMethod = - request.headers().firstHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD); - if (accessControlRequestMethod != null) { - return HttpMethod.valueOf(accessControlRequestMethod); - } - } - return request.method(); - } + private static HttpMethod resolveMethod(ServerRequest request) { + if (CorsUtils.isPreFlightRequest(request.servletRequest())) { + String accessControlRequestMethod = + request.headers().firstHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD); + if (accessControlRequestMethod != null) { + return HttpMethod.valueOf(accessControlRequestMethod); + } + } + return request.method(); + } - private static boolean contentTypeMatch(ServerRequest request, MediaType expected) { - if (CorsUtils.isPreFlightRequest(request.servletRequest())) { - return true; - } - ServerRequest.Headers headers = request.headers(); - MediaType actual = headers.contentType().orElse(MediaType.APPLICATION_OCTET_STREAM); - boolean contentTypeMatch = expected.includes(actual); - traceMatch("Content-Type", expected, actual, contentTypeMatch); - return contentTypeMatch; - } + private static boolean contentTypeMatch(ServerRequest request, MediaType expected) { + if (CorsUtils.isPreFlightRequest(request.servletRequest())) { + return true; + } + ServerRequest.Headers headers = request.headers(); + MediaType actual = headers.contentType().orElse(MediaType.APPLICATION_OCTET_STREAM); + boolean contentTypeMatch = expected.includes(actual); + traceMatch("Content-Type", expected, actual, contentTypeMatch); + return contentTypeMatch; + } - private static boolean acceptMatch(ServerRequest request, List expected) { - if (CorsUtils.isPreFlightRequest(request.servletRequest())) { - return true; - } - ServerRequest.Headers headers = request.headers(); - List acceptedMediaTypes = acceptedMediaTypes(headers); - boolean match = false; - outer: - for (MediaType acceptedMediaType : acceptedMediaTypes) { - for (MediaType mediaType : expected) { - if (acceptedMediaType.isCompatibleWith(mediaType)) { - match = true; - break outer; - } - } - } - traceMatch("Accept", expected, acceptedMediaTypes, match); - return match; - } + private static boolean acceptMatch(ServerRequest request, List expected) { + if (CorsUtils.isPreFlightRequest(request.servletRequest())) { + return true; + } + ServerRequest.Headers headers = request.headers(); + List acceptedMediaTypes = acceptedMediaTypes(headers); + boolean match = false; + outer: + for (MediaType acceptedMediaType : acceptedMediaTypes) { + for (MediaType mediaType : expected) { + if (acceptedMediaType.isCompatibleWith(mediaType)) { + match = true; + break outer; + } + } + } + traceMatch("Accept", expected, acceptedMediaTypes, match); + return match; + } - private static List acceptedMediaTypes(ServerRequest.Headers headers) { - List acceptedMediaTypes = headers.accept(); - if (acceptedMediaTypes.isEmpty()) { - acceptedMediaTypes = Collections.singletonList(MediaType.ALL); - } else { - MimeTypeUtils.sortBySpecificity(acceptedMediaTypes); - } - return acceptedMediaTypes; - } + private static List acceptedMediaTypes(ServerRequest.Headers headers) { + List acceptedMediaTypes = headers.accept(); + if (acceptedMediaTypes.isEmpty()) { + acceptedMediaTypes = Collections.singletonList(MediaType.ALL); + } + else { + MimeTypeUtils.sortBySpecificity(acceptedMediaTypes); + } + return acceptedMediaTypes; + } - private static boolean pathMatch(ServerRequest request, PathPattern pattern) { - PathContainer pathContainer = request.requestPath().pathWithinApplication(); - boolean pathMatch = pattern.matches(pathContainer); - traceMatch("Pattern", pattern.getPatternString(), request.path(), pathMatch); - return pathMatch; - } + private static boolean pathMatch(ServerRequest request, PathPattern pattern) { + PathContainer pathContainer = request.requestPath().pathWithinApplication(); + boolean pathMatch = pattern.matches(pathContainer); + traceMatch("Pattern", pattern.getPatternString(), request.path(), pathMatch); + return pathMatch; + } - private static void traceMatch(String prefix, Object desired, @Nullable Object actual, boolean match) { - if (logger.isTraceEnabled()) { - logger.trace(String.format("%s \"%s\" %s against value \"%s\"", - prefix, desired, match ? "matches" : "does not match", actual)); - } - } + private static void traceMatch(String prefix, Object desired, @Nullable Object actual, boolean match) { + if (logger.isTraceEnabled()) { + logger.trace(String.format("%s \"%s\" %s against value \"%s\"", + prefix, desired, match ? "matches" : "does not match", actual)); + } + } + } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlSseHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlSseHandler.java index 63dc2cc4..5ca16d03 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlSseHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlSseHandler.java @@ -20,11 +20,10 @@ import java.io.IOException; import java.util.Collections; import java.util.Map; -import jakarta.servlet.ServletException; - import graphql.ErrorType; import graphql.ExecutionResult; import graphql.GraphQLError; +import jakarta.servlet.ServletException; import org.reactivestreams.Publisher; import reactor.core.publisher.BaseSubscriber; import reactor.core.publisher.Flux; @@ -52,109 +51,108 @@ import org.springframework.web.servlet.function.ServerResponse; */ public class GraphQlSseHandler extends AbstractGraphQlHttpHandler { - private final IdGenerator idGenerator = new AlternativeJdkIdGenerator(); + private final IdGenerator idGenerator = new AlternativeJdkIdGenerator(); - public GraphQlSseHandler(WebGraphQlHandler graphQlHandler) { - super(graphQlHandler, null); - } + public GraphQlSseHandler(WebGraphQlHandler graphQlHandler) { + super(graphQlHandler, null); + } - /** - * Handle GraphQL requests over HTTP using the Server-Sent Events protocol. - * - * @param serverRequest the incoming HTTP request - * @return the HTTP response - * @throws ServletException may be raised when reading the request body, e.g. - * {@link HttpMediaTypeNotSupportedException}. - */ - public ServerResponse handleRequest(ServerRequest serverRequest) throws ServletException { + /** + * Handle GraphQL requests over HTTP using the Server-Sent Events protocol. + * @param serverRequest the incoming HTTP request + * @return the HTTP response + * @throws ServletException may be raised when reading the request body, e.g. + * {@link HttpMediaTypeNotSupportedException}. + */ + public ServerResponse handleRequest(ServerRequest serverRequest) throws ServletException { - WebGraphQlRequest graphQlRequest = new WebGraphQlRequest( - serverRequest.uri(), serverRequest.headers().asHttpHeaders(), initCookies(serverRequest), - serverRequest.attributes(), readBody(serverRequest), this.idGenerator.generateId().toString(), - LocaleContextHolder.getLocale()); + WebGraphQlRequest graphQlRequest = new WebGraphQlRequest( + serverRequest.uri(), serverRequest.headers().asHttpHeaders(), initCookies(serverRequest), + serverRequest.attributes(), readBody(serverRequest), this.idGenerator.generateId().toString(), + LocaleContextHolder.getLocale()); - if (logger.isDebugEnabled()) { - logger.debug("Executing: " + graphQlRequest); - } - return ServerResponse.sse(sseBuilder -> { - this.graphQlHandler.handleRequest(graphQlRequest) - .flatMapMany(this::handleResponse) - .subscribe(new SendMessageSubscriber(graphQlRequest.getId(), sseBuilder)); - }); - } + if (logger.isDebugEnabled()) { + logger.debug("Executing: " + graphQlRequest); + } + return ServerResponse.sse((sseBuilder) -> this.graphQlHandler.handleRequest(graphQlRequest) + .flatMapMany(this::handleResponse) + .subscribe(new SendMessageSubscriber(graphQlRequest.getId(), sseBuilder))); + } - @SuppressWarnings("unchecked") - private Publisher> handleResponse(WebGraphQlResponse response) { - if (logger.isDebugEnabled()) { - logger.debug("Execution result ready" - + (!CollectionUtils.isEmpty(response.getErrors()) ? " with errors: " + response.getErrors() : "") - + "."); - } - if (response.getData() instanceof Publisher) { - // Subscription - return Flux.from((Publisher) response.getData()).map(ExecutionResult::toSpecification); - } - if (logger.isDebugEnabled()) { - logger.debug("Only subscriptions are supported, DataFetcher must return a Publisher type"); - } - // Single response (query or mutation) are not supported - String errorMessage = "SSE transport only supports Subscription operations"; - GraphQLError unsupportedOperationError = GraphQLError.newError().errorType(ErrorType.OperationNotSupported) - .message(errorMessage).build(); - return Flux.error(new SubscriptionPublisherException(Collections.singletonList(unsupportedOperationError), - new IllegalArgumentException(errorMessage))); - } + @SuppressWarnings("unchecked") + private Publisher> handleResponse(WebGraphQlResponse response) { + if (logger.isDebugEnabled()) { + logger.debug("Execution result ready" + + (!CollectionUtils.isEmpty(response.getErrors()) ? " with errors: " + response.getErrors() : "") + + "."); + } + if (response.getData() instanceof Publisher) { + // Subscription + return Flux.from((Publisher) response.getData()).map(ExecutionResult::toSpecification); + } + if (logger.isDebugEnabled()) { + logger.debug("Only subscriptions are supported, DataFetcher must return a Publisher type"); + } + // Single response (query or mutation) are not supported + String errorMessage = "SSE transport only supports Subscription operations"; + GraphQLError unsupportedOperationError = GraphQLError.newError().errorType(ErrorType.OperationNotSupported) + .message(errorMessage).build(); + return Flux.error(new SubscriptionPublisherException(Collections.singletonList(unsupportedOperationError), + new IllegalArgumentException(errorMessage))); + } - private static class SendMessageSubscriber extends BaseSubscriber> { + private static class SendMessageSubscriber extends BaseSubscriber> { - final String id; + final String id; - final ServerResponse.SseBuilder sseBuilder; + final ServerResponse.SseBuilder sseBuilder; - public SendMessageSubscriber(String id, ServerResponse.SseBuilder sseBuilder) { - this.id = id; - this.sseBuilder = sseBuilder; - } + SendMessageSubscriber(String id, ServerResponse.SseBuilder sseBuilder) { + this.id = id; + this.sseBuilder = sseBuilder; + } - @Override - protected void hookOnNext(Map value) { - writeNext(value); - } + @Override + protected void hookOnNext(Map value) { + writeNext(value); + } - @Override - protected void hookOnError(Throwable throwable) { - if (throwable instanceof SubscriptionPublisherException subscriptionException) { - ExecutionResult errorResult = ExecutionResult.newExecutionResult().errors(subscriptionException.getErrors()).build(); - writeNext(errorResult.toSpecification()); - } - else { - this.sseBuilder.error(throwable); - } - this.hookOnComplete(); - } + @Override + protected void hookOnError(Throwable throwable) { + if (throwable instanceof SubscriptionPublisherException subscriptionException) { + ExecutionResult errorResult = ExecutionResult.newExecutionResult().errors(subscriptionException.getErrors()).build(); + writeNext(errorResult.toSpecification()); + } + else { + this.sseBuilder.error(throwable); + } + this.hookOnComplete(); + } - private void writeNext(Map value) { - try { - this.sseBuilder.event("next"); - this.sseBuilder.data(value); - } catch (IOException exception) { - this.onError(exception); - } - } + private void writeNext(Map value) { + try { + this.sseBuilder.event("next"); + this.sseBuilder.data(value); + } + catch (IOException exception) { + this.onError(exception); + } + } - @Override - protected void hookOnComplete() { - try { - this.sseBuilder.event("complete").data(""); - } catch (IOException exc) { - throw new RuntimeException(exc); - } - this.sseBuilder.complete(); - } + @Override + protected void hookOnComplete() { + try { + this.sseBuilder.event("complete").data(""); + } + catch (IOException exc) { + throw new RuntimeException(exc); + } + this.sseBuilder.complete(); + } - } + } } 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 c2131d08..72afd153 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 @@ -134,6 +134,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub /** * Initialize a {@link WebSocketHttpRequestHandler} that wraps this instance * and also inserts a {@link HandshakeInterceptor} for context propagation. + * @param handshakeHandler the handler for WebSocket handshake * @since 1.1.0 */ public WebSocketHttpRequestHandler initWebSocketHttpRequestHandler(HandshakeHandler handshakeHandler) { @@ -146,6 +147,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub * Return a {@link WebSocketHttpRequestHandler} that uses this instance as * its {@link WebGraphQlHandler} and adds a {@link HandshakeInterceptor} to * propagate context. + * @param handshakeHandler the handler for WebSocket handshake * @deprecated as of 1.1.0 in favor of {@link #initWebSocketHttpRequestHandler(HandshakeHandler)} */ @Deprecated(since = "1.1.0", forRemoval = true) @@ -241,7 +243,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub this.webSocketGraphQlInterceptor.handleConnectionInitialization(state.getSessionInfo(), payload) .defaultIfEmpty(Collections.emptyMap()) .publishOn(state.getScheduler()) // Serial blocking send via single thread - .doOnNext(ackPayload -> { + .doOnNext((ackPayload) -> { TextMessage outputMessage = encode(GraphQlWebSocketMessage.connectionAck(ackPayload)); try { session.sendMessage(outputMessage); @@ -250,7 +252,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub throw new IllegalStateException(ex); } }) - .onErrorResume(ex -> { + .onErrorResume((ex) -> { GraphQlStatus.closeSession(session, GraphQlStatus.UNAUTHORIZED_STATUS); return Mono.empty(); }) @@ -297,7 +299,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub } return responseFlux - .map(responseMap -> encode(GraphQlWebSocketMessage.next(id, responseMap))) + .map((responseMap) -> encode(GraphQlWebSocketMessage.next(id, responseMap))) .concatWith(Mono.fromCallable(() -> encode(GraphQlWebSocketMessage.complete(id)))) .onErrorResume((ex) -> { if (ex instanceof SubscriptionExistsException) { @@ -346,7 +348,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub * {@code HandshakeInterceptor} that propagates ThreadLocal context through * the attributes map in {@code WebSocketSession}. */ - private static class ContextHandshakeInterceptor implements HandshakeInterceptor { + private static final class ContextHandshakeInterceptor implements HandshakeInterceptor { private static final String KEY = ContextSnapshot.class.getName(); @@ -367,7 +369,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub @Nullable Exception exception) { } - public static AutoCloseable setThreadLocals(WebSocketSession session) { + static AutoCloseable setThreadLocals(WebSocketSession session) { ContextSnapshot snapshot = (ContextSnapshot) session.getAttributes().get(KEY); Assert.notNull(snapshot, "Expected ContextSnapshot in WebSocketSession attributes"); return snapshot.setThreadLocals(); @@ -375,7 +377,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub } - private static class GraphQlStatus { + private static final class GraphQlStatus { private static final CloseStatus INVALID_MESSAGE_STATUS = new CloseStatus(4400, "Invalid message"); @@ -416,7 +418,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub } - private static class HttpOutputMessageAdapter extends ByteArrayOutputStream implements HttpOutputMessage { + private static final class HttpOutputMessageAdapter extends ByteArrayOutputStream implements HttpOutputMessage { private static final HttpHeaders noOpHeaders = new HttpHeaders(); @@ -447,7 +449,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub this.scheduler = Schedulers.newSingle("GraphQL-WsSession-" + graphQlSessionId); } - public WebSocketSessionInfo getSessionInfo() { + WebSocketSessionInfo getSessionInfo() { return this.sessionInfo; } @@ -485,7 +487,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub } - private static class WebMvcSessionInfo implements WebSocketSessionInfo { + private static final class WebMvcSessionInfo implements WebSocketSessionInfo { private final WebSocketSession session; @@ -569,7 +571,7 @@ public class GraphQlWebSocketHandler extends TextWebSocketHandler implements Sub } @SuppressWarnings("serial") - private static class SubscriptionExistsException extends RuntimeException { + private static final class SubscriptionExistsException extends RuntimeException { } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java index fd03317c..d1db0914 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java @@ -70,6 +70,7 @@ public class GraphiQlHandler { /** * Render the GraphiQL page as "text/html", or if the "path" query parameter * is missing, add it and redirect back to the same URL. + * @param request the HTTP server request */ public ServerResponse handleRequest(ServerRequest request) { return (request.param("path").isPresent() ? diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/SchemaHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/SchemaHandler.java index a0954757..66800bcf 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/SchemaHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/SchemaHandler.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.server.webmvc; import graphql.schema.idl.SchemaPrinter; @@ -27,6 +28,7 @@ import org.springframework.web.servlet.function.ServerResponse; * {@link graphql.schema.GraphQLSchema} printed via {@link SchemaPrinter}. * * @author Rossen Stoyanchev + * @since 1.0.0 */ public class SchemaHandler { @@ -43,7 +45,7 @@ public class SchemaHandler { public ServerResponse handleRequest(ServerRequest request) { return ServerResponse.ok() .contentType(MediaType.TEXT_PLAIN) - .body(this.printer.print(graphQlSource.schema())); + .body(this.printer.print(this.graphQlSource.schema())); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/support/AbstractGraphQlResponse.java b/spring-graphql/src/main/java/org/springframework/graphql/support/AbstractGraphQlResponse.java index 6cbe888f..e3222678 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/support/AbstractGraphQlResponse.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/support/AbstractGraphQlResponse.java @@ -126,7 +126,7 @@ public abstract class AbstractGraphQlResponse implements GraphQlResponse { else { Assert.isTrue(value instanceof List, () -> "Invalid path " + path + ", data: " + response.getData()); int index = (int) segment; - value = (index < ((List) value).size() ? ((List) value).get(index) : null); + value = (index < ((List) value).size()) ? ((List) value).get(index) : null; } } return value; @@ -142,7 +142,7 @@ public abstract class AbstractGraphQlResponse implements GraphQlResponse { return Collections.emptyList(); } return response.getErrors().stream() - .filter(error -> { + .filter((error) -> { String errorPath = error.getPath(); return (!errorPath.isEmpty() && (errorPath.startsWith(path) || path.startsWith(errorPath))); }) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/support/CachingDocumentSource.java b/spring-graphql/src/main/java/org/springframework/graphql/support/CachingDocumentSource.java index 73cf5260..9b6b7e24 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/support/CachingDocumentSource.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/support/CachingDocumentSource.java @@ -39,6 +39,7 @@ public class CachingDocumentSource implements DocumentSource { /** * Constructor with the {@code DocumentSource} to actually load documents. + * @param delegate the delegate document source */ public CachingDocumentSource(DocumentSource delegate) { this.delegate = delegate; @@ -61,14 +62,14 @@ public class CachingDocumentSource implements DocumentSource { * Whether {@link #setCacheEnabled(boolean) caching} is enabled. */ public boolean isCacheEnabled() { - return cacheEnabled; + return this.cacheEnabled; } @Override public Mono getDocument(String name) { - return (isCacheEnabled() ? - this.documentCache.computeIfAbsent(name, k -> this.delegate.getDocument(name).cache()) : + return ((isCacheEnabled()) ? + this.documentCache.computeIfAbsent(name, (k) -> this.delegate.getDocument(name).cache()) : this.delegate.getDocument(name)); } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultExecutionGraphQlRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultExecutionGraphQlRequest.java index 2f0a6c0d..d05171fc 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultExecutionGraphQlRequest.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultExecutionGraphQlRequest.java @@ -111,13 +111,13 @@ public class DefaultExecutionGraphQlRequest extends DefaultGraphQlRequest implem .variables(getVariables()) .extensions(getExtensions()) .locale(this.locale) - .executionId(this.executionId != null ? this.executionId : ExecutionId.from(this.id)); + .executionId((this.executionId != null) ? this.executionId : ExecutionId.from(this.id)); ExecutionInput executionInput = inputBuilder.build(); for (BiFunction configurer : this.executionInputConfigurers) { ExecutionInput current = executionInput; - executionInput = executionInput.transform(builder -> configurer.apply(current, builder)); + executionInput = executionInput.transform((builder) -> configurer.apply(current, builder)); } return executionInput; @@ -125,7 +125,7 @@ public class DefaultExecutionGraphQlRequest extends DefaultGraphQlRequest implem @Override public String toString() { - return super.toString() + ", id=" + getId() + (getLocale() != null ? ", Locale=" + getLocale() : ""); + return super.toString() + ", id=" + getId() + ((getLocale() != null) ? ", Locale=" + getLocale() : ""); } } diff --git a/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultExecutionGraphQlResponse.java b/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultExecutionGraphQlResponse.java index afe8f3e8..37bd3d0b 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultExecutionGraphQlResponse.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultExecutionGraphQlResponse.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.support; import java.util.Collections; @@ -50,6 +51,8 @@ public class DefaultExecutionGraphQlResponse extends AbstractGraphQlResponse imp /** * Constructor to create initial instance. + * @param input the execution input for this graphql operation + * @param result the execution result for this graphql operation */ public DefaultExecutionGraphQlResponse(ExecutionInput input, ExecutionResult result) { Assert.notNull(input, "ExecutionInput is required"); @@ -60,6 +63,7 @@ public class DefaultExecutionGraphQlResponse extends AbstractGraphQlResponse imp /** * Constructor to re-wrap from transport specific subclass. + * @param response the execution response */ protected DefaultExecutionGraphQlResponse(ExecutionGraphQlResponse response) { this(response.getExecutionInput(), response.getExecutionResult()); @@ -94,7 +98,7 @@ public class DefaultExecutionGraphQlResponse extends AbstractGraphQlResponse imp @Override public Map getExtensions() { - return (this.result.getExtensions() != null ? this.result.getExtensions() : Collections.emptyMap()); + return (this.result.getExtensions() != null) ? this.result.getExtensions() : Collections.emptyMap(); } @Override @@ -132,18 +136,18 @@ public class DefaultExecutionGraphQlResponse extends AbstractGraphQlResponse imp public String getPath() { return getParsedPath().stream() .reduce("", - (s, o) -> s + (o instanceof Integer ? "[" + o + "]" : (s.isEmpty() ? o : "." + o)), + (s, o) -> s + ((o instanceof Integer) ? "[" + o + "]" : ((s.isEmpty()) ? o : "." + o)), (s, s2) -> null); } @Override public List getParsedPath() { - return (this.delegate.getPath() != null ? this.delegate.getPath() : Collections.emptyList()); + return (this.delegate.getPath() != null) ? this.delegate.getPath() : Collections.emptyList(); } @Override public Map getExtensions() { - return (this.delegate.getExtensions() != null ? this.delegate.getExtensions() : Collections.emptyMap()); + return (this.delegate.getExtensions() != null) ? this.delegate.getExtensions() : Collections.emptyMap(); } @Override @@ -156,8 +160,10 @@ public class DefaultExecutionGraphQlResponse extends AbstractGraphQlResponse imp /** * Builder to transform the response's {@link ExecutionResult}. + * @param the builder type + * @param the response type */ - public static abstract class Builder, R extends ExecutionGraphQlResponse> { + public abstract static class Builder, R extends ExecutionGraphQlResponse> { private final R original; @@ -209,6 +215,8 @@ public class DefaultExecutionGraphQlResponse extends AbstractGraphQlResponse imp /** * Subclasses to create the specific response instance. + * @param original the original response instance + * @param newResult the new execution result for this response */ protected abstract R build(R original, ExecutionResult newResult); diff --git a/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultGraphQlRequest.java b/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultGraphQlRequest.java index 9d238616..e118463a 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultGraphQlRequest.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/support/DefaultGraphQlRequest.java @@ -76,8 +76,8 @@ public class DefaultGraphQlRequest implements GraphQlRequest { Assert.notNull(document, "'document' is required"); this.document = document; this.operationName = operationName; - this.variables = (variables != null ? variables : Collections.emptyMap()); - this.extensions = (extensions != null ? extensions : Collections.emptyMap()); + this.variables = (variables != null) ? variables : Collections.emptyMap(); + this.extensions = (extensions != null) ? extensions : Collections.emptyMap(); } @@ -121,7 +121,7 @@ public class DefaultGraphQlRequest implements GraphQlRequest { @Override public boolean equals(Object o) { - if (! (o instanceof DefaultGraphQlRequest)) { + if (!(o instanceof DefaultGraphQlRequest)) { return false; } DefaultGraphQlRequest other = (DefaultGraphQlRequest) o; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/support/DocumentSource.java b/spring-graphql/src/main/java/org/springframework/graphql/support/DocumentSource.java index a4e203dc..ef9cafd5 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/support/DocumentSource.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/support/DocumentSource.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.support; import reactor.core.publisher.Mono; diff --git a/spring-graphql/src/main/java/org/springframework/graphql/support/ResourceDocumentSource.java b/spring-graphql/src/main/java/org/springframework/graphql/support/ResourceDocumentSource.java index 72bd93b7..c86ea59d 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/support/ResourceDocumentSource.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/support/ResourceDocumentSource.java @@ -63,6 +63,8 @@ public class ResourceDocumentSource implements DocumentSource { /** * Constructor with given locations and extensions. + * @param locations the resource locations + * @param extensions the file extensions for document sources */ public ResourceDocumentSource(List locations, List extensions) { this.locations = Collections.unmodifiableList(new ArrayList<>(locations)); @@ -90,7 +92,7 @@ public class ResourceDocumentSource implements DocumentSource { @Override public Mono getDocument(String name) { return Flux.fromIterable(this.locations) - .flatMapIterable(location -> getCandidateResources(name, location)) + .flatMapIterable((location) -> getCandidateResources(name, location)) .filter(Resource::exists) .next() .map(this::resourceToString) @@ -104,7 +106,7 @@ public class ResourceDocumentSource implements DocumentSource { private List getCandidateResources(String name, Resource location) { return this.extensions.stream() - .map(ext -> { + .map((ext) -> { try { return location.createRelative(name + ext); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/Author.java b/spring-graphql/src/test/java/org/springframework/graphql/Author.java index 21b0745b..41250fcd 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/Author.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/Author.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql; public class Author { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/BookCriteria.java b/spring-graphql/src/test/java/org/springframework/graphql/BookCriteria.java index 2390bb8a..826d9d23 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/BookCriteria.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/BookCriteria.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql; public class BookCriteria { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/BookSource.java b/spring-graphql/src/test/java/org/springframework/graphql/BookSource.java index d7705af6..20de0e17 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/BookSource.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/BookSource.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql; import java.util.ArrayList; @@ -35,7 +36,6 @@ public class BookSource { public static final Resource paginationSchema = new ClassPathResource("books/pagination-schema.graphqls"); - private static final Map booksMap = new HashMap<>(); private static final Map booksWithoutAuthorsMap; @@ -63,6 +63,10 @@ public class BookSource { .collect(Collectors.toMap(Book::getId, Function.identity())); } + private BookSource() { + + } + public static List books() { return new ArrayList<>(booksMap.values()); @@ -95,22 +99,22 @@ public class BookSource { public static String booksConnectionQuery(@Nullable String arguments) { arguments = StringUtils.hasText(arguments) ? "(" + arguments + ")" : ""; return "{" + - " books" + arguments + " {" + - " edges {" + - " cursor," + - " node {" + - " id" + - " name" + - " }" + - " }" + - " pageInfo {" + - " startCursor," + - " endCursor," + - " hasPreviousPage," + - " hasNextPage" + - " }" + - " }" + - "}"; + " books" + arguments + " {" + + " edges {" + + " cursor," + + " node {" + + " id" + + " name" + + " }" + + " }" + + " pageInfo {" + + " startCursor," + + " endCursor," + + " hasPreviousPage," + + " hasNextPage" + + " }" + + " }" + + "}"; } } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/DefaultExecutionGraphQlRequestTests.java b/spring-graphql/src/test/java/org/springframework/graphql/DefaultExecutionGraphQlRequestTests.java index a8aa1891..5c020e4c 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/DefaultExecutionGraphQlRequestTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/DefaultExecutionGraphQlRequestTests.java @@ -53,4 +53,4 @@ class DefaultExecutionGraphQlRequestTests { assertThat(this.request.getLocale()).isEqualTo(Locale.getDefault()); } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/ResponseHelper.java b/spring-graphql/src/test/java/org/springframework/graphql/ResponseHelper.java index 9eab3093..fb77eb42 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/ResponseHelper.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/ResponseHelper.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql; import java.lang.reflect.Type; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/DefaultGraphQlClientResponseTests.java b/spring-graphql/src/test/java/org/springframework/graphql/client/DefaultGraphQlClientResponseTests.java index c39be5a3..52003fe2 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/DefaultGraphQlClientResponseTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/DefaultGraphQlClientResponseTests.java @@ -16,7 +16,6 @@ package org.springframework.graphql.client; -import graphql.language.SourceLocation; import java.io.IOException; import java.util.Arrays; import java.util.Collections; @@ -26,6 +25,7 @@ import java.util.Map; import graphql.GraphQLError; import graphql.GraphqlErrorBuilder; import graphql.execution.ResultPath; +import graphql.language.SourceLocation; import org.junit.jupiter.api.Test; import org.testcontainers.shaded.com.fasterxml.jackson.databind.DeserializationFeature; import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTests.java b/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTests.java index 3545ee74..63eb9251 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/GraphQlClientTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.client; import java.util.ArrayList; @@ -84,7 +85,7 @@ public class GraphQlClientTests extends GraphQlClientTestSupport { getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":\"Luke Skywalker\"}}"); Map map = graphQlClient().document(document) - .retrieve("").toEntity(new ParameterizedTypeReference>() {}) + .retrieve("").toEntity(new ParameterizedTypeReference>() { }) .block(TIMEOUT); assertThat(map).containsEntry("me", MovieCharacter.create("Luke Skywalker")); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/HttpGraphQlTransportIntegrationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/client/HttpGraphQlTransportIntegrationTests.java index 37eddff4..503a1c72 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/HttpGraphQlTransportIntegrationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/HttpGraphQlTransportIntegrationTests.java @@ -33,65 +33,66 @@ import static org.assertj.core.api.Assertions.assertThat; /** * Integration tests for {@link HttpGraphQlTransport}. + * * @author Brian Clozel */ @ExtendWith(MockWebServerExtension.class) class HttpGraphQlTransportIntegrationTests { - @Test - void shouldStreamSubscriptionResultsOverSse(MockWebServer server) { - WebClient webClient = WebClient.create(server.url("/graphql").toString()); - HttpGraphQlClient graphQlClient = HttpGraphQlClient.create(webClient); - Flux responses = graphQlClient - .document("subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } ") - .executeSubscription(); + @Test + void shouldStreamSubscriptionResultsOverSse(MockWebServer server) { + WebClient webClient = WebClient.create(server.url("/graphql").toString()); + HttpGraphQlClient graphQlClient = HttpGraphQlClient.create(webClient); + Flux responses = graphQlClient + .document("subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } ") + .executeSubscription(); - server.enqueue(new MockResponse().addHeader("Content-Type", MediaType.TEXT_EVENT_STREAM_VALUE) - .setBody(""" - event:next - data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - - event:next - data:{"data":{"bookSearch":{"id":"5","name":"Animal Farm"}}} - - event:complete + server.enqueue(new MockResponse().addHeader("Content-Type", MediaType.TEXT_EVENT_STREAM_VALUE) + .setBody(""" + event:next + data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - """)); + event:next + data:{"data":{"bookSearch":{"id":"5","name":"Animal Farm"}}} - StepVerifier.create(responses) - .assertNext(item -> assertThat(item.field("bookSearch").toEntity(Book.class).getName()).isEqualTo("Nineteen Eighty-Four")) - .assertNext(item -> assertThat(item.field("bookSearch").toEntity(Book.class).getName()).isEqualTo("Animal Farm")) - .verifyComplete(); - } + event:complete - @Test - void shouldStreamSubscriptionErrorsOverSse(MockWebServer server) { - WebClient webClient = WebClient.create(server.url("/graphql").toString()); - HttpGraphQlClient graphQlClient = HttpGraphQlClient.create(webClient); - Flux responses = graphQlClient - .document("subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } ") - .executeSubscription(); + """)); - server.enqueue(new MockResponse().addHeader("Content-Type", MediaType.TEXT_EVENT_STREAM_VALUE) - .setBody(""" - event:next - data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - - event:next - data:{"errors":[{"message":"Subscription error","locations":[],"extensions":{"classification":"INTERNAL_ERROR"}}]} - - event:complete + StepVerifier.create(responses) + .assertNext(item -> assertThat(item.field("bookSearch").toEntity(Book.class).getName()).isEqualTo("Nineteen Eighty-Four")) + .assertNext(item -> assertThat(item.field("bookSearch").toEntity(Book.class).getName()).isEqualTo("Animal Farm")) + .verifyComplete(); + } - """)); - StepVerifier.create(responses) - .assertNext(item -> assertThat(item.field("bookSearch").toEntity(Book.class).getName()).isEqualTo("Nineteen Eighty-Four")) - .assertNext(item -> { - assertThat(item.getErrors()).hasSize(1); - assertThat(item.getErrors().get(0).getErrorType().toString()).isEqualTo("INTERNAL_ERROR"); - assertThat(item.getErrors().get(0).getMessage()).isEqualTo("Subscription error"); - }) - .verifyComplete(); - } + @Test + void shouldStreamSubscriptionErrorsOverSse(MockWebServer server) { + WebClient webClient = WebClient.create(server.url("/graphql").toString()); + HttpGraphQlClient graphQlClient = HttpGraphQlClient.create(webClient); + Flux responses = graphQlClient + .document("subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } ") + .executeSubscription(); + + server.enqueue(new MockResponse().addHeader("Content-Type", MediaType.TEXT_EVENT_STREAM_VALUE) + .setBody(""" + event:next + data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} + + event:next + data:{"errors":[{"message":"Subscription error","locations":[],"extensions":{"classification":"INTERNAL_ERROR"}}]} + + event:complete + + """)); + StepVerifier.create(responses) + .assertNext(item -> assertThat(item.field("bookSearch").toEntity(Book.class).getName()).isEqualTo("Nineteen Eighty-Four")) + .assertNext(item -> { + assertThat(item.getErrors()).hasSize(1); + assertThat(item.getErrors().get(0).getErrorType().toString()).isEqualTo("INTERNAL_ERROR"); + assertThat(item.getErrors().get(0).getMessage()).isEqualTo("Subscription error"); + }) + .verifyComplete(); + } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/MockGraphQlWebSocketServer.java b/spring-graphql/src/test/java/org/springframework/graphql/client/MockGraphQlWebSocketServer.java index 26b8159c..341b1926 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/MockGraphQlWebSocketServer.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/MockGraphQlWebSocketServer.java @@ -46,7 +46,7 @@ import org.springframework.web.reactive.socket.WebSocketSession; */ public final class MockGraphQlWebSocketServer implements WebSocketHandler { - private final static Log logger = LogFactory.getLog(MockGraphQlWebSocketServer.class); + private static final Log logger = LogFactory.getLog(MockGraphQlWebSocketServer.class); @Nullable diff --git a/spring-graphql/src/test/java/org/springframework/graphql/client/WebSocketGraphQlTransportTests.java b/spring-graphql/src/test/java/org/springframework/graphql/client/WebSocketGraphQlTransportTests.java index 2b99674f..a28e5f90 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/client/WebSocketGraphQlTransportTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/client/WebSocketGraphQlTransportTests.java @@ -34,9 +34,9 @@ import reactor.test.StepVerifier; import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlResponse; import org.springframework.graphql.ResponseError; -import org.springframework.graphql.support.DefaultGraphQlRequest; import org.springframework.graphql.server.support.GraphQlWebSocketMessage; import org.springframework.graphql.server.support.GraphQlWebSocketMessageType; +import org.springframework.graphql.support.DefaultGraphQlRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.codec.ClientCodecConfigurer; import org.springframework.web.reactive.socket.CloseStatus; @@ -46,8 +46,8 @@ import org.springframework.web.reactive.socket.client.WebSocketClient; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * Tests for {@link WebSocketGraphQlTransport} using {@link TestWebSocketClient} @@ -57,7 +57,7 @@ import static org.mockito.Mockito.when; */ public class WebSocketGraphQlTransportTests { - private final static Duration TIMEOUT = Duration.ofSeconds(5); + private static final Duration TIMEOUT = Duration.ofSeconds(5); private static final CodecDelegate CODEC_DELEGATE = new CodecDelegate(ClientCodecConfigurer.create()); @@ -65,7 +65,7 @@ public class WebSocketGraphQlTransportTests { private final MockGraphQlWebSocketServer mockServer = new MockGraphQlWebSocketServer(); private final TestWebSocketClient webSocketClient = new TestWebSocketClient(this.mockServer); - + private final WebSocketGraphQlTransport transport = createTransport(this.webSocketClient); private final GraphQlResponse response1 = new ResponseMapGraphQlResponse( @@ -283,8 +283,8 @@ public class WebSocketGraphQlTransportTests { IOException ex = new IOException("Connect failure"); WebSocketClient client = mock(WebSocketClient.class); - when(client.execute(any(URI.class), any(HttpHeaders.class), any(WebSocketHandler.class))) - .thenReturn(Mono.error(ex)); + given(client.execute(any(URI.class), any(HttpHeaders.class), any(WebSocketHandler.class))) + .willReturn(Mono.error(ex)); StepVerifier.create(createTransport(client).start()) .expectErrorMessage(ex.getMessage()) @@ -324,7 +324,7 @@ public class WebSocketGraphQlTransportTests { private static WebSocketGraphQlTransport createTransport(WebSocketClient client) { return new WebSocketGraphQlTransport( URI.create("/"), HttpHeaders.EMPTY, client, ClientCodecConfigurer.create(), - new WebSocketGraphQlClientInterceptor() {}); + new WebSocketGraphQlClientInterceptor() { }); } private void assertActualClientMessages(GraphQlWebSocketMessage... expectedMessages) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java index 74bb3841..680802e6 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/GraphQlArgumentBinderTests.java @@ -662,8 +662,12 @@ class GraphQlArgumentBinderTests { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } Item item = (Item) o; return name.equals(item.name); } @@ -709,4 +713,4 @@ class GraphQlArgumentBinderTests { record ConstructorEnumInput>(List enums) { } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/federation/EntityMappingInvocationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/federation/EntityMappingInvocationTests.java index e008fbde..2870dfae 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/federation/EntityMappingInvocationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/federation/EntityMappingInvocationTests.java @@ -60,18 +60,19 @@ public class EntityMappingInvocationTests { private static final Resource federationSchema = new ClassPathResource("books/federation-schema.graphqls"); private static final String document = """ - query Entities($representations: [_Any!]!) { - _entities(representations: $representations) { - ...on Book { - id - author { - id - firstName - lastName - } - }} - } - """; + query Entities($representations: [_Any!]!) { + _entities(representations: $representations) { + ...on Book { + id + author { + id + firstName + lastName + } + } + } + } + """; @Test diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurerTests.java index f215e668..ccd9db81 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurerTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.List; @@ -47,9 +48,9 @@ public class AnnotatedControllerConfigurerTests { List resolvers = configurer.getArgumentResolvers().getResolvers(); int size = resolvers.size(); - assertThat(resolvers).element(size -1).isInstanceOf(SourceMethodArgumentResolver.class); - assertThat(resolvers).element(size -2).isSameAs(customResolver2); - assertThat(resolvers).element(size -3).isSameAs(customResolver1); + assertThat(resolvers).element(size - 1).isInstanceOf(SourceMethodArgumentResolver.class); + assertThat(resolvers).element(size - 2).isSameAs(customResolver2); + assertThat(resolvers).element(size - 3).isSameAs(customResolver1); } @Test diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java index 76160f3d..c0845378 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.Arrays; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolverTests.java index 10483d77..1293fcab 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentMethodArgumentResolverTests.java @@ -216,4 +216,4 @@ class ArgumentMethodArgumentResolverTests extends ArgumentResolverTestSupport { } } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentResolverTestSupport.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentResolverTestSupport.java index 61328865..05ac73d9 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentResolverTestSupport.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentResolverTestSupport.java @@ -32,14 +32,14 @@ import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.util.ClassUtils; /** - * Base class to test resolving {@link @Argument} and {@link @Arguments} + * Base class to test resolving {@code @Argument} and {@code @Arguments} * annotated method parameters. * * @author Rossen Stoyanchev */ class ArgumentResolverTestSupport { - private static final TypeReference> MAP_TYPE_REFERENCE = new TypeReference<>() {}; + private static final TypeReference> MAP_TYPE_REFERENCE = new TypeReference<>() { }; private final ObjectMapper mapper = new ObjectMapper(); @@ -61,4 +61,4 @@ class ArgumentResolverTestSupport { return DataFetchingEnvironmentImpl.newDataFetchingEnvironment().arguments(arguments).build(); } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentsMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentsMethodArgumentResolverTests.java index a231425d..66ef2ed2 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentsMethodArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ArgumentsMethodArgumentResolverTests.java @@ -130,4 +130,4 @@ class ArgumentsMethodArgumentResolverTests extends ArgumentResolverTestSupport { } } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AuthenticationPrincipalArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AuthenticationPrincipalArgumentResolverTests.java index ce8fd0ba..0aac0ad8 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AuthenticationPrincipalArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AuthenticationPrincipalArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.annotation.Retention; @@ -56,20 +57,20 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; */ class AuthenticationPrincipalArgumentResolverTests { - private final static Class STRING_CLASS = String.class; + private static final Class STRING_CLASS = String.class; - private final static Class USER_DETAILS_CLASS = UserDetails.class; + private static final Class USER_DETAILS_CLASS = UserDetails.class; - private final static Class MONO_USER_DETAILS_CLASS = + private static final Class MONO_USER_DETAILS_CLASS = ResolvableType.forClassWithGenerics(Mono.class, UserDetails.class).getRawClass(); - private final static Class MONO_STRING_CLASS = + private static final Class MONO_STRING_CLASS = ResolvableType.forClassWithGenerics(Mono.class, String.class).getRawClass(); - private final static Class PUBLISHER_USER_DETAILS_CLASS = + private static final Class PUBLISHER_USER_DETAILS_CLASS = ResolvableType.forClassWithGenerics(Publisher.class, UserDetails.class).getRawClass(); - private final static Class TESTPUBLISHER_USER_DETAILS_CLASS = + private static final Class TESTPUBLISHER_USER_DETAILS_CLASS = ResolvableType.forClassWithGenerics(TestPublisher.class, UserDetails.class).getRawClass(); @@ -82,7 +83,6 @@ class AuthenticationPrincipalArgumentResolverTests { SecurityContextHolder.clearContext(); } - @Test void supportsParameterWhenNoAnnotation() { MethodParameter parameter = firstParameter(UserController.class, "noParameter", USER_DETAILS_CLASS); @@ -417,4 +417,4 @@ class AuthenticationPrincipalArgumentResolverTests { public @interface CurrentUser { } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingDetectionTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingDetectionTests.java index 93e3f4da..abb925d7 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingDetectionTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingDetectionTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.ArrayList; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java index 2fbaa344..45282685 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.List; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingPrincipalMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingPrincipalMethodArgumentResolverTests.java index fa6dd7c2..cf47ded8 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingPrincipalMethodArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingPrincipalMethodArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.security.Principal; @@ -33,7 +34,6 @@ import reactor.util.context.Context; import org.springframework.graphql.ExecutionGraphQlResponse; import org.springframework.graphql.ResponseHelper; -import org.springframework.graphql.TestExecutionRequest; import org.springframework.graphql.data.method.annotation.BatchMapping; import org.springframework.lang.Nullable; import org.springframework.security.authentication.TestingAuthenticationToken; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingTestSupport.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingTestSupport.java index 9506ad3a..38e02c2b 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingTestSupport.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingTestSupport.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.ArrayList; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ContextValueMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ContextValueMethodArgumentResolverTests.java index c56efcd0..4426245b 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ContextValueMethodArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ContextValueMethodArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.reflect.Method; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethodTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethodTests.java index d4e06b7d..7a78bf85 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethodTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetcherHandlerMethodTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentArgumentResolverTests.java index 17117b7c..c4dc8d6b 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataFetchingEnvironmentArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.reflect.Method; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataLoaderArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataLoaderArgumentResolverTests.java index 0a90c8c4..c0a0d74f 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataLoaderArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/DataLoaderArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.reflect.Method; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/LocalContextValueMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/LocalContextValueMethodArgumentResolverTests.java index eca93e3f..8b2a3298 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/LocalContextValueMethodArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/LocalContextValueMethodArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.reflect.Method; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ProjectedPayloadMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ProjectedPayloadMethodArgumentResolverTests.java index 1554509f..f375808b 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ProjectedPayloadMethodArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/ProjectedPayloadMethodArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.List; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingBeanFactoryInitializationAotProcessorTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingBeanFactoryInitializationAotProcessorTests.java index 0bff594c..198619a7 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingBeanFactoryInitializationAotProcessorTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingBeanFactoryInitializationAotProcessorTests.java @@ -37,9 +37,6 @@ import graphql.schema.DataFetchingFieldSelectionSet; import org.dataloader.DataLoader; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.springframework.graphql.data.method.annotation.*; -import org.springframework.validation.BindException; -import org.springframework.web.bind.annotation.ControllerAdvice; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -62,7 +59,17 @@ import org.springframework.data.web.ProjectedPayload; import org.springframework.graphql.Author; import org.springframework.graphql.Book; import org.springframework.graphql.data.ArgumentValue; +import org.springframework.graphql.data.method.annotation.Argument; +import org.springframework.graphql.data.method.annotation.BatchMapping; +import org.springframework.graphql.data.method.annotation.ContextValue; +import org.springframework.graphql.data.method.annotation.GraphQlExceptionHandler; +import org.springframework.graphql.data.method.annotation.LocalContextValue; +import org.springframework.graphql.data.method.annotation.MutationMapping; +import org.springframework.graphql.data.method.annotation.QueryMapping; +import org.springframework.graphql.data.method.annotation.SchemaMapping; import org.springframework.stereotype.Controller; +import org.springframework.validation.BindException; +import org.springframework.web.bind.annotation.ControllerAdvice; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -502,7 +509,7 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests { } } } - catch (IntrospectionException e) { + catch (IntrospectionException ex) { // ignoring type } return predicate; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingDetectionTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingDetectionTests.java index 50f3df1e..a7f68427 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingDetectionTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingDetectionTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.Map; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java index 8ec4b3a9..9f5116fe 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.Collections; @@ -285,7 +286,7 @@ public class SchemaMappingInvocationTests { private TestExecutionGraphQlService graphQlService() { - return graphQlService((configurer, setup) -> {}); + return graphQlService((configurer, setup) -> { }); } private TestExecutionGraphQlService graphQlService(BiConsumer consumer) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java index 07581069..de8fd528 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPaginationTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.util.List; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPrincipalMethodArgumentResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPrincipalMethodArgumentResolverTests.java index 3104e78f..49e4e949 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPrincipalMethodArgumentResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingPrincipalMethodArgumentResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.method.annotation.support; import java.lang.reflect.Method; @@ -26,8 +27,6 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.springframework.graphql.execution.DataFetcherExceptionResolver; -import org.springframework.graphql.execution.ErrorType; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -41,6 +40,8 @@ import org.springframework.graphql.ResponseHelper; import org.springframework.graphql.TestExecutionGraphQlService; import org.springframework.graphql.data.method.annotation.QueryMapping; import org.springframework.graphql.data.method.annotation.SubscriptionMapping; +import org.springframework.graphql.execution.DataFetcherExceptionResolver; +import org.springframework.graphql.execution.ErrorType; import org.springframework.lang.Nullable; import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.core.Authentication; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/Book.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/Book.java index 3a7c1c15..378ff5ff 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/Book.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/Book.java @@ -21,7 +21,8 @@ import org.springframework.graphql.Author; public class Book { - @Id Long id; + @Id + Long id; String name; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/QBook.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/QBook.java index 84248332..1f6bbbbc 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/QBook.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/QBook.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -27,21 +27,21 @@ import com.querydsl.core.types.dsl.StringPath; * Generated by Querydsl. */ public class QBook extends EntityPathBase { - private static final long serialVersionUID = 1773522017L; - public static final QBook book = new QBook("book"); - public final StringPath author = this.createString("author"); - public final NumberPath id = this.createNumber("id", Long.class); - public final StringPath name = this.createString("name"); + private static final long serialVersionUID = 1773522017L; + public static final QBook book = new QBook("book"); + public final StringPath author = this.createString("author"); + public final NumberPath id = this.createNumber("id", Long.class); + public final StringPath name = this.createString("name"); - public QBook(String variable) { - super(Book.class, PathMetadataFactory.forVariable(variable)); - } + public QBook(String variable) { + super(Book.class, PathMetadataFactory.forVariable(variable)); + } - public QBook(Path path) { - super(path.getType(), path.getMetadata()); - } + public QBook(Path path) { + super(path.getType(), path.getMetadata()); + } - public QBook(PathMetadata metadata) { - super(Book.class, metadata); - } + public QBook(PathMetadata metadata) { + super(Book.class, metadata); + } } 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 0eb54c67..ea8179a2 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 @@ -1,11 +1,11 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -60,10 +60,10 @@ import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; /** * Unit tests for {@link QuerydslDataFetcher}. @@ -229,7 +229,7 @@ class QuerydslDataFetcherTests { void shouldFavorExplicitWiring() { MockRepository mockRepository = mock(MockRepository.class); Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); - when(mockRepository.findBy(any(), any())).thenReturn(Optional.of(book)); + given(mockRepository.findBy(any(), any())).willReturn(Optional.of(book)); // 1) Automatic registration only WebGraphQlHandler handler = graphQlSetup(mockRepository).toWebGraphQlHandler(); @@ -286,7 +286,7 @@ class QuerydslDataFetcherTests { void shouldReactivelyFetchSingleItems() { ReactiveMockRepository mockRepository = mock(ReactiveMockRepository.class); Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); - when(mockRepository.findBy(any(), any())).thenReturn(Mono.just(book)); + given(mockRepository.findBy(any(), any())).willReturn(Mono.just(book)); Consumer tester = setup -> { WebGraphQlRequest request = request("{ bookById(id: 1) {name}}"); @@ -308,7 +308,7 @@ class QuerydslDataFetcherTests { ReactiveMockRepository mockRepository = mock(ReactiveMockRepository.class); Book book1 = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); Book book2 = new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg")); - when(mockRepository.findBy(any(), any())).thenReturn(Flux.just(book1, book2)); + given(mockRepository.findBy(any(), any())).willReturn(Flux.just(book1, book2)); Consumer tester = setup -> { WebGraphQlRequest request = request("{ books {name}}"); @@ -400,7 +400,7 @@ class QuerydslDataFetcherTests { QuerydslBinderCustomizer { @Override - default void customize(QuerydslBindings bindings, QBook book){ + default void customize(QuerydslBindings bindings, QBook book) { bindings.bind(book.name).firstOptional((path, value) -> value.map(path::startsWith)); } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/Author.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/Author.java index 38c338fa..2854c04b 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/Author.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/Author.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.query.jpa; import jakarta.persistence.Entity; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/ProjectingBookJpaRepository.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/ProjectingBookJpaRepository.java index 598935b2..e3c43f33 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/ProjectingBookJpaRepository.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/jpa/ProjectingBookJpaRepository.java @@ -20,13 +20,12 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.graphql.data.GraphQlRepository; import org.springframework.graphql.data.query.QueryByExampleDataFetcher.Builder; import org.springframework.graphql.data.query.QueryByExampleDataFetcher.QueryByExampleBuilderCustomizer; -import org.springframework.graphql.data.query.jpa.QueryByExampleDataFetcherJpaTests.BookDto; @GraphQlRepository public interface ProjectingBookJpaRepository extends JpaRepository, QueryByExampleBuilderCustomizer { @Override - default Builder customize(Builder builder){ + default Builder customize(Builder builder) { return builder.projectAs(BookProjection.class); } } 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 796677f2..723eaa14 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 @@ -1,11 +1,11 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -62,8 +62,8 @@ import org.springframework.transaction.PlatformTransactionManager; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * Integration tests for {@link QueryByExampleDataFetcher} with JPA repository. @@ -171,7 +171,7 @@ class QueryByExampleDataFetcherJpaTests { void shouldFavorExplicitWiring() { BookJpaRepository mockRepository = mock(BookJpaRepository.class); Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); - when(mockRepository.findBy(any(), any())).thenReturn(Optional.of(book)); + given(mockRepository.findBy(any(), any())).willReturn(Optional.of(book)); // 1) Automatic registration only WebGraphQlHandler handler = graphQlSetup(mockRepository).toWebGraphQlHandler(); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/Author.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/Author.java index afa15c16..e6612e1f 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/Author.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/mongo/Author.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.data.query.mongo; import org.springframework.data.annotation.Id; 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 b4b21c9d..1fc64ae5 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 @@ -1,11 +1,11 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -59,9 +59,9 @@ import org.springframework.lang.Nullable; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * Integration tests for {@link QueryByExampleDataFetcher} with MongoDB repository. @@ -168,7 +168,7 @@ class QueryByExampleDataFetcherMongoDbTests { void shouldFavorExplicitWiring() { BookMongoRepository mockRepository = mock(BookMongoRepository.class); Book book = new Book("42", "Hitchhiker's Guide to the Galaxy", new Author("0", "Douglas", "Adams")); - when(mockRepository.findBy(any(), any())).thenReturn(Optional.of(book)); + given(mockRepository.findBy(any(), any())).willReturn(Optional.of(book)); // 1) Automatic registration only WebGraphQlHandler handler = graphQlSetup(mockRepository).toWebGraphQlHandler(); 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 312d8c26..ac42113a 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 @@ -1,11 +1,11 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/Author.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/Author.java index 201a7646..a2c192fd 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/Author.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/Author.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/BookNeo4jRepository.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/BookNeo4jRepository.java index f2658cba..52886fcd 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/BookNeo4jRepository.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/BookNeo4jRepository.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/BookReactiveNeo4jRepository.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/BookReactiveNeo4jRepository.java index 090803bc..13baea16 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/BookReactiveNeo4jRepository.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/BookReactiveNeo4jRepository.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/QueryByExampleDataFetcherNeo4jTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/QueryByExampleDataFetcherNeo4jTests.java index 40dc3722..359f6cf8 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/QueryByExampleDataFetcherNeo4jTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/QueryByExampleDataFetcherNeo4jTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -61,9 +61,9 @@ import org.springframework.lang.Nullable; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; /** * Integration tests for {@link QueryByExampleDataFetcher} with Neo4j repository. @@ -170,7 +170,7 @@ class QueryByExampleDataFetcherNeo4jTests { void shouldFavorExplicitWiring() { BookNeo4jRepository mockRepository = mock(BookNeo4jRepository.class); Book book = new Book("42", "Hitchhiker's Guide to the Galaxy", new Author("0", "Douglas", "Adams")); - when(mockRepository.findBy(any(), any())).thenReturn(Optional.of(book)); + given(mockRepository.findBy(any(), any())).willReturn(Optional.of(book)); // 1) Automatic registration only WebGraphQlHandler handler = graphQlSetup(mockRepository).toWebGraphQlHandler(); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/QueryByExampleDataFetcherReactiveNeo4jDbTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/QueryByExampleDataFetcherReactiveNeo4jDbTests.java index 5c2f6957..4a562ecb 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/QueryByExampleDataFetcherReactiveNeo4jDbTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/query/neo4j/QueryByExampleDataFetcherReactiveNeo4jDbTests.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2020-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. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java index fd0f6b9e..47eca06f 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.List; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java index a92a7c40..195e892d 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.ArrayList; @@ -36,25 +37,25 @@ public class ClassNameTypeResolverTests { private static final String schema = """ type Query { - animals: [Animal!]!, - sightings: [Sighting!]! + animals: [Animal!]!, + sightings: [Sighting!]! } interface Animal { - name: String! + name: String! } type Bird implements Animal { - name: String! - flightless: Boolean! + name: String! + flightless: Boolean! } type Mammal implements Animal { - name: String! - herbivore: Boolean! + name: String! + herbivore: Boolean! } type Plant { - family: String! + family: String! } type Vegetable { - family: String! + family: String! } union Sighting = Bird | Mammal | Plant | Vegetable """; @@ -80,16 +81,16 @@ public class ClassNameTypeResolverTests { String document = """ query Animals { - animals { - __typename - name - ... on Bird { - flightless + animals { + __typename + name + ... on Bird { + flightless + } + ... on Mammal { + herbivore + } } - ... on Mammal { - herbivore - } - } } """; @@ -114,18 +115,18 @@ public class ClassNameTypeResolverTests { String document = """ query Sightings { - sightings { - __typename - ... on Bird { - name - } - ... on Mammal { - name - } - ... on Plant { - family - } - } + sightings { + __typename + ... on Bird { + name + } + ... on Mammal { + name + } + ... on Plant { + family + } + } } """; @@ -149,10 +150,10 @@ public class ClassNameTypeResolverTests { String document = """ query Animals { - animals { - __typename - name - } + animals { + __typename + name + } } """; @@ -165,7 +166,6 @@ public class ClassNameTypeResolverTests { } - interface Animal { String getName(); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/CompositeSubscriptionExceptionResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/CompositeSubscriptionExceptionResolverTests.java index 17f232ab..2181a47f 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/CompositeSubscriptionExceptionResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/CompositeSubscriptionExceptionResolverTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.time.Duration; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurerTests.java index 0473ba87..c1ac2c45 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ConnectionTypeDefinitionConfigurerTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.List; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistryTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistryTests.java index 08e2d414..bc2b0011 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistryTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultBatchLoaderRegistryTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.Map; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilderTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilderTests.java index 58339a52..a1204b27 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilderTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/DefaultSchemaResourceGraphQlSourceBuilderTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.List; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java index d9590881..0c086e54 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java @@ -26,7 +26,6 @@ import io.micrometer.context.ContextRegistry; import io.micrometer.context.ContextSnapshot; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; -import reactor.util.context.Context; import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.ResponseHelper; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorInterfaceTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorInterfaceTests.java index 952ce3da..f8cd6a33 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorInterfaceTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorInterfaceTests.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.List; @@ -31,7 +32,7 @@ import org.springframework.stereotype.Controller; */ public class SchemaMappingInspectorInterfaceTests extends SchemaMappingInspectorTestSupport { - private final static String schema = """ + private static final String schema = """ type Query { vehicles: [Vehicle!]! } @@ -67,8 +68,8 @@ public class SchemaMappingInspectorInterfaceTests extends SchemaMappingInspector interface Vehicle { String name(); } - record Car(String name) implements Vehicle {} - record Bike(String name) implements Vehicle {} + record Car(String name) implements Vehicle { } + record Bike(String name) implements Vehicle { } @Controller static class VehicleController { @@ -116,8 +117,8 @@ public class SchemaMappingInspectorInterfaceTests extends SchemaMappingInspector interface Vehicle { String name(); } - record CarImpl(String name) implements Vehicle {} - record BikeImpl(String name) implements Vehicle {} + record CarImpl(String name) implements Vehicle { } + record BikeImpl(String name) implements Vehicle { } @Controller static class VehicleController { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorTestSupport.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorTestSupport.java index 2d200379..149a9e78 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorTestSupport.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorTestSupport.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.Arrays; @@ -37,7 +38,7 @@ import org.springframework.graphql.data.method.annotation.support.AnnotatedContr public class SchemaMappingInspectorTestSupport { protected SchemaReport inspectSchema(String schemaContent, Class... controllers) { - return inspectSchema(schemaContent, initializer -> {}, controllers); + return inspectSchema(schemaContent, initializer -> { }, controllers); } protected SchemaReport inspectSchema( diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorTests.java index 4ef38a51..ba031df1 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorTests.java @@ -86,12 +86,11 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { allBooks: [Book] } - type Book { id: ID name: String missing: Boolean - } + } """; SchemaReport report = inspectSchema(schema, BookController.class); assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Book", "missing"); @@ -103,7 +102,6 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { optionalBook: Book } - type Book { id: ID name: String @@ -120,27 +118,23 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { paginatedBooks: BookConnection } - type BookConnection { edges: [BookEdge]! pageInfo: PageInfo! } - type BookEdge { cursor: String! # ... } - type PageInfo { startCursor: String # ... } - type Book { id: ID name: String missing: Boolean - } + } """; SchemaReport report = inspectSchema(schema, BookController.class); assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Book", "missing"); @@ -152,8 +146,8 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { } extend type Query { - greeting: String - } + greeting: String + } """; SchemaReport report = inspectSchema(schema, EmptyController.class); assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Query", "greeting"); @@ -174,11 +168,10 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Mutation { createBook: Book } - type Book { id: ID name: String - } + } """; SchemaReport report = inspectSchema(schema, GreetingController.class); assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Mutation", "createBook"); @@ -193,11 +186,10 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Mutation { createBook: Book } - type Book { id: ID name: String - } + } """; SchemaReport report = inspectSchema(schema, GreetingController.class, BookController.class); assertThatReport(report).hasUnmappedFieldCount(0).hasSkippedTypeCount(0); @@ -212,12 +204,12 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Mutation { } extend type Mutation { - createBook: Book - } - type Book { + createBook: Book + } + type Book { id: ID name: String - } + } """; SchemaReport report = inspectSchema(schema, GreetingController.class); assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Mutation", "createBook"); @@ -238,11 +230,10 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Subscription { bookSearch(author: String) : [Book!]! } - type Book { id: ID name: String - } + } """; SchemaReport report = inspectSchema(schema, GreetingController.class); assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Subscription", "bookSearch"); @@ -257,12 +248,12 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Subscription { } extend type Subscription { - bookSearch(author: String) : [Book!]! - } - type Book { + bookSearch(author: String) : [Book!]! + } + type Book { id: ID name: String - } + } """; SchemaReport report = inspectSchema(schema, GreetingController.class); assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Subscription", "bookSearch"); @@ -277,11 +268,10 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Subscription { bookSearch(author: String) : [Book!]! } - type Book { id: ID name: String - } + } """; SchemaReport report = inspectSchema(schema, GreetingController.class, BookController.class); assertThatReport(report).hasUnmappedFieldCount(0).hasSkippedTypeCount(0); @@ -300,11 +290,10 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { bookById(id: ID): Book } - type Book { id: ID name: String - } + } """; SchemaReport report = inspectSchema(schema, BookController.class); assertThatReport(report).hasUnmappedFieldCount(0).hasSkippedTypeCount(0); @@ -316,12 +305,11 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { bookById(id: ID): Book } - type Book { id: ID name: String fetcher: String - } + } """; SchemaReport report = inspectSchema(schema, BookController.class); assertThatReport(report).hasUnmappedFieldCount(0).hasSkippedTypeCount(0); @@ -333,13 +321,11 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { books: [Book] } - type Book { id: ID name: String author: Author - } - + } type Author { id: ID firstName: String @@ -356,12 +342,11 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { bookById(id: ID): Book } - type Book { id: ID name: String missing: Boolean - } + } """; SchemaReport report = inspectSchema(schema, BookController.class); assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Book", "missing"); @@ -384,13 +369,11 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { bookById(id: ID): Book } - type Book { id: ID name: String author: Author - } - + } type Author { id: ID firstName: String @@ -407,13 +390,11 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { bookById(id: ID): Book } - type Book { id: ID name: String author: Author - } - + } type Author { id: ID firstName: String @@ -431,13 +412,11 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { teamById(id: ID): Team } - type Team { name: String members: [TeamMember] - } - - type TeamMember { + } + type TeamMember { name: String team: Team missing: String @@ -453,14 +432,13 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { bookById(id: ID): Book } - type Book { id: ID name: String - } - extend type Book { + } + extend type Book { missing: Boolean - } + } """; SchemaReport report = inspectSchema(schema, BookController.class); assertThatReport(report).hasUnmappedFieldCount(1).containsUnmappedFields("Book", "missing"); @@ -472,11 +450,10 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { bookById(id: ID): Book } - type Book { id: ID name: String - } + } """; GraphQLSchema schema = SchemaGenerator.createdMockedSchema(schemaContent); @@ -494,11 +471,10 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { type Query { bookObject(id: ID): Book } - type Book { id: ID name: String - } + } """; SchemaReport report = inspectSchema(schemaContent, BookController.class); assertThatReport(report).hasUnmappedFieldCount(0).hasSkippedTypeCount(1).containsSkippedTypes("Book"); @@ -544,7 +520,7 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { name: String missing: Boolean author: Author - } + } type Author { id: ID } @@ -688,4 +664,4 @@ class SchemaMappingInspectorTests extends SchemaMappingInspectorTestSupport { } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorUnionTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorUnionTests.java index ec14f060..be337daa 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorUnionTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/SchemaMappingInspectorUnionTests.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.execution; import java.util.List; @@ -31,7 +32,7 @@ import org.springframework.stereotype.Controller; */ public class SchemaMappingInspectorUnionTests extends SchemaMappingInspectorTestSupport { - private final static String schema = """ + private static final String schema = """ type Query { search: [SearchResult!]! } @@ -60,9 +61,9 @@ public class SchemaMappingInspectorUnionTests extends SchemaMappingInspectorTest } - sealed interface ResultItem permits Photo, Video {} - record Photo() implements ResultItem {} - record Video() implements ResultItem {} + sealed interface ResultItem permits Photo, Video { } + record Photo() implements ResultItem { } + record Video() implements ResultItem { } @Controller static class SearchController { @@ -74,7 +75,7 @@ public class SchemaMappingInspectorUnionTests extends SchemaMappingInspectorTest } } - + @Nested class GraphQlAndJavaTypeNameMismatch { @@ -107,9 +108,9 @@ public class SchemaMappingInspectorUnionTests extends SchemaMappingInspectorTest .hasSkippedTypeCount(1).containsSkippedTypes("Video"); } - sealed interface ResultItem permits PhotoImpl, VideoImpl {} - record PhotoImpl() implements ResultItem {} - record VideoImpl() implements ResultItem {} + sealed interface ResultItem permits PhotoImpl, VideoImpl { } + record PhotoImpl() implements ResultItem { } + record VideoImpl() implements ResultItem { } @Controller static class SearchController { @@ -121,7 +122,7 @@ public class SchemaMappingInspectorUnionTests extends SchemaMappingInspectorTest } } - + @Nested class SkippedTypes { @@ -131,7 +132,7 @@ public class SchemaMappingInspectorUnionTests extends SchemaMappingInspectorTest assertThatReport(report).hasSkippedTypeCount(2).containsSkippedTypes("Photo", "Video"); } - interface ResultItem {} + interface ResultItem { } @Controller static class SearchController { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/observation/DefaultDataFetcherObservationConventionTests.java b/spring-graphql/src/test/java/org/springframework/graphql/observation/DefaultDataFetcherObservationConventionTests.java index cdd3f735..6e0f7ca9 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/observation/DefaultDataFetcherObservationConventionTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/observation/DefaultDataFetcherObservationConventionTests.java @@ -100,4 +100,4 @@ class DefaultDataFetcherObservationConventionTests { consumer.accept(builder); return builder.build(); } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/observation/DefaultExecutionRequestObservationConventionTests.java b/spring-graphql/src/test/java/org/springframework/graphql/observation/DefaultExecutionRequestObservationConventionTests.java index d4eca661..e31d8e99 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/observation/DefaultExecutionRequestObservationConventionTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/observation/DefaultExecutionRequestObservationConventionTests.java @@ -57,7 +57,7 @@ class DefaultExecutionRequestObservationConventionTests { void hasContextualName() { ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greeting }") .operationName("mutation").build(); - ExecutionRequestObservationContext context = createObservationContext(input, builder -> {}); + ExecutionRequestObservationContext context = createObservationContext(input, builder -> { }); assertThat(this.convention.getContextualName(context)).isEqualTo("graphql mutation"); } @@ -106,4 +106,4 @@ class DefaultExecutionRequestObservationConventionTests { return context; } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java index 33db5cdb..6b1f4247 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/observation/GraphQlObservationInstrumentationTests.java @@ -16,6 +16,12 @@ package org.springframework.graphql.observation; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.stream.Stream; + import graphql.GraphQLContext; import graphql.GraphqlErrorBuilder; import graphql.execution.DataFetcherResult; @@ -32,6 +38,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import reactor.core.publisher.Mono; import org.springframework.graphql.Author; import org.springframework.graphql.Book; @@ -43,13 +50,6 @@ import org.springframework.graphql.ResponseHelper; import org.springframework.graphql.TestExecutionRequest; import org.springframework.graphql.execution.DataFetcherExceptionResolver; import org.springframework.graphql.execution.ErrorType; -import reactor.core.publisher.Mono; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -297,7 +297,7 @@ class GraphQlObservationInstrumentationTests { @Test void shouldNotOverrideExistingLocalContext() { - + String document = """ { bookById(id: 1) { @@ -320,7 +320,7 @@ class GraphQlObservationInstrumentationTests { return BookSource.getAuthor(101L).getFirstName(); }; - ExecutionGraphQlRequest request = TestExecutionRequest.forDocument(document); + ExecutionGraphQlRequest request = TestExecutionRequest.forDocument(document); Mono responseMono = graphQlSetup .queryFetcher("bookById", bookDataFetcher) .dataFetcher("Book", "author", authorDataFetcher) diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java index 4d778748..3fe4089a 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java @@ -13,12 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.server.webflux; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + import org.springframework.core.codec.DataBufferEncoder; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.graphql.GraphQlRequest; @@ -39,13 +48,6 @@ import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.result.view.ViewResolver; import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.List; -import java.util.Locale; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlRequestPredicatesTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlRequestPredicatesTests.java index 0aaea59d..710b1ab0 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlRequestPredicatesTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlRequestPredicatesTests.java @@ -40,133 +40,133 @@ import static org.assertj.core.api.Assertions.assertThat; */ class GraphQlRequestPredicatesTests { - @Nested - class HttpPredicatesTests { + @Nested + class HttpPredicatesTests { - RequestPredicate httpPredicate = GraphQlRequestPredicates.graphQlHttp("/graphql"); + RequestPredicate httpPredicate = GraphQlRequestPredicates.graphQlHttp("/graphql"); - @Test - void shouldAcceptGraphQlHttpRequest() { - ServerWebExchange exchange = createMatchingHttpExchange(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isTrue(); - } + @Test + void shouldAcceptGraphQlHttpRequest() { + ServerWebExchange exchange = createMatchingHttpExchange(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isTrue(); + } - @Test - void shouldAcceptCorsRequest() { - ServerWebExchange exchange = createMatchingHttpExchange() - .mutate().request(req -> req.method(HttpMethod.OPTIONS).header("Origin", "https://example.org") - .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")).build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isTrue(); - } + @Test + void shouldAcceptCorsRequest() { + ServerWebExchange exchange = createMatchingHttpExchange() + .mutate().request(req -> req.method(HttpMethod.OPTIONS).header("Origin", "https://example.org") + .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")).build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isTrue(); + } - @Test - void shouldRejectRequestWithGetMethod() { - ServerWebExchange exchange = createMatchingHttpExchange() - .mutate().request(req -> req.method(HttpMethod.GET)).build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithGetMethod() { + ServerWebExchange exchange = createMatchingHttpExchange() + .mutate().request(req -> req.method(HttpMethod.GET)).build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithDifferentPath() { - ServerWebExchange exchange = createMatchingHttpExchange() - .mutate().request(req -> req.path("/invalid")).build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithDifferentPath() { + ServerWebExchange exchange = createMatchingHttpExchange() + .mutate().request(req -> req.path("/invalid")).build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithDifferentContentType() { - ServerWebExchange exchange = createMatchingHttpExchange() - .mutate().request(req -> req.headers(headers -> headers.setContentType(MediaType.TEXT_HTML))) - .build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithDifferentContentType() { + ServerWebExchange exchange = createMatchingHttpExchange() + .mutate().request(req -> req.headers(headers -> headers.setContentType(MediaType.TEXT_HTML))) + .build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithIncompatibleAccept() { - ServerWebExchange exchange = createMatchingHttpExchange() - .mutate().request(req -> req.headers(headers -> headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML)))) - .build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithIncompatibleAccept() { + ServerWebExchange exchange = createMatchingHttpExchange() + .mutate().request(req -> req.headers(headers -> headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML)))) + .build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isFalse(); + } - private MockServerWebExchange createMatchingHttpExchange() { - MockServerHttpRequest request = MockServerHttpRequest.post("/graphql") - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL_RESPONSE) - .build(); - return MockServerWebExchange.from(request); - } + private MockServerWebExchange createMatchingHttpExchange() { + MockServerHttpRequest request = MockServerHttpRequest.post("/graphql") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_GRAPHQL_RESPONSE) + .build(); + return MockServerWebExchange.from(request); + } - } + } - @Nested - class SsePredicatesTests { + @Nested + class SsePredicatesTests { - RequestPredicate ssePredicate = GraphQlRequestPredicates.graphQlSse("/graphql"); + RequestPredicate ssePredicate = GraphQlRequestPredicates.graphQlSse("/graphql"); - @Test - void shouldAcceptGraphQlSseRequest() { - ServerWebExchange exchange = createMatchingSseExchange(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isTrue(); - } + @Test + void shouldAcceptGraphQlSseRequest() { + ServerWebExchange exchange = createMatchingSseExchange(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isTrue(); + } - @Test - void shouldAcceptCorsRequest() { - ServerWebExchange exchange = createMatchingSseExchange() - .mutate().request(req -> req.method(HttpMethod.OPTIONS).header("Origin", "https://example.org") - .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")).build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isTrue(); - } + @Test + void shouldAcceptCorsRequest() { + ServerWebExchange exchange = createMatchingSseExchange() + .mutate().request(req -> req.method(HttpMethod.OPTIONS).header("Origin", "https://example.org") + .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")).build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isTrue(); + } - @Test - void shouldRejectRequestWithGetMethod() { - ServerWebExchange exchange = createMatchingSseExchange() - .mutate().request(req -> req.method(HttpMethod.GET)).build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithGetMethod() { + ServerWebExchange exchange = createMatchingSseExchange() + .mutate().request(req -> req.method(HttpMethod.GET)).build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithDifferentPath() { - ServerWebExchange exchange = createMatchingSseExchange() - .mutate().request(req -> req.path("/invalid")).build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithDifferentPath() { + ServerWebExchange exchange = createMatchingSseExchange() + .mutate().request(req -> req.path("/invalid")).build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithDifferentContentType() { - ServerWebExchange exchange = createMatchingSseExchange() - .mutate().request(req -> req.headers(headers -> headers.setContentType(MediaType.TEXT_HTML))) - .build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithDifferentContentType() { + ServerWebExchange exchange = createMatchingSseExchange() + .mutate().request(req -> req.headers(headers -> headers.setContentType(MediaType.TEXT_HTML))) + .build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithIncompatibleAccept() { - ServerWebExchange exchange = createMatchingSseExchange() - .mutate().request(req -> req.headers(headers -> headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML)))) - .build(); - ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithIncompatibleAccept() { + ServerWebExchange exchange = createMatchingSseExchange() + .mutate().request(req -> req.headers(headers -> headers.setAccept(Collections.singletonList(MediaType.TEXT_HTML)))) + .build(); + ServerRequest serverRequest = ServerRequest.create(exchange, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isFalse(); + } - private MockServerWebExchange createMatchingSseExchange() { - MockServerHttpRequest request = MockServerHttpRequest.post("/graphql") - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.TEXT_EVENT_STREAM) - .build(); - return MockServerWebExchange.from(request); - } - } + private MockServerWebExchange createMatchingSseExchange() { + MockServerHttpRequest request = MockServerHttpRequest.post("/graphql") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.TEXT_EVENT_STREAM) + .build(); + return MockServerWebExchange.from(request); + } + } } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlSseHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlSseHandlerTests.java index 5dd90a3e..1b38cf06 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlSseHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlSseHandlerTests.java @@ -50,127 +50,127 @@ import static org.assertj.core.api.Assertions.assertThat; */ class GraphQlSseHandlerTests { - private static final List> MESSAGE_WRITERS = Collections.singletonList(new ServerSentEventHttpMessageWriter(new Jackson2JsonEncoder())); + private static final List> MESSAGE_WRITERS = Collections.singletonList(new ServerSentEventHttpMessageWriter(new Jackson2JsonEncoder())); - private static final DataFetcher BOOK_SEARCH = environment -> { - String author = environment.getArgument("author"); - return Flux.fromIterable(BookSource.books()) - .filter((book) -> book.getAuthor().getFullName().contains(author)); - }; + private static final DataFetcher BOOK_SEARCH = environment -> { + String author = environment.getArgument("author"); + return Flux.fromIterable(BookSource.books()) + .filter((book) -> book.getAuthor().getFullName().contains(author)); + }; - private final MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/graphql") - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.TEXT_EVENT_STREAM).build(); + private final MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/graphql") + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.TEXT_EVENT_STREAM).build(); - @Test - void shouldRejectQueryOperations() { - SerializableGraphQlRequest request = initRequest("{ bookById(id: 42) {name} }"); - GraphQlSseHandler sseHandler = createSseHandler(BOOK_SEARCH); - MockServerHttpResponse httpResponse = handleRequest(this.httpRequest, sseHandler, request); + @Test + void shouldRejectQueryOperations() { + SerializableGraphQlRequest request = initRequest("{ bookById(id: 42) {name} }"); + GraphQlSseHandler sseHandler = createSseHandler(BOOK_SEARCH); + MockServerHttpResponse httpResponse = handleRequest(this.httpRequest, sseHandler, request); - assertThat(httpResponse.getHeaders().getContentType().isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue(); - assertThat(httpResponse.getBodyAsString().block()).isEqualTo( - """ - event:next - data:{"errors":[{"message":"SSE transport only supports Subscription operations","locations":[],"extensions":{"classification":"OperationNotSupported"}}]} - - event:complete - data:{} - - """); - } + assertThat(httpResponse.getHeaders().getContentType().isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue(); + assertThat(httpResponse.getBodyAsString().block()).isEqualTo( + """ + event:next + data:{"errors":[{"message":"SSE transport only supports Subscription operations","locations":[],"extensions":{"classification":"OperationNotSupported"}}]} - @Test - void shouldWriteMultipleEventsForSubscription() { - SerializableGraphQlRequest request = initRequest("subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } }"); - GraphQlSseHandler sseHandler = createSseHandler(BOOK_SEARCH); - MockServerHttpResponse httpResponse = handleRequest(this.httpRequest, sseHandler, request); + event:complete + data:{} - assertThat(httpResponse.getHeaders().getContentType().isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue(); - assertThat(httpResponse.getBodyAsString().block()).isEqualTo( - """ - event:next - data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - - event:next - data:{"data":{"bookSearch":{"id":"5","name":"Animal Farm"}}} - - event:complete - data:{} - - """); - } + """); + } - @Test - void shouldWriteEventsAndTerminalError() { - SerializableGraphQlRequest request = initRequest("subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } }"); - DataFetcher errorDataFetcher = env -> Flux.just(BookSource.getBook(1L)) - .concatWith(Flux.error(new IllegalStateException("test error"))); - GraphQlSseHandler sseHandler = createSseHandler(errorDataFetcher); - MockServerHttpResponse httpResponse = handleRequest(this.httpRequest, sseHandler, request); + @Test + void shouldWriteMultipleEventsForSubscription() { + SerializableGraphQlRequest request = initRequest("subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } }"); + GraphQlSseHandler sseHandler = createSseHandler(BOOK_SEARCH); + MockServerHttpResponse httpResponse = handleRequest(this.httpRequest, sseHandler, request); - assertThat(httpResponse.getHeaders().getContentType().isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue(); - assertThat(httpResponse.getBodyAsString().block()).isEqualTo( - """ - event:next - data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - - event:next - data:{"errors":[{"message":"Subscription error","locations":[],"extensions":{"classification":"INTERNAL_ERROR"}}]} - - event:complete - data:{} + assertThat(httpResponse.getHeaders().getContentType().isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue(); + assertThat(httpResponse.getBodyAsString().block()).isEqualTo( + """ + event:next + data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - """); - } + event:next + data:{"data":{"bookSearch":{"id":"5","name":"Animal Farm"}}} - private GraphQlSseHandler createSseHandler(DataFetcher subscriptionDataFetcher) { - return new GraphQlSseHandler(GraphQlSetup.schemaResource(BookSource.schema) - .queryFetcher("bookById", (env) -> BookSource.getBookWithoutAuthor(1L)) - .subscriptionFetcher("bookSearch", subscriptionDataFetcher) - .toWebGraphQlHandler()); - } + event:complete + data:{} - private static SerializableGraphQlRequest initRequest(String document) { - SerializableGraphQlRequest request = new SerializableGraphQlRequest(); - request.setQuery(document); - return request; - } + """); + } - private MockServerHttpResponse handleRequest( - MockServerHttpRequest httpRequest, GraphQlSseHandler handler, GraphQlRequest body) { + @Test + void shouldWriteEventsAndTerminalError() { + SerializableGraphQlRequest request = initRequest("subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } }"); + DataFetcher errorDataFetcher = env -> Flux.just(BookSource.getBook(1L)) + .concatWith(Flux.error(new IllegalStateException("test error"))); + GraphQlSseHandler sseHandler = createSseHandler(errorDataFetcher); + MockServerHttpResponse httpResponse = handleRequest(this.httpRequest, sseHandler, request); - MockServerWebExchange exchange = MockServerWebExchange.from(httpRequest); + assertThat(httpResponse.getHeaders().getContentType().isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue(); + assertThat(httpResponse.getBodyAsString().block()).isEqualTo( + """ + event:next + data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - MockServerRequest serverRequest = MockServerRequest.builder() - .exchange(exchange) - .uri(((ServerWebExchange) exchange).getRequest().getURI()) - .method(((ServerWebExchange) exchange).getRequest().getMethod()) - .headers(((ServerWebExchange) exchange).getRequest().getHeaders()) - .body(Mono.just(body)); + event:next + data:{"errors":[{"message":"Subscription error","locations":[],"extensions":{"classification":"INTERNAL_ERROR"}}]} - handler.handleRequest(serverRequest) - .flatMap(response -> response.writeTo(exchange, new DefaultContext())) - .block(); + event:complete + data:{} - return exchange.getResponse(); - } + """); + } + + private GraphQlSseHandler createSseHandler(DataFetcher subscriptionDataFetcher) { + return new GraphQlSseHandler(GraphQlSetup.schemaResource(BookSource.schema) + .queryFetcher("bookById", (env) -> BookSource.getBookWithoutAuthor(1L)) + .subscriptionFetcher("bookSearch", subscriptionDataFetcher) + .toWebGraphQlHandler()); + } + + private static SerializableGraphQlRequest initRequest(String document) { + SerializableGraphQlRequest request = new SerializableGraphQlRequest(); + request.setQuery(document); + return request; + } + + private MockServerHttpResponse handleRequest( + MockServerHttpRequest httpRequest, GraphQlSseHandler handler, GraphQlRequest body) { + + MockServerWebExchange exchange = MockServerWebExchange.from(httpRequest); + + MockServerRequest serverRequest = MockServerRequest.builder() + .exchange(exchange) + .uri(((ServerWebExchange) exchange).getRequest().getURI()) + .method(((ServerWebExchange) exchange).getRequest().getMethod()) + .headers(((ServerWebExchange) exchange).getRequest().getHeaders()) + .body(Mono.just(body)); + + handler.handleRequest(serverRequest) + .flatMap(response -> response.writeTo(exchange, new DefaultContext())) + .block(); + + return exchange.getResponse(); + } - private static class DefaultContext implements ServerResponse.Context { + private static class DefaultContext implements ServerResponse.Context { - @Override - public List> messageWriters() { - return MESSAGE_WRITERS; - } + @Override + public List> messageWriters() { + return MESSAGE_WRITERS; + } - @Override - public List viewResolvers() { - return Collections.emptyList(); - } + @Override + public List viewResolvers() { + return Collections.emptyList(); + } - } + } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphiQlHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphiQlHandlerTests.java index 63b533dd..c571e016 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphiQlHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphiQlHandlerTests.java @@ -142,4 +142,4 @@ class GraphiQlHandlerTests { } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java index a46b653b..dac02207 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.server.webmvc; import java.io.IOException; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlRequestPredicatesTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlRequestPredicatesTests.java index 807f05bf..38ba2e98 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlRequestPredicatesTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlRequestPredicatesTests.java @@ -36,131 +36,131 @@ import static org.assertj.core.api.Assertions.assertThat; */ class GraphQlRequestPredicatesTests { - @Nested - class HttpPredicatesTests { + @Nested + class HttpPredicatesTests { - RequestPredicate httpPredicate = GraphQlRequestPredicates.graphQlHttp("/graphql"); + RequestPredicate httpPredicate = GraphQlRequestPredicates.graphQlHttp("/graphql"); - @Test - void shouldAcceptGraphQlHttpRequest() { - MockHttpServletRequest request = createMatchingHttpRequest(); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isTrue(); - } + @Test + void shouldAcceptGraphQlHttpRequest() { + MockHttpServletRequest request = createMatchingHttpRequest(); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isTrue(); + } - @Test - void shouldAcceptCorsRequest() { - MockHttpServletRequest request = createMatchingHttpRequest(); - request.setMethod("OPTIONS"); - request.addHeader("Origin", "https://example.com"); - request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isTrue(); - } + @Test + void shouldAcceptCorsRequest() { + MockHttpServletRequest request = createMatchingHttpRequest(); + request.setMethod("OPTIONS"); + request.addHeader("Origin", "https://example.com"); + request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isTrue(); + } - @Test - void shouldRejectRequestWithGetMethod() { - MockHttpServletRequest request = createMatchingHttpRequest(); - request.setMethod("GET"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithGetMethod() { + MockHttpServletRequest request = createMatchingHttpRequest(); + request.setMethod("GET"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithDifferentPath() { - MockHttpServletRequest request = createMatchingHttpRequest(); - request.setRequestURI("/invalid"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithDifferentPath() { + MockHttpServletRequest request = createMatchingHttpRequest(); + request.setRequestURI("/invalid"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithDifferentContentType() { - MockHttpServletRequest request = createMatchingHttpRequest(); - request.setContentType("text/xml"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithDifferentContentType() { + MockHttpServletRequest request = createMatchingHttpRequest(); + request.setContentType("text/xml"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithIncompatibleAccept() { - MockHttpServletRequest request = createMatchingHttpRequest(); - request.removeHeader("Accept"); - request.addHeader("Accept", "text/xml"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(httpPredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithIncompatibleAccept() { + MockHttpServletRequest request = createMatchingHttpRequest(); + request.removeHeader("Accept"); + request.addHeader("Accept", "text/xml"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(httpPredicate.test(serverRequest)).isFalse(); + } - private MockHttpServletRequest createMatchingHttpRequest() { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/graphql"); - request.setContentType("application/json"); - request.addHeader("Accept", "application/graphql-response+json"); - return request; - } + private MockHttpServletRequest createMatchingHttpRequest() { + MockHttpServletRequest request = new MockHttpServletRequest("POST", "/graphql"); + request.setContentType("application/json"); + request.addHeader("Accept", "application/graphql-response+json"); + return request; + } - } + } - @Nested - class SsePredicatesTests { + @Nested + class SsePredicatesTests { - RequestPredicate ssePredicate = GraphQlRequestPredicates.graphQlSse("/graphql"); + RequestPredicate ssePredicate = GraphQlRequestPredicates.graphQlSse("/graphql"); - @Test - void shouldAcceptGraphQlSseRequest() { - MockHttpServletRequest request = createMatchingSseRequest(); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isTrue(); - } + @Test + void shouldAcceptGraphQlSseRequest() { + MockHttpServletRequest request = createMatchingSseRequest(); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isTrue(); + } - @Test - void shouldAcceptCorsRequest() { - MockHttpServletRequest request = createMatchingSseRequest(); - request.setMethod("OPTIONS"); - request.addHeader("Origin", "https://example.com"); - request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isTrue(); - } + @Test + void shouldAcceptCorsRequest() { + MockHttpServletRequest request = createMatchingSseRequest(); + request.setMethod("OPTIONS"); + request.addHeader("Origin", "https://example.com"); + request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isTrue(); + } - @Test - void shouldRejectRequestWithGetMethod() { - MockHttpServletRequest request = createMatchingSseRequest(); - request.setMethod("GET"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithGetMethod() { + MockHttpServletRequest request = createMatchingSseRequest(); + request.setMethod("GET"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithDifferentPath() { - MockHttpServletRequest request = createMatchingSseRequest(); - request.setRequestURI("/invalid"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithDifferentPath() { + MockHttpServletRequest request = createMatchingSseRequest(); + request.setRequestURI("/invalid"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithDifferentContentType() { - MockHttpServletRequest request = createMatchingSseRequest(); - request.setContentType("text/xml"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithDifferentContentType() { + MockHttpServletRequest request = createMatchingSseRequest(); + request.setContentType("text/xml"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isFalse(); + } - @Test - void shouldRejectRequestWithIncompatibleAccept() { - MockHttpServletRequest request = createMatchingSseRequest(); - request.removeHeader("Accept"); - request.addHeader("Accept", "text/xml"); - ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); - assertThat(ssePredicate.test(serverRequest)).isFalse(); - } + @Test + void shouldRejectRequestWithIncompatibleAccept() { + MockHttpServletRequest request = createMatchingSseRequest(); + request.removeHeader("Accept"); + request.addHeader("Accept", "text/xml"); + ServerRequest serverRequest = ServerRequest.create(request, Collections.emptyList()); + assertThat(ssePredicate.test(serverRequest)).isFalse(); + } - private MockHttpServletRequest createMatchingSseRequest() { - MockHttpServletRequest request = new MockHttpServletRequest("POST", "/graphql"); - request.addHeader("Content-Type", "application/json"); - request.addHeader("Accept", "text/event-stream"); - return request; - } - } + private MockHttpServletRequest createMatchingSseRequest() { + MockHttpServletRequest request = new MockHttpServletRequest("POST", "/graphql"); + request.addHeader("Content-Type", "application/json"); + request.addHeader("Accept", "text/event-stream"); + return request; + } + } } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlSseHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlSseHandlerTests.java index e0db8f58..9ac23bff 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlSseHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlSseHandlerTests.java @@ -49,124 +49,124 @@ import static org.awaitility.Awaitility.await; */ class GraphQlSseHandlerTests { - private static final List> MESSAGE_READERS = - Collections.singletonList(new MappingJackson2HttpMessageConverter()); + private static final List> MESSAGE_READERS = + Collections.singletonList(new MappingJackson2HttpMessageConverter()); - private static final DataFetcher BOOK_SEARCH = environment -> { - String author = environment.getArgument("author"); - return Flux.fromIterable(BookSource.books()) - .filter((book) -> book.getAuthor().getFullName().contains(author)); - }; + private static final DataFetcher BOOK_SEARCH = environment -> { + String author = environment.getArgument("author"); + return Flux.fromIterable(BookSource.books()) + .filter((book) -> book.getAuthor().getFullName().contains(author)); + }; - @Test - void shouldRejectQueryOperations() throws Exception { - GraphQlSseHandler sseHandler = createSseHandler(BOOK_SEARCH); - MockHttpServletRequest request = createServletRequest("{ \"query\": \"{ bookById(id: 42) {name} }\"}"); - MockHttpServletResponse response = handleRequest(request, sseHandler); + @Test + void shouldRejectQueryOperations() throws Exception { + GraphQlSseHandler sseHandler = createSseHandler(BOOK_SEARCH); + MockHttpServletRequest request = createServletRequest("{ \"query\": \"{ bookById(id: 42) {name} }\"}"); + MockHttpServletResponse response = handleRequest(request, sseHandler); - assertThat(response.getContentType()).isEqualTo(MediaType.TEXT_EVENT_STREAM_VALUE); - assertThat(response.getContentAsString()).isEqualTo( - """ - event:next - data:{"errors":[{"message":"SSE transport only supports Subscription operations","locations":[],"extensions":{"classification":"OperationNotSupported"}}]} - - event:complete - data: - - """); - } + assertThat(response.getContentType()).isEqualTo(MediaType.TEXT_EVENT_STREAM_VALUE); + assertThat(response.getContentAsString()).isEqualTo( + """ + event:next + data:{"errors":[{"message":"SSE transport only supports Subscription operations","locations":[],"extensions":{"classification":"OperationNotSupported"}}]} - @Test - void shouldWriteMultipleEventsForSubscription() throws Exception { - GraphQlSseHandler sseHandler = createSseHandler(BOOK_SEARCH); - MockHttpServletRequest request = createServletRequest(""" - { - "query": "subscription TestSubscription { bookSearch(author:\\\"Orwell\\\") { id name } }" - } - """); - MockHttpServletResponse response = handleRequest(request, sseHandler); + event:complete + data: - assertThat(response.getContentType()).isEqualTo(MediaType.TEXT_EVENT_STREAM_VALUE); - assertThat(response.getContentAsString()).isEqualTo( - """ - event:next - data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - - event:next - data:{"data":{"bookSearch":{"id":"5","name":"Animal Farm"}}} - - event:complete - data: - - """); - } + """); + } - @Test - void shouldWriteEventsAndTerminalError() throws Exception { - DataFetcher errorDataFetcher = env -> Flux.just(BookSource.getBook(1L)) - .concatWith(Flux.error(new IllegalStateException("test error"))); - GraphQlSseHandler sseHandler = createSseHandler(errorDataFetcher); - MockHttpServletRequest request = createServletRequest(""" - { - "query": "subscription TestSubscription { bookSearch(author:\\\"Orwell\\\") { id name } }" - } - """); - MockHttpServletResponse response = handleRequest(request, sseHandler); + @Test + void shouldWriteMultipleEventsForSubscription() throws Exception { + GraphQlSseHandler sseHandler = createSseHandler(BOOK_SEARCH); + MockHttpServletRequest request = createServletRequest(""" + { + "query": "subscription TestSubscription { bookSearch(author:\\\"Orwell\\\") { id name } }" + } + """); + MockHttpServletResponse response = handleRequest(request, sseHandler); - assertThat(response.getContentType()).isEqualTo(MediaType.TEXT_EVENT_STREAM_VALUE); - assertThat(response.getContentAsString()).isEqualTo( - """ - event:next - data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - - event:next - data:{"errors":[{"message":"Subscription error","locations":[],"extensions":{"classification":"INTERNAL_ERROR"}}]} - - event:complete - data: - - """); - } + assertThat(response.getContentType()).isEqualTo(MediaType.TEXT_EVENT_STREAM_VALUE); + assertThat(response.getContentAsString()).isEqualTo( + """ + event:next + data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} - private GraphQlSseHandler createSseHandler(DataFetcher subscriptionDataFetcher) { - return new GraphQlSseHandler(GraphQlSetup.schemaResource(BookSource.schema) - .queryFetcher("bookById", (env) -> BookSource.getBookWithoutAuthor(1L)) - .subscriptionFetcher("bookSearch", subscriptionDataFetcher) - .toWebGraphQlHandler()); - } + event:next + data:{"data":{"bookSearch":{"id":"5","name":"Animal Farm"}}} - private MockHttpServletRequest createServletRequest(String query) { - MockHttpServletRequest servletRequest = new MockHttpServletRequest("POST", "/"); - servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE); - servletRequest.setContent(query.getBytes(StandardCharsets.UTF_8)); - servletRequest.addHeader("Accept", MediaType.TEXT_EVENT_STREAM_VALUE); - servletRequest.setAsyncSupported(true); - return servletRequest; - } + event:complete + data: - private MockHttpServletResponse handleRequest( - MockHttpServletRequest servletRequest, GraphQlSseHandler handler) throws ServletException, IOException { + """); + } - ServerRequest request = ServerRequest.create(servletRequest, MESSAGE_READERS); - ServerResponse response = handler.handleRequest(request); - if (response instanceof AsyncServerResponse asyncResponse) { - asyncResponse.block(); - } + @Test + void shouldWriteEventsAndTerminalError() throws Exception { + DataFetcher errorDataFetcher = env -> Flux.just(BookSource.getBook(1L)) + .concatWith(Flux.error(new IllegalStateException("test error"))); + GraphQlSseHandler sseHandler = createSseHandler(errorDataFetcher); + MockHttpServletRequest request = createServletRequest(""" + { + "query": "subscription TestSubscription { bookSearch(author:\\\"Orwell\\\") { id name } }" + } + """); + MockHttpServletResponse response = handleRequest(request, sseHandler); - MockHttpServletResponse servletResponse = new MockHttpServletResponse(); - response.writeTo(servletRequest, servletResponse, new DefaultContext()); - await().atMost(Duration.ofMillis(500)).until(() -> servletResponse.getContentAsString().contains("complete")); - return servletResponse; - } + assertThat(response.getContentType()).isEqualTo(MediaType.TEXT_EVENT_STREAM_VALUE); + assertThat(response.getContentAsString()).isEqualTo( + """ + event:next + data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}} + + event:next + data:{"errors":[{"message":"Subscription error","locations":[],"extensions":{"classification":"INTERNAL_ERROR"}}]} + + event:complete + data: + + """); + } + + private GraphQlSseHandler createSseHandler(DataFetcher subscriptionDataFetcher) { + return new GraphQlSseHandler(GraphQlSetup.schemaResource(BookSource.schema) + .queryFetcher("bookById", (env) -> BookSource.getBookWithoutAuthor(1L)) + .subscriptionFetcher("bookSearch", subscriptionDataFetcher) + .toWebGraphQlHandler()); + } + + private MockHttpServletRequest createServletRequest(String query) { + MockHttpServletRequest servletRequest = new MockHttpServletRequest("POST", "/"); + servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE); + servletRequest.setContent(query.getBytes(StandardCharsets.UTF_8)); + servletRequest.addHeader("Accept", MediaType.TEXT_EVENT_STREAM_VALUE); + servletRequest.setAsyncSupported(true); + return servletRequest; + } + + private MockHttpServletResponse handleRequest( + MockHttpServletRequest servletRequest, GraphQlSseHandler handler) throws ServletException, IOException { + + ServerRequest request = ServerRequest.create(servletRequest, MESSAGE_READERS); + ServerResponse response = handler.handleRequest(request); + if (response instanceof AsyncServerResponse asyncResponse) { + asyncResponse.block(); + } + + MockHttpServletResponse servletResponse = new MockHttpServletResponse(); + response.writeTo(servletRequest, servletResponse, new DefaultContext()); + await().atMost(Duration.ofMillis(500)).until(() -> servletResponse.getContentAsString().contains("complete")); + return servletResponse; + } - private static class DefaultContext implements ServerResponse.Context { + private static class DefaultContext implements ServerResponse.Context { - @Override - public List> messageConverters() { - return MESSAGE_READERS; - } + @Override + public List> messageConverters() { + return MESSAGE_READERS; + } - } + } -} \ No newline at end of file +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java index 6ea1e37e..7960846d 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java @@ -25,7 +25,6 @@ import java.util.Map; import jakarta.servlet.ServletException; import jakarta.servlet.http.MappingMatch; - import org.junit.jupiter.api.Test; import org.springframework.core.io.ByteArrayResource; diff --git a/spring-graphql/src/test/java/org/springframework/graphql/support/DefaultGraphQlRequestTests.java b/spring-graphql/src/test/java/org/springframework/graphql/support/DefaultGraphQlRequestTests.java index d922149a..5672a4dc 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/support/DefaultGraphQlRequestTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/support/DefaultGraphQlRequestTests.java @@ -52,4 +52,4 @@ class DefaultGraphQlRequestTests { .containsEntry("extensions", extensions); } -} \ No newline at end of file +} diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlServiceSetup.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlServiceSetup.java index 6081d94e..9183373b 100644 --- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlServiceSetup.java +++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlServiceSetup.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql; import org.springframework.graphql.execution.DataLoaderRegistrar; diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlSetup.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlSetup.java index cd329c65..0d8c3e79 100644 --- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlSetup.java +++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/GraphQlSetup.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql; import java.nio.charset.StandardCharsets; @@ -58,7 +59,7 @@ import org.springframework.graphql.server.webflux.GraphQlHttpHandler; * @author Rossen Stoyanchev */ @SuppressWarnings("unused") -public class GraphQlSetup implements GraphQlServiceSetup { +public final class GraphQlSetup implements GraphQlServiceSetup { private final GraphQlSource.SchemaResourceBuilder graphQlSourceBuilder; @@ -85,8 +86,8 @@ public class GraphQlSetup implements GraphQlServiceSetup { } public GraphQlSetup dataFetcher(String type, String field, DataFetcher dataFetcher) { - return runtimeWiring(wiringBuilder -> - wiringBuilder.type(type, typeBuilder -> typeBuilder.dataFetcher(field, dataFetcher))); + return runtimeWiring((wiringBuilder) -> + wiringBuilder.type(type, (typeBuilder) -> typeBuilder.dataFetcher(field, dataFetcher))); } public GraphQlSetup typeDefinitionConfigurer(TypeDefinitionConfigurer configurer) { @@ -170,7 +171,7 @@ public class GraphQlSetup implements GraphQlServiceSetup { } public TestExecutionGraphQlService toGraphQlService() { - GraphQlSource source = graphQlSourceBuilder.build(); + GraphQlSource source = this.graphQlSourceBuilder.build(); DefaultExecutionGraphQlService service = new DefaultExecutionGraphQlService(source); this.dataLoaderRegistrars.forEach(service::addDataLoaderRegistrar); return new TestExecutionGraphQlService(service); diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/MockWebServerExtension.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/MockWebServerExtension.java index 4e92e15e..d9492530 100644 --- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/MockWebServerExtension.java +++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/MockWebServerExtension.java @@ -34,28 +34,28 @@ import org.junit.jupiter.api.extension.ParameterResolver; */ public class MockWebServerExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver { - private MockWebServer mockWebServer; + private MockWebServer mockWebServer; - @Override - public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { - return parameterContext.getParameter().getType() - .equals(MockWebServer.class); - } + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return parameterContext.getParameter().getType() + .equals(MockWebServer.class); + } - @Override - public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { - return this.mockWebServer; - } + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return this.mockWebServer; + } - @Override - public void beforeEach(ExtensionContext extensionContext) throws Exception { - this.mockWebServer = new MockWebServer(); - this.mockWebServer.start(); - } + @Override + public void beforeEach(ExtensionContext extensionContext) throws Exception { + this.mockWebServer = new MockWebServer(); + this.mockWebServer.start(); + } - @Override - public void afterEach(ExtensionContext extensionContext) throws Exception { - this.mockWebServer.shutdown(); - } + @Override + public void afterEach(ExtensionContext extensionContext) throws Exception { + this.mockWebServer.shutdown(); + } } diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/TestExecutionGraphQlService.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/TestExecutionGraphQlService.java index cad66b78..f4e18895 100644 --- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/TestExecutionGraphQlService.java +++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/TestExecutionGraphQlService.java @@ -22,6 +22,7 @@ import reactor.core.publisher.Mono; * Wrap an {@link ExecutionGraphQlService} to expose an addition convenience * method that takes a String document, and essentially hides the call to * {@link TestExecutionRequest#forDocument(String)}. + * @author Rossen Stoyanchev */ public class TestExecutionGraphQlService implements ExecutionGraphQlService { diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/TestExecutionRequest.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/TestExecutionRequest.java index ad3a5134..20453316 100644 --- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/TestExecutionRequest.java +++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/TestExecutionRequest.java @@ -29,7 +29,7 @@ import org.springframework.graphql.support.DefaultExecutionGraphQlRequest; * * @author Rossen Stoyanchev */ -public class TestExecutionRequest extends DefaultExecutionGraphQlRequest { +public final class TestExecutionRequest extends DefaultExecutionGraphQlRequest { private static final AtomicLong idIndex = new AtomicLong(); diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/client/TestWebSocketClient.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/client/TestWebSocketClient.java index 41669b90..40ab0442 100644 --- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/client/TestWebSocketClient.java +++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/client/TestWebSocketClient.java @@ -52,11 +52,12 @@ public final class TestWebSocketClient implements WebSocketClient { /** * Return the connection at the specified index from a list of connections * based on order of execution. + * @param index the index of the connection to return */ public TestWebSocketConnection getConnection(int index) { Assert.isTrue(index < this.connections.size(), "No connection at index=" + index + ", total=" + this.connections.size()); - return connections.get(index); + return this.connections.get(index); } /** diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/client/TestWebSocketConnection.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/client/TestWebSocketConnection.java index 7efbe021..d8abd4c3 100644 --- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/client/TestWebSocketConnection.java +++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/client/TestWebSocketConnection.java @@ -144,7 +144,7 @@ public final class TestWebSocketConnection { private Mono invokeHandler(WebSocketHandler handler, TestWebSocketSession session, boolean isClient) { return handler.handle(session) .then(Mono.defer(() -> session.close(CloseStatus.NORMAL))) - .onErrorResume(ex -> { + .onErrorResume((ex) -> { logger.error("Unhandled " + (isClient ? "client" : "server") + " error: " + ex.getMessage()); return session.close(CloseStatus.PROTOCOL_ERROR).then(Mono.error(ex)); }); @@ -153,6 +153,7 @@ public final class TestWebSocketConnection { /** * Close the connection from the client side. + * @param status the status to use when closing the session */ public Mono closeClientSession(CloseStatus status) { return this.clientSession.close(status); @@ -160,6 +161,7 @@ public final class TestWebSocketConnection { /** * Close the connection from the server side. + * @param status the status to use when closing the session */ public Mono closeServerSession(CloseStatus status) { return this.serverSession.close(status); @@ -218,7 +220,7 @@ public final class TestWebSocketConnection { } - public List getSentMessages() { + List getSentMessages() { return new ArrayList<>(this.sentMessages); } @@ -226,7 +228,7 @@ public final class TestWebSocketConnection { public Mono send(Publisher messages) { return Flux.from(messages) .doOnNext(this::saveMessage) - .doOnNext(message -> { + .doOnNext((message) -> { Sinks.EmitResult result = this.sendSink.tryEmitNext(message); Assert.state(result.isSuccess(), this + " failed to send: " + message + ", with " + result); }) @@ -253,6 +255,7 @@ public final class TestWebSocketConnection { return this.closeStatusSink.asMono(); } + @Override public Mono close(CloseStatus status) { if (logger.isDebugEnabled()) { logger.debug("Closing " + this + " with " + status); @@ -267,7 +270,7 @@ public final class TestWebSocketConnection { } else { this.closeStatusSink.tryEmitEmpty(); - }; + } } @Override diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/execution/MockExecutionGraphQlService.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/execution/MockExecutionGraphQlService.java index 34572e9d..37ad8025 100644 --- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/execution/MockExecutionGraphQlService.java +++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/execution/MockExecutionGraphQlService.java @@ -71,6 +71,7 @@ public class MockExecutionGraphQlService implements ExecutionGraphQlService { /** * Set the default response to fall back on as a "data"-only response. + * @param dataJson the JSON data response */ public void setDefaultResponse(String dataJson) { ExecutionInput input = ExecutionInput.newExecutionInput().query("").build(); @@ -80,6 +81,8 @@ public class MockExecutionGraphQlService implements ExecutionGraphQlService { /** * Set a "data"-only response for the given document. + * @param document the graphql document + * @param dataJson the JSON data for the given document */ public void setDataAsJson(String document, String dataJson) { setResponse(document, decode(dataJson)); @@ -87,6 +90,8 @@ public class MockExecutionGraphQlService implements ExecutionGraphQlService { /** * Set a "data"-stream response for the given document. + * @param document the graphql document + * @param dataJson the JSON data for the given document */ public void setDataAsJsonStream(String document, String... dataJson) { setResponseStream(document, Arrays.stream(dataJson).map(this::decode)); @@ -94,6 +99,8 @@ public class MockExecutionGraphQlService implements ExecutionGraphQlService { /** * Set an "errors" response for the given document. + * @param document the graphql document + * @param errors the errors for the given document */ public void setErrors(String document, GraphQLError... errors) { setResponse(document, null, errors); @@ -101,6 +108,8 @@ public class MockExecutionGraphQlService implements ExecutionGraphQlService { /** * Set an "errors" response for the given document. + * @param document the graphql document + * @param errorBuilderConsumer a consumer that builds errors for the given document */ public void setError(String document, Consumer> errorBuilderConsumer) { GraphqlErrorBuilder errorBuilder = GraphqlErrorBuilder.newError(); @@ -110,6 +119,9 @@ public class MockExecutionGraphQlService implements ExecutionGraphQlService { /** * Set a "data" and "errors" response for the given document. + * @param document the graphql document + * @param dataJson the JSON data for the given document + * @param errors the errors for the given document */ public void setDataAsJsonAndErrors(String document, String dataJson, GraphQLError... errors) { setResponse(document, decode(dataJson), errors); @@ -117,6 +129,9 @@ public class MockExecutionGraphQlService implements ExecutionGraphQlService { /** * Set a "data" and "errors" response for the given document. + * @param document the graphql document + * @param data the map to be used as data for the response + * @param errors the errors to be used for the response */ private void setResponse(String document, @Nullable Map data, GraphQLError... errors) { ExecutionResultImpl.Builder builder = new ExecutionResultImpl.Builder(); @@ -131,6 +146,8 @@ public class MockExecutionGraphQlService implements ExecutionGraphQlService { /** * Set a response for the given document. + * @param document the graphql document + * @param result the execution result for the given document */ @SuppressWarnings("unused") public void setResponse(String document, ExecutionResult result) { @@ -140,13 +157,15 @@ public class MockExecutionGraphQlService implements ExecutionGraphQlService { /** * Set a response stream for the given document. + * @param document the graphql document + * @param dataStream a Stream of maps to be used as data for the response */ @SuppressWarnings("unused") public void setResponseStream(String document, Stream> dataStream) { ExecutionInput input = ExecutionInput.newExecutionInput().query(document).build(); List resultList = dataStream - .map(data -> ExecutionResult.newExecutionResult().data(data).build()) - .map(result -> new DefaultExecutionGraphQlResponse(input, result)).toList(); + .map((data) -> ExecutionResult.newExecutionResult().data(data).build()) + .map((result) -> new DefaultExecutionGraphQlResponse(input, result)).toList(); this.responses.put(document, new DefaultExecutionGraphQlResponse(input, ExecutionResult.newExecutionResult().data(Flux.fromIterable(resultList)).build())); } diff --git a/spring-graphql/src/testFixtures/java/org/springframework/graphql/server/WebGraphQlSetup.java b/spring-graphql/src/testFixtures/java/org/springframework/graphql/server/WebGraphQlSetup.java index 8073683a..dfb7028e 100644 --- a/spring-graphql/src/testFixtures/java/org/springframework/graphql/server/WebGraphQlSetup.java +++ b/spring-graphql/src/testFixtures/java/org/springframework/graphql/server/WebGraphQlSetup.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.graphql.server; import org.springframework.graphql.server.webflux.GraphQlHttpHandler; diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index f21b4613..25a746ca 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -1,7 +1,15 @@ - + - \ No newline at end of file + + + + + + + diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml index 2853a86c..dacac5c7 100644 --- a/src/checkstyle/checkstyle.xml +++ b/src/checkstyle/checkstyle.xml @@ -6,48 +6,19 @@ - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - \ No newline at end of file +

KeyValue
query{@link #getDocument() document}