diff --git a/vaadin-spring/src/main/java/com/vaadin/flow/spring/VaadinServletContextInitializer.java b/vaadin-spring/src/main/java/com/vaadin/flow/spring/VaadinServletContextInitializer.java index 784d22723..eb76f0846 100644 --- a/vaadin-spring/src/main/java/com/vaadin/flow/spring/VaadinServletContextInitializer.java +++ b/vaadin-spring/src/main/java/com/vaadin/flow/spring/VaadinServletContextInitializer.java @@ -37,6 +37,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.Executor; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -61,6 +62,7 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.core.task.TaskExecutor; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.core.type.filter.AssignableTypeFilter; @@ -366,6 +368,8 @@ public void failFastContextInitialized(ServletContextEvent event) isDevModeAlreadyStarted(event.getServletContext())) { return; } + config.getInitParameters().put(Executor.class, + appContext.getBean(TaskExecutor.class)); Set basePackages; if (isScanOnlySet()) { diff --git a/vaadin-spring/src/test/java/com/vaadin/flow/spring/VaadinServletContextInitializerTest.java b/vaadin-spring/src/test/java/com/vaadin/flow/spring/VaadinServletContextInitializerTest.java index ee909bdd0..37918f9dd 100644 --- a/vaadin-spring/src/test/java/com/vaadin/flow/spring/VaadinServletContextInitializerTest.java +++ b/vaadin-spring/src/test/java/com/vaadin/flow/spring/VaadinServletContextInitializerTest.java @@ -1,20 +1,17 @@ package com.vaadin.flow.spring; -import com.google.common.collect.Maps; +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; -import com.vaadin.flow.component.Component; -import com.vaadin.flow.function.DeploymentConfiguration; -import com.vaadin.flow.router.BeforeEnterEvent; -import com.vaadin.flow.router.ErrorParameter; -import com.vaadin.flow.router.HasErrorParameter; -import com.vaadin.flow.router.NotFoundException; -import com.vaadin.flow.router.RouteNotFoundError; -import com.vaadin.flow.server.VaadinServletContext; -import com.vaadin.flow.server.startup.ApplicationRouteRegistry; -import com.vaadin.flow.server.startup.DevModeInitializer; -import com.vaadin.flow.server.startup.ServletDeployer; -import com.vaadin.flow.spring.router.SpringRouteNotFoundError; +import java.util.Collections; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; +import com.google.common.collect.Maps; import org.apache.commons.lang3.StringUtils; import org.junit.Assert; import org.junit.Before; @@ -22,28 +19,34 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.boot.autoconfigure.AutoConfigurationPackages; import org.springframework.context.ApplicationContext; import org.springframework.core.env.Environment; +import org.springframework.core.task.TaskExecutor; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Stream; +import com.vaadin.flow.component.Component; +import com.vaadin.flow.function.DeploymentConfiguration; +import com.vaadin.flow.router.BeforeEnterEvent; +import com.vaadin.flow.router.ErrorParameter; +import com.vaadin.flow.router.HasErrorParameter; +import com.vaadin.flow.router.NotFoundException; +import com.vaadin.flow.router.RouteNotFoundError; +import com.vaadin.flow.server.VaadinServletContext; +import com.vaadin.flow.server.startup.ApplicationRouteRegistry; +import com.vaadin.flow.server.startup.DevModeInitializer; +import com.vaadin.flow.server.startup.ServletDeployer; +import com.vaadin.flow.spring.router.SpringRouteNotFoundError; @RunWith(PowerMockRunner.class) -@PrepareForTest({DevModeInitializer.class, +@PrepareForTest({ DevModeInitializer.class, VaadinServletContextInitializer.SpringStubServletConfig.class, - VaadinServletContextInitializer.class, - ServletDeployer.class, + VaadinServletContextInitializer.class, ServletDeployer.class, ServletDeployer.StubServletConfig.class, - AutoConfigurationPackages.class}) + AutoConfigurationPackages.class }) public class VaadinServletContextInitializerTest { @Mock @@ -58,9 +61,27 @@ public class VaadinServletContextInitializerTest { @Mock private DeploymentConfiguration deploymentConfiguration; + private Properties properties; + + @Mock + private TaskExecutor executor; + @Before public void init() { - PowerMockito.mockStatic(VaadinServletContextInitializer.SpringStubServletConfig.class); + PowerMockito.mockStatic( + VaadinServletContextInitializer.SpringStubServletConfig.class); + MockitoAnnotations.initMocks(this); + + properties = new Properties(); + + Mockito.when(deploymentConfiguration.getInitParameters()) + .thenReturn(properties); + + Mockito.when(applicationContext.getBean(TaskExecutor.class)) + .thenReturn(executor); + + PowerMockito.mockStatic( + VaadinServletContextInitializer.SpringStubServletConfig.class); PowerMockito.mockStatic(ServletDeployer.class); PowerMockito.mockStatic(ServletDeployer.StubServletConfig.class); PowerMockito.mockStatic(DevModeInitializer.class); @@ -68,30 +89,37 @@ public void init() { } @Test - public void onStartup_devModeNotInitialized_devModeInitialized() throws Exception { + public void onStartup_devModeNotInitialized_devModeInitialized() + throws Exception { initDefaultMocks(); - VaadinServletContextInitializer vaadinServletContextInitializer = - getStubbedVaadinServletContextInitializer(); + VaadinServletContextInitializer vaadinServletContextInitializer = getStubbedVaadinServletContextInitializer(); // Simulate Spring context start only vaadinServletContextInitializer.onStartup(servletContext); - // This is how PowerMockito works, call PowerMockito.verifyStatic() first + // This is how PowerMockito works, call PowerMockito.verifyStatic() + // first // to start verifying behavior of DevModeInitializer static methods PowerMockito.verifyStatic(DevModeInitializer.class); - // IMPORTANT: Call the static method we want to verify. - // In our case, we want to check if Dev Mode has been started within onStartup() call, - // that means DevModeInitializer.initDevModeHandler() should has been called exactly one time - DevModeInitializer.initDevModeHandler(Mockito.any(), Mockito.any(), Mockito.any()); + // IMPORTANT: Call the static method we want to verify. + // In our case, we want to check if Dev Mode has been started within + // onStartup() call, + // that means DevModeInitializer.initDevModeHandler() should has been + // called exactly one time + DevModeInitializer.initDevModeHandler(Mockito.any(), Mockito.any(), + Mockito.any()); + + Mockito.verify(applicationContext).getBean(TaskExecutor.class); + Assert.assertSame(executor, properties.get(Executor.class)); } @Test - public void onStartup_devModeAlreadyInitialized_devModeInitializationSkipped() throws Exception { + public void onStartup_devModeAlreadyInitialized_devModeInitializationSkipped() + throws Exception { initDefaultMocks(); - VaadinServletContextInitializer vaadinServletContextInitializer = - getStubbedVaadinServletContextInitializer(); + VaadinServletContextInitializer vaadinServletContextInitializer = getStubbedVaadinServletContextInitializer(); DevModeInitializer devModeInitializer = getStubbedDevModeInitializer(); @@ -99,22 +127,27 @@ public void onStartup_devModeAlreadyInitialized_devModeInitializationSkipped() t devModeInitializer.process(Collections.emptySet(), servletContext); vaadinServletContextInitializer.onStartup(servletContext); - // This is how PowerMockito works, call PowerMockito.verifyStatic() first + // This is how PowerMockito works, call PowerMockito.verifyStatic() + // first // to start verifying behavior of DevModeInitializer static methods PowerMockito.verifyStatic(DevModeInitializer.class); - // IMPORTANT: Call the static method we want to verify. + // IMPORTANT: Call the static method we want to verify. // In our case, we want to check if Dev Mode has been started within - // devModeInitializer.process() call (i.e. from Servlet Container), and not started again + // devModeInitializer.process() call (i.e. from Servlet Container), and + // not started again // within DevModeInitializer.initDevModeHandler() (Spring context), // so, we expect this method has been called exactly one time: - DevModeInitializer.initDevModeHandler(Mockito.any(), Mockito.any(), Mockito.any()); + DevModeInitializer.initDevModeHandler(Mockito.any(), Mockito.any(), + Mockito.any()); } @Test - public void errorParameterServletContextListenerEvent_defaultRouteNotFoundView_defaultRouteNotFoundViewIsRegistered() throws Exception { + public void errorParameterServletContextListenerEvent_defaultRouteNotFoundView_defaultRouteNotFoundViewIsRegistered() + throws Exception { // given initDefaultMocks(); - Runnable when = initRouteNotFoundMocksAndGetContextInitializedMockCall(getStubbedVaadinServletContextInitializer()); + Runnable when = initRouteNotFoundMocksAndGetContextInitializedMockCall( + getStubbedVaadinServletContextInitializer()); // when when.run(); @@ -122,28 +155,28 @@ public void errorParameterServletContextListenerEvent_defaultRouteNotFoundView_d // then ApplicationRouteRegistry registry = ApplicationRouteRegistry .getInstance(new VaadinServletContext(servletContext)); - final Class navigationTarget = - registry.getErrorNavigationTarget(new NotFoundException()).get().getNavigationTarget(); + final Class navigationTarget = registry + .getErrorNavigationTarget(new NotFoundException()).get() + .getNavigationTarget(); Assert.assertEquals(SpringRouteNotFoundError.class, navigationTarget); } @Test - public void errorParameterServletContextListenerEvent_hasCustomRouteNotFoundViewExtendingRouteNotFoundError_customRouteNotFoundViewIsRegistered() throws Exception { + public void errorParameterServletContextListenerEvent_hasCustomRouteNotFoundViewExtendingRouteNotFoundError_customRouteNotFoundViewIsRegistered() + throws Exception { // given initDefaultMocks(); VaadinServletContextInitializer initializer = getStubbedVaadinServletContextInitializer(); - Runnable when = initRouteNotFoundMocksAndGetContextInitializedMockCall(initializer); + Runnable when = initRouteNotFoundMocksAndGetContextInitializedMockCall( + initializer); class TestErrorView extends RouteNotFoundError { } - PowerMockito.doReturn(Stream.of(TestErrorView.class)) - .when(initializer, - "findByAnnotationOrSuperType", - Mockito.anyCollection(), - Mockito.any(), - Mockito.anyCollection(), - Mockito.anyCollection()); + PowerMockito.doReturn(Stream.of(TestErrorView.class)).when(initializer, + "findByAnnotationOrSuperType", Mockito.anyCollection(), + Mockito.any(), Mockito.anyCollection(), + Mockito.anyCollection()); // when when.run(); @@ -151,32 +184,34 @@ class TestErrorView extends RouteNotFoundError { // then ApplicationRouteRegistry registry = ApplicationRouteRegistry .getInstance(new VaadinServletContext(servletContext)); - final Class navigationTarget = - registry.getErrorNavigationTarget(new NotFoundException()).get().getNavigationTarget(); + final Class navigationTarget = registry + .getErrorNavigationTarget(new NotFoundException()).get() + .getNavigationTarget(); Assert.assertEquals(TestErrorView.class, navigationTarget); } @Test - public void errorParameterServletContextListenerEvent_hasCustomRouteNotFoundViewImplementingHasErrorParameter_customRouteNotFoundViewIsRegistered() throws Exception { + public void errorParameterServletContextListenerEvent_hasCustomRouteNotFoundViewImplementingHasErrorParameter_customRouteNotFoundViewIsRegistered() + throws Exception { // given initDefaultMocks(); VaadinServletContextInitializer initializer = getStubbedVaadinServletContextInitializer(); - Runnable when = initRouteNotFoundMocksAndGetContextInitializedMockCall(initializer); + Runnable when = initRouteNotFoundMocksAndGetContextInitializedMockCall( + initializer); - class TestErrorView extends Component implements HasErrorParameter { + class TestErrorView extends Component + implements HasErrorParameter { @Override - public int setErrorParameter(BeforeEnterEvent event, ErrorParameter parameter) { + public int setErrorParameter(BeforeEnterEvent event, + ErrorParameter parameter) { return 0; } } - PowerMockito.doReturn(Stream.of(TestErrorView.class)) - .when(initializer, - "findByAnnotationOrSuperType", - Mockito.anyCollection(), - Mockito.any(), - Mockito.anyCollection(), - Mockito.anyCollection()); + PowerMockito.doReturn(Stream.of(TestErrorView.class)).when(initializer, + "findByAnnotationOrSuperType", Mockito.anyCollection(), + Mockito.any(), Mockito.anyCollection(), + Mockito.anyCollection()); // when when.run(); @@ -184,8 +219,9 @@ public int setErrorParameter(BeforeEnterEvent event, ErrorParameter navigationTarget = - registry.getErrorNavigationTarget(new NotFoundException()).get().getNavigationTarget(); + final Class navigationTarget = registry + .getErrorNavigationTarget(new NotFoundException()).get() + .getNavigationTarget(); Assert.assertEquals(TestErrorView.class, navigationTarget); } @@ -197,22 +233,26 @@ private Runnable initRouteNotFoundMocksAndGetContextInitializedMockCall( AtomicReference theListener = new AtomicReference<>(); Mockito.doAnswer(answer -> { ServletContextListener listener = answer.getArgument(0); - if ("ErrorParameterServletContextListener".equals( - listener.getClass().getSimpleName())) { + if ("ErrorParameterServletContextListener" + .equals(listener.getClass().getSimpleName())) { theListener.set(listener); } return null; - }).when(servletContext).addListener(Mockito.any(ServletContextListener.class)); + }).when(servletContext) + .addListener(Mockito.any(ServletContextListener.class)); vaadinServletContextInitializer.onStartup(servletContext); - Mockito.when(applicationContext.getBeanNamesForType(VaadinScanPackagesRegistrar.VaadinScanPackages.class)) - .thenReturn(new String[]{}); + Mockito.when(applicationContext.getBeanNamesForType( + VaadinScanPackagesRegistrar.VaadinScanPackages.class)) + .thenReturn(new String[] {}); PowerMockito.when(AutoConfigurationPackages.class, "has", applicationContext).thenReturn(false); - ServletContextEvent initEventMock = Mockito.mock(ServletContextEvent.class); - Mockito.when(initEventMock.getServletContext()).thenReturn(servletContext); + ServletContextEvent initEventMock = Mockito + .mock(ServletContextEvent.class); + Mockito.when(initEventMock.getServletContext()) + .thenReturn(servletContext); return () -> { theListener.get().contextInitialized(initEventMock); @@ -221,51 +261,45 @@ private Runnable initRouteNotFoundMocksAndGetContextInitializedMockCall( private DevModeInitializer getStubbedDevModeInitializer() throws Exception { PowerMockito.when(ServletDeployer.StubServletConfig.class, - "createDeploymentConfiguration", - Mockito.any(), - Mockito.any()) + "createDeploymentConfiguration", Mockito.any(), Mockito.any()) .thenReturn(deploymentConfiguration); - PowerMockito.when(DevModeInitializer.class, - "isDevModeAlreadyStarted", - servletContext) - .thenCallRealMethod(); + PowerMockito.when(DevModeInitializer.class, "isDevModeAlreadyStarted", + servletContext).thenCallRealMethod(); return new DevModeInitializer(); } - private VaadinServletContextInitializer getStubbedVaadinServletContextInitializer() throws Exception { - VaadinServletContextInitializer vaadinServletContextInitializerMock = - PowerMockito.spy(new VaadinServletContextInitializer(applicationContext)); + private VaadinServletContextInitializer getStubbedVaadinServletContextInitializer() + throws Exception { + VaadinServletContextInitializer vaadinServletContextInitializerMock = PowerMockito + .spy(new VaadinServletContextInitializer(applicationContext)); - PowerMockito.when(VaadinServletContextInitializer.SpringStubServletConfig.class, - "createDeploymentConfiguration", - Mockito.any(), - Mockito.any(), - Mockito.any()) - .thenReturn(deploymentConfiguration); + PowerMockito.when( + VaadinServletContextInitializer.SpringStubServletConfig.class, + "createDeploymentConfiguration", Mockito.any(), Mockito.any(), + Mockito.any()).thenReturn(deploymentConfiguration); - PowerMockito.doReturn(Stream.empty()) - .when(vaadinServletContextInitializerMock, - "findByAnnotationOrSuperType", - Mockito.anyCollection(), - Mockito.any(), - Mockito.anyCollection(), - Mockito.anyCollection()); + PowerMockito.doReturn(Stream.empty()).when( + vaadinServletContextInitializerMock, + "findByAnnotationOrSuperType", Mockito.anyCollection(), + Mockito.any(), Mockito.anyCollection(), + Mockito.anyCollection()); Mockito.doAnswer(answer -> { - ServletContextListener devModeListener = - answer.getArgument(0); - if ("DevModeServletContextListener".equals( - devModeListener.getClass().getSimpleName())) { - devModeListener.contextInitialized(new ServletContextEvent(servletContext)); + ServletContextListener devModeListener = answer.getArgument(0); + if ("DevModeServletContextListener" + .equals(devModeListener.getClass().getSimpleName())) { + devModeListener.contextInitialized( + new ServletContextEvent(servletContext)); } return null; - }).when(servletContext).addListener(Mockito.any(ServletContextListener.class)); + }).when(servletContext) + .addListener(Mockito.any(ServletContextListener.class)); - PowerMockito.doNothing() - .when(ServletDeployer.class); - ServletDeployer.logAppStartupToConsole(Mockito.any(), Mockito.anyBoolean()); + PowerMockito.doNothing().when(ServletDeployer.class); + ServletDeployer.logAppStartupToConsole(Mockito.any(), + Mockito.anyBoolean()); return vaadinServletContextInitializerMock; } @@ -278,18 +312,18 @@ private void initDefaultMocks() { } private void mockServletContext() { - final Map servletContextAttributesMap = Maps.newHashMap(); + final Map servletContextAttributesMap = Maps + .newHashMap(); Mockito.doAnswer(answer -> { - String key = answer.getArgument(0, String.class); - Object value = answer.getArgument(1, Object.class); - servletContextAttributesMap.putIfAbsent(key, value); - return null; - }) - .when(servletContext) - .setAttribute(Mockito.anyString(), Mockito.any()); + String key = answer.getArgument(0, String.class); + Object value = answer.getArgument(1, Object.class); + servletContextAttributesMap.putIfAbsent(key, value); + return null; + }).when(servletContext).setAttribute(Mockito.anyString(), + Mockito.any()); Mockito.when(servletContext.getAttribute(Mockito.anyString())) - .thenAnswer(answer -> - servletContextAttributesMap.get(answer.getArgument(0, String.class))); + .thenAnswer(answer -> servletContextAttributesMap + .get(answer.getArgument(0, String.class))); Mockito.when(servletContext.getServletRegistrations()) .thenReturn(Maps.newHashMap()); } @@ -307,6 +341,7 @@ private void mockDeploymentConfiguration() { } private void mockApplicationContext() { - Mockito.when(applicationContext.getEnvironment()).thenReturn(environment); + Mockito.when(applicationContext.getEnvironment()) + .thenReturn(environment); } }