Search in sources :

Example 6 with WebAsyncManager

use of org.springframework.web.context.request.async.WebAsyncManager in project spring-framework by spring-projects.

the class ResponseBodyEmitterReturnValueHandlerTests method responseBodyFluxWithError.

// gh-21972
@Test
public void responseBodyFluxWithError() throws Exception {
    this.request.addHeader("Accept", "text/event-stream");
    MethodParameter type = on(TestController.class).resolveReturnType(Flux.class, String.class);
    Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();
    this.handler.handleReturnValue(sink.asFlux(), type, this.mavContainer, this.webRequest);
    assertThat(this.request.isAsyncStarted()).isTrue();
    IllegalStateException ex = new IllegalStateException("wah wah");
    sink.tryEmitError(ex);
    sink.tryEmitComplete();
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(this.webRequest);
    assertThat(asyncManager.getConcurrentResult()).isSameAs(ex);
    assertThat(this.response.getContentType()).isNull();
}
Also used : WebAsyncManager(org.springframework.web.context.request.async.WebAsyncManager) Sinks(reactor.core.publisher.Sinks) MethodParameter(org.springframework.core.MethodParameter) Test(org.junit.jupiter.api.Test)

Example 7 with WebAsyncManager

use of org.springframework.web.context.request.async.WebAsyncManager in project spring-framework by spring-projects.

the class OpenEntityManagerInViewInterceptor method preHandle.

@Override
public void preHandle(WebRequest request) throws DataAccessException {
    String key = getParticipateAttributeName();
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
    if (asyncManager.hasConcurrentResult() && applyEntityManagerBindingInterceptor(asyncManager, key)) {
        return;
    }
    EntityManagerFactory emf = obtainEntityManagerFactory();
    if (TransactionSynchronizationManager.hasResource(emf)) {
        // Do not modify the EntityManager: just mark the request accordingly.
        Integer count = (Integer) request.getAttribute(key, WebRequest.SCOPE_REQUEST);
        int newCount = (count != null ? count + 1 : 1);
        request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST);
    } else {
        logger.debug("Opening JPA EntityManager in OpenEntityManagerInViewInterceptor");
        try {
            EntityManager em = createEntityManager();
            EntityManagerHolder emHolder = new EntityManagerHolder(em);
            TransactionSynchronizationManager.bindResource(emf, emHolder);
            AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(emf, emHolder);
            asyncManager.registerCallableInterceptor(key, interceptor);
            asyncManager.registerDeferredResultInterceptor(key, interceptor);
        } catch (PersistenceException ex) {
            throw new DataAccessResourceFailureException("Could not create JPA EntityManager", ex);
        }
    }
}
Also used : WebAsyncManager(org.springframework.web.context.request.async.WebAsyncManager) EntityManager(jakarta.persistence.EntityManager) DataAccessResourceFailureException(org.springframework.dao.DataAccessResourceFailureException) EntityManagerFactory(jakarta.persistence.EntityManagerFactory) PersistenceException(jakarta.persistence.PersistenceException) EntityManagerHolder(org.springframework.orm.jpa.EntityManagerHolder)

Example 8 with WebAsyncManager

use of org.springframework.web.context.request.async.WebAsyncManager in project spring-framework by spring-projects.

the class OpenSessionInViewInterceptor method preHandle.

/**
 * Open a new Hibernate {@code Session} according and bind it to the thread via the
 * {@link TransactionSynchronizationManager}.
 */
@Override
public void preHandle(WebRequest request) throws DataAccessException {
    String key = getParticipateAttributeName();
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
    if (asyncManager.hasConcurrentResult() && applySessionBindingInterceptor(asyncManager, key)) {
        return;
    }
    if (TransactionSynchronizationManager.hasResource(obtainSessionFactory())) {
        // Do not modify the Session: just mark the request accordingly.
        Integer count = (Integer) request.getAttribute(key, WebRequest.SCOPE_REQUEST);
        int newCount = (count != null ? count + 1 : 1);
        request.setAttribute(getParticipateAttributeName(), newCount, WebRequest.SCOPE_REQUEST);
    } else {
        logger.debug("Opening Hibernate Session in OpenSessionInViewInterceptor");
        Session session = openSession();
        SessionHolder sessionHolder = new SessionHolder(session);
        TransactionSynchronizationManager.bindResource(obtainSessionFactory(), sessionHolder);
        AsyncRequestInterceptor asyncRequestInterceptor = new AsyncRequestInterceptor(obtainSessionFactory(), sessionHolder);
        asyncManager.registerCallableInterceptor(key, asyncRequestInterceptor);
        asyncManager.registerDeferredResultInterceptor(key, asyncRequestInterceptor);
    }
}
Also used : WebAsyncManager(org.springframework.web.context.request.async.WebAsyncManager) SessionHolder(org.springframework.orm.hibernate5.SessionHolder) Session(org.hibernate.Session)

Example 9 with WebAsyncManager

use of org.springframework.web.context.request.async.WebAsyncManager in project spring-framework by spring-projects.

the class OpenEntityManagerInViewFilter method doFilterInternal.

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    EntityManagerFactory emf = lookupEntityManagerFactory(request);
    boolean participate = false;
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
    String key = getAlreadyFilteredAttributeName();
    if (TransactionSynchronizationManager.hasResource(emf)) {
        // Do not modify the EntityManager: just set the participate flag.
        participate = true;
    } else {
        boolean isFirstRequest = !isAsyncDispatch(request);
        if (isFirstRequest || !applyEntityManagerBindingInterceptor(asyncManager, key)) {
            logger.debug("Opening JPA EntityManager in OpenEntityManagerInViewFilter");
            try {
                EntityManager em = createEntityManager(emf);
                EntityManagerHolder emHolder = new EntityManagerHolder(em);
                TransactionSynchronizationManager.bindResource(emf, emHolder);
                AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(emf, emHolder);
                asyncManager.registerCallableInterceptor(key, interceptor);
                asyncManager.registerDeferredResultInterceptor(key, interceptor);
            } catch (PersistenceException ex) {
                throw new DataAccessResourceFailureException("Could not create JPA EntityManager", ex);
            }
        }
    }
    try {
        filterChain.doFilter(request, response);
    } finally {
        if (!participate) {
            EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.unbindResource(emf);
            if (!isAsyncStarted(request)) {
                logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewFilter");
                EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
            }
        }
    }
}
Also used : WebAsyncManager(org.springframework.web.context.request.async.WebAsyncManager) EntityManager(jakarta.persistence.EntityManager) DataAccessResourceFailureException(org.springframework.dao.DataAccessResourceFailureException) EntityManagerFactory(jakarta.persistence.EntityManagerFactory) PersistenceException(jakarta.persistence.PersistenceException) EntityManagerHolder(org.springframework.orm.jpa.EntityManagerHolder)

Example 10 with WebAsyncManager

use of org.springframework.web.context.request.async.WebAsyncManager in project spring-framework by spring-projects.

the class OpenEntityManagerInViewTests method testOpenEntityManagerInViewFilterAsyncScenario.

@Test
public void testOpenEntityManagerInViewFilterAsyncScenario() throws Exception {
    given(manager.isOpen()).willReturn(true);
    final EntityManagerFactory factory2 = mock(EntityManagerFactory.class);
    final EntityManager manager2 = mock(EntityManager.class);
    given(factory2.createEntityManager()).willReturn(manager2);
    given(manager2.isOpen()).willReturn(true);
    MockServletContext sc = new MockServletContext();
    StaticWebApplicationContext wac = new StaticWebApplicationContext();
    wac.setServletContext(sc);
    wac.getDefaultListableBeanFactory().registerSingleton("entityManagerFactory", factory);
    wac.getDefaultListableBeanFactory().registerSingleton("myEntityManagerFactory", factory2);
    wac.refresh();
    sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
    MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
    MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
    filterConfig2.addInitParameter("entityManagerFactoryBeanName", "myEntityManagerFactory");
    final OpenEntityManagerInViewFilter filter = new OpenEntityManagerInViewFilter();
    filter.init(filterConfig);
    final OpenEntityManagerInViewFilter filter2 = new OpenEntityManagerInViewFilter();
    filter2.init(filterConfig2);
    final AtomicInteger count = new AtomicInteger();
    final FilterChain filterChain = (servletRequest, servletResponse) -> {
        assertThat(TransactionSynchronizationManager.hasResource(factory)).isTrue();
        servletRequest.setAttribute("invoked", Boolean.TRUE);
        count.incrementAndGet();
    };
    final AtomicInteger count2 = new AtomicInteger();
    final FilterChain filterChain2 = (servletRequest, servletResponse) -> {
        assertThat(TransactionSynchronizationManager.hasResource(factory2)).isTrue();
        filter.doFilter(servletRequest, servletResponse, filterChain);
        count2.incrementAndGet();
    };
    FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);
    AsyncWebRequest asyncWebRequest = mock(AsyncWebRequest.class);
    given(asyncWebRequest.isAsyncStarted()).willReturn(true);
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(this.request);
    asyncManager.setTaskExecutor(this.taskExecutor);
    asyncManager.setAsyncWebRequest(asyncWebRequest);
    asyncManager.startCallableProcessing((Callable<String>) () -> "anything");
    this.taskExecutor.await();
    assertThat(asyncManager.getConcurrentResult()).as("Concurrent result ").isEqualTo("anything");
    assertThat(TransactionSynchronizationManager.hasResource(factory)).isFalse();
    assertThat(TransactionSynchronizationManager.hasResource(factory2)).isFalse();
    filter2.doFilter(this.request, this.response, filterChain3);
    assertThat(TransactionSynchronizationManager.hasResource(factory)).isFalse();
    assertThat(TransactionSynchronizationManager.hasResource(factory2)).isFalse();
    assertThat(count.get()).isEqualTo(1);
    assertThat(count2.get()).isEqualTo(1);
    assertThat(request.getAttribute("invoked")).isNotNull();
    verify(asyncWebRequest, times(2)).addCompletionHandler(any(Runnable.class));
    verify(asyncWebRequest).addTimeoutHandler(any(Runnable.class));
    verify(asyncWebRequest, times(2)).addCompletionHandler(any(Runnable.class));
    verify(asyncWebRequest).startAsync();
    // Async dispatch after concurrent handling produces result ...
    reset(asyncWebRequest);
    given(asyncWebRequest.isAsyncStarted()).willReturn(false);
    assertThat(TransactionSynchronizationManager.hasResource(factory)).isFalse();
    assertThat(TransactionSynchronizationManager.hasResource(factory2)).isFalse();
    filter.doFilter(this.request, this.response, filterChain3);
    assertThat(TransactionSynchronizationManager.hasResource(factory)).isFalse();
    assertThat(TransactionSynchronizationManager.hasResource(factory2)).isFalse();
    assertThat(count.get()).isEqualTo(2);
    assertThat(count2.get()).isEqualTo(2);
    verify(this.manager).close();
    verify(manager2).close();
    wac.close();
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) BeforeEach(org.junit.jupiter.api.BeforeEach) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) AsyncWebRequest(org.springframework.web.context.request.async.AsyncWebRequest) StaticWebApplicationContext(org.springframework.web.context.support.StaticWebApplicationContext) Callable(java.util.concurrent.Callable) WebAsyncManager(org.springframework.web.context.request.async.WebAsyncManager) TransactionSynchronizationManager(org.springframework.transaction.support.TransactionSynchronizationManager) ServletWebRequest(org.springframework.web.context.request.ServletWebRequest) MockHttpServletResponse(org.springframework.web.testfixture.servlet.MockHttpServletResponse) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BDDMockito.given(org.mockito.BDDMockito.given) SimpleAsyncTaskExecutor(org.springframework.core.task.SimpleAsyncTaskExecutor) AsyncEvent(jakarta.servlet.AsyncEvent) StandardServletAsyncWebRequest(org.springframework.web.context.request.async.StandardServletAsyncWebRequest) WebAsyncUtils(org.springframework.web.context.request.async.WebAsyncUtils) MockHttpServletRequest(org.springframework.web.testfixture.servlet.MockHttpServletRequest) FilterChain(jakarta.servlet.FilterChain) WebApplicationContext(org.springframework.web.context.WebApplicationContext) MockFilterConfig(org.springframework.web.testfixture.servlet.MockFilterConfig) Mockito.times(org.mockito.Mockito.times) EntityManagerFactory(jakarta.persistence.EntityManagerFactory) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) AfterEach(org.junit.jupiter.api.AfterEach) AsyncListener(jakarta.servlet.AsyncListener) EntityManager(jakarta.persistence.EntityManager) MockAsyncContext(org.springframework.web.testfixture.servlet.MockAsyncContext) PassThroughFilterChain(org.springframework.web.testfixture.servlet.PassThroughFilterChain) Mockito.reset(org.mockito.Mockito.reset) MockServletContext(org.springframework.web.testfixture.servlet.MockServletContext) Mockito.mock(org.mockito.Mockito.mock) WebAsyncManager(org.springframework.web.context.request.async.WebAsyncManager) FilterChain(jakarta.servlet.FilterChain) PassThroughFilterChain(org.springframework.web.testfixture.servlet.PassThroughFilterChain) StaticWebApplicationContext(org.springframework.web.context.support.StaticWebApplicationContext) AsyncWebRequest(org.springframework.web.context.request.async.AsyncWebRequest) StandardServletAsyncWebRequest(org.springframework.web.context.request.async.StandardServletAsyncWebRequest) MockServletContext(org.springframework.web.testfixture.servlet.MockServletContext) MockFilterConfig(org.springframework.web.testfixture.servlet.MockFilterConfig) EntityManager(jakarta.persistence.EntityManager) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) EntityManagerFactory(jakarta.persistence.EntityManagerFactory) PassThroughFilterChain(org.springframework.web.testfixture.servlet.PassThroughFilterChain) Test(org.junit.jupiter.api.Test)

Aggregations

WebAsyncManager (org.springframework.web.context.request.async.WebAsyncManager)18 AsyncWebRequest (org.springframework.web.context.request.async.AsyncWebRequest)7 Test (org.junit.jupiter.api.Test)6 StandardServletAsyncWebRequest (org.springframework.web.context.request.async.StandardServletAsyncWebRequest)5 ServletWebRequest (org.springframework.web.context.request.ServletWebRequest)4 EntityManager (jakarta.persistence.EntityManager)3 EntityManagerFactory (jakarta.persistence.EntityManagerFactory)3 AsyncEvent (jakarta.servlet.AsyncEvent)3 AsyncListener (jakarta.servlet.AsyncListener)3 IOException (java.io.IOException)3 MockAsyncContext (org.springframework.web.testfixture.servlet.MockAsyncContext)3 PersistenceException (jakarta.persistence.PersistenceException)2 ServletException (jakarta.servlet.ServletException)2 Session (org.hibernate.Session)2 DataAccessResourceFailureException (org.springframework.dao.DataAccessResourceFailureException)2 Nullable (org.springframework.lang.Nullable)2 EntityManagerHolder (org.springframework.orm.jpa.EntityManagerHolder)2 NestedServletException (org.springframework.web.util.NestedServletException)2 FilterChain (jakarta.servlet.FilterChain)1 HttpServletRequest (jakarta.servlet.http.HttpServletRequest)1