FYI, this change broke 22 tests in the embedded setup.  The change is 
definitely a good one, but when we have a moment to catch our breath we should 
find a way to at least mock this.

For RequestScoped I ended up making a TestNG Listener that stars/stops a 
request scope before and after each test method.  That was a nice approach as 
the guts themselves weren't mocked and what we're testing is the real behavior. 
 Not sure if we could do something similar (always start a session or other 
scope), but an idea.

-David

On Jul 15, 2011, at 4:41 PM, [email protected] wrote:

> Author: djencks
> Date: Fri Jul 15 23:41:06 2011
> New Revision: 1147347
> 
> URL: http://svn.apache.org/viewvc?rev=1147347&view=rev
> Log:
> GERONIMO-5050 add in session management to contexts service
> 
> Modified:
>    openejb/trunk/openejb3/container/openejb-core/pom.xml
>    
> openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java
>    openejb/trunk/openejb3/pom.xml
> 
> Modified: openejb/trunk/openejb3/container/openejb-core/pom.xml
> URL: 
> http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/pom.xml?rev=1147347&r1=1147346&r2=1147347&view=diff
> ==============================================================================
> --- openejb/trunk/openejb3/container/openejb-core/pom.xml (original)
> +++ openejb/trunk/openejb3/container/openejb-core/pom.xml Fri Jul 15 23:41:06 
> 2011
> @@ -425,6 +425,10 @@
>       <groupId>org.apache.openwebbeans</groupId>
>     </dependency>
>     <dependency>
> +      <groupId>org.apache.openwebbeans</groupId>
> +      <artifactId>openwebbeans-web</artifactId>
> +    </dependency>
> +    <dependency>
>       <groupId>org.beanshell</groupId>
>       <artifactId>bsh</artifactId>
>     </dependency>
> 
> Modified: 
> openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java
> URL: 
> http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java?rev=1147347&r1=1147346&r2=1147347&view=diff
> ==============================================================================
> --- 
> openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java
>  (original)
> +++ 
> openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/cdi/CdiAppContextsService.java
>  Fri Jul 15 23:41:06 2011
> @@ -18,44 +18,43 @@ package org.apache.openejb.cdi;
> 
> import org.apache.openejb.util.LogCategory;
> import org.apache.openejb.util.Logger;
> +import org.apache.webbeans.config.OWBLogConst;
> import org.apache.webbeans.config.WebBeansContext;
> -import org.apache.webbeans.context.AbstractContextsService;
> -import org.apache.webbeans.context.ApplicationContext;
> -import org.apache.webbeans.context.ConversationContext;
> -import org.apache.webbeans.context.DependentContext;
> -import org.apache.webbeans.context.RequestContext;
> -import org.apache.webbeans.context.SessionContext;
> -import org.apache.webbeans.context.SingletonContext;
> +import org.apache.webbeans.context.*;
> +import org.apache.webbeans.el.ELContextStore;
> import org.apache.webbeans.spi.ContextsService;
> +import org.apache.webbeans.web.context.ServletRequestContext;
> +import org.apache.webbeans.web.context.SessionContextManager;
> 
> -import javax.enterprise.context.ApplicationScoped;
> -import javax.enterprise.context.ContextException;
> -import javax.enterprise.context.ConversationScoped;
> -import javax.enterprise.context.Dependent;
> -import javax.enterprise.context.RequestScoped;
> -import javax.enterprise.context.SessionScoped;
> +import javax.enterprise.context.*;
> import javax.enterprise.context.spi.Context;
> import javax.inject.Singleton;
> -
> +import javax.servlet.ServletRequestEvent;
> +import javax.servlet.http.HttpServletRequest;
> +import javax.servlet.http.HttpSession;
> import java.lang.annotation.Annotation;
> 
> public class CdiAppContextsService extends AbstractContextsService implements 
> ContextsService {
> 
>     private static final Logger logger = 
> Logger.getInstance(LogCategory.OPENEJB.createChild("cdi"), 
> CdiAppContextsService.class);
>     private final ThreadLocal<RequestContext> requestContext = new 
> ThreadLocal<RequestContext>();
> +
>     private final ThreadLocal<SessionContext> sessionContext = new 
> ThreadLocal<SessionContext>();
> +    private final SessionContextManager sessionCtxManager = new 
> SessionContextManager();
> +
> +    /**
> +     * Conversation context manager
> +     */
>     private final ThreadLocal<ConversationContext> conversationContext;
> +
>     private final DependentContext dependentContext = new DependentContext();
> 
> -    private final ApplicationContext currentApplicationContext = new 
> ApplicationContext();
> -    private final SingletonContext currentSingletonContext = new 
> SingletonContext();
> +    private final ApplicationContext applicationContext = new 
> ApplicationContext();
> 
> -    public CdiAppContextsService() {
> -        this(false);
> -    }
> +    private final SingletonContext singletonContext = new SingletonContext();
> 
> -    public CdiAppContextsService(WebBeansContext webBeansContext) {
> -        
> this(webBeansContext.getOpenWebBeansConfiguration().supportsConversation());
> +    public CdiAppContextsService() {
> +        
> this(WebBeansContext.currentInstance().getOpenWebBeansConfiguration().supportsConversation());
>     }
> 
>     public CdiAppContextsService(boolean supportsConversation) {
> @@ -65,28 +64,54 @@ public class CdiAppContextsService exten
>         } else {
>             conversationContext = null;
>         }
> +        applicationContext.setActive(true);
> +        singletonContext.setActive(true);
>     }
> 
>     @Override
>     public void init(Object initializeObject) {
> -        currentApplicationContext.setActive(true);
> -        currentSingletonContext.setActive(true);
> +        //Start application context
> +        startContext(ApplicationScoped.class, initializeObject);
> +
> +        //Start signelton context
> +        startContext(Singleton.class, initializeObject);
> +    }
> +
> +    public void destroy(Object destroyObject) {
> +//        //Destroy application context
> +//        endContext(ApplicationScoped.class, destroyObject);
> +//
> +//        //Destroy singleton context
> +//        endContext(Singleton.class, destroyObject);
> +
> +
> +        //Remove thread locals
> +        //for preventing memory leaks
> +        requestContext.set(null);
> +        requestContext.remove();
> +        sessionContext.set(null);
> +        sessionContext.remove();
> +        conversationContext.set(null);
> +        conversationContext.remove();
> +
>     }
> 
>     @Override
> -    public void startContext(Class<? extends Annotation> scopeType, Object 
> startParameter) throws ContextException {
> +    public void endContext(Class<? extends Annotation> scopeType, Object 
> endParameters) {
> +
>         if (supportsContext(scopeType)) {
>             if (scopeType.equals(RequestScoped.class)) {
> -                initRequestContext();
> +                destroyRequestContext();
>             } else if (scopeType.equals(SessionScoped.class)) {
> -                initSessionContext();
> +                destroySessionContext((HttpSession) endParameters);
>             } else if (scopeType.equals(ApplicationScoped.class)) {
> +                destroyApplicationContext();
>             } else if (scopeType.equals(Dependent.class)) {
>                 // Do nothing
>             } else if (scopeType.equals(Singleton.class)) {
> -                initSingletonContext();
> -            } else if (conversationContext != null && 
> scopeType.equals(ConversationScoped.class)) {
> -                initConversationContext((ConversationContext)startParameter);
> +                destroySingletonContext();
> +            } else if (supportsConversation() && 
> scopeType.equals(ConversationScoped.class)) {
> +                destroyConversationContext();
>             } else {
>                 if (logger.isWarningEnabled()) {
>                     logger.warning("CDI-OpenWebBeans container in OpenEJB 
> does not support context scope "
> @@ -95,24 +120,42 @@ public class CdiAppContextsService exten
>                 }
>             }
>         }
> +
>     }
> 
>     @Override
> -    public void endContext(Class<? extends Annotation> scopeType, Object 
> endParameters) {
> +    public Context getCurrentContext(Class<? extends Annotation> scopeType) {
> +        if (scopeType.equals(RequestScoped.class)) {
> +            return getRequestContext();
> +        } else if (scopeType.equals(SessionScoped.class)) {
> +            return getSessionContext();
> +        } else if (scopeType.equals(ApplicationScoped.class)) {
> +            return getApplicationContext();
> +        } else if (supportsConversation() && 
> scopeType.equals(ConversationScoped.class)) {
> +            return getConversationContext();
> +        } else if (scopeType.equals(Dependent.class)) {
> +            return dependentContext;
> +        } else if (scopeType.equals(Singleton.class)) {
> +            return getSingletonContext();
> +        }
> 
> +        return null;
> +    }
> +
> +    @Override
> +    public void startContext(Class<? extends Annotation> scopeType, Object 
> startParameter) throws ContextException {
>         if (supportsContext(scopeType)) {
>             if (scopeType.equals(RequestScoped.class)) {
> -                destroyRequestContext();
> +                initRequestContext((ServletRequestEvent) startParameter);
>             } else if (scopeType.equals(SessionScoped.class)) {
> -                destroySessionContext();
> +                initSessionContext((HttpSession) startParameter);
>             } else if (scopeType.equals(ApplicationScoped.class)) {
> -                destroyApplicationContext();
>             } else if (scopeType.equals(Dependent.class)) {
>                 // Do nothing
>             } else if (scopeType.equals(Singleton.class)) {
> -                destroySingletonContext();
> -            } else if (conversationContext != null && 
> scopeType.equals(ConversationScoped.class)) {
> -                destroyConversationContext();
> +                initSingletonContext();
> +            } else if (supportsConversation() && 
> scopeType.equals(ConversationScoped.class)) {
> +                initConversationContext((ConversationContext) 
> startParameter);
>             } else {
>                 if (logger.isWarningEnabled()) {
>                     logger.warning("CDI-OpenWebBeans container in OpenEJB 
> does not support context scope "
> @@ -121,54 +164,135 @@ public class CdiAppContextsService exten
>                 }
>             }
>         }
> -
>     }
> 
>     @Override
> -    public Context getCurrentContext(Class<? extends Annotation> scopeType) {
> -        if (supportsContext(scopeType)) {
> -            if (scopeType.equals(RequestScoped.class)) {
> -                return getRequestContext();
> -            } else if (scopeType.equals(SessionScoped.class)) {
> -                return getSessionContext();
> -            } else if (scopeType.equals(ApplicationScoped.class)) {
> -                return currentApplicationContext;
> -            } else if (scopeType.equals(Dependent.class)) {
> -                return dependentContext;
> -            } else if (conversationContext != null && 
> scopeType.equals(ConversationScoped.class)) {
> -                return getConversationContext();
> -            } else {
> -                return currentSingletonContext;
> -            }
> +    public boolean supportsContext(Class<? extends Annotation> scopeType) {
> +        if (scopeType.equals(RequestScoped.class)
> +                || scopeType.equals(SessionScoped.class)
> +                || scopeType.equals(ApplicationScoped.class)
> +                || scopeType.equals(Dependent.class)
> +                || scopeType.equals(Singleton.class)
> +                || (scopeType.equals(ConversationScoped.class) && 
> supportsConversation())) {
> +            return true;
>         }
> 
> -        return null;
> +        return false;
>     }
> 
> -    private Context getRequestContext() {
> -        RequestContext context = requestContext.get();
> -//        if (context == null) {
> -//
> -//            context = new RequestContext();
> -//            context.setActive(true);
> +    private void initRequestContext(ServletRequestEvent event) {
> +
> +        RequestContext rq = new ServletRequestContext();
> +        rq.setActive(true);
> +
> +        requestContext.set(rq);// set thread local
> +        if (event != null) {
> +            HttpServletRequest request = (HttpServletRequest) 
> event.getServletRequest();
> +            ((ServletRequestContext) rq).setServletRequest(request);
> +
> +            if (request != null) {
> +                //Re-initialize thread local for session
> +                HttpSession session = request.getSession(false);
> +
> +                if (session != null) {
> +                    initSessionContext(session);
> +                }
> +
> +//                //Init thread local application context
> +//                initApplicationContext(event.getServletContext());
> //
> -//            requestContext.set(context);
> -//        }
> -        return context;
> +//                //Init thread local sigleton context
> +//                initSingletonContext(event.getServletContext());
> +            }
> +        }
>     }
> 
> -    private Context getSessionContext() {
> -        SessionContext context = sessionContext.get();
> -        if (context == null) {
> +    private void destroyRequestContext() {
> +        //Get context
> +        RequestContext context = getRequestContext();
> 
> -            context = new SessionContext();
> -            context.setActive(true);
> +        //Destroy context
> +        if (context != null) {
> +            context.destroy();
> +        }
> 
> -            sessionContext.set(context);
> +        // clean up the EL caches after each request
> +        ELContextStore elStore = ELContextStore.getInstance(false);
> +        if (elStore != null) {
> +            elStore.destroyELContextStore();
>         }
> -        return context;
> +
> +        //Clear thread locals
> +        requestContext.set(null);
> +        requestContext.remove();
> +
> +        //Also clear application and singleton context
> +//        applicationContext.set(null);
> +//        applicationContext.remove();
> +
> +        //Singleton context
> +//        singletonContext.set(null);
> +//        singletonContext.remove();
> +
> +        //Conversation context
> +        conversationContext.set(null);
> +        conversationContext.remove();
> +    }
> +
> +    /**
> +     * Creates the session context at the session start.
> +     *
> +     * @param session http session object
> +     */
> +    private void initSessionContext(HttpSession session) {
> +        if (session == null) {
> +            // no session -> no SessionContext
> +            return;
> +        }
> +
> +        String sessionId = session.getId();
> +        //Current context
> +        SessionContext currentSessionContext = 
> sessionCtxManager.getSessionContextWithSessionId(sessionId);
> +
> +        //No current context
> +        if (currentSessionContext == null) {
> +            currentSessionContext = new SessionContext();
> +            sessionCtxManager.addNewSessionContext(sessionId, 
> currentSessionContext);
> +        }
> +        //Activate
> +        currentSessionContext.setActive(true);
> +
> +        //Set thread local
> +        sessionContext.set(currentSessionContext);
>     }
> 
> +    /**
> +     * Destroys the session context and all of its components at the end of 
> the
> +     * session.
> +     *
> +     * @param session http session object
> +     */
> +    private void destroySessionContext(HttpSession session) {
> +        if (session != null) {
> +            //Get current session context
> +            SessionContext context = sessionContext.get();
> +
> +            //Destroy context
> +            if (context != null) {
> +                context.destroy();
> +            }
> +
> +            //Clear thread locals
> +            sessionContext.set(null);
> +            sessionContext.remove();
> +
> +            //Remove session from manager
> +            
> sessionCtxManager.destroySessionContextWithSessionId(session.getId());
> +        }
> +    }
> +
> +    //we don't have initApplicationContext
> +
>     private void destroyApplicationContext() {
>         // look for thread local
>         // this can be set by initRequestContext
> @@ -182,29 +306,6 @@ public class CdiAppContextsService exten
> //        this.currentSingletonContext.destroy();
>     }
> 
> -    @Override
> -    public boolean supportsContext(Class<? extends Annotation> scopeType) {
> -        if (scopeType.equals(RequestScoped.class)
> -                || scopeType.equals(SessionScoped.class)
> -                || scopeType.equals(ApplicationScoped.class)
> -                || scopeType.equals(Dependent.class)
> -                || scopeType.equals(Singleton.class)
> -                || (scopeType.equals(ConversationScoped.class) && 
> conversationContext != null)) {
> -            return true;
> -        }
> -
> -        return false;
> -    }
> -
> -    /**
> -     * Get current conversation ctx.
> -     *
> -     * @return conversation context
> -     */
> -    private ConversationContext getConversationContext() {
> -        return conversationContext.get();
> -    }
> -
>     /**
>      * Initialize conversation context.
>      *
> @@ -241,62 +342,90 @@ public class CdiAppContextsService exten
>         conversationContext.remove();
>     }
> 
> -    private void initRequestContext() {
> -
> -        RequestContext rq = new RequestContext();
> -        rq.setActive(true);
> 
> -        requestContext.set(rq);
> +    private RequestContext getRequestContext() {
> +        return requestContext.get();
>     }
> 
> -    private void destroyRequestContext() {
> -        // Get context
> -        RequestContext context = requestContext.get();
> +    private Context getSessionContext() {
> +        SessionContext context = sessionContext.get();
> +        if (context == null) {
> 
> -        // Destroy context
> -        if (context != null) {
> -            context.destroy();
> +            lazyStartSessionContext();
> +            context = sessionContext.get();
>         }
> -
> -        // Remove
> -        requestContext.remove();
> +        return context;
>     }
> 
> -    private void initSessionContext() {
> +    /**
> +     * Gets application context.
> +     *
> +     * @return application context
> +     */
> +    private ApplicationContext getApplicationContext() {
> +        return applicationContext;
> +    }
> 
> -        SessionContext rq = new SessionContext();
> -        rq.setActive(true);
> +    /**
> +     * Gets singleton context.
> +     *
> +     * @return singleton context
> +     */
> +    private SingletonContext getSingletonContext() {
> +        return singletonContext;
> +    }
> 
> -        sessionContext.set(rq);
> +    /**
> +     * Get current conversation ctx.
> +     *
> +     * @return conversation context
> +     */
> +    private ConversationContext getConversationContext() {
> +        return conversationContext.get();
>     }
> 
> -    private void destroySessionContext() {
> -        // Get context
> -        SessionContext context = sessionContext.get();
> +    private Context lazyStartSessionContext() {
> 
> -        // Destroy context
> -        if (context != null) {
> -            context.destroy();
> +        if (logger.isDebugEnabled()) {
> +            logger.debug(">lazyStartSessionContext");
>         }
> 
> -        // Remove
> -        sessionContext.remove();
> -    }
> -
> -    public void destroy(Object destroyObject) {
> -//        //Destroy application context
> -//        endContext(ApplicationScoped.class, destroyObject);
> -//
> -//        //Destroy singleton context
> -//        endContext(Singleton.class, destroyObject);
> +        Context webContext = null;
> +        Context context = getCurrentContext(RequestScoped.class);
> +        if (context instanceof ServletRequestContext) {
> +            ServletRequestContext requestContext = (ServletRequestContext) 
> context;
> +            HttpServletRequest servletRequest = 
> requestContext.getServletRequest();
> +            if (null != servletRequest) { // this could be null if there is 
> no active request context
> +                try {
> +                    HttpSession currentSession = servletRequest.getSession();
> +                    initSessionContext(currentSession);
> +//                    if (failoverService != null && 
> failoverService.isSupportFailOver())
> +//                    {
> +//                        failoverService.sessionIsInUse(currentSession);
> +//                    }
> +
> +                    if (logger.isDebugEnabled()) {
> +                        logger.debug("Lazy SESSION context initialization 
> SUCCESS");
> +                    }
> +                } catch (Exception e) {
> +                    logger.error(OWBLogConst.ERROR_0013, e);
> +                }
> 
> +            } else {
> +                logger.warning("Could NOT lazily initialize session context 
> because NO active request context");
> +            }
> +        } else {
> +            logger.warning("Could NOT lazily initialize session context 
> because of " + context + " RequestContext");
> +        }
> 
> -        //Remove thread locals
> -        //for preventing memory leaks
> -        requestContext.remove();
> +        if (logger.isDebugEnabled()) {
> +            logger.debug("<lazyStartSessionContext " + webContext);
> +        }
> +        return webContext;
> +    }
> 
> -        //Thread local values to null
> -        requestContext.set(null);
> +    private boolean supportsConversation() {
> +        return conversationContext != null;
>     }
> 
> }
> 
> Modified: openejb/trunk/openejb3/pom.xml
> URL: 
> http://svn.apache.org/viewvc/openejb/trunk/openejb3/pom.xml?rev=1147347&r1=1147346&r2=1147347&view=diff
> ==============================================================================
> --- openejb/trunk/openejb3/pom.xml (original)
> +++ openejb/trunk/openejb3/pom.xml Fri Jul 15 23:41:06 2011
> @@ -1256,6 +1256,11 @@
>         </exclusions>
>       </dependency>
>       <dependency>
> +        <groupId>org.apache.openwebbeans</groupId>
> +        <artifactId>openwebbeans-web</artifactId>
> +        <version>${org.apache.openwebbeans.version}</version>
> +      </dependency>
> +      <dependency>
>         <artifactId>openwebbeans-ee-common</artifactId>
>         <groupId>org.apache.openwebbeans</groupId>
>         <version>${org.apache.openwebbeans.version}</version>
> 
> 
> 

Reply via email to