Suggest setting spring.main.web-application-type=reactive if mvc on classpath.
See gh-2176K
This commit is contained in:
@@ -29,6 +29,10 @@
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
||||
@@ -18,12 +18,50 @@ package org.springframework.cloud.gateway.sample;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.web.server.LocalServerPort;
|
||||
import org.springframework.cloud.client.DefaultServiceInstance;
|
||||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||||
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
|
||||
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
|
||||
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
|
||||
import org.springframework.cloud.loadbalancer.support.ServiceInstanceListSuppliers;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
@LoadBalancerClient(name = "myservice", configuration = MyServiceConf.class)
|
||||
public class MvcFailureAnalyzerApplication {
|
||||
|
||||
@GetMapping("hello")
|
||||
public String hello() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
public RouteLocator myRouteLocator(RouteLocatorBuilder builder) {
|
||||
return builder.routes().route(r -> r.path("/myprefix/**")
|
||||
.filters(f -> f.stripPrefix(1)).uri("lb://myservice")).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MyServiceConf {
|
||||
|
||||
@LocalServerPort
|
||||
private int port = 0;
|
||||
|
||||
@Bean
|
||||
public ServiceInstanceListSupplier staticServiceInstanceListSupplier() {
|
||||
return ServiceInstanceListSuppliers.from("myservice", new DefaultServiceInstance(
|
||||
"myservice-1", "myservice", "localhost", port, false));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,9 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.cloud.gateway.support.MvcFoundOnClasspathException;
|
||||
import org.springframework.cloud.gateway.support.MvcFoundOnClasspathFailureAnalyzer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
@@ -40,8 +43,8 @@ public class MvcFailureAnalyzerApplicationTests {
|
||||
() -> new SpringApplication(MvcFailureAnalyzerApplication.class)
|
||||
.run("--server.port=0")).hasRootCauseInstanceOf(
|
||||
MvcFoundOnClasspathException.class);
|
||||
assertThat(output).contains("Spring MVC found on classpath",
|
||||
"Please remove spring-boot-starter-web dependency");
|
||||
assertThat(output).contains(MvcFoundOnClasspathFailureAnalyzer.MESSAGE,
|
||||
MvcFoundOnClasspathFailureAnalyzer.ACTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -49,8 +52,28 @@ public class MvcFailureAnalyzerApplicationTests {
|
||||
assertThatCode(() -> new SpringApplication(MvcFailureAnalyzerApplication.class)
|
||||
.run("--spring.cloud.gateway.enabled=false", "--server.port=0"))
|
||||
.doesNotThrowAnyException();
|
||||
assertThat(output).doesNotContain("Spring MVC found on classpath",
|
||||
"Please remove spring-boot-starter-web dependency");
|
||||
assertThat(output).doesNotContain(MvcFoundOnClasspathFailureAnalyzer.MESSAGE,
|
||||
MvcFoundOnClasspathFailureAnalyzer.ACTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionNotThrownWhenReactiveTypeSet(CapturedOutput output) {
|
||||
assertThatCode(() -> {
|
||||
ConfigurableApplicationContext context = new SpringApplication(
|
||||
MvcFailureAnalyzerApplication.class).run(
|
||||
"--spring.main.web-application-type=reactive",
|
||||
"--server.port=0", "--debug=true");
|
||||
Integer port = context.getEnvironment().getProperty("local.server.port",
|
||||
Integer.class);
|
||||
WebTestClient client = WebTestClient.bindToServer()
|
||||
.baseUrl("http://localhost:" + port).build();
|
||||
client.get().uri("/myprefix/hello").exchange().expectStatus().isOk()
|
||||
.expectBody(String.class).isEqualTo("Hello");
|
||||
context.close();
|
||||
}).doesNotThrowAnyException();
|
||||
assertThat(output).doesNotContain(MvcFoundOnClasspathFailureAnalyzer.MESSAGE,
|
||||
MvcFoundOnClasspathFailureAnalyzer.ACTION);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.cloud.gateway.support.MvcFoundOnClasspathException;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -38,6 +39,7 @@ public class GatewayClassPathWarningAutoConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(name = "org.springframework.web.servlet.DispatcherServlet")
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
|
||||
protected static class SpringMvcFoundOnClasspathConfiguration {
|
||||
|
||||
public SpringMvcFoundOnClasspathConfiguration() {
|
||||
|
||||
@@ -22,12 +22,20 @@ import org.springframework.boot.diagnostics.FailureAnalysis;
|
||||
public class MvcFoundOnClasspathFailureAnalyzer
|
||||
extends AbstractFailureAnalyzer<MvcFoundOnClasspathException> {
|
||||
|
||||
/**
|
||||
* Message for MvcFoundOnClasspathException.
|
||||
*/
|
||||
public static final String MESSAGE = "Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.";
|
||||
|
||||
/**
|
||||
* Action for MvcFoundOnClasspathException.
|
||||
*/
|
||||
public static final String ACTION = "Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.";
|
||||
|
||||
@Override
|
||||
protected FailureAnalysis analyze(Throwable rootFailure,
|
||||
MvcFoundOnClasspathException cause) {
|
||||
String message = "Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.";
|
||||
String action = "Please remove spring-boot-starter-web dependency.";
|
||||
return new FailureAnalysis(message, action, cause);
|
||||
return new FailureAnalysis(MESSAGE, ACTION, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user