diff --git a/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java b/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java index cb72deb650..484a3fa336 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java @@ -174,7 +174,6 @@ public class DocumentConfigurationProperties extends DefaultTask { } private void webPrefixes(Config prefix) { - prefix.accept("spring.graphql"); prefix.accept("spring.hateoas"); prefix.accept("spring.http"); prefix.accept("spring.servlet"); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle index 324d8c2ba1..33e1749c2d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle @@ -127,7 +127,6 @@ dependencies { optional("org.springframework.data:spring-data-elasticsearch") { exclude group: "commons-logging", module: "commons-logging" } - optional("org.springframework.graphql:spring-graphql") optional("org.springframework.integration:spring-integration-core") optional("org.springframework.kafka:spring-kafka") optional("org.springframework.security:spring-security-config") diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java index 5bc5625ee7..5ff5ca08b4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java @@ -62,8 +62,6 @@ public class MetricsProperties { private final Data data = new Data(); - private final Graphql graphql = new Graphql(); - private final System system = new System(); private final Distribution distribution = new Distribution(); @@ -92,10 +90,6 @@ public class MetricsProperties { return this.data; } - public Graphql getGraphql() { - return this.graphql; - } - public System getSystem() { return this.system; } @@ -274,20 +268,6 @@ public class MetricsProperties { } - public static class Graphql { - - /** - * Auto-timed queries settings. - */ - @NestedConfigurationProperty - private final AutoTimeProperties autotime = new AutoTimeProperties(); - - public AutoTimeProperties getAutotime() { - return this.autotime; - } - - } - public static class System { private final Diskspace diskspace = new Diskspace(); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/graphql/GraphQlMetricsAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/graphql/GraphQlMetricsAutoConfiguration.java deleted file mode 100644 index c9ad464b6f..0000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/graphql/GraphQlMetricsAutoConfiguration.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.actuate.autoconfigure.metrics.graphql; - -import java.util.stream.Collectors; - -import graphql.GraphQL; -import io.micrometer.core.instrument.MeterRegistry; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties; -import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; -import org.springframework.boot.actuate.metrics.graphql.DefaultGraphQlTagsProvider; -import org.springframework.boot.actuate.metrics.graphql.GraphQlMetricsInstrumentation; -import org.springframework.boot.actuate.metrics.graphql.GraphQlTagsContributor; -import org.springframework.boot.actuate.metrics.graphql.GraphQlTagsProvider; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.execution.GraphQlSource; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for instrumentation of Spring - * GraphQL endpoints. - * - * @author Brian Clozel - * @since 2.7.0 - */ -@Configuration(proxyBeanMethods = false) -@AutoConfigureAfter({ MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, - SimpleMetricsExportAutoConfiguration.class }) -@ConditionalOnBean(MeterRegistry.class) -@ConditionalOnClass({ GraphQL.class, GraphQlSource.class }) -@EnableConfigurationProperties(MetricsProperties.class) -public class GraphQlMetricsAutoConfiguration { - - @Bean - @ConditionalOnMissingBean(GraphQlTagsProvider.class) - public DefaultGraphQlTagsProvider graphQlTagsProvider(ObjectProvider contributors) { - return new DefaultGraphQlTagsProvider(contributors.orderedStream().collect(Collectors.toList())); - } - - @Bean - public GraphQlMetricsInstrumentation graphQlMetricsInstrumentation(MeterRegistry meterRegistry, - GraphQlTagsProvider tagsProvider, MetricsProperties properties) { - return new GraphQlMetricsInstrumentation(meterRegistry, tagsProvider, properties.getGraphql().getAutotime()); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories index 5d257850d2..2a60a14063 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories @@ -67,7 +67,6 @@ org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetri org.springframework.boot.actuate.autoconfigure.metrics.export.stackdriver.StackdriverMetricsExportAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.export.statsd.StatsdMetricsExportAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront.WavefrontMetricsExportAutoConfiguration,\ -org.springframework.boot.actuate.autoconfigure.metrics.graphql.GraphQlMetricsAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.integration.IntegrationMetricsAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.jdbc.DataSourcePoolMetricsAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.mongo.MongoMetricsAutoConfiguration,\ diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java index 7675208da0..5de0389b31 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java @@ -32,7 +32,6 @@ import org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoCo import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration; import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.util.ApplicationContextTestUtils; @@ -70,7 +69,7 @@ class SpringApplicationHierarchyTests { @Configuration @EnableAutoConfiguration(exclude = { ElasticsearchDataAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class, CassandraAutoConfiguration.class, - CassandraDataAutoConfiguration.class, GraphQlAutoConfiguration.class, MongoDataAutoConfiguration.class, + CassandraDataAutoConfiguration.class, MongoDataAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class }) @@ -81,7 +80,7 @@ class SpringApplicationHierarchyTests { @Configuration @EnableAutoConfiguration(exclude = { ElasticsearchDataAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class, CassandraAutoConfiguration.class, - CassandraDataAutoConfiguration.class, GraphQlAutoConfiguration.class, MongoDataAutoConfiguration.class, + CassandraDataAutoConfiguration.class, MongoDataAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, Neo4jAutoConfiguration.class, Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, MetricsAutoConfiguration.class }) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java index 1c95dff9de..c25193341f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java @@ -34,7 +34,6 @@ import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration; import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; @@ -76,12 +75,12 @@ class WebEndpointsAutoConfigurationIntegrationTests { } @EnableAutoConfiguration(exclude = { FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class, - CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class, GraphQlAutoConfiguration.class, - Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, MongoAutoConfiguration.class, - MongoDataAutoConfiguration.class, MongoReactiveAutoConfiguration.class, - MongoReactiveDataAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class, - HazelcastAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, SolrAutoConfiguration.class, - RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class, MetricsAutoConfiguration.class }) + CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class, Neo4jDataAutoConfiguration.class, + Neo4jRepositoriesAutoConfiguration.class, MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, + MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, + RepositoryRestMvcAutoConfiguration.class, HazelcastAutoConfiguration.class, + ElasticsearchDataAutoConfiguration.class, SolrAutoConfiguration.class, RedisAutoConfiguration.class, + RedisRepositoriesAutoConfiguration.class, MetricsAutoConfiguration.class }) @SpringBootConfiguration static class WebEndpointTestApplication { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/graphql/GraphQlMetricsAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/graphql/GraphQlMetricsAutoConfigurationTests.java deleted file mode 100644 index 5c7c502dbd..0000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/graphql/GraphQlMetricsAutoConfigurationTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.actuate.autoconfigure.metrics.graphql; - -import graphql.ExecutionResult; -import graphql.GraphQLError; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.schema.DataFetcher; -import io.micrometer.core.instrument.Tag; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun; -import org.springframework.boot.actuate.metrics.graphql.DefaultGraphQlTagsProvider; -import org.springframework.boot.actuate.metrics.graphql.GraphQlMetricsInstrumentation; -import org.springframework.boot.actuate.metrics.graphql.GraphQlTagsProvider; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link GraphQlMetricsAutoConfiguration}. - * - * @author Brian Clozel - */ -class GraphQlMetricsAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().with(MetricsRun.simple()) - .withConfiguration(AutoConfigurations.of(GraphQlMetricsAutoConfiguration.class)); - - @Test - void backsOffWhenMeterRegistryIsMissing() { - new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(GraphQlMetricsAutoConfiguration.class)) - .run((context) -> assertThat(context).doesNotHaveBean(DefaultGraphQlTagsProvider.class) - .doesNotHaveBean(GraphQlMetricsInstrumentation.class)); - } - - @Test - void definesTagsProviderAndInstrumentationWhenMeterRegistryIsPresent() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(DefaultGraphQlTagsProvider.class) - .hasSingleBean(GraphQlMetricsInstrumentation.class)); - } - - @Test - void tagsProviderBacksOffIfAlreadyPresent() { - this.contextRunner.withUserConfiguration(TagsProviderConfiguration.class).run((context) -> assertThat(context) - .doesNotHaveBean(DefaultGraphQlTagsProvider.class).hasSingleBean(TestGraphQlTagsProvider.class)); - } - - @Configuration(proxyBeanMethods = false) - static class TagsProviderConfiguration { - - @Bean - TestGraphQlTagsProvider tagsProvider() { - return new TestGraphQlTagsProvider(); - } - - } - - static class TestGraphQlTagsProvider implements GraphQlTagsProvider { - - @Override - public Iterable getExecutionTags(InstrumentationExecutionParameters parameters, ExecutionResult result, - Throwable exception) { - return null; - } - - @Override - public Iterable getErrorTags(InstrumentationExecutionParameters parameters, GraphQLError error) { - return null; - } - - @Override - public Iterable getDataFetchingTags(DataFetcher dataFetcher, - InstrumentationFieldFetchParameters parameters, Throwable exception) { - return null; - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/build.gradle b/spring-boot-project/spring-boot-actuator/build.gradle index f2b7ff9ed4..a9064cd715 100644 --- a/spring-boot-project/spring-boot-actuator/build.gradle +++ b/spring-boot-project/spring-boot-actuator/build.gradle @@ -77,7 +77,6 @@ dependencies { optional("org.springframework.data:spring-data-mongodb") optional("org.springframework.data:spring-data-redis") optional("org.springframework.data:spring-data-rest-webmvc") - optional("org.springframework.graphql:spring-graphql") optional("org.springframework.integration:spring-integration-core") optional("org.springframework.security:spring-security-core") optional("org.springframework.security:spring-security-web") diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/DefaultGraphQlTagsProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/DefaultGraphQlTagsProvider.java deleted file mode 100644 index 656a841c99..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/DefaultGraphQlTagsProvider.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.actuate.metrics.graphql; - -import java.util.Collections; -import java.util.List; - -import graphql.ExecutionResult; -import graphql.GraphQLError; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.schema.DataFetcher; -import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.Tags; - -/** - * Default implementation for {@link GraphQlTagsProvider}. - * - * @author Brian Clozel - * @since 2.7.0 - */ -public class DefaultGraphQlTagsProvider implements GraphQlTagsProvider { - - private final List contributors; - - public DefaultGraphQlTagsProvider(List contributors) { - this.contributors = contributors; - } - - public DefaultGraphQlTagsProvider() { - this(Collections.emptyList()); - } - - @Override - public Iterable getExecutionTags(InstrumentationExecutionParameters parameters, ExecutionResult result, - Throwable exception) { - Tags tags = Tags.of(GraphQlTags.executionOutcome(result, exception)); - for (GraphQlTagsContributor contributor : this.contributors) { - tags = tags.and(contributor.getExecutionTags(parameters, result, exception)); - } - return tags; - } - - @Override - public Iterable getErrorTags(InstrumentationExecutionParameters parameters, GraphQLError error) { - Tags tags = Tags.of(GraphQlTags.errorType(error), GraphQlTags.errorPath(error)); - for (GraphQlTagsContributor contributor : this.contributors) { - tags = tags.and(contributor.getErrorTags(parameters, error)); - } - return tags; - } - - @Override - public Iterable getDataFetchingTags(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, - Throwable exception) { - Tags tags = Tags.of(GraphQlTags.dataFetchingOutcome(exception), GraphQlTags.dataFetchingPath(parameters)); - for (GraphQlTagsContributor contributor : this.contributors) { - tags = tags.and(contributor.getDataFetchingTags(dataFetcher, parameters, exception)); - } - return tags; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlMetricsInstrumentation.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlMetricsInstrumentation.java deleted file mode 100644 index 893cc2622b..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlMetricsInstrumentation.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.actuate.metrics.graphql; - -import java.util.concurrent.CompletionStage; -import java.util.concurrent.atomic.AtomicLong; - -import graphql.ExecutionResult; -import graphql.execution.instrumentation.InstrumentationContext; -import graphql.execution.instrumentation.InstrumentationState; -import graphql.execution.instrumentation.SimpleInstrumentation; -import graphql.execution.instrumentation.SimpleInstrumentationContext; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.schema.DataFetcher; -import io.micrometer.core.instrument.DistributionSummary; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.Timer; - -import org.springframework.boot.actuate.metrics.AutoTimer; -import org.springframework.lang.Nullable; - -public class GraphQlMetricsInstrumentation extends SimpleInstrumentation { - - private final MeterRegistry registry; - - private final GraphQlTagsProvider tagsProvider; - - private final AutoTimer autoTimer; - - private final DistributionSummary dataFetchingSummary; - - public GraphQlMetricsInstrumentation(MeterRegistry registry, GraphQlTagsProvider tagsProvider, - AutoTimer autoTimer) { - this.registry = registry; - this.tagsProvider = tagsProvider; - this.autoTimer = autoTimer; - this.dataFetchingSummary = DistributionSummary.builder("graphql.request.datafetch.count").baseUnit("calls") - .description("Count of DataFetcher calls per request.").register(this.registry); - } - - @Override - public InstrumentationState createState() { - return new RequestMetricsInstrumentationState(this.autoTimer, this.registry); - } - - @Override - public InstrumentationContext beginExecution(InstrumentationExecutionParameters parameters) { - if (this.autoTimer.isEnabled()) { - RequestMetricsInstrumentationState state = parameters.getInstrumentationState(); - state.startTimer(); - return new SimpleInstrumentationContext() { - @Override - public void onCompleted(ExecutionResult result, Throwable exc) { - Iterable tags = GraphQlMetricsInstrumentation.this.tagsProvider.getExecutionTags(parameters, - result, exc); - state.tags(tags).stopTimer(); - if (!result.getErrors().isEmpty()) { - result.getErrors() - .forEach((error) -> GraphQlMetricsInstrumentation.this.registry.counter("graphql.error", - GraphQlMetricsInstrumentation.this.tagsProvider.getErrorTags(parameters, error)) - .increment()); - } - GraphQlMetricsInstrumentation.this.dataFetchingSummary.record(state.getDataFetchingCount()); - } - }; - } - return super.beginExecution(parameters); - } - - @Override - public DataFetcher instrumentDataFetcher(DataFetcher dataFetcher, - InstrumentationFieldFetchParameters parameters) { - if (this.autoTimer.isEnabled() && !parameters.isTrivialDataFetcher()) { - return (environment) -> { - Timer.Sample sample = Timer.start(this.registry); - try { - Object value = dataFetcher.get(environment); - if (value instanceof CompletionStage) { - CompletionStage completion = (CompletionStage) value; - return completion.whenComplete( - (result, error) -> recordDataFetcherMetric(sample, dataFetcher, parameters, error)); - } - else { - recordDataFetcherMetric(sample, dataFetcher, parameters, null); - return value; - } - } - catch (Throwable throwable) { - recordDataFetcherMetric(sample, dataFetcher, parameters, throwable); - throw throwable; - } - }; - } - return super.instrumentDataFetcher(dataFetcher, parameters); - } - - private void recordDataFetcherMetric(Timer.Sample sample, DataFetcher dataFetcher, - InstrumentationFieldFetchParameters parameters, @Nullable Throwable throwable) { - Timer.Builder timer = this.autoTimer.builder("graphql.datafetcher"); - timer.tags(this.tagsProvider.getDataFetchingTags(dataFetcher, parameters, throwable)); - sample.stop(timer.register(this.registry)); - RequestMetricsInstrumentationState state = parameters.getInstrumentationState(); - state.incrementDataFetchingCount(); - } - - static class RequestMetricsInstrumentationState implements InstrumentationState { - - private final MeterRegistry registry; - - private final Timer.Builder timer; - - private Timer.Sample sample; - - private AtomicLong dataFetchingCount = new AtomicLong(0L); - - RequestMetricsInstrumentationState(AutoTimer autoTimer, MeterRegistry registry) { - this.timer = autoTimer.builder("graphql.request"); - this.registry = registry; - } - - RequestMetricsInstrumentationState tags(Iterable tags) { - this.timer.tags(tags); - return this; - } - - void startTimer() { - this.sample = Timer.start(this.registry); - } - - void stopTimer() { - this.sample.stop(this.timer.register(this.registry)); - } - - void incrementDataFetchingCount() { - this.dataFetchingCount.incrementAndGet(); - } - - long getDataFetchingCount() { - return this.dataFetchingCount.get(); - } - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTags.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTags.java deleted file mode 100644 index ded7572502..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTags.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.actuate.metrics.graphql; - -import java.util.List; - -import graphql.ErrorClassification; -import graphql.ErrorType; -import graphql.ExecutionResult; -import graphql.GraphQLError; -import graphql.execution.ExecutionStepInfo; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.schema.GraphQLObjectType; -import io.micrometer.core.instrument.Tag; - -import org.springframework.lang.Nullable; -import org.springframework.util.CollectionUtils; - -/** - * Factory methods for Tags associated with a GraphQL request. - * - * @author Brian Clozel - * @since 1.0.0 - */ -public final class GraphQlTags { - - private static final Tag OUTCOME_SUCCESS = Tag.of("outcome", "SUCCESS"); - - private static final Tag OUTCOME_ERROR = Tag.of("outcome", "ERROR"); - - private static final Tag UNKNOWN_ERRORTYPE = Tag.of("errorType", "UNKNOWN"); - - private GraphQlTags() { - - } - - public static Tag executionOutcome(ExecutionResult result, @Nullable Throwable exception) { - if (exception == null && result.getErrors().isEmpty()) { - return OUTCOME_SUCCESS; - } - else { - return OUTCOME_ERROR; - } - } - - public static Tag errorType(GraphQLError error) { - ErrorClassification errorType = error.getErrorType(); - if (errorType instanceof ErrorType) { - return Tag.of("errorType", ((ErrorType) errorType).name()); - } - return UNKNOWN_ERRORTYPE; - } - - public static Tag errorPath(GraphQLError error) { - StringBuilder builder = new StringBuilder(); - List pathSegments = error.getPath(); - if (!CollectionUtils.isEmpty(pathSegments)) { - builder.append('$'); - for (Object segment : pathSegments) { - try { - int index = Integer.parseUnsignedInt(segment.toString()); - builder.append("[*]"); - } - catch (NumberFormatException exc) { - builder.append('.'); - builder.append(segment); - } - } - } - return Tag.of("errorPath", builder.toString()); - } - - public static Tag dataFetchingOutcome(@Nullable Throwable exception) { - return (exception != null) ? OUTCOME_ERROR : OUTCOME_SUCCESS; - } - - public static Tag dataFetchingPath(InstrumentationFieldFetchParameters parameters) { - ExecutionStepInfo executionStepInfo = parameters.getExecutionStepInfo(); - StringBuilder dataFetchingType = new StringBuilder(); - if (executionStepInfo.hasParent() && executionStepInfo.getParent().getType() instanceof GraphQLObjectType) { - dataFetchingType.append(((GraphQLObjectType) executionStepInfo.getParent().getType()).getName()); - dataFetchingType.append('.'); - } - dataFetchingType.append(executionStepInfo.getPath().getSegmentName()); - return Tag.of("path", dataFetchingType.toString()); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTagsContributor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTagsContributor.java deleted file mode 100644 index 99806736d8..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTagsContributor.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.actuate.metrics.graphql; - -import graphql.ExecutionResult; -import graphql.GraphQLError; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.schema.DataFetcher; -import io.micrometer.core.instrument.Tag; - -import org.springframework.lang.Nullable; - -/** - * A contributor of {@link Tag Tags} for Spring GraphQL-based request handling. Typically, - * used by a {@link GraphQlTagsProvider} to provide tags in addition to its defaults. - * - * @author Brian Clozel - * @since 2.7.0 - */ -public interface GraphQlTagsContributor { - - Iterable getExecutionTags(InstrumentationExecutionParameters parameters, ExecutionResult result, - @Nullable Throwable exception); - - Iterable getErrorTags(InstrumentationExecutionParameters parameters, GraphQLError error); - - Iterable getDataFetchingTags(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, - @Nullable Throwable exception); - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTagsProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTagsProvider.java deleted file mode 100644 index 13ba9555b6..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTagsProvider.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.actuate.metrics.graphql; - -import graphql.ExecutionResult; -import graphql.GraphQLError; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.schema.DataFetcher; -import io.micrometer.core.instrument.Tag; - -import org.springframework.lang.Nullable; - -/** - * Provides {@link Tag Tags} for Spring GraphQL-based request handling. - * - * @author Brian Clozel - * @since 2.7.0 - */ -public interface GraphQlTagsProvider { - - Iterable getExecutionTags(InstrumentationExecutionParameters parameters, ExecutionResult result, - @Nullable Throwable exception); - - Iterable getErrorTags(InstrumentationExecutionParameters parameters, GraphQLError error); - - Iterable getDataFetchingTags(DataFetcher dataFetcher, InstrumentationFieldFetchParameters parameters, - @Nullable Throwable exception); - -} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/package-info.java deleted file mode 100644 index 03a0361170..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/graphql/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-2021 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. - */ - -/** - * Provides instrumentation support for Spring GraphQL. - */ -package org.springframework.boot.actuate.metrics.graphql; diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/graphql/GraphQlMetricsInstrumentationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/graphql/GraphQlMetricsInstrumentationTests.java deleted file mode 100644 index 7d5f6e63e3..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/graphql/GraphQlMetricsInstrumentationTests.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.actuate.metrics.graphql; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; - -import graphql.ExecutionInput; -import graphql.ExecutionResult; -import graphql.ExecutionResultImpl; -import graphql.execution.instrumentation.InstrumentationContext; -import graphql.execution.instrumentation.InstrumentationState; -import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters; -import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters; -import graphql.schema.DataFetcher; -import graphql.schema.DataFetchingEnvironment; -import graphql.schema.DataFetchingEnvironmentImpl; -import graphql.schema.GraphQLSchema; -import graphql.schema.idl.SchemaGenerator; -import io.micrometer.core.instrument.DistributionSummary; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.MockClock; -import io.micrometer.core.instrument.Timer; -import io.micrometer.core.instrument.simple.SimpleConfig; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.metrics.AutoTimer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link GraphQlMetricsInstrumentation}. - * - * @author Brian Clozel - */ -class GraphQlMetricsInstrumentationTests { - - private final ExecutionInput input = ExecutionInput.newExecutionInput("{greeting}").build(); - - private final GraphQLSchema schema = SchemaGenerator.createdMockedSchema("type Query { greeting: String }"); - - private MeterRegistry registry; - - private GraphQlMetricsInstrumentation instrumentation; - - private InstrumentationState state; - - private InstrumentationExecutionParameters parameters; - - @BeforeEach - void setup() { - this.registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock()); - this.instrumentation = new GraphQlMetricsInstrumentation(this.registry, mock(GraphQlTagsProvider.class), - AutoTimer.ENABLED); - this.state = this.instrumentation.createState(); - this.parameters = new InstrumentationExecutionParameters(this.input, this.schema, this.state); - } - - @Test - void shouldRecordTimerWhenResult() { - InstrumentationContext execution = this.instrumentation.beginExecution(this.parameters); - ExecutionResult result = new ExecutionResultImpl("Hello", null); - execution.onCompleted(result, null); - - Timer timer = this.registry.find("graphql.request").timer(); - assertThat(timer).isNotNull(); - assertThat(timer.takeSnapshot().count()).isEqualTo(1); - } - - @Test - void shouldRecordDataFetchingCount() throws Exception { - InstrumentationContext execution = this.instrumentation.beginExecution(this.parameters); - ExecutionResult result = new ExecutionResultImpl("Hello", null); - - DataFetcher dataFetcher = mock(DataFetcher.class); - given(dataFetcher.get(any())).willReturn("Hello"); - InstrumentationFieldFetchParameters fieldFetchParameters = mockFieldFetchParameters(false); - - DataFetcher instrumented = this.instrumentation.instrumentDataFetcher(dataFetcher, fieldFetchParameters); - DataFetchingEnvironment environment = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().build(); - instrumented.get(environment); - - execution.onCompleted(result, null); - - DistributionSummary summary = this.registry.find("graphql.request.datafetch.count").summary(); - assertThat(summary).isNotNull(); - assertThat(summary.count()).isEqualTo(1); - } - - @Test - void shouldRecordDataFetchingMetricWhenSuccess() throws Exception { - DataFetcher dataFetcher = mock(DataFetcher.class); - given(dataFetcher.get(any())).willReturn("Hello"); - InstrumentationFieldFetchParameters fieldFetchParameters = mockFieldFetchParameters(false); - - DataFetcher instrumented = this.instrumentation.instrumentDataFetcher(dataFetcher, fieldFetchParameters); - DataFetchingEnvironment environment = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().build(); - instrumented.get(environment); - - Timer timer = this.registry.find("graphql.datafetcher").timer(); - assertThat(timer).isNotNull(); - assertThat(timer.takeSnapshot().count()).isEqualTo(1); - } - - @Test - void shouldRecordDataFetchingMetricWhenSuccessCompletionStage() throws Exception { - DataFetcher> dataFetcher = mock(DataFetcher.class); - given(dataFetcher.get(any())).willReturn(CompletableFuture.completedFuture("Hello")); - InstrumentationFieldFetchParameters fieldFetchParameters = mockFieldFetchParameters(false); - - DataFetcher instrumented = this.instrumentation.instrumentDataFetcher(dataFetcher, fieldFetchParameters); - DataFetchingEnvironment environment = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().build(); - instrumented.get(environment); - - Timer timer = this.registry.find("graphql.datafetcher").timer(); - assertThat(timer).isNotNull(); - assertThat(timer.takeSnapshot().count()).isEqualTo(1); - } - - @Test - void shouldRecordDataFetchingMetricWhenError() throws Exception { - DataFetcher> dataFetcher = mock(DataFetcher.class); - given(dataFetcher.get(any())).willThrow(new IllegalStateException("test")); - InstrumentationFieldFetchParameters fieldFetchParameters = mockFieldFetchParameters(false); - - DataFetcher instrumented = this.instrumentation.instrumentDataFetcher(dataFetcher, fieldFetchParameters); - DataFetchingEnvironment environment = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().build(); - assertThatThrownBy(() -> instrumented.get(environment)).isInstanceOf(IllegalStateException.class); - - Timer timer = this.registry.find("graphql.datafetcher").timer(); - assertThat(timer).isNotNull(); - assertThat(timer.takeSnapshot().count()).isEqualTo(1); - } - - @Test - void shouldNotRecordDataFetchingMetricWhenTrivial() throws Exception { - DataFetcher dataFetcher = mock(DataFetcher.class); - given(dataFetcher.get(any())).willReturn("Hello"); - InstrumentationFieldFetchParameters fieldFetchParameters = mockFieldFetchParameters(true); - - DataFetcher instrumented = this.instrumentation.instrumentDataFetcher(dataFetcher, fieldFetchParameters); - DataFetchingEnvironment environment = DataFetchingEnvironmentImpl.newDataFetchingEnvironment().build(); - instrumented.get(environment); - - Timer timer = this.registry.find("graphql.datafetcher").timer(); - assertThat(timer).isNull(); - } - - private InstrumentationFieldFetchParameters mockFieldFetchParameters(boolean isTrivial) { - InstrumentationFieldFetchParameters fieldFetchParameters = mock(InstrumentationFieldFetchParameters.class); - given(fieldFetchParameters.isTrivialDataFetcher()).willReturn(isTrivial); - given(fieldFetchParameters.getInstrumentationState()).willReturn(this.state); - return fieldFetchParameters; - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTagsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTagsTests.java deleted file mode 100644 index 84f1283e38..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/graphql/GraphQlTagsTests.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.actuate.metrics.graphql; - -import java.util.Arrays; - -import graphql.ErrorType; -import graphql.ExecutionResult; -import graphql.ExecutionResultImpl; -import graphql.GraphQLError; -import graphql.GraphqlErrorBuilder; -import io.micrometer.core.instrument.Tag; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link GraphQlTags}. - * - * @author Brian Clozel - */ -class GraphQlTagsTests { - - @Test - void executionOutcomeShouldSucceed() { - ExecutionResult result = ExecutionResultImpl.newExecutionResult().build(); - Tag outcomeTag = GraphQlTags.executionOutcome(result, null); - assertThat(outcomeTag.getValue()).isEqualTo("SUCCESS"); - } - - @Test - void executionOutcomeShouldErrorWhenExceptionThrown() { - ExecutionResult result = ExecutionResultImpl.newExecutionResult().build(); - Tag tag = GraphQlTags.executionOutcome(result, new IllegalArgumentException("test error")); - assertThat(tag.getValue()).isEqualTo("ERROR"); - } - - @Test - void executionOutcomeShouldErrorWhenResponseErrors() { - GraphQLError error = GraphqlErrorBuilder.newError().message("Invalid query").build(); - Tag tag = GraphQlTags.executionOutcome(ExecutionResultImpl.newExecutionResult().addError(error).build(), null); - assertThat(tag.getValue()).isEqualTo("ERROR"); - } - - @Test - void errorTypeShouldBeDefinedIfPresent() { - GraphQLError error = GraphqlErrorBuilder.newError().errorType(ErrorType.DataFetchingException) - .message("test error").build(); - Tag errorTypeTag = GraphQlTags.errorType(error); - assertThat(errorTypeTag.getValue()).isEqualTo("DataFetchingException"); - } - - @Test - void errorPathShouldUseJsonPathFormat() { - GraphQLError error = GraphqlErrorBuilder.newError().path(Arrays.asList("project", "name")).message("test error") - .build(); - Tag errorPathTag = GraphQlTags.errorPath(error); - assertThat(errorPathTag.getValue()).isEqualTo("$.project.name"); - } - - @Test - void errorPathShouldUseJsonPathFormatForIndices() { - GraphQLError error = GraphqlErrorBuilder.newError().path(Arrays.asList("issues", "42", "title")) - .message("test error").build(); - Tag errorPathTag = GraphQlTags.errorPath(error); - assertThat(errorPathTag.getValue()).isEqualTo("$.issues[*].title"); - } - - @Test - void dataFetchingOutcomeShouldBeSuccessfulIfNoException() { - Tag fetchingOutcomeTag = GraphQlTags.dataFetchingOutcome(null); - assertThat(fetchingOutcomeTag.getValue()).isEqualTo("SUCCESS"); - } - - @Test - void dataFetchingOutcomeShouldBeErrorIfException() { - Tag fetchingOutcomeTag = GraphQlTags.dataFetchingOutcome(new IllegalStateException("error state")); - assertThat(fetchingOutcomeTag.getValue()).isEqualTo("ERROR"); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index 9fc02cd0cf..5bc1a394d3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -137,7 +137,6 @@ dependencies { optional("org.springframework.data:spring-data-neo4j") optional("org.springframework.data:spring-data-r2dbc") optional("org.springframework.data:spring-data-redis") - optional("org.springframework.graphql:spring-graphql") optional("org.springframework.hateoas:spring-hateoas") optional("org.springframework.security:spring-security-acl") optional("org.springframework.security:spring-security-config") @@ -174,7 +173,6 @@ dependencies { testImplementation("com.github.h-thurow:simple-jndi") testImplementation("com.ibm.db2:jcc") testImplementation("com.jayway.jsonpath:json-path") - testImplementation("com.querydsl:querydsl-core") testImplementation("com.squareup.okhttp3:mockwebserver") testImplementation("com.sun.xml.messaging.saaj:saaj-impl") testImplementation("io.projectreactor:reactor-test") @@ -193,7 +191,6 @@ dependencies { testImplementation("org.mockito:mockito-core") testImplementation("org.mockito:mockito-junit-jupiter") testImplementation("org.springframework:spring-test") - testImplementation("org.springframework.graphql:spring-graphql-test") testImplementation("org.springframework.kafka:spring-kafka-test") testImplementation("org.springframework.security:spring-security-test") testImplementation("org.testcontainers:cassandra") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java deleted file mode 100644 index 6b2327d2d0..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfiguration.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import graphql.GraphQL; -import graphql.execution.instrumentation.Instrumentation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.Resource; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.format.support.DefaultFormattingConversionService; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.data.method.annotation.support.AnnotatedControllerConfigurer; -import org.springframework.graphql.execution.BatchLoaderRegistry; -import org.springframework.graphql.execution.DataFetcherExceptionResolver; -import org.springframework.graphql.execution.DefaultBatchLoaderRegistry; -import org.springframework.graphql.execution.ExecutionGraphQlService; -import org.springframework.graphql.execution.GraphQlSource; -import org.springframework.graphql.execution.MissingSchemaException; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for creating a Spring GraphQL base - * infrastructure. - * - * @author Brian Clozel - * @since 2.7.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ GraphQL.class, GraphQlSource.class }) -@EnableConfigurationProperties(GraphQlProperties.class) -public class GraphQlAutoConfiguration { - - private static final Log logger = LogFactory.getLog(GraphQlAutoConfiguration.class); - - private final BatchLoaderRegistry batchLoaderRegistry = new DefaultBatchLoaderRegistry(); - - @Bean - @ConditionalOnMissingBean - public GraphQlSource graphQlSource(ResourcePatternResolver resourcePatternResolver, GraphQlProperties properties, - ObjectProvider exceptionResolversProvider, - ObjectProvider instrumentationsProvider, - ObjectProvider wiringConfigurers, - ObjectProvider sourceCustomizers) { - - List schemaResources = resolveSchemaResources(resourcePatternResolver, - properties.getSchema().getLocations(), properties.getSchema().getFileExtensions()); - GraphQlSource.Builder builder = GraphQlSource.builder() - .schemaResources(schemaResources.toArray(new Resource[0])) - .exceptionResolvers(exceptionResolversProvider.orderedStream().collect(Collectors.toList())) - .instrumentation(instrumentationsProvider.orderedStream().collect(Collectors.toList())); - wiringConfigurers.orderedStream().forEach(builder::configureRuntimeWiring); - sourceCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); - try { - return builder.build(); - } - catch (MissingSchemaException exc) { - throw new InvalidSchemaLocationsException(properties.getSchema().getLocations(), resourcePatternResolver, - exc); - } - } - - @Bean - @ConditionalOnMissingBean - public BatchLoaderRegistry batchLoaderRegistry() { - return this.batchLoaderRegistry; - } - - @Bean - @ConditionalOnMissingBean - public GraphQlService graphQlService(GraphQlSource graphQlSource) { - ExecutionGraphQlService service = new ExecutionGraphQlService(graphQlSource); - service.addDataLoaderRegistrar(this.batchLoaderRegistry); - return service; - } - - @Bean - @ConditionalOnMissingBean - public AnnotatedControllerConfigurer annotatedControllerConfigurer() { - AnnotatedControllerConfigurer annotatedControllerConfigurer = new AnnotatedControllerConfigurer(); - annotatedControllerConfigurer.setConversionService(new DefaultFormattingConversionService()); - return annotatedControllerConfigurer; - } - - private List resolveSchemaResources(ResourcePatternResolver resolver, String[] schemaLocations, - String[] fileExtensions) { - List schemaResources = new ArrayList<>(); - for (String location : schemaLocations) { - for (String extension : fileExtensions) { - String resourcePattern = location + "*" + extension; - try { - schemaResources.addAll(Arrays.asList(resolver.getResources(resourcePattern))); - } - catch (IOException ex) { - logger.debug("Could not resolve schema location: '" + resourcePattern + "'", ex); - } - } - } - return schemaResources; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlCorsProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlCorsProperties.java deleted file mode 100644 index 01021b3b06..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlCorsProperties.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import java.time.Duration; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.convert.DurationUnit; -import org.springframework.lang.Nullable; -import org.springframework.util.CollectionUtils; -import org.springframework.web.cors.CorsConfiguration; - -/** - * Configuration properties for GraphQL endpoint's CORS support. - * - * @author Andy Wilkinson - * @author Brian Clozel - * @since 2.7.0 - */ -@ConfigurationProperties(prefix = "spring.graphql.cors") -public class GraphQlCorsProperties { - - /** - * Comma-separated list of origins to allow with '*' allowing all origins. When - * allow-credentials is enabled, '*' cannot be used, and setting origin patterns - * should be considered instead. When neither allowed origins nor allowed origin - * patterns are set, cross-origin requests are effectively disabled. - */ - private List allowedOrigins = new ArrayList<>(); - - /** - * Comma-separated list of origin patterns to allow. Unlike allowed origins which only - * support '*', origin patterns are more flexible, e.g. 'https://*.example.com', and - * can be used with allow-credentials. When neither allowed origins nor allowed origin - * patterns are set, cross-origin requests are effectively disabled. - */ - private List allowedOriginPatterns = new ArrayList<>(); - - /** - * Comma-separated list of HTTP methods to allow. '*' allows all methods. When not - * set, defaults to GET. - */ - private List allowedMethods = new ArrayList<>(); - - /** - * Comma-separated list of HTTP headers to allow in a request. '*' allows all headers. - */ - private List allowedHeaders = new ArrayList<>(); - - /** - * Comma-separated list of headers to include in a response. - */ - private List exposedHeaders = new ArrayList<>(); - - /** - * Whether credentials are supported. When not set, credentials are not supported. - */ - @Nullable - private Boolean allowCredentials; - - /** - * How long the response from a pre-flight request can be cached by clients. If a - * duration suffix is not specified, seconds will be used. - */ - @DurationUnit(ChronoUnit.SECONDS) - private Duration maxAge = Duration.ofSeconds(1800); - - public List getAllowedOrigins() { - return this.allowedOrigins; - } - - public void setAllowedOrigins(List allowedOrigins) { - this.allowedOrigins = allowedOrigins; - } - - public List getAllowedOriginPatterns() { - return this.allowedOriginPatterns; - } - - public void setAllowedOriginPatterns(List allowedOriginPatterns) { - this.allowedOriginPatterns = allowedOriginPatterns; - } - - public List getAllowedMethods() { - return this.allowedMethods; - } - - public void setAllowedMethods(List allowedMethods) { - this.allowedMethods = allowedMethods; - } - - public List getAllowedHeaders() { - return this.allowedHeaders; - } - - public void setAllowedHeaders(List allowedHeaders) { - this.allowedHeaders = allowedHeaders; - } - - public List getExposedHeaders() { - return this.exposedHeaders; - } - - public void setExposedHeaders(List exposedHeaders) { - this.exposedHeaders = exposedHeaders; - } - - @Nullable - public Boolean getAllowCredentials() { - return this.allowCredentials; - } - - public void setAllowCredentials(Boolean allowCredentials) { - this.allowCredentials = allowCredentials; - } - - public Duration getMaxAge() { - return this.maxAge; - } - - public void setMaxAge(Duration maxAge) { - this.maxAge = maxAge; - } - - @Nullable - public CorsConfiguration toCorsConfiguration() { - if (CollectionUtils.isEmpty(this.allowedOrigins) && CollectionUtils.isEmpty(this.allowedOriginPatterns)) { - return null; - } - PropertyMapper map = PropertyMapper.get(); - CorsConfiguration config = new CorsConfiguration(); - map.from(this::getAllowedOrigins).to(config::setAllowedOrigins); - map.from(this::getAllowedOriginPatterns).to(config::setAllowedOriginPatterns); - map.from(this::getAllowedHeaders).whenNot(CollectionUtils::isEmpty).to(config::setAllowedHeaders); - map.from(this::getAllowedMethods).whenNot(CollectionUtils::isEmpty).to(config::setAllowedMethods); - map.from(this::getExposedHeaders).whenNot(CollectionUtils::isEmpty).to(config::setExposedHeaders); - map.from(this::getMaxAge).whenNonNull().as(Duration::getSeconds).to(config::setMaxAge); - map.from(this::getAllowCredentials).whenNonNull().to(config::setAllowCredentials); - return config; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlProperties.java deleted file mode 100644 index 3df070e745..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlProperties.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import java.time.Duration; -import java.util.Arrays; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * {@link ConfigurationProperties properties} for Spring GraphQL. - * - * @author Brian Clozel - * @since 2.7.0 - */ -@ConfigurationProperties(prefix = "spring.graphql") -public class GraphQlProperties { - - /** - * Path at which to expose a GraphQL request HTTP endpoint. - */ - private String path = "/graphql"; - - private final Graphiql graphiql = new Graphiql(); - - private final Schema schema = new Schema(); - - private final Websocket websocket = new Websocket(); - - public Graphiql getGraphiql() { - return this.graphiql; - } - - public String getPath() { - return this.path; - } - - public void setPath(String path) { - this.path = path; - } - - public Schema getSchema() { - return this.schema; - } - - public Websocket getWebsocket() { - return this.websocket; - } - - public static class Schema { - - /** - * Locations of GraphQL schema files. - */ - private String[] locations = new String[] { "classpath:graphql/**/" }; - - /** - * File extensions for GraphQL schema files. - */ - private String[] fileExtensions = new String[] { ".graphqls", ".gqls" }; - - private final Printer printer = new Printer(); - - public String[] getLocations() { - return this.locations; - } - - public void setLocations(String[] locations) { - this.locations = appendSlashIfNecessary(locations); - } - - public String[] getFileExtensions() { - return this.fileExtensions; - } - - public void setFileExtensions(String[] fileExtensions) { - this.fileExtensions = fileExtensions; - } - - private String[] appendSlashIfNecessary(String[] locations) { - return Arrays.stream(locations).map((location) -> location.endsWith("/") ? location : location + "/") - .toArray(String[]::new); - } - - public Printer getPrinter() { - return this.printer; - } - - public static class Printer { - - /** - * Whether the endpoint that prints the schema is enabled. Schema is available - * under spring.graphql.path + "/schema". - */ - private boolean enabled = false; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - } - - } - - public static class Graphiql { - - /** - * Path to the GraphiQL UI endpoint. - */ - private String path = "/graphiql"; - - /** - * Whether the default GraphiQL UI is enabled. - */ - private boolean enabled = false; - - public String getPath() { - return this.path; - } - - public void setPath(String path) { - this.path = path; - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - } - - public static class Websocket { - - /** - * Path of the GraphQL WebSocket subscription endpoint. - */ - private String path; - - /** - * Time within which the initial {@code CONNECTION_INIT} type message must be - * received. - */ - private Duration connectionInitTimeout = Duration.ofSeconds(60); - - public String getPath() { - return this.path; - } - - public void setPath(String path) { - this.path = path; - } - - public Duration getConnectionInitTimeout() { - return this.connectionInitTimeout; - } - - public void setConnectionInitTimeout(Duration connectionInitTimeout) { - this.connectionInitTimeout = connectionInitTimeout; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer.java deleted file mode 100644 index 5157d7a7f9..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/GraphQlSourceBuilderCustomizer.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import org.springframework.graphql.execution.GraphQlSource; - -/** - * Callback interface that can be implemented by beans wishing to customize properties of - * {@link org.springframework.graphql.execution.GraphQlSource.Builder} whilst retaining - * default auto-configuration. - * - * @author Rossen Stoyanchev - * @since 2.7.0 - */ -@FunctionalInterface -public interface GraphQlSourceBuilderCustomizer { - - /** - * Customize the {@link GraphQlSource.Builder} instance. - * @param builder builder the builder to customize - */ - void customize(GraphQlSource.Builder builder); - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsException.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsException.java deleted file mode 100644 index 71f15f9861..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsException.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.autoconfigure.graphql; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.springframework.core.NestedRuntimeException; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.util.Assert; - -/** - * {@link InvalidSchemaLocationsException} thrown when no schema file could be found in - * the provided locations. - * - * @author Brian Clozel - * @since 2.7.0 - */ -public class InvalidSchemaLocationsException extends NestedRuntimeException { - - private final List schemaLocations; - - public InvalidSchemaLocationsException(String[] locations, ResourcePatternResolver resolver) { - this(locations, resolver, null); - } - - public InvalidSchemaLocationsException(String[] locations, ResourcePatternResolver resolver, Throwable cause) { - super("No schema file could be found in the provided locations.", cause); - Assert.notEmpty(locations, "locations should not be empty"); - Assert.notNull(resolver, "resolver should not be null"); - List providedLocations = new ArrayList<>(); - for (String location : locations) { - try { - String uri = resolver.getResource(location).getURI().toASCIIString(); - providedLocations.add(new SchemaLocation(location, uri)); - } - catch (IOException ex) { - providedLocations.add(new SchemaLocation(location, "")); - } - } - this.schemaLocations = Collections.unmodifiableList(providedLocations); - } - - /** - * Return the list of provided locations where to look for schemas. - * @return the list of locations - */ - public List getSchemaLocations() { - return this.schemaLocations; - } - - /** - * The location where to look for schemas. - */ - public static class SchemaLocation { - - private final String location; - - private final String uri; - - SchemaLocation(String location, String uri) { - this.location = location; - this.uri = uri; - } - - /** - * Return the location String to be resolved by a {@link ResourcePatternResolver}. - * @return the location - */ - public String getLocation() { - return this.location; - } - - /** - * Return the resolved URI String for this location, an empty String if resolution - * failed. - * @return the resolved location or an empty String - */ - public String getUri() { - return this.uri; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsExceptionFailureAnalyzer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsExceptionFailureAnalyzer.java deleted file mode 100644 index 66b8aa34bf..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsExceptionFailureAnalyzer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; -import org.springframework.boot.diagnostics.FailureAnalysis; - -/** - * An implementation of {@link AbstractFailureAnalyzer} to analyze failures caused by - * {@link InvalidSchemaLocationsException}. - * - * @author Brian Clozel - */ -class InvalidSchemaLocationsExceptionFailureAnalyzer extends AbstractFailureAnalyzer { - - @Override - protected FailureAnalysis analyze(Throwable rootFailure, InvalidSchemaLocationsException cause) { - String message = "Could not find any GraphQL schema file under configured locations."; - StringBuilder action = new StringBuilder( - "Check that the following locations contain schema files: " + System.lineSeparator()); - for (InvalidSchemaLocationsException.SchemaLocation schemaLocation : cause.getSchemaLocations()) { - action.append(String.format("- '%s' (%s)" + System.lineSeparator(), schemaLocation.getUri(), - schemaLocation.getLocation())); - } - return new FailureAnalysis(message, action.toString(), cause); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfiguration.java deleted file mode 100644 index 504d4bf024..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfiguration.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2002-2021 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.boot.autoconfigure.graphql.data; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import graphql.GraphQL; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.repository.query.QueryByExampleExecutor; -import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor; -import org.springframework.graphql.data.query.QueryByExampleDataFetcher; -import org.springframework.graphql.execution.GraphQlSource; - -/** - * {@link EnableAutoConfiguration Auto-configuration} that creates a - * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories with Query - * By Example support and register them as {@code DataFetcher}s for any queries with a - * matching return type. - * - * @author Rossen Stoyanchev - * @since 2.7.0 - * @see QueryByExampleDataFetcher#autoRegistrationTypeVisitor(List, List) - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ GraphQL.class, QueryByExampleDataFetcher.class, QueryByExampleExecutor.class }) -@ConditionalOnBean(GraphQlSource.class) -@AutoConfigureAfter(GraphQlAutoConfiguration.class) -public class GraphQlQueryByExampleAutoConfiguration { - - @Bean - public GraphQlSourceBuilderCustomizer queryByExampleRegistrar( - ObjectProvider> executorsProvider, - ObjectProvider> reactiveExecutorsProvider) { - - return (builder) -> { - List> executors = executorsProvider.stream().collect(Collectors.toList()); - List> reactiveExecutors = reactiveExecutorsProvider.stream() - .collect(Collectors.toList()); - if (!executors.isEmpty()) { - builder.typeVisitors(Collections.singletonList( - QueryByExampleDataFetcher.autoRegistrationTypeVisitor(executors, reactiveExecutors))); - } - }; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfiguration.java deleted file mode 100644 index d10c0dcab0..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfiguration.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2002-2021 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.boot.autoconfigure.graphql.data; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import graphql.GraphQL; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.querydsl.QuerydslPredicateExecutor; -import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor; -import org.springframework.graphql.data.query.QuerydslDataFetcher; -import org.springframework.graphql.execution.GraphQlSource; - -/** - * {@link EnableAutoConfiguration Auto-configuration} that creates a - * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories with - * Querydsl support and register them as {@code DataFetcher}s for any queries with a - * matching return type. - * - * @author Rossen Stoyanchev - * @since 2.7.0 - * @see QuerydslDataFetcher#autoRegistrationTypeVisitor(List, List) - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ GraphQL.class, QuerydslDataFetcher.class, QuerydslPredicateExecutor.class }) -@ConditionalOnBean(GraphQlSource.class) -@AutoConfigureAfter(GraphQlAutoConfiguration.class) -public class GraphQlQuerydslAutoConfiguration { - - @Bean - public GraphQlSourceBuilderCustomizer querydslRegistrar( - ObjectProvider> executorsProvider, - ObjectProvider> reactiveExecutorsProvider) { - - return (builder) -> { - List> executors = executorsProvider.stream().collect(Collectors.toList()); - List> reactiveExecutors = reactiveExecutorsProvider.stream() - .collect(Collectors.toList()); - if (!executors.isEmpty()) { - builder.typeVisitors(Collections - .singletonList(QuerydslDataFetcher.autoRegistrationTypeVisitor(executors, reactiveExecutors))); - } - }; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfiguration.java deleted file mode 100644 index e36ec5ba03..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfiguration.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2002-2021 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.boot.autoconfigure.graphql.data; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import graphql.GraphQL; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor; -import org.springframework.graphql.data.query.QueryByExampleDataFetcher; -import org.springframework.graphql.execution.GraphQlSource; - -/** - * {@link EnableAutoConfiguration Auto-configuration} that creates a - * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories with Query - * By Example support and register them as {@code DataFetcher}s for any queries with a - * matching return type. - * - * @author Rossen Stoyanchev - * @since 2.7.0 - * @see QueryByExampleDataFetcher#autoRegistrationTypeVisitor(List, List) - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ GraphQL.class, QueryByExampleDataFetcher.class, ReactiveQueryByExampleExecutor.class }) -@ConditionalOnBean(GraphQlSource.class) -@AutoConfigureAfter(GraphQlAutoConfiguration.class) -public class GraphQlReactiveQueryByExampleAutoConfiguration { - - @Bean - public GraphQlSourceBuilderCustomizer reactiveQueryByExampleRegistrar( - ObjectProvider> executorsProvider) { - - return (builder) -> { - List> executors = executorsProvider.stream().collect(Collectors.toList()); - if (!executors.isEmpty()) { - builder.typeVisitors(Collections.singletonList( - QueryByExampleDataFetcher.autoRegistrationTypeVisitor(Collections.emptyList(), executors))); - } - }; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfiguration.java deleted file mode 100644 index 91b5689855..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfiguration.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2002-2021 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.boot.autoconfigure.graphql.data; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import graphql.GraphQL; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor; -import org.springframework.graphql.data.query.QuerydslDataFetcher; -import org.springframework.graphql.execution.GraphQlSource; - -/** - * {@link EnableAutoConfiguration Auto-configuration} that creates a - * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories with - * Querydsl support and register them as {@code DataFetcher}s for any queries with a - * matching return type. - * - * @author Rossen Stoyanchev - * @since 2.7.0 - * @see QuerydslDataFetcher#autoRegistrationTypeVisitor(List, List) - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ GraphQL.class, QuerydslDataFetcher.class, ReactiveQuerydslPredicateExecutor.class }) -@ConditionalOnBean(GraphQlSource.class) -@AutoConfigureAfter(GraphQlAutoConfiguration.class) -public class GraphQlReactiveQuerydslAutoConfiguration { - - @Bean - public GraphQlSourceBuilderCustomizer reactiveQuerydslRegistrar( - ObjectProvider> executorsProvider) { - - return (builder) -> { - List> executors = executorsProvider.stream() - .collect(Collectors.toList()); - if (!executors.isEmpty()) { - builder.typeVisitors(Collections.singletonList( - QuerydslDataFetcher.autoRegistrationTypeVisitor(Collections.emptyList(), executors))); - } - }; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/package-info.java deleted file mode 100644 index 0f1a57d4f4..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-2021 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. - */ - -/** - * Auto-configuration classes for data integrations with GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql.data; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/package-info.java deleted file mode 100644 index a44fbef233..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2021 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. - */ - -/** - * Auto-configuration for Spring GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java deleted file mode 100644 index b7f8136d7f..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfiguration.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql.reactive; - -import java.util.Collections; -import java.util.stream.Collectors; - -import graphql.GraphQL; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlCorsProperties; -import org.springframework.boot.autoconfigure.graphql.GraphQlProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.ResourceLoader; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.execution.GraphQlSource; -import org.springframework.graphql.web.WebGraphQlHandler; -import org.springframework.graphql.web.WebInterceptor; -import org.springframework.graphql.web.webflux.GraphQlHttpHandler; -import org.springframework.graphql.web.webflux.GraphQlWebSocketHandler; -import org.springframework.graphql.web.webflux.GraphiQlHandler; -import org.springframework.graphql.web.webflux.SchemaHandler; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.codec.ServerCodecConfigurer; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.reactive.HandlerMapping; -import org.springframework.web.reactive.config.CorsRegistry; -import org.springframework.web.reactive.config.WebFluxConfigurer; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; -import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; -import org.springframework.web.reactive.socket.server.support.WebSocketUpgradeHandlerPredicate; - -import static org.springframework.web.reactive.function.server.RequestPredicates.accept; -import static org.springframework.web.reactive.function.server.RequestPredicates.contentType; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for enabling Spring GraphQL over - * WebFlux. - * - * @author Brian Clozel - * @since 2.7.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@ConditionalOnClass({ GraphQL.class, GraphQlHttpHandler.class }) -@ConditionalOnBean(GraphQlService.class) -@AutoConfigureAfter(GraphQlAutoConfiguration.class) -@EnableConfigurationProperties(GraphQlCorsProperties.class) -public class GraphQlWebFluxAutoConfiguration { - - private static final Log logger = LogFactory.getLog(GraphQlWebFluxAutoConfiguration.class); - - @Bean - @ConditionalOnMissingBean - public GraphQlHttpHandler graphQlHttpHandler(WebGraphQlHandler webGraphQlHandler) { - return new GraphQlHttpHandler(webGraphQlHandler); - } - - @Bean - @ConditionalOnMissingBean - public WebGraphQlHandler webGraphQlHandler(GraphQlService service, - ObjectProvider interceptorsProvider) { - return WebGraphQlHandler.builder(service) - .interceptors(interceptorsProvider.orderedStream().collect(Collectors.toList())).build(); - } - - @Bean - public RouterFunction graphQlEndpoint(GraphQlHttpHandler handler, GraphQlSource graphQlSource, - GraphQlProperties properties, ResourceLoader resourceLoader) { - - String graphQLPath = properties.getPath(); - if (logger.isInfoEnabled()) { - logger.info("GraphQL endpoint HTTP POST " + graphQLPath); - } - - RouterFunctions.Builder builder = RouterFunctions.route() - .GET(graphQLPath, - (request) -> ServerResponse.status(HttpStatus.METHOD_NOT_ALLOWED) - .headers((headers) -> headers.setAllow(Collections.singleton(HttpMethod.POST))).build()) - .POST(graphQLPath, accept(MediaType.APPLICATION_JSON).and(contentType(MediaType.APPLICATION_JSON)), - handler::handleRequest); - - if (properties.getGraphiql().isEnabled()) { - GraphiQlHandler graphiQlHandler = new GraphiQlHandler(graphQLPath); - builder = builder.GET(properties.getGraphiql().getPath(), graphiQlHandler::handleRequest); - } - - if (properties.getSchema().getPrinter().isEnabled()) { - SchemaHandler schemaHandler = new SchemaHandler(graphQlSource); - builder = builder.GET(graphQLPath + "/schema", schemaHandler::handleRequest); - } - - return builder.build(); - } - - @Configuration(proxyBeanMethods = false) - public static class GraphQlEndpointCorsConfiguration implements WebFluxConfigurer { - - final GraphQlProperties graphQlProperties; - - final GraphQlCorsProperties corsProperties; - - public GraphQlEndpointCorsConfiguration(GraphQlProperties graphQlProps, GraphQlCorsProperties corsProps) { - this.graphQlProperties = graphQlProps; - this.corsProperties = corsProps; - } - - @Override - public void addCorsMappings(CorsRegistry registry) { - CorsConfiguration configuration = this.corsProperties.toCorsConfiguration(); - if (configuration != null) { - registry.addMapping(this.graphQlProperties.getPath()).combine(configuration); - } - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnProperty(prefix = "spring.graphql.websocket", name = "path") - public static class WebSocketConfiguration { - - @Bean - @ConditionalOnMissingBean - public GraphQlWebSocketHandler graphQlWebSocketHandler(WebGraphQlHandler webGraphQlHandler, - GraphQlProperties properties, ServerCodecConfigurer configurer) { - return new GraphQlWebSocketHandler(webGraphQlHandler, configurer, - properties.getWebsocket().getConnectionInitTimeout()); - } - - @Bean - public HandlerMapping graphQlWebSocketEndpoint(GraphQlWebSocketHandler graphQlWebSocketHandler, - GraphQlProperties properties) { - String path = properties.getWebsocket().getPath(); - if (logger.isInfoEnabled()) { - logger.info("GraphQL endpoint WebSocket " + path); - } - SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); - mapping.setHandlerPredicate(new WebSocketUpgradeHandlerPredicate()); - mapping.setUrlMap(Collections.singletonMap(path, graphQlWebSocketHandler)); - mapping.setOrder(-2); // Ahead of HTTP endpoint ("routerFunctionMapping" bean) - return mapping; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/package-info.java deleted file mode 100644 index c0b8ec565e..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/reactive/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-2021 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. - */ - -/** - * Auto-configuration classes for WebFlux support in Spring GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql.reactive; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfiguration.java deleted file mode 100644 index 6773857e70..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.autoconfigure.graphql.security; - -import graphql.GraphQL; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.security.ReactiveSecurityDataFetcherExceptionResolver; -import org.springframework.graphql.web.webflux.GraphQlHttpHandler; -import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for enabling Security support for - * Spring GraphQL with WebFlux. - * - * @author Brian Clozel - * @since 2.7.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) -@ConditionalOnClass({ GraphQL.class, GraphQlHttpHandler.class, EnableWebFluxSecurity.class }) -@ConditionalOnBean(GraphQlHttpHandler.class) -@AutoConfigureAfter(GraphQlWebFluxAutoConfiguration.class) -public class GraphQlWebFluxSecurityAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public ReactiveSecurityDataFetcherExceptionResolver reactiveSecurityDataFetcherExceptionResolver() { - return new ReactiveSecurityDataFetcherExceptionResolver(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfiguration.java deleted file mode 100644 index bff7bfc7d8..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfiguration.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.autoconfigure.graphql.security; - -import graphql.GraphQL; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.security.SecurityContextThreadLocalAccessor; -import org.springframework.graphql.security.SecurityDataFetcherExceptionResolver; -import org.springframework.graphql.web.webmvc.GraphQlHttpHandler; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for enabling Security support for - * Spring GraphQL with MVC. - * - * @author Brian Clozel - * @since 2.7.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@ConditionalOnClass({ GraphQL.class, GraphQlHttpHandler.class, EnableWebSecurity.class }) -@ConditionalOnBean(GraphQlHttpHandler.class) -@AutoConfigureAfter(GraphQlWebMvcAutoConfiguration.class) -public class GraphQlWebMvcSecurityAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public SecurityDataFetcherExceptionResolver securityDataFetcherExceptionResolver() { - return new SecurityDataFetcherExceptionResolver(); - } - - @Bean - @ConditionalOnMissingBean - public SecurityContextThreadLocalAccessor securityContextThreadLocalAccessor() { - return new SecurityContextThreadLocalAccessor(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/package-info.java deleted file mode 100644 index 6d1c5e30bf..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/security/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-2021 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. - */ - -/** - * Auto-configuration classes for Security support in Spring GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql.security; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java deleted file mode 100644 index fd5a2210fe..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfiguration.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql.servlet; - -import java.util.Collections; -import java.util.Map; -import java.util.stream.Collectors; - -import javax.websocket.server.ServerContainer; - -import graphql.GraphQL; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlCorsProperties; -import org.springframework.boot.autoconfigure.graphql.GraphQlProperties; -import org.springframework.boot.autoconfigure.http.HttpMessageConverters; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.ResourceLoader; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.execution.GraphQlSource; -import org.springframework.graphql.execution.ThreadLocalAccessor; -import org.springframework.graphql.web.WebGraphQlHandler; -import org.springframework.graphql.web.WebInterceptor; -import org.springframework.graphql.web.webmvc.GraphQlHttpHandler; -import org.springframework.graphql.web.webmvc.GraphQlWebSocketHandler; -import org.springframework.graphql.web.webmvc.GraphiQlHandler; -import org.springframework.graphql.web.webmvc.SchemaHandler; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.converter.GenericHttpMessageConverter; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.servlet.HandlerMapping; -import org.springframework.web.servlet.config.annotation.CorsRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.function.RequestPredicates; -import org.springframework.web.servlet.function.RouterFunction; -import org.springframework.web.servlet.function.RouterFunctions; -import org.springframework.web.servlet.function.ServerResponse; -import org.springframework.web.socket.WebSocketHandler; -import org.springframework.web.socket.server.support.DefaultHandshakeHandler; -import org.springframework.web.socket.server.support.WebSocketHandlerMapping; -import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for enabling Spring GraphQL over - * Spring MVC. - * - * @author Brian Clozel - * @since 2.7.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@ConditionalOnClass({ GraphQL.class, GraphQlHttpHandler.class }) -@ConditionalOnBean(GraphQlService.class) -@AutoConfigureAfter(GraphQlAutoConfiguration.class) -@EnableConfigurationProperties(GraphQlCorsProperties.class) -public class GraphQlWebMvcAutoConfiguration { - - private static final Log logger = LogFactory.getLog(GraphQlWebMvcAutoConfiguration.class); - - @Bean - @ConditionalOnMissingBean - public GraphQlHttpHandler graphQlHttpHandler(WebGraphQlHandler webGraphQlHandler) { - return new GraphQlHttpHandler(webGraphQlHandler); - } - - @Bean - @ConditionalOnMissingBean - public WebGraphQlHandler webGraphQlHandler(GraphQlService service, - ObjectProvider interceptorsProvider, - ObjectProvider accessorsProvider) { - return WebGraphQlHandler.builder(service) - .interceptors(interceptorsProvider.orderedStream().collect(Collectors.toList())) - .threadLocalAccessors(accessorsProvider.orderedStream().collect(Collectors.toList())).build(); - } - - @Bean - public RouterFunction graphQlRouterFunction(GraphQlHttpHandler handler, GraphQlSource graphQlSource, - GraphQlProperties properties, ResourceLoader resourceLoader) { - - String graphQLPath = properties.getPath(); - if (logger.isInfoEnabled()) { - logger.info("GraphQL endpoint HTTP POST " + graphQLPath); - } - - RouterFunctions.Builder builder = RouterFunctions.route() - .GET(graphQLPath, - (request) -> ServerResponse.status(HttpStatus.METHOD_NOT_ALLOWED) - .headers((headers) -> headers.setAllow(Collections.singleton(HttpMethod.POST))).build()) - .POST(graphQLPath, RequestPredicates.contentType(MediaType.APPLICATION_JSON) - .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), handler::handleRequest); - - if (properties.getGraphiql().isEnabled()) { - GraphiQlHandler graphiQLHandler = new GraphiQlHandler(graphQLPath); - builder = builder.GET(properties.getGraphiql().getPath(), graphiQLHandler::handleRequest); - } - - if (properties.getSchema().getPrinter().isEnabled()) { - SchemaHandler schemaHandler = new SchemaHandler(graphQlSource); - builder = builder.GET(graphQLPath + "/schema", schemaHandler::handleRequest); - } - - return builder.build(); - } - - @Configuration(proxyBeanMethods = false) - public static class GraphQlEndpointCorsConfiguration implements WebMvcConfigurer { - - final GraphQlProperties graphQlProperties; - - final GraphQlCorsProperties corsProperties; - - public GraphQlEndpointCorsConfiguration(GraphQlProperties graphQlProps, GraphQlCorsProperties corsProps) { - this.graphQlProperties = graphQlProps; - this.corsProperties = corsProps; - } - - @Override - public void addCorsMappings(CorsRegistry registry) { - CorsConfiguration configuration = this.corsProperties.toCorsConfiguration(); - if (configuration != null) { - registry.addMapping(this.graphQlProperties.getPath()).combine(configuration); - } - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass({ ServerContainer.class, WebSocketHandler.class }) - @ConditionalOnProperty(prefix = "spring.graphql.websocket", name = "path") - public static class WebSocketConfiguration { - - @Bean - @ConditionalOnMissingBean - public GraphQlWebSocketHandler graphQlWebSocketHandler(WebGraphQlHandler webGraphQlHandler, - GraphQlProperties properties, HttpMessageConverters converters) { - - return new GraphQlWebSocketHandler(webGraphQlHandler, getJsonConverter(converters), - properties.getWebsocket().getConnectionInitTimeout()); - } - - @SuppressWarnings("unchecked") - private static GenericHttpMessageConverter getJsonConverter(HttpMessageConverters converters) { - return converters.getConverters().stream() - .filter((candidate) -> candidate.canRead(Map.class, MediaType.APPLICATION_JSON)).findFirst() - .map((converter) -> (GenericHttpMessageConverter) converter) - .orElseThrow(() -> new IllegalStateException("No JSON converter")); - } - - @Bean - public HandlerMapping graphQlWebSocketMapping(GraphQlWebSocketHandler handler, GraphQlProperties properties) { - String path = properties.getWebsocket().getPath(); - if (logger.isInfoEnabled()) { - logger.info("GraphQL endpoint WebSocket " + path); - } - WebSocketHandlerMapping mapping = new WebSocketHandlerMapping(); - mapping.setWebSocketUpgradeMatch(true); - mapping.setUrlMap(Collections.singletonMap(path, - new WebSocketHttpRequestHandler(handler, new DefaultHandshakeHandler()))); - mapping.setOrder(2); // Ahead of HTTP endpoint ("routerFunctionMapping" bean) - return mapping; - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/package-info.java deleted file mode 100644 index 04cf403792..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/servlet/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-2021 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. - */ - -/** - * Auto-configuration classes for MVC support in Spring GraphQL. - */ -package org.springframework.boot.autoconfigure.graphql.servlet; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 29997c9174..c5808c2860 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -951,14 +951,6 @@ "level": "error" } }, - { - "name": "spring.graphql.schema.locations", - "defaultValue": "classpath:graphql/**/" - }, - { - "name": "spring.graphql.schema.file-extensions", - "defaultValue": ".graphqls,.gqls" - }, { "name": "spring.groovy.template.prefix", "defaultValue": "" @@ -2198,45 +2190,6 @@ } ] }, - { - "name": "spring.graphql.cors.allowed-headers", - "values": [ - { - "value": "*" - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.graphql.cors.allowed-methods", - "values": [ - { - "value": "*" - } - ], - "providers": [ - { - "name": "any" - } - ] - }, - { - "name": "spring.graphql.cors.allowed-origins", - "values": [ - { - "value": "*" - } - ], - "providers": [ - { - "name": "any" - } - ] - }, { "name": "spring.jmx.server", "providers": [ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index f4479e3c06..9bd2faba0d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -64,15 +64,6 @@ org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\ org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQueryByExampleAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQuerydslAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.data.GraphQlQueryByExampleAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.data.GraphQlQuerydslAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.security.GraphQlWebFluxSecurityAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.security.GraphQlWebMvcSecurityAutoConfiguration,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\ org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\ @@ -161,7 +152,6 @@ org.springframework.boot.diagnostics.FailureAnalyzer=\ org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\ org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\ org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\ -org.springframework.boot.autoconfigure.graphql.InvalidSchemaLocationsExceptionFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\ org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\ org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java deleted file mode 100644 index 0dbea1be83..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import org.springframework.data.annotation.Id; - -/** - * Sample class for - * - * @author Brian Clozel - */ -public class Book { - - @Id - String id; - - String name; - - int pageCount; - - String author; - - public Book() { - } - - public Book(String id, String name, int pageCount, String author) { - this.id = id; - this.name = name; - this.pageCount = pageCount; - this.author = author; - } - - public String getId() { - return this.id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public int getPageCount() { - return this.pageCount; - } - - public void setPageCount(int pageCount) { - this.pageCount = pageCount; - } - - public String getAuthor() { - return this.author; - } - - public void setAuthor(String author) { - this.author = author; - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java deleted file mode 100644 index 5f1f388f9a..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlAutoConfigurationTests.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import graphql.GraphQL; -import graphql.execution.instrumentation.ChainedInstrumentation; -import graphql.execution.instrumentation.Instrumentation; -import graphql.schema.GraphQLSchema; -import graphql.schema.idl.RuntimeWiring; -import org.assertj.core.api.InstanceOfAssertFactories; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.ClassPathResource; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.data.method.annotation.support.AnnotatedControllerConfigurer; -import org.springframework.graphql.execution.BatchLoaderRegistry; -import org.springframework.graphql.execution.DataFetcherExceptionResolver; -import org.springframework.graphql.execution.GraphQlSource; -import org.springframework.graphql.execution.MissingSchemaException; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link GraphQlAutoConfiguration}. - */ -class GraphQlAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(GraphQlAutoConfiguration.class)); - - @Test - void shouldContributeDefaultBeans() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(GraphQlSource.class); - assertThat(context).hasSingleBean(BatchLoaderRegistry.class); - assertThat(context).hasSingleBean(GraphQlService.class); - assertThat(context).hasSingleBean(AnnotatedControllerConfigurer.class); - }); - } - - @Test - void schemaShouldScanNestedFolders() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(GraphQlSource.class); - GraphQlSource graphQlSource = context.getBean(GraphQlSource.class); - GraphQLSchema schema = graphQlSource.schema(); - assertThat(schema.getObjectType("Book")).isNotNull(); - }); - } - - @Test - void shouldFailWhenSchemaFileIsMissing() { - this.contextRunner.withPropertyValues("spring.graphql.schema.locations:classpath:missing/").run((context) -> { - assertThat(context).hasFailed(); - assertThat(context).getFailure().getRootCause().isInstanceOf(MissingSchemaException.class); - }); - } - - @Test - void shouldUseProgrammaticallyDefinedBuilder() { - this.contextRunner.withUserConfiguration(CustomGraphQlBuilderConfiguration.class).run((context) -> { - assertThat(context).hasBean("customGraphQlSourceBuilder"); - assertThat(context).hasSingleBean(GraphQlSource.Builder.class); - }); - } - - @Test - void shouldScanLocationsWithCustomExtension() { - this.contextRunner.withPropertyValues("spring.graphql.schema.file-extensions:.graphqls,.custom") - .run((context) -> { - assertThat(context).hasSingleBean(GraphQlSource.class); - GraphQlSource graphQlSource = context.getBean(GraphQlSource.class); - GraphQLSchema schema = graphQlSource.schema(); - assertThat(schema.getObjectType("Book")).isNotNull(); - assertThat(schema.getObjectType("Person")).isNotNull(); - }); - } - - @Test - void shouldBackOffWithCustomGraphQlSource() { - this.contextRunner.withUserConfiguration(CustomGraphQlSourceConfiguration.class).run((context) -> { - assertThat(context).getBeanNames(GraphQlSource.class).containsOnly("customGraphQlSource"); - assertThat(context).hasSingleBean(GraphQlProperties.class); - }); - } - - @Test - void shouldConfigureDataFetcherExceptionResolvers() { - this.contextRunner.withUserConfiguration(DataFetcherExceptionResolverConfiguration.class).run((context) -> { - GraphQlSource graphQlSource = context.getBean(GraphQlSource.class); - GraphQL graphQL = graphQlSource.graphQl(); - assertThat(graphQL.getQueryStrategy()).extracting("dataFetcherExceptionHandler") - .satisfies((exceptionHandler) -> assertThat(exceptionHandler.getClass().getName()) - .endsWith("ExceptionResolversExceptionHandler")); - }); - } - - @Test - void shouldConfigureInstrumentation() { - this.contextRunner.withUserConfiguration(InstrumentationConfiguration.class).run((context) -> { - GraphQlSource graphQlSource = context.getBean(GraphQlSource.class); - Instrumentation customInstrumentation = context.getBean("customInstrumentation", Instrumentation.class); - GraphQL graphQL = graphQlSource.graphQl(); - assertThat(graphQL).extracting("instrumentation").isInstanceOf(ChainedInstrumentation.class) - .extracting("instrumentations", InstanceOfAssertFactories.iterable(Instrumentation.class)) - .contains(customInstrumentation); - }); - } - - @Test - void shouldApplyRuntimeWiringConfigurers() { - this.contextRunner.withUserConfiguration(RuntimeWiringConfigurerConfiguration.class).run((context) -> { - RuntimeWiringConfigurerConfiguration.CustomRuntimeWiringConfigurer configurer = context - .getBean(RuntimeWiringConfigurerConfiguration.CustomRuntimeWiringConfigurer.class); - assertThat(configurer.applied).isTrue(); - }); - } - - @Test - void shouldApplyGraphQlSourceBuilderCustomizer() { - this.contextRunner.withUserConfiguration(GraphQlSourceBuilderCustomizerConfiguration.class).run((context) -> { - GraphQlSourceBuilderCustomizerConfiguration.CustomGraphQlSourceBuilderCustomizer customizer = context - .getBean(GraphQlSourceBuilderCustomizerConfiguration.CustomGraphQlSourceBuilderCustomizer.class); - assertThat(customizer.applied).isTrue(); - }); - } - - @Configuration(proxyBeanMethods = false) - static class CustomGraphQlBuilderConfiguration { - - @Bean - GraphQlSource.Builder customGraphQlSourceBuilder() { - return GraphQlSource.builder().schemaResources(new ClassPathResource("graphql/schema.graphqls"), - new ClassPathResource("graphql/types/book.graphqls")); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomGraphQlSourceConfiguration { - - @Bean - GraphQlSource customGraphQlSource() { - return mock(GraphQlSource.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class DataFetcherExceptionResolverConfiguration { - - @Bean - DataFetcherExceptionResolver customDataFetcherExceptionResolver() { - return mock(DataFetcherExceptionResolver.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class InstrumentationConfiguration { - - @Bean - Instrumentation customInstrumentation() { - return mock(Instrumentation.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class RuntimeWiringConfigurerConfiguration { - - @Bean - CustomRuntimeWiringConfigurer customRuntimeWiringConfigurer() { - return new CustomRuntimeWiringConfigurer(); - } - - public static class CustomRuntimeWiringConfigurer implements RuntimeWiringConfigurer { - - public boolean applied = false; - - @Override - public void configure(RuntimeWiring.Builder builder) { - this.applied = true; - } - - } - - } - - static class GraphQlSourceBuilderCustomizerConfiguration { - - @Bean - CustomGraphQlSourceBuilderCustomizer customGraphQlSourceBuilderCustomizer() { - return new CustomGraphQlSourceBuilderCustomizer(); - } - - public static class CustomGraphQlSourceBuilderCustomizer implements GraphQlSourceBuilderCustomizer { - - public boolean applied = false; - - @Override - public void customize(GraphQlSource.Builder builder) { - this.applied = true; - } - - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlTestDataFetchers.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlTestDataFetchers.java deleted file mode 100644 index c7dbc44238..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/GraphQlTestDataFetchers.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import java.util.Arrays; -import java.util.List; - -import graphql.schema.DataFetcher; -import reactor.core.publisher.Flux; - -import org.springframework.lang.Nullable; - -/** - * Test utility class holding {@link DataFetcher} implementations. - * - * @author Brian Clozel - */ -public final class GraphQlTestDataFetchers { - - private static List books = Arrays.asList(new Book("book-1", "GraphQL for beginners", 100, "John GraphQL"), - new Book("book-2", "Harry Potter and the Philosopher's Stone", 223, "Joanne Rowling"), - new Book("book-3", "Moby Dick", 635, "Moby Dick"), new Book("book-3", "Moby Dick", 635, "Moby Dick")); - - private GraphQlTestDataFetchers() { - - } - - public static DataFetcher getBookByIdDataFetcher() { - return (environment) -> getBookById(environment.getArgument("id")); - } - - public static DataFetcher getBooksOnSaleDataFetcher() { - return (environment) -> getBooksOnSale(environment.getArgument("minPages")); - } - - @Nullable - public static Book getBookById(String id) { - return books.stream().filter((book) -> book.getId().equals(id)).findFirst().orElse(null); - } - - public static Flux getBooksOnSale(int minPages) { - return Flux.fromIterable(books).filter((book) -> book.getPageCount() >= minPages); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsExceptionFailureAnalyzerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsExceptionFailureAnalyzerTests.java deleted file mode 100644 index 24bc06be73..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsExceptionFailureAnalyzerTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.diagnostics.FailureAnalysis; -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; -import org.springframework.core.io.support.ResourcePatternResolver; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link InvalidSchemaLocationsExceptionFailureAnalyzer} - * - * @author Brian Clozel - */ -class InvalidSchemaLocationsExceptionFailureAnalyzerTests { - - private final InvalidSchemaLocationsExceptionFailureAnalyzer analyzer = new InvalidSchemaLocationsExceptionFailureAnalyzer(); - - private final ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); - - private final String[] missingLocation = new String[] { - "classpath:org/springframework/boot/autoconfigure/graphql/missing/" }; - - private final String[] existingLocation = new String[] { - "classpath:org/springframework/boot/autoconfigure/graphql/" }; - - @Test - void shouldReportCause() { - InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(this.existingLocation, - this.resolver); - FailureAnalysis analysis = this.analyzer.analyze(exception); - assertThat(analysis.getCause()).isInstanceOf(InvalidSchemaLocationsException.class); - assertThat(analysis.getAction()).contains("Check that the following locations contain schema files:"); - } - - @Test - void shouldListUnresolvableLocation() { - InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(this.missingLocation, - this.resolver); - FailureAnalysis analysis = this.analyzer.analyze(exception); - assertThat(analysis.getAction()).contains(this.existingLocation[0]).doesNotContain("file:"); - } - - @Test - void shouldListExistingLocation() { - InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(this.existingLocation, - this.resolver); - FailureAnalysis analysis = this.analyzer.analyze(exception); - assertThat(analysis.getAction()).contains(this.existingLocation[0]).contains("file:"); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsExceptionTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsExceptionTests.java deleted file mode 100644 index b61e3cb50d..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/InvalidSchemaLocationsExceptionTests.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import org.junit.jupiter.api.Test; - -import org.springframework.core.io.support.PathMatchingResourcePatternResolver; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests for {@link InvalidSchemaLocationsException}. - * - * @author Brian Clozel - */ -class InvalidSchemaLocationsExceptionTests { - - private final String schemaFolder = "graphql/"; - - private final String[] locations = new String[] { "classpath:" + this.schemaFolder }; - - @Test - void shouldRejectEmptyLocations() { - assertThatIllegalArgumentException().isThrownBy( - () -> new InvalidSchemaLocationsException(new String[] {}, new PathMatchingResourcePatternResolver())) - .isInstanceOf(IllegalArgumentException.class).withMessage("locations should not be empty"); - } - - @Test - void shouldRejectNullResolver() { - assertThatIllegalArgumentException().isThrownBy(() -> new InvalidSchemaLocationsException(this.locations, null)) - .isInstanceOf(IllegalArgumentException.class).withMessage("resolver should not be null"); - } - - @Test - void shouldExposeConfiguredLocations() { - InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(this.locations, - new PathMatchingResourcePatternResolver()); - assertThat(exception.getSchemaLocations()).hasSize(1); - InvalidSchemaLocationsException.SchemaLocation schemaLocation = exception.getSchemaLocations().get(0); - assertThat(schemaLocation.getLocation()).isEqualTo(this.locations[0]); - assertThat(schemaLocation.getUri()).endsWith(this.schemaFolder); - } - - @Test - void shouldNotFailWithUnresolvableLocations() { - String unresolved = "classpath:unresolved/"; - InvalidSchemaLocationsException exception = new InvalidSchemaLocationsException(new String[] { unresolved }, - new PathMatchingResourcePatternResolver()); - assertThat(exception.getSchemaLocations()).hasSize(1); - InvalidSchemaLocationsException.SchemaLocation schemaLocation = exception.getSchemaLocations().get(0); - assertThat(schemaLocation.getLocation()).isEqualTo(unresolved); - assertThat(schemaLocation.getUri()).isEmpty(); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/QBook.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/QBook.java deleted file mode 100644 index c7e95ac4e7..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/QBook.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql; - -import com.querydsl.core.types.Path; -import com.querydsl.core.types.PathMetadata; -import com.querydsl.core.types.PathMetadataFactory; -import com.querydsl.core.types.dsl.EntityPathBase; -import com.querydsl.core.types.dsl.NumberPath; -import com.querydsl.core.types.dsl.StringPath; - -/** - * QBook is a Querydsl query type for Book. This class is usually generated by the - * Querydsl annotation processor. - */ -public class QBook extends EntityPathBase { - - private static final long serialVersionUID = -1932588188L; - - public static final QBook book = new QBook("book"); - - public final StringPath author = createString("author"); - - public final StringPath id = createString("id"); - - public final StringPath name = createString("name"); - - public final NumberPath pageCount = createNumber("pageCount", Integer.class); - - public QBook(String variable) { - super(Book.class, PathMetadataFactory.forVariable(variable)); - } - - public QBook(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QBook(PathMetadata metadata) { - super(Book.class, metadata); - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfigurationTests.java deleted file mode 100644 index be28b3e908..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfigurationTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql.data; - -import java.util.Optional; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.query.QueryByExampleExecutor; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.data.GraphQlRepository; -import org.springframework.graphql.test.tester.GraphQlTester; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link GraphQlQueryByExampleAutoConfiguration} - * - * @author Brian Clozel - */ -class GraphQlQueryByExampleAutoConfigurationTests { - - private static final Book book = new Book("42", "Test title", 42, "Test Author"); - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(GraphQlAutoConfiguration.class, GraphQlQueryByExampleAutoConfiguration.class)) - .withUserConfiguration(MockRepositoryConfig.class) - .withPropertyValues("spring.main.web-application-type=reactive"); - - @Test - void shouldRegisterDataFetcherForQueryByExampleRepositories() { - this.contextRunner.run((context) -> { - GraphQlService graphQlService = context.getBean(GraphQlService.class); - GraphQlTester graphQlTester = GraphQlTester.create(graphQlService); - graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class) - .isEqualTo("Test title"); - }); - } - - @Configuration(proxyBeanMethods = false) - static class MockRepositoryConfig { - - @Bean - MockRepository mockRepository() { - MockRepository mockRepository = mock(MockRepository.class); - given(mockRepository.findBy(any(), any())).willReturn(Optional.of(book)); - return mockRepository; - } - - } - - @GraphQlRepository - interface MockRepository extends CrudRepository, QueryByExampleExecutor { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfigurationTests.java deleted file mode 100644 index c687d0834e..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfigurationTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql.data; - -import java.util.Optional; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.querydsl.QuerydslPredicateExecutor; -import org.springframework.data.repository.CrudRepository; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.data.GraphQlRepository; -import org.springframework.graphql.test.tester.GraphQlTester; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link GraphQlQuerydslAutoConfiguration}. - * - * @author Brian Clozel - */ -class GraphQlQuerydslAutoConfigurationTests { - - private static final Book book = new Book("42", "Test title", 42, "Test Author"); - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(GraphQlAutoConfiguration.class, GraphQlQuerydslAutoConfiguration.class)) - .withUserConfiguration(MockRepositoryConfig.class) - .withPropertyValues("spring.main.web-application-type=reactive"); - - @Test - void shouldRegisterDataFetcherForQueryDslRepositories() { - this.contextRunner.run((context) -> { - GraphQlService graphQlService = context.getBean(GraphQlService.class); - GraphQlTester graphQlTester = GraphQlTester.create(graphQlService); - graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class) - .isEqualTo("Test title"); - }); - } - - @Configuration(proxyBeanMethods = false) - static class MockRepositoryConfig { - - @Bean - MockRepository mockRepository() { - MockRepository mockRepository = mock(MockRepository.class); - given(mockRepository.findBy(any(), any())).willReturn(Optional.of(book)); - return mockRepository; - } - - } - - @GraphQlRepository - interface MockRepository extends CrudRepository, QuerydslPredicateExecutor { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java deleted file mode 100644 index 20eb88e797..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql.data; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor; -import org.springframework.data.repository.reactive.ReactiveCrudRepository; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.data.GraphQlRepository; -import org.springframework.graphql.test.tester.GraphQlTester; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link GraphQlReactiveQueryByExampleAutoConfiguration} - * - * @author Brian Clozel - */ -class GraphQlReactiveQueryByExampleAutoConfigurationTests { - - private static final Mono bookPublisher = Mono.just(new Book("42", "Test title", 42, "Test Author")); - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(GraphQlAutoConfiguration.class, - GraphQlReactiveQueryByExampleAutoConfiguration.class)) - .withUserConfiguration(MockRepositoryConfig.class) - .withPropertyValues("spring.main.web-application-type=reactive"); - - @Test - void shouldRegisterDataFetcherForQueryByExampleRepositories() { - this.contextRunner.run((context) -> { - GraphQlService graphQlService = context.getBean(GraphQlService.class); - GraphQlTester graphQlTester = GraphQlTester.create(graphQlService); - graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class) - .isEqualTo("Test title"); - }); - } - - @Configuration(proxyBeanMethods = false) - static class MockRepositoryConfig { - - @Bean - MockRepository mockRepository() { - MockRepository mockRepository = mock(MockRepository.class); - given(mockRepository.findBy(any(), any())).willReturn(bookPublisher); - return mockRepository; - } - - } - - @GraphQlRepository - interface MockRepository extends ReactiveCrudRepository, ReactiveQueryByExampleExecutor { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfigurationTests.java deleted file mode 100644 index 4d5d461462..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfigurationTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql.data; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor; -import org.springframework.data.repository.reactive.ReactiveCrudRepository; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.data.GraphQlRepository; -import org.springframework.graphql.test.tester.GraphQlTester; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link GraphQlReactiveQuerydslAutoConfiguration} - * - * @author Brian Clozel - */ -class GraphQlReactiveQuerydslAutoConfigurationTests { - - private static final Mono bookPublisher = Mono.just(new Book("42", "Test title", 42, "Test Author")); - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(GraphQlAutoConfiguration.class, - GraphQlReactiveQuerydslAutoConfiguration.class)) - .withUserConfiguration(MockRepositoryConfig.class) - .withPropertyValues("spring.main.web-application-type=reactive"); - - @Test - void shouldRegisterDataFetcherForQueryDslRepositories() { - this.contextRunner.run((context) -> { - GraphQlService graphQlService = context.getBean(GraphQlService.class); - GraphQlTester graphQlTester = GraphQlTester.create(graphQlService); - graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class) - .isEqualTo("Test title"); - }); - } - - @Configuration(proxyBeanMethods = false) - static class MockRepositoryConfig { - - @Bean - MockRepository mockRepository() { - MockRepository mockRepository = mock(MockRepository.class); - given(mockRepository.findBy(any(), any())).willReturn(bookPublisher); - return mockRepository; - } - - } - - @GraphQlRepository - interface MockRepository extends ReactiveCrudRepository, ReactiveQuerydslPredicateExecutor { - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfigurationTests.java deleted file mode 100644 index 64aadfe805..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/reactive/GraphQlWebFluxAutoConfigurationTests.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql.reactive; - -import java.util.Collections; -import java.util.function.Consumer; - -import graphql.schema.idl.TypeRuntimeWiring; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlTestDataFetchers; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; -import org.springframework.graphql.web.WebGraphQlHandler; -import org.springframework.graphql.web.WebInterceptor; -import org.springframework.graphql.web.webflux.GraphQlHttpHandler; -import org.springframework.graphql.web.webflux.GraphQlWebSocketHandler; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.test.web.reactive.server.WebTestClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.containsString; - -/** - * Tests for {@link GraphQlWebFluxAutoConfiguration} - * - * @author Brian Clozel - */ -class GraphQlWebFluxAutoConfigurationTests { - - private static final String BASE_URL = "https://spring.example.org/"; - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class, - CodecsAutoConfiguration.class, JacksonAutoConfiguration.class, GraphQlAutoConfiguration.class, - GraphQlWebFluxAutoConfiguration.class)) - .withUserConfiguration(DataFetchersConfiguration.class, CustomWebInterceptor.class) - .withPropertyValues("spring.main.web-application-type=reactive", "spring.graphql.graphiql.enabled=true", - "spring.graphql.schema.printer.enabled=true", - "spring.graphql.cors.allowed-origins=https://example.com", - "spring.graphql.cors.allowed-methods=POST", "spring.graphql.cors.allow-credentials=true"); - - @Test - void shouldContributeDefaultBeans() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(GraphQlHttpHandler.class) - .hasSingleBean(WebGraphQlHandler.class).doesNotHaveBean(GraphQlWebSocketHandler.class)); - } - - @Test - void simpleQueryShouldWork() { - testWithWebClient((client) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author } }"; - client.post().uri("/graphql").bodyValue("{ \"query\": \"" + query + "\"}").exchange().expectStatus().isOk() - .expectBody().jsonPath("data.bookById.name").isEqualTo("GraphQL for beginners"); - }); - } - - @Test - void httpGetQueryShouldBeSupported() { - testWithWebClient((client) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author } }"; - client.get().uri("/graphql?query={query}", "{ \"query\": \"" + query + "\"}").exchange().expectStatus() - .isEqualTo(HttpStatus.METHOD_NOT_ALLOWED).expectHeader().valueEquals("Allow", "POST"); - }); - } - - @Test - void shouldRejectMissingQuery() { - testWithWebClient( - (client) -> client.post().uri("/graphql").bodyValue("{}").exchange().expectStatus().isBadRequest()); - } - - @Test - void shouldRejectQueryWithInvalidJson() { - testWithWebClient( - (client) -> client.post().uri("/graphql").bodyValue(":)").exchange().expectStatus().isBadRequest()); - } - - @Test - void shouldConfigureWebInterceptors() { - testWithWebClient((client) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author } }"; - - client.post().uri("/graphql").bodyValue("{ \"query\": \"" + query + "\"}").exchange().expectStatus().isOk() - .expectHeader().valueEquals("X-Custom-Header", "42"); - }); - } - - @Test - void shouldExposeSchemaEndpoint() { - testWithWebClient((client) -> client.get().uri("/graphql/schema").accept(MediaType.ALL).exchange() - .expectStatus().isOk().expectHeader().contentType(MediaType.TEXT_PLAIN).expectBody(String.class) - .value(containsString("type Book"))); - } - - @Test - void shouldExposeGraphiqlEndpoint() { - testWithWebClient((client) -> { - client.get().uri("/graphiql").exchange().expectStatus().is3xxRedirection().expectHeader() - .location("https://spring.example.org/graphiql?path=/graphql"); - client.get().uri("/graphiql?path=/graphql").accept(MediaType.ALL).exchange().expectStatus().isOk() - .expectHeader().contentType(MediaType.TEXT_HTML); - }); - } - - @Test - void shouldSupportCors() { - testWithWebClient((client) -> { - String query = "{" + " bookById(id: \\\"book-1\\\"){ " + " id" + " name" + " pageCount" - + " author" + " }" + "}"; - client.post().uri("/graphql").bodyValue("{ \"query\": \"" + query + "\"}") - .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST") - .header(HttpHeaders.ORIGIN, "https://example.com").exchange().expectStatus().isOk().expectHeader() - .valueEquals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "https://example.com").expectHeader() - .valueEquals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); - }); - } - - @Test - void shouldConfigureWebSocketBeans() { - this.contextRunner.withPropertyValues("spring.graphql.websocket.path=/ws") - .run((context) -> assertThat(context).hasSingleBean(GraphQlWebSocketHandler.class)); - } - - private void testWithWebClient(Consumer consumer) { - this.contextRunner.run((context) -> { - WebTestClient client = WebTestClient.bindToApplicationContext(context).configureClient() - .defaultHeaders((headers) -> { - headers.setContentType(MediaType.APPLICATION_JSON); - headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - }).baseUrl(BASE_URL).build(); - consumer.accept(client); - }); - } - - @Configuration(proxyBeanMethods = false) - static class DataFetchersConfiguration { - - @Bean - RuntimeWiringConfigurer bookDataFetcher() { - return (builder) -> builder.type(TypeRuntimeWiring.newTypeWiring("Query").dataFetcher("bookById", - GraphQlTestDataFetchers.getBookByIdDataFetcher())); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomWebInterceptor { - - @Bean - WebInterceptor customWebInterceptor() { - return (webInput, interceptorChain) -> interceptorChain.next(webInput) - .map((output) -> output.transform((builder) -> builder.responseHeader("X-Custom-Header", "42"))); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfigurationTests.java deleted file mode 100644 index 9b6f1db534..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebFluxSecurityAutoConfigurationTests.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.autoconfigure.graphql.security; - -import java.util.Collections; -import java.util.function.Consumer; - -import graphql.schema.idl.TypeRuntimeWiring; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlTestDataFetchers; -import org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration; -import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; -import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.execution.ErrorType; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; -import org.springframework.graphql.security.ReactiveSecurityDataFetcherExceptionResolver; -import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; -import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; -import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.web.server.SecurityWebFilterChain; -import org.springframework.test.web.reactive.server.WebTestClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.security.config.Customizer.withDefaults; - -/** - * Tests for {@link GraphQlWebFluxSecurityAutoConfiguration}. - * - * @author Brian Clozel - */ -class GraphQlWebFluxSecurityAutoConfigurationTests { - - private static final String BASE_URL = "https://spring.example.org/graphql"; - - private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class, - CodecsAutoConfiguration.class, JacksonAutoConfiguration.class, GraphQlAutoConfiguration.class, - GraphQlWebFluxAutoConfiguration.class, GraphQlWebFluxSecurityAutoConfiguration.class, - ReactiveSecurityAutoConfiguration.class)) - .withUserConfiguration(DataFetchersConfiguration.class, SecurityConfig.class) - .withPropertyValues("spring.main.web-application-type=reactive"); - - @Test - void contributesExceptionResolver() { - this.contextRunner.run( - (context) -> assertThat(context).hasSingleBean(ReactiveSecurityDataFetcherExceptionResolver.class)); - } - - @Test - void anonymousUserShouldBeUnauthorized() { - testWithWebClient((client) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author }}"; - client.post().uri("").bodyValue("{ \"query\": \"" + query + "\"}").exchange().expectStatus().isOk() - .expectBody().jsonPath("data.bookById.name").doesNotExist() - .jsonPath("errors[0].extensions.classification").isEqualTo(ErrorType.UNAUTHORIZED.toString()); - }); - } - - @Test - void authenticatedUserShouldGetData() { - testWithWebClient((client) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author }}"; - client.post().uri("").headers((headers) -> headers.setBasicAuth("rob", "rob")) - .bodyValue("{ \"query\": \"" + query + "\"}").exchange().expectStatus().isOk().expectBody() - .jsonPath("data.bookById.name").isEqualTo("GraphQL for beginners") - .jsonPath("errors[0].extensions.classification").doesNotExist(); - }); - } - - private void testWithWebClient(Consumer consumer) { - this.contextRunner.run((context) -> { - WebTestClient client = WebTestClient.bindToApplicationContext(context).configureClient() - .defaultHeaders((headers) -> { - headers.setContentType(MediaType.APPLICATION_JSON); - headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - }).baseUrl(BASE_URL).build(); - consumer.accept(client); - }); - } - - @Configuration(proxyBeanMethods = false) - static class DataFetchersConfiguration { - - @Bean - RuntimeWiringConfigurer bookDataFetcher(BookService bookService) { - return (builder) -> builder.type(TypeRuntimeWiring.newTypeWiring("Query").dataFetcher("bookById", - (env) -> bookService.getBookdById(env.getArgument("id")))); - } - - @Bean - BookService bookService() { - return new BookService(); - } - - } - - static class BookService { - - @PreAuthorize("hasRole('USER')") - @Nullable - Mono getBookdById(String id) { - return Mono.justOrEmpty(GraphQlTestDataFetchers.getBookById(id)); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableWebFluxSecurity - @EnableReactiveMethodSecurity - static class SecurityConfig { - - @Bean - SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) throws Exception { - return http.csrf((spec) -> spec.disable()) - // Demonstrate that method security works - // Best practice to use both for defense in depth - .authorizeExchange((requests) -> requests.anyExchange().permitAll()).httpBasic(withDefaults()) - .build(); - } - - @Bean - @SuppressWarnings("deprecation") - MapReactiveUserDetailsService userDetailsService() { - User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); - UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); - UserDetails admin = userBuilder.username("admin").password("admin").roles("USER", "ADMIN").build(); - return new MapReactiveUserDetailsService(rob, admin); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java deleted file mode 100644 index ebdf9a7d40..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/security/GraphQlWebMvcSecurityAutoConfigurationTests.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.autoconfigure.graphql.security; - -import graphql.schema.idl.TypeRuntimeWiring; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.Book; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlTestDataFetchers; -import org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.execution.ErrorType; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; -import org.springframework.graphql.security.SecurityContextThreadLocalAccessor; -import org.springframework.graphql.security.SecurityDataFetcherExceptionResolver; -import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.DefaultSecurityFilterChain; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.security.config.Customizer.withDefaults; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** - * Tests for {@link GraphQlWebMvcSecurityAutoConfiguration}. - * - * @author Brian Clozel - */ -class GraphQlWebMvcSecurityAutoConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, JacksonAutoConfiguration.class, - GraphQlAutoConfiguration.class, GraphQlWebMvcAutoConfiguration.class, - GraphQlWebMvcSecurityAutoConfiguration.class, SecurityAutoConfiguration.class)) - .withUserConfiguration(DataFetchersConfiguration.class, SecurityConfig.class) - .withPropertyValues("spring.main.web-application-type=servlet"); - - @Test - void contributesSecurityComponents() { - this.contextRunner.run((context) -> { - assertThat(context).hasSingleBean(SecurityDataFetcherExceptionResolver.class); - assertThat(context).hasSingleBean(SecurityContextThreadLocalAccessor.class); - }); - } - - @Test - void anonymousUserShouldBeUnauthorized() { - testWith((mockMvc) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author }}"; - MvcResult result = mockMvc.perform(post("/graphql").content("{\"query\": \"" + query + "\"}")).andReturn(); - mockMvc.perform(asyncDispatch(result)).andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("data.bookById.name").doesNotExist()).andExpect( - jsonPath("errors[0].extensions.classification").value(ErrorType.UNAUTHORIZED.toString())); - }); - } - - @Test - void authenticatedUserShouldGetData() { - testWith((mockMvc) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author }}"; - MvcResult result = mockMvc - .perform(post("/graphql").content("{\"query\": \"" + query + "\"}").with(user("rob"))).andReturn(); - mockMvc.perform(asyncDispatch(result)).andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("data.bookById.name").value("GraphQL for beginners")) - .andExpect(jsonPath("errors").doesNotExist()); - }); - - } - - private void testWith(MockMvcConsumer mockMvcConsumer) { - this.contextRunner.run((context) -> { - MediaType mediaType = MediaType.APPLICATION_JSON; - MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context) - .defaultRequest(post("/graphql").contentType(mediaType).accept(mediaType)).apply(springSecurity()) - .build(); - mockMvcConsumer.accept(mockMvc); - }); - } - - private interface MockMvcConsumer { - - void accept(MockMvc mockMvc) throws Exception; - - } - - @Configuration(proxyBeanMethods = false) - static class DataFetchersConfiguration { - - @Bean - RuntimeWiringConfigurer bookDataFetcher(BookService bookService) { - return (builder) -> builder.type(TypeRuntimeWiring.newTypeWiring("Query").dataFetcher("bookById", - (env) -> bookService.getBookdById(env.getArgument("id")))); - } - - @Bean - BookService bookService() { - return new BookService(); - } - - } - - static class BookService { - - @PreAuthorize("hasRole('USER')") - @Nullable - Book getBookdById(String id) { - return GraphQlTestDataFetchers.getBookById(id); - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableWebSecurity - @EnableGlobalMethodSecurity(prePostEnabled = true) - static class SecurityConfig { - - @Bean - DefaultSecurityFilterChain springWebFilterChain(HttpSecurity http) throws Exception { - return http.csrf((c) -> c.disable()) - // Demonstrate that method security works - // Best practice to use both for defense in depth - .authorizeRequests((requests) -> requests.anyRequest().permitAll()).httpBasic(withDefaults()) - .build(); - } - - @Bean - static InMemoryUserDetailsManager userDetailsService() { - User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); - UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); - UserDetails admin = userBuilder.username("admin").password("admin").roles("USER", "ADMIN").build(); - return new InMemoryUserDetailsManager(rob, admin); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfigurationTests.java deleted file mode 100644 index 3e1f57a16a..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/servlet/GraphQlWebMvcAutoConfigurationTests.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.autoconfigure.graphql.servlet; - -import graphql.schema.idl.TypeRuntimeWiring; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.boot.autoconfigure.graphql.GraphQlTestDataFetchers; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; -import org.springframework.graphql.web.WebGraphQlHandler; -import org.springframework.graphql.web.WebInterceptor; -import org.springframework.graphql.web.webmvc.GraphQlHttpHandler; -import org.springframework.graphql.web.webmvc.GraphQlWebSocketHandler; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** - * Tests for {@link GraphQlWebMvcAutoConfiguration}. - * - * @author Brian Clozel - */ -class GraphQlWebMvcAutoConfigurationTests { - - private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of(DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class, - HttpMessageConvertersAutoConfiguration.class, JacksonAutoConfiguration.class, - GraphQlAutoConfiguration.class, GraphQlWebMvcAutoConfiguration.class)) - .withUserConfiguration(DataFetchersConfiguration.class, CustomWebInterceptor.class) - .withPropertyValues("spring.main.web-application-type=servlet", "spring.graphql.graphiql.enabled=true", - "spring.graphql.schema.printer.enabled=true", - "spring.graphql.cors.allowed-origins=https://example.com", - "spring.graphql.cors.allowed-methods=POST", "spring.graphql.cors.allow-credentials=true"); - - @Test - void shouldContributeDefaultBeans() { - this.contextRunner.run((context) -> assertThat(context).hasSingleBean(GraphQlHttpHandler.class) - .hasSingleBean(WebGraphQlHandler.class).doesNotHaveBean(GraphQlWebSocketHandler.class)); - } - - @Test - void simpleQueryShouldWork() { - testWith((mockMvc) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author } }"; - MvcResult result = mockMvc.perform(post("/graphql").content("{\"query\": \"" + query + "\"}")).andReturn(); - mockMvc.perform(asyncDispatch(result)).andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("data.bookById.name").value("GraphQL for beginners")); - }); - } - - @Test - void httpGetQueryShouldBeSupported() { - testWith((mockMvc) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author } }"; - mockMvc.perform(get("/graphql?query={query}", "{\"query\": \"" + query + "\"}")) - .andExpect(status().isMethodNotAllowed()).andExpect(header().string("Allow", "POST")); - }); - } - - @Test - void shouldRejectMissingQuery() { - testWith((mockMvc) -> mockMvc.perform(post("/graphql").content("{}")).andExpect(status().isBadRequest())); - } - - @Test - void shouldRejectQueryWithInvalidJson() { - testWith((mockMvc) -> mockMvc.perform(post("/graphql").content(":)")).andExpect(status().isBadRequest())); - } - - @Test - void shouldConfigureWebInterceptors() { - testWith((mockMvc) -> { - String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author } }"; - MvcResult result = mockMvc.perform(post("/graphql").content("{\"query\": \"" + query + "\"}")).andReturn(); - mockMvc.perform(asyncDispatch(result)).andExpect(status().isOk()) - .andExpect(header().string("X-Custom-Header", "42")); - }); - } - - @Test - void shouldExposeSchemaEndpoint() { - testWith((mockMvc) -> mockMvc.perform(get("/graphql/schema")).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.TEXT_PLAIN)) - .andExpect(content().string(Matchers.containsString("type Book")))); - } - - @Test - void shouldExposeGraphiqlEndpoint() { - testWith((mockMvc) -> { - mockMvc.perform(get("/graphiql")).andExpect(status().is3xxRedirection()) - .andExpect(redirectedUrl("http://localhost/graphiql?path=/graphql")); - mockMvc.perform(get("/graphiql?path=/graphql")).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.TEXT_HTML)); - }); - } - - @Test - void shouldSupportCors() { - testWith((mockMvc) -> { - String query = "{" + " bookById(id: \\\"book-1\\\"){ " + " id" + " name" + " pageCount" - + " author" + " }" + "}"; - MvcResult result = mockMvc.perform(post("/graphql") - .header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST") - .header(HttpHeaders.ORIGIN, "https://example.com").content("{\"query\": \"" + query + "\"}")) - .andReturn(); - mockMvc.perform(asyncDispatch(result)).andExpect(status().isOk()) - .andExpect(header().stringValues(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "https://example.com")) - .andExpect(header().stringValues(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true")); - }); - } - - @Test - void shouldConfigureWebSocketBeans() { - this.contextRunner.withPropertyValues("spring.graphql.websocket.path=/ws") - .run((context) -> assertThat(context).hasSingleBean(GraphQlWebSocketHandler.class)); - } - - private void testWith(MockMvcConsumer mockMvcConsumer) { - this.contextRunner.run((context) -> { - MediaType mediaType = MediaType.APPLICATION_JSON; - MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context) - .defaultRequest(post("/graphql").contentType(mediaType).accept(mediaType)).build(); - mockMvcConsumer.accept(mockMvc); - }); - } - - private interface MockMvcConsumer { - - void accept(MockMvc mockMvc) throws Exception; - - } - - @Configuration(proxyBeanMethods = false) - static class DataFetchersConfiguration { - - @Bean - RuntimeWiringConfigurer bookDataFetcher() { - return (builder) -> builder.type(TypeRuntimeWiring.newTypeWiring("Query").dataFetcher("bookById", - GraphQlTestDataFetchers.getBookByIdDataFetcher())); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomWebInterceptor { - - @Bean - WebInterceptor customWebInterceptor() { - return (webInput, interceptorChain) -> interceptorChain.next(webInput) - .map((output) -> output.transform((builder) -> builder.responseHeader("X-Custom-Header", "42"))); - } - - } - -} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/graphql/schema.graphqls b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/graphql/schema.graphqls deleted file mode 100644 index c2009b57ff..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/graphql/schema.graphqls +++ /dev/null @@ -1,4 +0,0 @@ -type Query { - greeting(name: String! = "Spring"): String! - bookById(id: ID): Book -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/graphql/types/book.graphqls b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/graphql/types/book.graphqls deleted file mode 100644 index 16217d759b..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/graphql/types/book.graphqls +++ /dev/null @@ -1,6 +0,0 @@ -type Book { - id: ID - name: String - pageCount: Int - author: String -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/graphql/types/person.custom b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/graphql/types/person.custom deleted file mode 100644 index 8cff728ad1..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/graphql/types/person.custom +++ /dev/null @@ -1,4 +0,0 @@ -type Person { - id: ID - name: String -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 08951f3a9e..69f33ab4b4 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -273,13 +273,6 @@ bom { ] } } - library("GraphQL Java", "17.3") { - group("com.graphql-java") { - modules = [ - "graphql-java" - ] - } - } library("Groovy", "3.0.9") { group("org.codehaus.groovy") { imports = [ @@ -1164,7 +1157,6 @@ bom { "spring-boot-starter-data-neo4j", "spring-boot-starter-data-rest", "spring-boot-starter-freemarker", - "spring-boot-starter-graphql", "spring-boot-starter-groovy-templates", "spring-boot-starter-hateoas", "spring-boot-starter-integration", @@ -1321,14 +1313,6 @@ bom { ] } } - library("Spring GraphQL", "1.0.0-SNAPSHOT") { - group("org.springframework.graphql") { - modules = [ - "spring-graphql", - "spring-graphql-test" - ] - } - } library("Spring HATEOAS", "2.0.0-SNAPSHOT") { group("org.springframework.hateoas") { modules = [ diff --git a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java index 9e7f760d04..88e0487fdc 100755 --- a/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java +++ b/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java @@ -62,7 +62,6 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro static { Map properties = new HashMap<>(); properties.put("spring.freemarker.cache", "false"); - properties.put("spring.graphql.graphiql.enabled", "true"); properties.put("spring.groovy.template.cache", "false"); properties.put("spring.mustache.cache", "false"); properties.put("server.servlet.session.persistent", "true"); diff --git a/spring-boot-project/spring-boot-docs/build.gradle b/spring-boot-project/spring-boot-docs/build.gradle index 2c6dd5445b..c842f1f7b4 100644 --- a/spring-boot-project/spring-boot-docs/build.gradle +++ b/spring-boot-project/spring-boot-docs/build.gradle @@ -133,8 +133,6 @@ dependencies { implementation("org.springframework.data:spring-data-neo4j") implementation("org.springframework.data:spring-data-redis") implementation("org.springframework.data:spring-data-r2dbc") - implementation("org.springframework.graphql:spring-graphql") - implementation("org.springframework.graphql:spring-graphql-test") implementation("org.springframework.kafka:spring-kafka") implementation("org.springframework.kafka:spring-kafka-test") implementation("org.springframework.restdocs:spring-restdocs-mockmvc") { @@ -268,9 +266,8 @@ tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) { "spring-data-r2dbc-version": versionConstraints["org.springframework.data:spring-data-r2dbc"], "spring-data-rest-version": versionConstraints["org.springframework.data:spring-data-rest-core"], "spring-framework-version": versionConstraints["org.springframework:spring-core"], - "spring-graphql-version": versionConstraints["org.springframework.graphql:spring-graphql"], - "spring-integration-version": versionConstraints["org.springframework.integration:spring-integration-core"], "spring-kafka-version": versionConstraints["org.springframework.kafka:spring-kafka"], + "spring-integration-version": versionConstraints["org.springframework.integration:spring-integration-core"], "spring-security-version": securityVersion, "spring-webservices-version": versionConstraints["org.springframework.ws:spring-ws-core"] } @@ -313,9 +310,6 @@ syncDocumentationSourceForAsciidoctor { from("src/main/groovy") { into "main/groovy" } - from("src/main/resources") { - into "main/resources" - } } syncDocumentationSourceForAsciidoctorMultipage { @@ -337,9 +331,6 @@ syncDocumentationSourceForAsciidoctorMultipage { from("src/main/groovy") { into "main/groovy" } - from("src/main/resources") { - into "main/resources" - } } syncDocumentationSourceForAsciidoctorPdf { @@ -361,9 +352,6 @@ syncDocumentationSourceForAsciidoctorPdf { from("src/main/groovy") { into "main/groovy" } - from("src/main/resources") { - into "main/resources" - } } task zip(type: Zip) { diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc index 25131f3a92..942caee297 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/actuator/metrics.adoc @@ -837,58 +837,6 @@ A `CacheMetricsRegistrar` bean is made available to make that process easier. -[[actuator.metrics.supported.spring-graphql]] -==== Spring GraphQL Metrics -Auto-configuration enables the instrumentation of GraphQL queries, for any supported transport. - -Spring Boot records a `graphql.request` timer with: - -[cols="1,2,2"] -|=== -|Tag | Description| Sample values - -|outcome -|Request outcome -|"SUCCESS", "ERROR" -|=== - -A single GraphQL query can involve many `DataFetcher` calls, so there is a dedicated `graphql.datafetcher` timer: - -[cols="1,2,2"] -|=== -|Tag | Description| Sample values - -|path -|data fetcher path -|"Query.project" - -|outcome -|data fetching outcome -|"SUCCESS", "ERROR" -|=== - - -The `graphql.request.datafetch.count` https://micrometer.io/docs/concepts#_distribution_summaries[distribution summary] counts the number of non-trivial `DataFetcher` calls made per request. -This metric is useful for detecting "N+1" data fetching issues and consider batch loading; it provides the `"TOTAL"` number of data fetcher calls made over the `"COUNT"` of recorded requests, as well as the `"MAX"` calls made for a single request over the considered period. -More options are available for <>. - -A single response can contain many GraphQL errors, counted by the `graphql.error` counter: - -[cols="1,2,2"] -|=== -|Tag | Description| Sample values - -|errorType -|error type -|"DataFetchingException" - -|errorPath -|error JSON Path -|"$.project" -|=== - - - [[actuator.metrics.supported.jdbc]] ==== DataSource Metrics Auto-configuration enables the instrumentation of all available `DataSource` objects with metrics prefixed with `jdbc.connections`. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc index 499b5e7bd0..aa7e253680 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/attributes.adoc @@ -21,7 +21,6 @@ :github-wiki: https://github.com/{github-repo}/wiki :docs-java: ../../main/java/org/springframework/boot/docs :docs-groovy: ../../main/groovy/org/springframework/boot/docs -:docs-resources: ../../main/resources :spring-boot-code: https://github.com/{github-repo}/tree/{github-tag} :spring-boot-api: https://docs.spring.io/spring-boot/docs/{spring-boot-version}/api :spring-boot-docs: https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference @@ -80,9 +79,6 @@ :spring-framework: https://spring.io/projects/spring-framework :spring-framework-api: https://docs.spring.io/spring-framework/docs/{spring-framework-version}/javadoc-api/org/springframework :spring-framework-docs: https://docs.spring.io/spring-framework/docs/{spring-framework-version}/reference/html -:spring-graphql: https://spring.io/projects/spring-graphql -:spring-graphql-api: https://docs.spring.io/spring-graphql/docs/{spring-graphql-version}/api/ -:spring-graphql-docs: https://docs.spring.io/spring-graphql/docs/{spring-graphql-version}/reference/html/ :spring-integration: https://spring.io/projects/spring-integration :spring-integration-docs: https://docs.spring.io/spring-integration/docs/{spring-integration-version}/reference/html/ :spring-kafka-docs: https://docs.spring.io/spring-kafka/docs/{spring-kafka-version}/reference/html/ diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/testing.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/testing.adoc index 032f953008..f7250beafe 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/testing.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/testing.adoc @@ -448,62 +448,6 @@ TIP: Sometimes writing Spring WebFlux tests is not enough; Spring Boot can help -[[features.testing.spring-boot-applications.spring-graphql-tests]] -==== Auto-configured Spring GraphQL Tests -Spring GraphQL offers a dedicated testing support module; you'll need to add it to your project: - -.Maven -[source,xml,indent=0,subs="verbatim"] ----- - - - org.springframework.graphql - spring-graphql-test - test - - - - org.springframework - spring-webflux - test - - ----- - -.Gradle -[source,gradle,indent=0,subs="verbatim"] ----- - dependencies { - testImplementation("org.springframework.graphql:spring-graphql-test") - // Unless already present in the implementation configuration - testImplementation("org.springframework:spring-webflux") - } ----- - -This testing module ships the {spring-graphql-docs}/testing.html#testing-webgraphqltester[WebGraphQlTester]. -The tester is heavily used in test, so be sure to become familiar with using it. - -Spring Boot helps you to test your {spring-graphql-docs}#controllers[Spring GraphQL Controllers] with the `@GraphQlTest` annotation. -`@GraphQlTest` auto-configures the Spring GraphQL infrastructure, without any transport nor server being involved. -This limits scanned beans to `@Controller`, `RuntimeWiringConfigurer`, `JsonComponent`, `Converter` and `GenericConverter`. -Regular `@Component` and `@ConfigurationProperties` beans are not scanned when the `@GraphQlTest` annotation is used. -`@EnableConfigurationProperties` can be used to include `@ConfigurationProperties` beans. - -TIP: A list of the auto-configurations that are enabled by `@GraphQlTest` can be <>. - -TIP: If you need to register extra components, such as Jackson `Module`, you can import additional configuration classes using `@Import` on your test. - -Often, `@GraphQlTest` is limited to a set of controllers and used in combination with the `@MockBean` annotation to provide mock implementations for required collaborators. - -[source,java,indent=0,subs="verbatim"] ----- -include::{docs-java}/features/testing/springbootapplications/springgraphqltests/GreetingControllerTests.java[] ----- - -TIP: You can also auto-configure `WebGraphQlTester` in a non-`@GraphQlTest` (such as `@SpringBootTest`) by annotating it with `@AutoConfigureWebGraphQlTester`. - - - [[features.testing.spring-boot-applications.autoconfigured-spring-data-cassandra]] ==== Auto-configured Data Cassandra Tests You can use `@DataCassandraTest` to test Cassandra applications. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/index.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/index.adoc index 74af721032..e9e41e1aca 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/index.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/index.adoc @@ -16,7 +16,7 @@ The reference documentation consists of the following sections: <> :: Upgrading from 1.x, Upgrading to a new feature release, and Upgrading the Spring Boot CLI. <> :: Build Systems, Structuring Your Code, Configuration, Spring Beans and Dependency Injection, DevTools, and more. <> :: Profiles, Logging, Security, Caching, Spring Integration, Testing, and more. -<> :: Servlet Web, Reactive Web, GraphQL, Embedded Container Support, Graceful Shutdown, and more. +<> :: Servlet Web, Reactive Web, Embedded Container Support, Graceful Shutdown, and more. <> :: SQL and NOSQL data access. <> :: Caching, Quartz Scheduler, REST clients, Sending email, Spring Web Services, and more. <> :: JMS, AMQP, RSocket, WebSocket, and Spring Integration. diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web.adoc index 0bf2c5be45..dc98318881 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web.adoc @@ -19,8 +19,6 @@ include::web/spring-security.adoc[] include::web/spring-session.adoc[] -include::web/spring-graphql.adoc[] - include::web/spring-hateoas.adoc[] include::web/whats-next.adoc[] diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-graphql.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-graphql.adoc deleted file mode 100644 index f2a4116629..0000000000 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/web/spring-graphql.adoc +++ /dev/null @@ -1,135 +0,0 @@ -[[web.graphql]] -== Spring GraphQL -If you want to build GraphQL applications, you can take advantage of Spring Boot's auto-configuration for {spring-graphql}[Spring GraphQL]. -The Spring GraphQL project is based on https://github.com/graphql-java/graphql-java[GraphQL Java]. -You'll need the `spring-boot-starter-graphql` starter at a minimum. -Because GraphQL is transport-agnostic, you'll also need to have one or more additional starters in your application to expose your GraphQL API over the web: - - -[cols="1,1,1"] -|=== -| Starter | Transport | Implementation - -| `spring-boot-starter-web` -| HTTP -| Spring MVC - -| `spring-boot-starter-websocket` -| WebSocket -| WebSocket for Servlet apps - -| `spring-boot-starter-webflux` -| HTTP, WebSocket -| Spring WebFlux - -|=== - - - -[[web.graphql.schema]] -=== GraphQL Schema - -A Spring GraphQL application requires a defined schema at startup. -By default, you can write ".graphqls" or ".gqls" schema files under `src/main/resources/graphql/**` and Spring Boot will pick them up automatically. -You can customize the locations with configprop:spring.graphql.schema.locations[] and the file extensions with configprop:spring.graphql.schema.file-extensions[]. - -In the following sections, we'll consider this sample GraphQL schema, defining two types and two queries: - -[source,json,indent=0,subs="verbatim,quotes"] ----- -include::{docs-resources}/graphql/schema.graphqls[] ----- - - -[[web.graphql.runtimewiring]] -=== GraphQL RuntimeWiring - -The GraphQL Java `RuntimeWiring.Builder` can be used to register custom scalar types, directives, type resolvers, `DataFetcher`s, and more. -You can declare `RuntimeWiringConfigurer` beans in your Spring config to get access to the `RuntimeWiring.Builder`. -Spring Boot detects such beans and adds them to the {spring-graphql-docs}#execution-graphqlsource[GraphQlSource builder]. - -Typically, however, applications will not implement `DataFetcher` directly and will instead create {spring-graphql-docs}#controllers[annotated controllers]. -Spring Boot will automatically register `@Controller` classes with annotated handler methods and registers those as `DataFetcher`s. -Here's a sample implementation for our greeting query with a `@Controller` class: - -[source,java,indent=0,subs="verbatim"] ----- -include::{docs-java}/web/graphql/GreetingController.java[] ----- - - - -[[web.graphql.data-query]] -=== Querydsl and QueryByExample Repositories support - -Spring Data offers support for both Querydsl and QueryByExample repositories. -Spring GraphQL can {spring-graphql-docs}#data[configure Querydsl and QueryByExample repositories as `DataFetcher`]. - -Spring Data repositories annotated with `@GraphQlRepository` and extending one of: - -* `QuerydslPredicateExecutor` -* `ReactiveQuerydslPredicateExecutor` -* `QueryByExampleExecutor` -* `ReactiveQueryByExampleExecutor` - -are detected by Spring Boot and considered as candidates for `DataFetcher` for matching top-level queries. - - - -[[web.graphql.web-endpoints]] -=== Web Endpoints - -The GraphQL HTTP endpoint is at HTTP POST "/graphql" by default. The path can be customized with configprop:spring.graphql.path[]. - -The GraphQL WebSocket endpoint is off by default. To enable it: - -* For a Servlet application, add the WebSocket starter `spring-boot-starter-websocket` -* For a WebFlux application, no additional dependency is required -* For both, the configprop:spring.graphql.websocket.path[] application property must be set - -Spring GraphQL provides a {spring-graphql-docs}#web-interception[Web Interception] model. -This is quite useful for retrieving information from an HTTP request header and set it in the GraphQL context or fetching information from the same context and writing it to a response header. -With Spring Boot, you can declare a `WebInterceptor` bean to have it registered with the web transport. - - - -[[web.graphql.cors]] -=== CORS - -{spring-framework-docs}/web.html#mvc-cors[Spring MVC] and {spring-framework-docs}/web-reactive.html#webflux-cors[Spring WebFlux] support CORS (Cross-Origin Resource Sharing) requests. -CORS is a critical part of the web config for GraphQL applications that are accessed from browsers using different domains. - -Spring Boot supports many configuration properties under the `spring.graphql.cors.*` namespace; here's a short configuration sample: - -[source,yaml,indent=0,subs="verbatim",configblocks] ----- - spring: - graphql: - cors: - allowed-origins: "https://example.org" - allowed-methods: GET,POST - max-age: 1800s ----- - - - -[[web.graphql.exception-handling]] -=== Exceptions Handling - -Spring GraphQL enables applications to register one or more Spring `DataFetcherExceptionResolver` components that are invoked sequentially. -The Exception must be resolved to a list of `graphql.GraphQLError` objects, see {spring-graphql-docs}#execution-exceptions[Spring GraphQL exception handling documentation]. -Spring Boot will automatically detect `DataFetcherExceptionResolver` beans and register them with the `GraphQlSource.Builder`. - - - -[[web.graphql.graphiql]] -=== GraphiQL and Schema printer - -Spring GraphQL offers infrastructure for helping developers when consuming or developing a GraphQL API. - -Spring GraphQL ships with a default https://github.com/graphql/graphiql[GraphiQL] page that is exposed at "/graphiql" by default. -This page is disabled by default and can be turned on with the configprop:spring.graphql.graphiql.enabled[] property. -Many applications exposing such a page will prefer a custom build. -A default implementation is very useful during development, this is why it is exposed automatically with <> during development. - -You can also choose to expose the GraphQL schema in text format at `/graphql/schema` when the configprop:spring.graphql.schema.printer.enabled[] property is enabled. diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/springgraphqltests/GreetingControllerTests.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/springgraphqltests/GreetingControllerTests.java deleted file mode 100644 index 1812730aca..0000000000 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/features/testing/springbootapplications/springgraphqltests/GreetingControllerTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.docs.features.testing.springbootapplications.springgraphqltests; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.docs.web.graphql.GreetingController; -import org.springframework.boot.test.autoconfigure.graphql.GraphQlTest; -import org.springframework.graphql.test.tester.GraphQlTester; - -@GraphQlTest(GreetingController.class) -class GreetingControllerTests { - - @Autowired - private GraphQlTester graphQlTester; - - @Test - void shouldGreetWithSpecificName() { - this.graphQlTester.query("{ greeting(name: \"Alice\") } ").execute().path("greeting").entity(String.class) - .isEqualTo("Hello, Alice!"); - } - - @Test - void shouldGreetWithDefaultName() { - this.graphQlTester.query("{ greeting } ").execute().path("greeting").entity(String.class) - .isEqualTo("Hello, Spring!"); - } - -} diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/graphql/GreetingController.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/graphql/GreetingController.java deleted file mode 100644 index 99566d9512..0000000000 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/graphql/GreetingController.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2002-2021 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.boot.docs.web.graphql; - -import org.springframework.graphql.data.method.annotation.Argument; -import org.springframework.graphql.data.method.annotation.QueryMapping; -import org.springframework.stereotype.Controller; - -@Controller -public class GreetingController { - - @QueryMapping - public String greeting(@Argument String name) { - return "Hello, " + name + "!"; - } - -} diff --git a/spring-boot-project/spring-boot-docs/src/main/resources/graphql/schema.graphqls b/spring-boot-project/spring-boot-docs/src/main/resources/graphql/schema.graphqls deleted file mode 100644 index fcbf6b0030..0000000000 --- a/spring-boot-project/spring-boot-docs/src/main/resources/graphql/schema.graphqls +++ /dev/null @@ -1,29 +0,0 @@ -type Query { - greeting(name: String! = "Spring"): String! - project(slug: ID!): Project -} - -""" A Project in the Spring portfolio """ -type Project { - """ Unique string id used in URLs """ - slug: ID! - """ Project name """ - name: String! - """ URL of the git repository """ - repositoryUrl: String! - """ Current support status """ - status: ProjectStatus! -} - -enum ProjectStatus { - """ Actively supported by the Spring team """ - ACTIVE - """ Supported by the community """ - COMMUNITY - """ Prototype, not officially supported yet """ - INCUBATING - """ Project being retired, in maintenance mode """ - ATTIC - """ End-Of-Lifed """ - EOL -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-graphql/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-graphql/build.gradle deleted file mode 100644 index 1099bc51fa..0000000000 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-graphql/build.gradle +++ /dev/null @@ -1,11 +0,0 @@ -plugins { - id "org.springframework.boot.starter" -} - -description = "Starter for building GraphQL applications with Spring GraphQL" - -dependencies { - api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-json")) - api("org.springframework.graphql:spring-graphql") -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle index e71df8b3b9..454c62176b 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle @@ -44,7 +44,6 @@ dependencies { optional("org.springframework.data:spring-data-neo4j") optional("org.springframework.data:spring-data-r2dbc") optional("org.springframework.data:spring-data-redis") - optional("org.springframework.graphql:spring-graphql-test") optional("org.springframework.restdocs:spring-restdocs-mockmvc") { exclude group: "javax.servlet", module: "javax.servlet-api" } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/AutoConfigureGraphQl.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/AutoConfigureGraphQl.java deleted file mode 100644 index cfea9dfdcc..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/AutoConfigureGraphQl.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; - -/** - * {@link ImportAutoConfiguration Auto-configuration imports} for typical Spring GraphQL - * tests. Most tests should consider using {@link GraphQlTest @GraphQlTest} rather than - * using this annotation directly. - * - * @author Brian Clozel - * @since 2.7.0 - * @see GraphQlTest - * @see org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration - * @see org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration - * @see org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@ImportAutoConfiguration -public @interface AutoConfigureGraphQl { - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTest.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTest.java deleted file mode 100644 index d0cfa2d55e..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration; -import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache; -import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters; -import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester; -import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester; -import org.springframework.boot.test.autoconfigure.json.AutoConfigureJson; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.core.annotation.AliasFor; -import org.springframework.core.env.Environment; -import org.springframework.test.context.BootstrapWith; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -/** - * Annotation to perform GraphQL tests focusing on GraphQL request execution without a Web - * layer, and loading only a subset of the application configuration. - *

- * The annotation disables full auto-configuration and instead loads only components - * relevant to GraphQL tests, including the following: - *

    - *
  • {@code @Controller} - *
  • {@code RuntimeWiringConfigurer} - *
  • {@code @JsonComponent} - *
  • {@code Converter} - *
  • {@code GenericConverter} - *
- *

- * The annotation does not automatically load {@code @Component}, {@code @Service}, - * {@code @Repository}, and other beans. - *

- * By default, tests annotated with {@code @GraphQlTest} have a - * {@link org.springframework.graphql.test.tester.GraphQlTester} configured. For more - * fine-grained control of the GraphQlTester, use - * {@link AutoConfigureGraphQlTester @AutoConfigureGraphQlTester}. - *

- * Typically {@code @GraphQlTest} is used in combination with - * {@link org.springframework.boot.test.mock.mockito.MockBean @MockBean} or - * {@link org.springframework.context.annotation.Import @Import} to load any collaborators - * and other components required for the tests. - *

- * To load your full application configuration instead and test via - * {@code WebGraphQlTester}, consider using - * {@link org.springframework.boot.test.context.SpringBootTest @SpringBootTest} combined - * with {@link AutoConfigureWebGraphQlTester @AutoConfigureWebGraphQlTester}. - * - * @author Brian Clozel - * @since 2.7.0 - * @see AutoConfigureGraphQlTester - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@BootstrapWith(GraphQlTestContextBootstrapper.class) -@ExtendWith(SpringExtension.class) -@OverrideAutoConfiguration(enabled = false) -@TypeExcludeFilters(GraphQlTypeExcludeFilter.class) -@AutoConfigureCache -@AutoConfigureJson -@AutoConfigureGraphQl -@AutoConfigureGraphQlTester -@ImportAutoConfiguration -public @interface GraphQlTest { - - /** - * Properties in form {@literal key=value} that should be added to the Spring - * {@link Environment} before the test runs. - * @return the properties to add - */ - String[] properties() default {}; - - /** - * Specifies the controllers to test. This is an alias of {@link #controllers()} which - * can be used for brevity if no other attributes are defined. See - * {@link #controllers()} for details. - * @see #controllers() - * @return the controllers to test - */ - @AliasFor("controllers") - Class[] value() default {}; - - /** - * Specifies the controllers to test. May be left blank if all {@code @Controller} - * beans should be added to the application context. - * @see #value() - * @return the controllers to test - */ - @AliasFor("value") - Class[] controllers() default {}; - - /** - * Determines if default filtering should be used with - * {@link SpringBootApplication @SpringBootApplication}. By default, only - * {@code @Controller} (when no explicit {@link #controllers() controllers} are - * defined), {@code RuntimeWiringConfigurer}, {@code @JsonComponent}, - * {@code Converter}, and {@code GenericConverter} beans are included. - * @see #includeFilters() - * @see #excludeFilters() - * @return if default filters should be used - */ - boolean useDefaultFilters() default true; - - /** - * A set of include filters which can be used to add otherwise filtered beans to the - * application context. - * @return include filters to apply - */ - ComponentScan.Filter[] includeFilters() default {}; - - /** - * A set of exclude filters which can be used to filter beans that would otherwise be - * added to the application context. - * @return exclude filters to apply - */ - ComponentScan.Filter[] excludeFilters() default {}; - - /** - * Auto-configuration exclusions that should be applied for this test. - * @return auto-configuration exclusions to apply - */ - @AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude") - Class[] excludeAutoConfiguration() default {}; - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestContextBootstrapper.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestContextBootstrapper.java deleted file mode 100644 index 5e05495cde..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestContextBootstrapper.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql; - -import org.springframework.boot.test.context.SpringBootTestContextBootstrapper; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.test.context.TestContextBootstrapper; - -/** - * {@link TestContextBootstrapper} for {@link GraphQlTest @GraphQlTest}. - * - * @author Brian Clozel - */ -class GraphQlTestContextBootstrapper extends SpringBootTestContextBootstrapper { - - @Override - protected String[] getProperties(Class testClass) { - return MergedAnnotations.from(testClass, MergedAnnotations.SearchStrategy.INHERITED_ANNOTATIONS) - .get(GraphQlTest.class).getValue("properties", String[].class).orElse(null); - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilter.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilter.java deleted file mode 100644 index 1ae5b52f60..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilter.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql; - -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.springframework.boot.context.TypeExcludeFilter; -import org.springframework.boot.jackson.JsonComponent; -import org.springframework.boot.test.autoconfigure.filter.StandardAnnotationCustomizableTypeExcludeFilter; -import org.springframework.core.convert.converter.Converter; -import org.springframework.core.convert.converter.GenericConverter; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; -import org.springframework.stereotype.Controller; -import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; - -/** - * {@link TypeExcludeFilter} for {@link GraphQlTest @GraphQlTest}. - * - * @author Brian Clozel - * @since 2.7.0 - */ -public class GraphQlTypeExcludeFilter extends StandardAnnotationCustomizableTypeExcludeFilter { - - private static final Class[] NO_CONTROLLERS = {}; - - private static final String[] OPTIONAL_INCLUDES = { "com.fasterxml.jackson.databind.Module" }; - - private static final Set> DEFAULT_INCLUDES; - - static { - Set> includes = new LinkedHashSet<>(); - includes.add(JsonComponent.class); - includes.add(RuntimeWiringConfigurer.class); - includes.add(Converter.class); - includes.add(GenericConverter.class); - for (String optionalInclude : OPTIONAL_INCLUDES) { - try { - includes.add(ClassUtils.forName(optionalInclude, null)); - } - catch (Exception ex) { - // Ignore - } - } - DEFAULT_INCLUDES = Collections.unmodifiableSet(includes); - } - - private static final Set> DEFAULT_INCLUDES_AND_CONTROLLER; - - static { - Set> includes = new LinkedHashSet<>(DEFAULT_INCLUDES); - includes.add(Controller.class); - DEFAULT_INCLUDES_AND_CONTROLLER = Collections.unmodifiableSet(includes); - } - - private final Class[] controllers; - - GraphQlTypeExcludeFilter(Class testClass) { - super(testClass); - this.controllers = getAnnotation().getValue("controllers", Class[].class).orElse(NO_CONTROLLERS); - } - - @Override - protected Set> getDefaultIncludes() { - if (ObjectUtils.isEmpty(this.controllers)) { - return DEFAULT_INCLUDES_AND_CONTROLLER; - } - return DEFAULT_INCLUDES; - } - - @Override - protected Set> getComponentIncludes() { - return new LinkedHashSet<>(Arrays.asList(this.controllers)); - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/package-info.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/package-info.java deleted file mode 100644 index ea4880ea00..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-2021 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. - */ - -/** - * Auto-configuration for GraphQL testing. - */ -package org.springframework.boot.test.autoconfigure.graphql; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/AutoConfigureGraphQlTester.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/AutoConfigureGraphQlTester.java deleted file mode 100644 index f940d3ed02..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/AutoConfigureGraphQlTester.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql.tester; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.graphql.test.tester.GraphQlTester; - -/** - * Annotation that can be applied to a test class to enable a {@link GraphQlTester}. - * - * @author Brian Clozel - * @since 2.7.0 - * @see GraphQlTesterAutoConfiguration - */ -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@ImportAutoConfiguration -public @interface AutoConfigureGraphQlTester { - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/AutoConfigureWebGraphQlTester.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/AutoConfigureWebGraphQlTester.java deleted file mode 100644 index 5c5a8e1bd6..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/AutoConfigureWebGraphQlTester.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql.tester; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.graphql.test.tester.WebGraphQlTester; - -/** - * Annotation that can be applied to a test class to enable a {@link WebGraphQlTester}. - * - *

- * This annotation should be used with - * {@link org.springframework.boot.test.context.SpringBootTest @SpringBootTest} tests with - * Spring MVC or Spring WebFlux mock infrastructures. - * - * @author Brian Clozel - * @since 2.7.0 - * @see WebGraphQlTesterAutoConfiguration - */ -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@AutoConfigureMockMvc -@AutoConfigureWebTestClient -@ImportAutoConfiguration -public @interface AutoConfigureWebGraphQlTester { - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfiguration.java deleted file mode 100644 index 684b3ef6b7..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfiguration.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql.tester; - -import graphql.GraphQL; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.test.tester.GraphQlTester; - -/** - * Auto-configuration for {@link GraphQlTester}. - * - * @author Brian Clozel - * @since 2.7.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ GraphQL.class, GraphQlTester.class }) -@AutoConfigureAfter(GraphQlAutoConfiguration.class) -public class GraphQlTesterAutoConfiguration { - - @Bean - @ConditionalOnBean(GraphQlService.class) - @ConditionalOnMissingBean - public GraphQlTester graphQlTester(GraphQlService graphQlService) { - return GraphQlTester.create(graphQlService); - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/WebGraphQlTesterAutoConfiguration.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/WebGraphQlTesterAutoConfiguration.java deleted file mode 100644 index e2f4fa469f..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/WebGraphQlTesterAutoConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql.tester; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.graphql.GraphQlProperties; -import org.springframework.boot.test.autoconfigure.web.reactive.WebTestClientAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.servlet.MockMvcAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.test.tester.WebGraphQlTester; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * Auto-configuration for {@link WebGraphQlTester}. - * - * @author Brian Clozel - * @since 2.7.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ WebClient.class, WebTestClient.class, WebGraphQlTester.class }) -@AutoConfigureAfter({ WebTestClientAutoConfiguration.class, MockMvcAutoConfiguration.class }) -public class WebGraphQlTesterAutoConfiguration { - - @Bean - @ConditionalOnBean(WebTestClient.class) - @ConditionalOnMissingBean - public WebGraphQlTester webTestClientGraphQlTester(WebTestClient webTestClient, GraphQlProperties properties) { - WebTestClient mutatedWebTestClient = webTestClient.mutate().baseUrl(properties.getPath()).build(); - return WebGraphQlTester.create(mutatedWebTestClient); - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/package-info.java b/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/package-info.java deleted file mode 100644 index 182468fa0e..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/graphql/tester/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-2021 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. - */ - -/** - * Auto-configuration for GraphQL tester. - */ -package org.springframework.boot.test.autoconfigure.graphql.tester; diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories index 81647f5d6d..8429c468b5 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-test-autoconfigure/src/main/resources/META-INF/spring.factories @@ -186,20 +186,6 @@ org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfigurati org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration -# AutoConfigureGraphQl auto-configuration imports -org.springframework.boot.test.autoconfigure.graphql.AutoConfigureGraphQl=\ -org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\ -org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\ -org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration - -# AutoConfigureGraphQlTester auto-configuration imports -org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester=\ -org.springframework.boot.test.autoconfigure.graphql.tester.GraphQlTesterAutoConfiguration - -# AutoConfigureWebGraphQlTester auto-configuration imports -org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester=\ -org.springframework.boot.test.autoconfigure.graphql.tester.WebGraphQlTesterAutoConfiguration - # AutoConfigureWebServiceClient org.springframework.boot.test.autoconfigure.webservices.client.AutoConfigureWebServiceClient=\ org.springframework.boot.test.autoconfigure.webservices.client.WebServiceClientTemplateAutoConfiguration,\ diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/Book.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/Book.java deleted file mode 100644 index 9f1cb863f0..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/Book.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql; - -public class Book { - - String id; - - String name; - - int pageCount; - - String author; - - public Book() { - } - - public Book(String id, String name, int pageCount, String author) { - this.id = id; - this.name = name; - this.pageCount = pageCount; - this.author = author; - } - - public String getId() { - return this.id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public int getPageCount() { - return this.pageCount; - } - - public void setPageCount(int pageCount) { - this.pageCount = pageCount; - } - - public String getAuthor() { - return this.author; - } - - public void setAuthor(String author) { - this.author = author; - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/BookController.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/BookController.java deleted file mode 100644 index 9e9fc970a4..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/BookController.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql; - -import org.springframework.graphql.data.method.annotation.Argument; -import org.springframework.graphql.data.method.annotation.QueryMapping; -import org.springframework.stereotype.Controller; - -/** - * Example {@code @Controller} to be tested with {@link GraphQlTest @GraphQlTest}. - * - * @author Brian Clozel - */ -@Controller -public class BookController { - - @QueryMapping - public Book bookById(@Argument String id) { - return new Book("42", "Sample Book", 100, "Jane Spring"); - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/ExampleGraphQlApplication.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/ExampleGraphQlApplication.java deleted file mode 100644 index 798592a56c..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/ExampleGraphQlApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql; - -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * Example {@link SpringBootApplication @SpringBootApplication} used with - * {@link GraphQlTest @GraphQlTest} tests. - * - * @author Brian Clozel - */ -@SpringBootApplication -public class ExampleGraphQlApplication { - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestIntegrationTest.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestIntegrationTest.java deleted file mode 100644 index 18807b332b..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTestIntegrationTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.autoconfigure.graphql; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.graphql.test.tester.GraphQlTester; - -/** - * Integration test for {@link GraphQlTest @GraphQlTest} annotated tests. - * - * @author Brian Clozel - */ -@GraphQlTest(BookController.class) -public class GraphQlTestIntegrationTest { - - @Autowired - private GraphQlTester graphQlTester; - - @Test - void getBookdByIdShouldReturnTestBook() { - String query = "{ bookById(id: \"book-1\"){ id name pageCount author } }"; - this.graphQlTester.query(query).execute().path("data.bookById.id").entity(String.class).isEqualTo("42"); - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilterTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilterTests.java deleted file mode 100644 index 53fa09adcb..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/GraphQlTypeExcludeFilterTests.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.test.autoconfigure.graphql; - -import java.io.IOException; - -import com.fasterxml.jackson.databind.module.SimpleModule; -import graphql.schema.idl.RuntimeWiring; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.FilterType; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.core.type.classreading.SimpleMetadataReaderFactory; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; -import org.springframework.graphql.web.WebInput; -import org.springframework.graphql.web.WebInterceptor; -import org.springframework.graphql.web.WebInterceptorChain; -import org.springframework.graphql.web.WebOutput; -import org.springframework.stereotype.Controller; -import org.springframework.stereotype.Repository; -import org.springframework.stereotype.Service; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link GraphQlTypeExcludeFilter} - * - * @author Brian Clozel - */ -class GraphQlTypeExcludeFilterTests { - - private MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(); - - @Test - void matchWhenHasNoControllers() throws Exception { - GraphQlTypeExcludeFilter filter = new GraphQlTypeExcludeFilter(WithNoControllers.class); - assertThat(excludes(filter, Controller1.class)).isFalse(); - assertThat(excludes(filter, Controller2.class)).isFalse(); - assertThat(excludes(filter, ExampleRuntimeWiringConfigurer.class)).isFalse(); - assertThat(excludes(filter, ExampleService.class)).isTrue(); - assertThat(excludes(filter, ExampleRepository.class)).isTrue(); - assertThat(excludes(filter, ExampleWebInterceptor.class)).isTrue(); - assertThat(excludes(filter, ExampleModule.class)).isFalse(); - } - - @Test - void matchWhenHasController() throws Exception { - GraphQlTypeExcludeFilter filter = new GraphQlTypeExcludeFilter(WithController.class); - assertThat(excludes(filter, Controller1.class)).isFalse(); - assertThat(excludes(filter, Controller2.class)).isTrue(); - assertThat(excludes(filter, ExampleRuntimeWiringConfigurer.class)).isFalse(); - assertThat(excludes(filter, ExampleService.class)).isTrue(); - assertThat(excludes(filter, ExampleRepository.class)).isTrue(); - assertThat(excludes(filter, ExampleWebInterceptor.class)).isTrue(); - assertThat(excludes(filter, ExampleModule.class)).isFalse(); - } - - @Test - void matchNotUsingDefaultFilters() throws Exception { - GraphQlTypeExcludeFilter filter = new GraphQlTypeExcludeFilter(NotUsingDefaultFilters.class); - assertThat(excludes(filter, Controller1.class)).isTrue(); - assertThat(excludes(filter, Controller2.class)).isTrue(); - assertThat(excludes(filter, ExampleRuntimeWiringConfigurer.class)).isTrue(); - assertThat(excludes(filter, ExampleService.class)).isTrue(); - assertThat(excludes(filter, ExampleRepository.class)).isTrue(); - assertThat(excludes(filter, ExampleWebInterceptor.class)).isTrue(); - assertThat(excludes(filter, ExampleModule.class)).isTrue(); - } - - @Test - void matchWithIncludeFilter() throws Exception { - GraphQlTypeExcludeFilter filter = new GraphQlTypeExcludeFilter(WithIncludeFilter.class); - assertThat(excludes(filter, Controller1.class)).isFalse(); - assertThat(excludes(filter, Controller2.class)).isFalse(); - assertThat(excludes(filter, ExampleRuntimeWiringConfigurer.class)).isFalse(); - assertThat(excludes(filter, ExampleService.class)).isTrue(); - assertThat(excludes(filter, ExampleRepository.class)).isFalse(); - assertThat(excludes(filter, ExampleWebInterceptor.class)).isTrue(); - assertThat(excludes(filter, ExampleModule.class)).isFalse(); - } - - @Test - void matchWithExcludeFilter() throws Exception { - GraphQlTypeExcludeFilter filter = new GraphQlTypeExcludeFilter(WithExcludeFilter.class); - assertThat(excludes(filter, Controller1.class)).isTrue(); - assertThat(excludes(filter, Controller2.class)).isFalse(); - assertThat(excludes(filter, ExampleRuntimeWiringConfigurer.class)).isFalse(); - assertThat(excludes(filter, ExampleService.class)).isTrue(); - assertThat(excludes(filter, ExampleRepository.class)).isTrue(); - assertThat(excludes(filter, ExampleWebInterceptor.class)).isTrue(); - assertThat(excludes(filter, ExampleModule.class)).isFalse(); - } - - private boolean excludes(GraphQlTypeExcludeFilter filter, Class type) throws IOException { - MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(type.getName()); - return filter.match(metadataReader, this.metadataReaderFactory); - } - - @GraphQlTest - static class WithNoControllers { - - } - - @GraphQlTest(Controller1.class) - static class WithController { - - } - - @GraphQlTest(useDefaultFilters = false) - static class NotUsingDefaultFilters { - - } - - @GraphQlTest(includeFilters = @ComponentScan.Filter(Repository.class)) - static class WithIncludeFilter { - - } - - @GraphQlTest(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = Controller1.class)) - static class WithExcludeFilter { - - } - - @Controller - static class Controller1 { - - } - - @Controller - static class Controller2 { - - } - - @Service - static class ExampleService { - - } - - @Repository - static class ExampleRepository { - - } - - static class ExampleRuntimeWiringConfigurer implements RuntimeWiringConfigurer { - - @Override - public void configure(RuntimeWiring.Builder builder) { - - } - - } - - static class ExampleWebInterceptor implements WebInterceptor { - - @Override - public Mono intercept(WebInput webInput, WebInterceptorChain chain) { - return null; - } - - } - - @SuppressWarnings("serial") - static class ExampleModule extends SimpleModule { - - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfigurationTests.java b/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfigurationTests.java deleted file mode 100644 index 322902f430..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/java/org/springframework/boot/test/autoconfigure/graphql/tester/GraphQlTesterAutoConfigurationTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.test.autoconfigure.graphql.tester; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.test.tester.GraphQlTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Tests for {@link GraphQlTesterAutoConfiguration}. - * - * @author Brian Clozel - */ -class GraphQlTesterAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(GraphQlTesterAutoConfiguration.class)); - - @Test - void shouldNotContributeTesterIfGraphQlServiceNotPresent() { - this.contextRunner.run((context) -> assertThat(context).hasNotFailed().doesNotHaveBean(GraphQlTester.class)); - } - - @Test - void shouldContributeTester() { - this.contextRunner.withUserConfiguration(CustomGraphQlServiceConfiguration.class) - .run((context) -> assertThat(context).hasNotFailed().hasSingleBean(GraphQlTester.class)); - } - - @Configuration(proxyBeanMethods = false) - static class CustomGraphQlServiceConfiguration { - - @Bean - GraphQlService graphQlService() { - return mock(GraphQlService.class); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/graphql/schema.graphqls b/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/graphql/schema.graphqls deleted file mode 100644 index 975b7ca60d..0000000000 --- a/spring-boot-project/spring-boot-test-autoconfigure/src/test/resources/graphql/schema.graphqls +++ /dev/null @@ -1,10 +0,0 @@ -type Query { - bookById(id: ID): Book -} - -type Book { - id: ID - name: String - pageCount: Int - author: String -} \ No newline at end of file diff --git a/spring-boot-project/spring-boot-test/build.gradle b/spring-boot-project/spring-boot-test/build.gradle index 119c511626..dc37c1cf72 100644 --- a/spring-boot-project/spring-boot-test/build.gradle +++ b/spring-boot-project/spring-boot-test/build.gradle @@ -36,7 +36,6 @@ dependencies { optional("org.springframework:spring-test") optional("org.springframework:spring-web") optional("org.springframework:spring-webflux") - optional("org.springframework.graphql:spring-graphql-test") optional("net.sourceforge.htmlunit:htmlunit") { exclude(group: "commons-logging", module: "commons-logging") } diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizer.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizer.java deleted file mode 100644 index d079bd5b76..0000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizer.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.graphql.tester; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.server.AbstractConfigurableWebServerFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.Ordered; -import org.springframework.graphql.test.tester.GraphQlTester; -import org.springframework.graphql.test.tester.WebGraphQlTester; -import org.springframework.test.context.ContextCustomizer; -import org.springframework.test.context.MergedContextConfiguration; -import org.springframework.test.context.TestContextAnnotationUtils; -import org.springframework.test.web.reactive.server.WebTestClient; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; -import org.springframework.web.context.WebApplicationContext; - -/** - * {@link ContextCustomizer} for {@link GraphQlTester}. - * - * @author Brian Clozel - */ -class GraphQlTesterContextCustomizer implements ContextCustomizer { - - @Override - public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { - SpringBootTest springBootTest = TestContextAnnotationUtils.findMergedAnnotation(mergedConfig.getTestClass(), - SpringBootTest.class); - if (springBootTest.webEnvironment().isEmbedded()) { - registerGraphQlTester(context); - } - } - - private void registerGraphQlTester(ConfigurableApplicationContext context) { - ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); - if (beanFactory instanceof BeanDefinitionRegistry) { - registerGraphQlTester((BeanDefinitionRegistry) beanFactory); - } - } - - private void registerGraphQlTester(BeanDefinitionRegistry registry) { - RootBeanDefinition definition = new RootBeanDefinition(GraphQlTesterRegistrar.class); - definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - registry.registerBeanDefinition(GraphQlTesterRegistrar.class.getName(), definition); - } - - @Override - public boolean equals(Object obj) { - return (obj != null) && (obj.getClass() == getClass()); - } - - @Override - public int hashCode() { - return getClass().hashCode(); - } - - private static class GraphQlTesterRegistrar - implements BeanDefinitionRegistryPostProcessor, Ordered, BeanFactoryAware { - - private BeanFactory beanFactory; - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - } - - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { - if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors((ListableBeanFactory) this.beanFactory, - GraphQlTester.class, false, false).length == 0) { - registry.registerBeanDefinition(WebGraphQlTester.class.getName(), - new RootBeanDefinition(GraphQlTesterFactory.class)); - } - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - - } - - @Override - public int getOrder() { - return Ordered.LOWEST_PRECEDENCE - 1; - } - - } - - public static class GraphQlTesterFactory implements FactoryBean, ApplicationContextAware { - - private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext"; - - private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext"; - - private ApplicationContext applicationContext; - - private GraphQlTester object; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - @Override - public boolean isSingleton() { - return true; - } - - @Override - public Class getObjectType() { - return GraphQlTester.class; - } - - @Override - public GraphQlTester getObject() throws Exception { - if (this.object == null) { - this.object = createGraphQlTester(); - } - return this.object; - } - - private WebGraphQlTester createGraphQlTester() { - WebTestClient webTestClient = this.applicationContext.getBean(WebTestClient.class); - boolean sslEnabled = isSslEnabled(this.applicationContext); - String port = this.applicationContext.getEnvironment().getProperty("local.server.port", "8080"); - WebTestClient mutatedWebClient = webTestClient.mutate().baseUrl(getBaseUrl(sslEnabled, port)).build(); - return WebGraphQlTester.create(mutatedWebClient); - } - - private String getBaseUrl(boolean sslEnabled, String port) { - String basePath = deduceBasePath(); - return (sslEnabled ? "https" : "http") + "://localhost:" + port + basePath; - } - - private String deduceBasePath() { - return deduceServerBasePath() + findConfiguredGraphQlPath(); - } - - private String findConfiguredGraphQlPath() { - String configuredPath = this.applicationContext.getEnvironment().getProperty("spring.graphql.path"); - return StringUtils.hasText(configuredPath) ? configuredPath : "/graphql"; - } - - private String deduceServerBasePath() { - String serverBasePath = ""; - WebApplicationType webApplicationType = deduceFromApplicationContext(this.applicationContext.getClass()); - if (webApplicationType == WebApplicationType.REACTIVE) { - serverBasePath = this.applicationContext.getEnvironment().getProperty("spring.webflux.base-path"); - - } - else if (webApplicationType == WebApplicationType.SERVLET) { - serverBasePath = ((WebApplicationContext) this.applicationContext).getServletContext().getContextPath(); - } - return (serverBasePath != null) ? serverBasePath : ""; - } - - static WebApplicationType deduceFromApplicationContext(Class applicationContextClass) { - if (isAssignable(SERVLET_APPLICATION_CONTEXT_CLASS, applicationContextClass)) { - return WebApplicationType.SERVLET; - } - if (isAssignable(REACTIVE_APPLICATION_CONTEXT_CLASS, applicationContextClass)) { - return WebApplicationType.REACTIVE; - } - return WebApplicationType.NONE; - } - - private static boolean isAssignable(String target, Class type) { - try { - return ClassUtils.resolveClassName(target, null).isAssignableFrom(type); - } - catch (Throwable ex) { - return false; - } - } - - private boolean isSslEnabled(ApplicationContext context) { - try { - AbstractConfigurableWebServerFactory webServerFactory = context - .getBean(AbstractConfigurableWebServerFactory.class); - return webServerFactory.getSsl() != null && webServerFactory.getSsl().isEnabled(); - } - catch (NoSuchBeanDefinitionException ex) { - return false; - } - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerFactory.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerFactory.java deleted file mode 100644 index 497db17727..0000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2020-2021 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.boot.test.graphql.tester; - -import java.util.List; - -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.graphql.test.tester.GraphQlTester; -import org.springframework.test.context.ContextConfigurationAttributes; -import org.springframework.test.context.ContextCustomizer; -import org.springframework.test.context.ContextCustomizerFactory; -import org.springframework.test.context.TestContextAnnotationUtils; -import org.springframework.util.ClassUtils; - -/** - * {@link ContextCustomizerFactory} for {@link GraphQlTester}. - * - * @author Brian Clozel - * @see GraphQlTesterContextCustomizer - */ -class GraphQlTesterContextCustomizerFactory implements ContextCustomizerFactory { - - private static final String GRAPHQLTESTER_CLASS = "org.springframework.graphql.test.tester.GraphQlTester"; - - private static final String WEBTESTCLIENT_CLASS = "org.springframework.test.web.reactive.server.WebTestClient"; - - @Override - public ContextCustomizer createContextCustomizer(Class testClass, - List configAttributes) { - SpringBootTest springBootTest = TestContextAnnotationUtils.findMergedAnnotation(testClass, - SpringBootTest.class); - return (springBootTest != null && isGraphQlTesterPresent()) ? new GraphQlTesterContextCustomizer() : null; - } - - private boolean isGraphQlTesterPresent() { - return ClassUtils.isPresent(WEBTESTCLIENT_CLASS, getClass().getClassLoader()) - && ClassUtils.isPresent(GRAPHQLTESTER_CLASS, getClass().getClassLoader()); - } - -} diff --git a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/package-info.java b/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/package-info.java deleted file mode 100644 index 9eeb1f664d..0000000000 --- a/spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/graphql/tester/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020-2021 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. - */ - -/** - * {@link org.springframework.graphql.test.tester.GraphQlTester} utilities. - */ -package org.springframework.boot.test.graphql.tester; diff --git a/spring-boot-project/spring-boot-test/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-test/src/main/resources/META-INF/spring.factories index 3dd1783cd9..5a75a417aa 100644 --- a/spring-boot-project/spring-boot-test/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-test/src/main/resources/META-INF/spring.factories @@ -2,7 +2,6 @@ org.springframework.test.context.ContextCustomizerFactory=\ org.springframework.boot.test.context.ImportsContextCustomizerFactory,\ org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizerFactory,\ -org.springframework.boot.test.graphql.tester.GraphQlTesterContextCustomizerFactory,\ org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory,\ org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory,\ org.springframework.boot.test.web.client.TestRestTemplateContextCustomizerFactory,\ diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerIntegrationTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerIntegrationTests.java deleted file mode 100644 index b9c334ca88..0000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerIntegrationTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.test.graphql.tester; - -import java.util.Collections; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.buffer.DefaultDataBufferFactory; -import org.springframework.graphql.test.tester.GraphQlTester; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.server.reactive.ContextPathCompositeHandler; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.test.annotation.DirtiesContext; - -/** - * Integration test for {@link GraphQlTesterContextCustomizer}. - * - * @author Brian Clozel - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = "spring.main.web-application-type=reactive") -@DirtiesContext -class GraphQlTesterContextCustomizerIntegrationTests { - - @Autowired - GraphQlTester graphQlTester; - - @Test - void shouldHandleGraphQlRequests() { - this.graphQlTester.query("{}").executeAndVerify(); - } - - @Configuration(proxyBeanMethods = false) - static class TestConfig { - - @Bean - TomcatReactiveWebServerFactory webServerFactory() { - return new TomcatReactiveWebServerFactory(0); - } - - @Bean - HttpHandler httpHandler() { - TestHandler httpHandler = new TestHandler(); - Map handlersMap = Collections.singletonMap("/graphql", httpHandler); - return new ContextPathCompositeHandler(handlersMap); - } - - } - - static class TestHandler implements HttpHandler { - - private static final DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); - - @Override - public Mono handle(ServerHttpRequest request, ServerHttpResponse response) { - response.setStatusCode(HttpStatus.OK); - response.getHeaders().setContentType(MediaType.APPLICATION_JSON); - return response.writeWith(Mono.just(factory.wrap("{\"data\":{}}".getBytes()))); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerWithCustomBasePathTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerWithCustomBasePathTests.java deleted file mode 100644 index 6c1ecb4e19..0000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerWithCustomBasePathTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.test.graphql.tester; - -import java.util.Collections; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.io.buffer.DefaultDataBufferFactory; -import org.springframework.graphql.test.tester.GraphQlTester; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.server.reactive.ContextPathCompositeHandler; -import org.springframework.http.server.reactive.HttpHandler; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.test.context.TestPropertySource; - -/** - * Tests for {@link GraphQlTesterContextCustomizer} with a custom context path for a - * Reactive web application. - * - * @author Brian Clozel - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@TestPropertySource(properties = { "spring.main.web-application-type=reactive", "spring.webflux.base-path=/test" }) -class GraphQlTesterContextCustomizerWithCustomBasePathTests { - - @Autowired - GraphQlTester graphQlTester; - - @Test - void shouldHandleGraphQlRequests() { - this.graphQlTester.query("{}").executeAndVerify(); - } - - @Configuration(proxyBeanMethods = false) - static class TestConfig { - - @Bean - TomcatReactiveWebServerFactory webServerFactory() { - return new TomcatReactiveWebServerFactory(0); - } - - @Bean - HttpHandler httpHandler() { - TestHandler httpHandler = new TestHandler(); - Map handlersMap = Collections.singletonMap("/test/graphql", httpHandler); - return new ContextPathCompositeHandler(handlersMap); - } - - } - - static class TestHandler implements HttpHandler { - - private static final DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); - - @Override - public Mono handle(ServerHttpRequest request, ServerHttpResponse response) { - response.setStatusCode(HttpStatus.OK); - response.getHeaders().setContentType(MediaType.APPLICATION_JSON); - return response.writeWith(Mono.just(factory.wrap("{\"data\":{}}".getBytes()))); - } - - } - -} diff --git a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerWithCustomContextPathTests.java b/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerWithCustomContextPathTests.java deleted file mode 100644 index 095e432041..0000000000 --- a/spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/graphql/tester/GraphQlTesterContextCustomizerWithCustomContextPathTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012-2021 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.boot.test.graphql.tester; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.graphql.test.tester.GraphQlTester; -import org.springframework.http.MediaType; -import org.springframework.test.context.TestPropertySource; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.servlet.DispatcherServlet; - -/** - * Tests for {@link GraphQlTesterContextCustomizer} with a custom context path for a - * Servlet web application. - * - * @author Brian Clozel - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@TestPropertySource(properties = "server.servlet.context-path=/test") -class GraphQlTesterContextCustomizerWithCustomContextPathTests { - - @Autowired - GraphQlTester graphQlTester; - - @Test - void shouldHandleGraphQlRequests() { - this.graphQlTester.query("{}").executeAndVerify(); - } - - @Configuration(proxyBeanMethods = false) - @Import(TestController.class) - static class TestConfig { - - @Bean - TomcatServletWebServerFactory webServerFactory() { - TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(0); - factory.setContextPath("/test"); - return factory; - } - - @Bean - DispatcherServlet dispatcherServlet() { - return new DispatcherServlet(); - } - - } - - @RestController - static class TestController { - - @PostMapping(path = "/graphql", produces = MediaType.APPLICATION_JSON_VALUE) - String graphql() { - return "{}"; - } - - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/build.gradle deleted file mode 100644 index 06affd54ba..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -plugins { - id "java" - id "org.springframework.boot.conventions" -} - -description = "Spring Boot GraphQL smoke test" - -dependencies { - implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-graphql")) - implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) - implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-security")) - - testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test")) - testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-webflux")) - testImplementation('org.springframework.graphql:spring-graphql-test') -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/GreetingController.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/GreetingController.java deleted file mode 100644 index 18c5c62d8d..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/GreetingController.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-2021 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 smoketest.graphql; - -import org.springframework.graphql.data.method.annotation.Argument; -import org.springframework.graphql.data.method.annotation.QueryMapping; -import org.springframework.stereotype.Controller; - -@Controller -public class GreetingController { - - private final GreetingService greetingService; - - public GreetingController(GreetingService greetingService) { - this.greetingService = greetingService; - } - - @QueryMapping - public String greeting(@Argument String name) { - return this.greetingService.greet(name); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/GreetingService.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/GreetingService.java deleted file mode 100644 index aa9c5bee02..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/GreetingService.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-2021 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 smoketest.graphql; - -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.stereotype.Component; - -@Component -public class GreetingService { - - @PreAuthorize("hasRole('ADMIN')") - public String greet(String name) { - return "Hello, " + name + "!"; - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/Project.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/Project.java deleted file mode 100644 index 5e8d514de6..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/Project.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-2021 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 smoketest.graphql; - -import java.util.Objects; - -public class Project { - - private String slug; - - private String name; - - public Project(String slug, String name) { - this.slug = slug; - this.name = name; - } - - public String getSlug() { - return this.slug; - } - - public void setSlug(String slug) { - this.slug = slug; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Project project = (Project) o; - return this.slug.equals(project.slug); - } - - @Override - public int hashCode() { - return Objects.hash(this.slug); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/ProjectsController.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/ProjectsController.java deleted file mode 100644 index e2fd01dae7..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/ProjectsController.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-2021 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 smoketest.graphql; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import org.springframework.graphql.data.method.annotation.Argument; -import org.springframework.graphql.data.method.annotation.QueryMapping; -import org.springframework.stereotype.Controller; - -@Controller -public class ProjectsController { - - private final List projects; - - public ProjectsController() { - this.projects = Arrays.asList(new Project("spring-boot", "Spring Boot"), - new Project("spring-graphql", "Spring GraphQL"), new Project("spring-framework", "Spring Framework")); - } - - @QueryMapping - public Optional project(@Argument String slug) { - return this.projects.stream().filter((project) -> project.getSlug().equals(slug)).findFirst(); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SampleGraphQlApplication.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SampleGraphQlApplication.java deleted file mode 100644 index 9674af544a..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SampleGraphQlApplication.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-2021 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 smoketest.graphql; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SampleGraphQlApplication { - - public static void main(String[] args) { - SpringApplication.run(SampleGraphQlApplication.class, args); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SecurityConfig.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SecurityConfig.java deleted file mode 100644 index cfe1e0a203..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/java/smoketest/graphql/SecurityConfig.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-2021 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 smoketest.graphql; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.DefaultSecurityFilterChain; - -import static org.springframework.security.config.Customizer.withDefaults; - -@Configuration -@EnableWebSecurity -@EnableGlobalMethodSecurity(prePostEnabled = true) -public class SecurityConfig { - - @Bean - DefaultSecurityFilterChain springWebFilterChain(HttpSecurity http) throws Exception { - return http.csrf((csrf) -> csrf.disable()) - // Demonstrate that method security works - // Best practice to use both for defense in depth - .authorizeRequests((requests) -> requests.anyRequest().permitAll()).httpBasic(withDefaults()).build(); - } - - @Bean - public static InMemoryUserDetailsManager userDetailsService() { - User.UserBuilder userBuilder = User.withDefaultPasswordEncoder(); - UserDetails rob = userBuilder.username("rob").password("rob").roles("USER").build(); - UserDetails admin = userBuilder.username("admin").password("admin").roles("USER", "ADMIN").build(); - return new InMemoryUserDetailsManager(rob, admin); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/resources/graphql/greeting.graphql b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/resources/graphql/greeting.graphql deleted file mode 100644 index 1521607a7b..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/resources/graphql/greeting.graphql +++ /dev/null @@ -1,3 +0,0 @@ -query greeting($name: String!) { - greeting(name: $name) -} \ No newline at end of file diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/resources/graphql/schema.graphqls b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/resources/graphql/schema.graphqls deleted file mode 100644 index b9c9d0e729..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/main/resources/graphql/schema.graphqls +++ /dev/null @@ -1,12 +0,0 @@ -type Query { - greeting(name: String! = "Spring"): String! - project(slug: ID!): Project -} - -""" A Project in the Spring portfolio """ -type Project { - """ Unique string id used in URLs """ - slug: ID! - """ Project name """ - name: String! -} \ No newline at end of file diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/test/java/smoketest/graphql/GreetingControllerTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/test/java/smoketest/graphql/GreetingControllerTests.java deleted file mode 100644 index 75c9565c68..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/test/java/smoketest/graphql/GreetingControllerTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-2021 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 smoketest.graphql; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureWebGraphQlTester; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.graphql.execution.ErrorType; -import org.springframework.graphql.test.tester.WebGraphQlTester; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest -@AutoConfigureWebGraphQlTester -class GreetingControllerTests { - - @Autowired - private WebGraphQlTester graphQlTester; - - @Test - void shouldUnauthorizeAnonymousUsers() { - this.graphQlTester.queryName("greeting").variable("name", "Brian").execute().errors().satisfy((errors) -> { - assertThat(errors).hasSize(1); - assertThat(errors.get(0).getErrorType()).isEqualTo(ErrorType.UNAUTHORIZED); - }); - } - - @Test - void shouldGreetWithSpecificName() { - this.graphQlTester.queryName("greeting").variable("name", "Brian") - .httpHeaders((headers) -> headers.setBasicAuth("admin", "admin")).execute().path("greeting") - .entity(String.class).isEqualTo("Hello, Brian!"); - } - - @Test - void shouldGreetWithDefaultName() { - this.graphQlTester.query("{ greeting }").httpHeaders((headers) -> headers.setBasicAuth("admin", "admin")) - .execute().path("greeting").entity(String.class).isEqualTo("Hello, Spring!"); - } - -} diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/test/java/smoketest/graphql/ProjectControllerTests.java b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/test/java/smoketest/graphql/ProjectControllerTests.java deleted file mode 100644 index 89d3e218a1..0000000000 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-graphql/src/test/java/smoketest/graphql/ProjectControllerTests.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-2021 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 smoketest.graphql; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.graphql.GraphQlTest; -import org.springframework.graphql.test.tester.GraphQlTester; - -@GraphQlTest(ProjectsController.class) -class ProjectControllerTests { - - @Autowired - private GraphQlTester graphQlTester; - - @Test - void shouldFindSpringGraphQl() { - this.graphQlTester.query("{ project(slug: \"spring-graphql\") { name } }").execute().path("project.name") - .entity(String.class).isEqualTo("Spring GraphQL"); - } - - @Test - void shouldNotFindUnknownProject() { - this.graphQlTester.query("{ project(slug: \"spring-unknown\") { name } }").execute().path("project.name") - .valueDoesNotExist(); - } - -}