From c3b03a1b1159405681e894f81930cff1a04f351a Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 23 Oct 2018 09:52:45 +0100 Subject: [PATCH] Use web-application-type=reactive by default if webflux present We want the default application type to be REACTIVE if webflux is present (formerly it was NONE). In AWS and Azure we also want the webflux beans to be switched off in a "lite" application context (formerly they were unconditional). --- .../context/FunctionalSpringApplication.java | 20 +++++++++++++++---- .../test/FunctionalSpringBootTest.java | 11 +++++----- .../function-sample-aws/pom.xml | 4 ++-- .../src/test/java/example/MapTests.java | 2 -- .../src/main/resources/application.properties | 2 +- .../function/FunctionEndpointInitializer.java | 10 ++++++++-- .../cloud/function/test/FunctionalTests.java | 3 ++- .../function/test/HeadersToMessageTests.java | 3 ++- .../cloud/function/test/PojoTests.java | 3 ++- 9 files changed, 39 insertions(+), 19 deletions(-) diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java index 334611dae..cc9dae1e7 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/FunctionalSpringApplication.java @@ -30,12 +30,14 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; +import org.springframework.util.ClassUtils; /** * @author Dave Syer * */ -public class FunctionalSpringApplication extends org.springframework.boot.SpringApplication { +public class FunctionalSpringApplication + extends org.springframework.boot.SpringApplication { /** * Name of default property source. @@ -45,7 +47,12 @@ public class FunctionalSpringApplication extends org.springframework.boot.Spring /** * Flag to say that context is functional beans. */ - private static final String SPRING_FUNCTIONAL_ENABLED = "spring.functional.enabled"; + public static final String SPRING_FUNCTIONAL_ENABLED = "spring.functional.enabled"; + + /** + * Enumeration of web application types. + */ + public static final String SPRING_WEB_APPLICATION_TYPE = "spring.main.web-application-type"; public static ConfigurableApplicationContext run(Class primarySource, String... args) { @@ -59,9 +66,13 @@ public class FunctionalSpringApplication extends org.springframework.boot.Spring public FunctionalSpringApplication(Class... primarySources) { super(primarySources); - // Prefer non-web applications, even if a server is on the classpath - setWebApplicationType(WebApplicationType.NONE); setApplicationContextClass(GenericApplicationContext.class); + if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", + null)) { + setWebApplicationType(WebApplicationType.REACTIVE); + } else { + setWebApplicationType(WebApplicationType.NONE); + } } @Override @@ -134,6 +145,7 @@ public class FunctionalSpringApplication extends org.springframework.boot.Spring .getSource(); Map map = new HashMap<>(source); map.put(SPRING_FUNCTIONAL_ENABLED, "true"); + map.put(SPRING_WEB_APPLICATION_TYPE, getWebApplicationType()); sources.replace(DEFAULT_PROPERTIES, new MapPropertySource(DEFAULT_PROPERTIES, map)); } diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalSpringBootTest.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalSpringBootTest.java index 66bca2690..847846588 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalSpringBootTest.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/test/FunctionalSpringBootTest.java @@ -23,6 +23,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.core.annotation.AliasFor; import org.springframework.test.context.ContextConfiguration; @@ -37,20 +38,20 @@ import org.springframework.test.context.ContextConfiguration; @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited -@org.springframework.boot.test.context.SpringBootTest(properties = "spring.functional.enabled=true", webEnvironment = WebEnvironment.NONE) +@SpringBootTest(properties = "spring.functional.enabled=true") @ContextConfiguration(loader = FunctionalTestContextLoader.class) public @interface FunctionalSpringBootTest { - @AliasFor(annotation=org.springframework.boot.test.context.SpringBootTest.class, attribute="properties") + @AliasFor(annotation=SpringBootTest.class, attribute="properties") String[] value() default {}; - @AliasFor(annotation=org.springframework.boot.test.context.SpringBootTest.class, attribute="value") + @AliasFor(annotation=SpringBootTest.class, attribute="value") String[] properties() default {}; - @AliasFor(annotation=org.springframework.boot.test.context.SpringBootTest.class, attribute="classes") + @AliasFor(annotation=SpringBootTest.class, attribute="classes") Class[] classes() default {}; - @AliasFor(annotation=org.springframework.boot.test.context.SpringBootTest.class, attribute="webEnvironment") + @AliasFor(annotation=SpringBootTest.class, attribute="webEnvironment") WebEnvironment webEnvironment() default WebEnvironment.MOCK; } diff --git a/spring-cloud-function-samples/function-sample-aws/pom.xml b/spring-cloud-function-samples/function-sample-aws/pom.xml index 3c1fd4dbd..ee6ee3a41 100644 --- a/spring-cloud-function-samples/function-sample-aws/pom.xml +++ b/spring-cloud-function-samples/function-sample-aws/pom.xml @@ -14,7 +14,7 @@ org.springframework.boot spring-boot-starter-parent - 2.1.0.M1 + 2.1.0.BUILD-SNAPSHOT @@ -35,7 +35,7 @@ org.springframework.cloud - spring-cloud-starter-function-web + spring-cloud-starter-function-webflux provided diff --git a/spring-cloud-function-samples/function-sample-aws/src/test/java/example/MapTests.java b/spring-cloud-function-samples/function-sample-aws/src/test/java/example/MapTests.java index 6b3524918..aec63a84e 100644 --- a/spring-cloud-function-samples/function-sample-aws/src/test/java/example/MapTests.java +++ b/spring-cloud-function-samples/function-sample-aws/src/test/java/example/MapTests.java @@ -16,7 +16,6 @@ package example; -import org.junit.Ignore; import org.junit.Test; import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler; @@ -27,7 +26,6 @@ import static org.assertj.core.api.Assertions.assertThat; * @author Dave Syer * */ -@Ignore public class MapTests { @Test diff --git a/spring-cloud-function-samples/function-sample/src/main/resources/application.properties b/spring-cloud-function-samples/function-sample/src/main/resources/application.properties index e4b566fd5..e8f295050 100644 --- a/spring-cloud-function-samples/function-sample/src/main/resources/application.properties +++ b/spring-cloud-function-samples/function-sample/src/main/resources/application.properties @@ -1,2 +1,2 @@ spring.cloud.function.stream.processor.name: uppercase -spring.cloud.function.scan.packages: com.example.functions \ No newline at end of file +spring.cloud.function.scan.packages: com.example.functions diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializer.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializer.java index 309ce854f..8baec9692 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializer.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/function/FunctionEndpointInitializer.java @@ -24,12 +24,14 @@ import java.util.function.Function; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.ResourceProperties; import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler; import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; import org.springframework.boot.web.reactive.error.ErrorAttributes; import org.springframework.cloud.function.context.FunctionCatalog; +import org.springframework.cloud.function.context.FunctionalSpringApplication; import org.springframework.cloud.function.context.catalog.FunctionInspector; import org.springframework.cloud.function.json.JsonMapper; import org.springframework.cloud.function.web.BasicStringConverter; @@ -76,8 +78,12 @@ class FunctionEndpointInitializer @Override public void initialize(GenericApplicationContext context) { - if (context.getEnvironment().getProperty("spring.functional.enabled", - Boolean.class, false) + if (context.getEnvironment().getProperty( + FunctionalSpringApplication.SPRING_WEB_APPLICATION_TYPE, + WebApplicationType.class, + WebApplicationType.REACTIVE) == WebApplicationType.REACTIVE + && context.getEnvironment().getProperty("spring.functional.enabled", + Boolean.class, false) && ClassUtils.isPresent( "org.springframework.http.server.reactive.HttpHandler", null)) { registerEndpoint(context); diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalTests.java index 18a6fdb76..c42319115 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/FunctionalTests.java @@ -35,7 +35,8 @@ import reactor.core.publisher.Mono; * */ @RunWith(SpringRunner.class) -@FunctionalSpringBootTest +//Only need web-application-type because MVC is on the classpath +@FunctionalSpringBootTest("spring.main.web-application-type=reactive") @AutoConfigureWebTestClient public class FunctionalTests { diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/HeadersToMessageTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/HeadersToMessageTests.java index c13cf26dd..7e4c2145e 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/HeadersToMessageTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/HeadersToMessageTests.java @@ -37,7 +37,8 @@ import reactor.core.publisher.Mono; * */ @RunWith(SpringRunner.class) -@FunctionalSpringBootTest +// Only need web-application-type because MVC is on the classpath +@FunctionalSpringBootTest("spring.main.web-application-type=reactive") @AutoConfigureWebTestClient public class HeadersToMessageTests { diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/PojoTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/PojoTests.java index 8389f6b6e..9e222a065 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/PojoTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/test/PojoTests.java @@ -35,7 +35,8 @@ import reactor.core.publisher.Mono; * */ @RunWith(SpringRunner.class) -@FunctionalSpringBootTest +//Only need web-application-type because MVC is on the classpath +@FunctionalSpringBootTest("spring.main.web-application-type=reactive") @AutoConfigureWebTestClient public class PojoTests {