Weld SVN: r5689 - in core/trunk: impl/src/main/java/org/jboss/weld/jsf and 3 other directories.
by weld-commits@lists.jboss.org
Author: dallen6
Date: 2010-01-31 15:43:39 -0500 (Sun, 31 Jan 2010)
New Revision: 5689
Added:
core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruOnDemandSessionBeanStore.java
core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruSessionBeanStore.java
core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/SomeBean.java
Modified:
core/trunk/impl/src/main/java/org/jboss/weld/conversation/ServletConversationManager.java
core/trunk/impl/src/main/java/org/jboss/weld/jsf/WeldPhaseListener.java
core/trunk/impl/src/main/java/org/jboss/weld/servlet/ConversationBeanStore.java
core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpSessionBeanStore.java
core/trunk/impl/src/main/java/org/jboss/weld/servlet/ServletLifecycle.java
core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/InvalidateSessionTest.java
core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/Storm.java
core/trunk/tests/src/test/resources/org/jboss/weld/tests/contexts/sessionInvalidation/storm.jsf
Log:
WELD-403
Modified: core/trunk/impl/src/main/java/org/jboss/weld/conversation/ServletConversationManager.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/conversation/ServletConversationManager.java 2010-01-31 19:33:56 UTC (rev 5688)
+++ core/trunk/impl/src/main/java/org/jboss/weld/conversation/ServletConversationManager.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -48,11 +48,12 @@
@Inject
private Instance<HttpSession> httpSession;
+ private boolean sessionInvalidated = false;
@Override
public BeanStore getBeanStore(String cid)
{
- return new ConversationBeanStore(httpSession.get(), cid);
+ return new ConversationBeanStore(httpSession.get(), sessionInvalidated, cid);
}
@Produces
@@ -76,4 +77,8 @@
return CONVERSATION_ID_NAME;
}
+ public void invalidateSession()
+ {
+ sessionInvalidated = true;
+ }
}
Modified: core/trunk/impl/src/main/java/org/jboss/weld/jsf/WeldPhaseListener.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/jsf/WeldPhaseListener.java 2010-01-31 19:33:56 UTC (rev 5688)
+++ core/trunk/impl/src/main/java/org/jboss/weld/jsf/WeldPhaseListener.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -45,7 +45,7 @@
import org.jboss.weld.context.ContextLifecycle;
import org.jboss.weld.context.ConversationContext;
import org.jboss.weld.context.SessionContext;
-import org.jboss.weld.servlet.ConversationBeanStore;
+import org.jboss.weld.conversation.AbstractConversationManager;
import org.slf4j.cal10n.LocLogger;
/**
@@ -165,11 +165,12 @@
ServletContext servletContext = getServletContext(facesContext);
HttpSession session = getHttpSession(facesContext);
httpSessionManager(servletContext).setSession(session);
- conversationManager(servletContext).beginOrRestoreConversation(getConversationId(facesContext));
+ AbstractConversationManager conversationManager = (AbstractConversationManager) conversationManager(servletContext);
+ conversationManager.beginOrRestoreConversation(getConversationId(facesContext));
String cid = conversation(servletContext).getUnderlyingId();
ConversationContext conversationContext = Container.instance().services().get(ContextLifecycle.class).getConversationContext();
- conversationContext.setBeanStore(new ConversationBeanStore(session, cid));
+ conversationContext.setBeanStore(conversationManager.getBeanStore(cid));
conversationContext.setActive(true);
}
Modified: core/trunk/impl/src/main/java/org/jboss/weld/servlet/ConversationBeanStore.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/servlet/ConversationBeanStore.java 2010-01-31 19:33:56 UTC (rev 5688)
+++ core/trunk/impl/src/main/java/org/jboss/weld/servlet/ConversationBeanStore.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -26,15 +26,15 @@
*
* @author Nicklas Karlsson
*/
-public class ConversationBeanStore extends HttpSessionBeanStore
+public class ConversationBeanStore extends HttpPassThruSessionBeanStore
{
private final String cid;
private final NamingScheme namingScheme;
- public ConversationBeanStore(HttpSession session, String cid)
+ public ConversationBeanStore(HttpSession session, boolean sessionInvalidated, String cid)
{
- super(session);
+ attachToSession(session);
this.cid = cid;
this.namingScheme = new NamingScheme(ConversationContext.class.getName() + "[" + cid + "]", "#");
}
Added: core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruOnDemandSessionBeanStore.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruOnDemandSessionBeanStore.java (rev 0)
+++ core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruOnDemandSessionBeanStore.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat, Inc. and/or its affiliates, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.weld.servlet;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * A BeanStore that passes through all attributes to a session that is only
+ * created on demand. In order to support on demand session creation, this
+ * BeanStore must be attached to a HttpServletRequest.
+ *
+ * @author David Allen
+ */
+public class HttpPassThruOnDemandSessionBeanStore extends HttpPassThruSessionBeanStore
+{
+ private final HttpServletRequest request;
+
+ public HttpPassThruOnDemandSessionBeanStore(HttpServletRequest request)
+ {
+ this.request = request;
+ }
+
+ @Override
+ protected void setAttribute(String key, Object instance)
+ {
+ if (!isAttachedToSession())
+ {
+ attachToSession(request.getSession(true));
+ }
+ super.setAttribute(key, instance);
+ }
+}
Property changes on: core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruOnDemandSessionBeanStore.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruSessionBeanStore.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruSessionBeanStore.java (rev 0)
+++ core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruSessionBeanStore.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -0,0 +1,150 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat, Inc. and/or its affiliates, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.weld.servlet;
+
+import java.util.Collections;
+import java.util.Enumeration;
+
+import javax.servlet.http.HttpSession;
+
+import org.jboss.weld.context.api.ContextualInstance;
+import org.jboss.weld.context.api.helpers.ConcurrentHashMapBeanStore;
+
+/**
+ * A BeanStore that maintains Contextuals in a hash map and writes them through
+ * to a HttpSession. It also has the capability to reload the hash map from an
+ * existing session or to rewrite the map entries into a session.
+ *
+ * @author David Allen
+ */
+public class HttpPassThruSessionBeanStore extends HttpSessionBeanStore
+{
+
+ private static final long serialVersionUID = 8923580660774253915L;
+
+ private ConcurrentHashMapBeanStore delegateBeanStore = new ConcurrentHashMapBeanStore();
+ private boolean attachedToSession = false;
+ private boolean invalidated = false;
+ private static final String SESSION_ATTRIBUTE_NAME = HttpPassThruSessionBeanStore.class.getName() + ".sessionBeanStore";
+
+ /**
+ * Attaches this pass-through bean store to the given session.
+ *
+ * @param session the HttpSession to pass contextuals to
+ */
+ public void attachToSession(HttpSession session)
+ {
+ super.attachToSession(session);
+ loadFromSession(session);
+ attachedToSession = true;
+ }
+
+ /**
+ * Detaches this bean store from the current session. This implies that any
+ * future lookups will be directly from the map maintained by this bean store
+ * and no further Contextuals will be stored in a session.
+ */
+ protected void detachFromSession()
+ {
+ attachedToSession = false;
+ }
+
+ /**
+ * Invalidates this session bean store, but it can still be used to service
+ * the remainder of a request.
+ */
+ public void invalidate()
+ {
+ detachFromSession();
+ invalidated = true;
+ }
+
+ /**
+ * Checks if this bean store is currently attached to a session.
+ *
+ * @return true if it is attached and using a session
+ */
+ public boolean isAttachedToSession()
+ {
+ return attachedToSession;
+ }
+
+ /**
+ * Determines if this session bean store has been invalidated.
+ *
+ * @return true if the bean store is already invalidated
+ */
+ public boolean isInvalidated()
+ {
+ return invalidated;
+ }
+
+ /**
+ * Loads the map from the given session into this map store, if it already
+ * exists in this session. If it does not already exist, then a new map is
+ * created since the session does not already have any contextuals stored in
+ * it.
+ *
+ * @param newSession a new HttpSession being attached
+ */
+ protected void loadFromSession(HttpSession newSession)
+ {
+ Object map = newSession.getAttribute(SESSION_ATTRIBUTE_NAME);
+ if (map != null)
+ {
+ delegateBeanStore = (ConcurrentHashMapBeanStore) map;
+ }
+ else
+ {
+ newSession.setAttribute(SESSION_ATTRIBUTE_NAME, delegateBeanStore);
+ }
+ }
+
+ @Override
+ protected Object getAttribute(String key)
+ {
+ return delegateBeanStore.get(key);
+ }
+
+ @Override
+ protected Enumeration<String> getAttributeNames()
+ {
+ return Collections.enumeration(delegateBeanStore.getContextualIds());
+ }
+
+ @Override
+ protected void removeAttribute(String key)
+ {
+ if (attachedToSession && !isInvalidated())
+ {
+ super.removeAttribute(key);
+ }
+ delegateBeanStore.delegate().remove(key);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void setAttribute(String key, Object instance)
+ {
+ if (attachedToSession && !isInvalidated())
+ {
+ super.setAttribute(key, instance);
+ }
+ delegateBeanStore.put(key, (ContextualInstance<? extends Object>) instance);
+ }
+}
Property changes on: core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpPassThruSessionBeanStore.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpSessionBeanStore.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpSessionBeanStore.java 2010-01-31 19:33:56 UTC (rev 5688)
+++ core/trunk/impl/src/main/java/org/jboss/weld/servlet/HttpSessionBeanStore.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -28,25 +28,28 @@
* A BeanStore that uses a HTTP session as backing storage
*
* @author Nicklas Karlsson
+ * @author David Allen
*
* @see org.jboss.weld.context.AbstractApplicationContext
*/
public class HttpSessionBeanStore extends AbstractAttributeBackedBeanStore
{
-
+
private static final NamingScheme NAMING_SCHEME = new NamingScheme(SessionContext.class.getName(), "#");
-
+
// The HTTP session context to use as backing map
- private final HttpSession session;
+ protected HttpSession session;
/**
- * Constructor
+ * Attaches this bean store to a session dynamically. This allows the session
+ * to be changed in cases where one session is invalidated and then a
+ * subsequent session is created within the same request.
*
- * @param session The HTTP session
+ * @param session the new HttpSession to use as the backing for this bean
+ * store
*/
- public HttpSessionBeanStore(HttpSession session)
+ public void attachToSession(HttpSession session)
{
- super();
this.session = session;
}
Modified: core/trunk/impl/src/main/java/org/jboss/weld/servlet/ServletLifecycle.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/servlet/ServletLifecycle.java 2010-01-31 19:33:56 UTC (rev 5688)
+++ core/trunk/impl/src/main/java/org/jboss/weld/servlet/ServletLifecycle.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -32,24 +32,24 @@
import org.jboss.weld.context.ContextLifecycle;
import org.jboss.weld.context.api.BeanStore;
import org.jboss.weld.context.api.helpers.ConcurrentHashMapBeanStore;
-import org.jboss.weld.conversation.ConversationManager;
+import org.jboss.weld.conversation.ServletConversationManager;
import org.jboss.weld.exceptions.ForbiddenStateException;
/**
- * Implementation of the Weld lifecycle that can react to servlet events
- * and drives the Session, Conversation and Request (for Servlet requests)
- * lifecycle
+ * Implementation of the Weld lifecycle that can react to servlet events and
+ * drives the Session, Conversation and Request (for Servlet requests) lifecycle
*
* @author Pete Muir
* @author Nicklas Karlsson
+ * @author David Allen
*/
public class ServletLifecycle
{
private final ContextLifecycle lifecycle;
-
- public static final String REQUEST_ATTRIBUTE_NAME = ServletLifecycle.class.getName() + ".requestBeanStore";
-
+
+ public static final String REQUEST_ATTRIBUTE_NAME = ServletLifecycle.class.getName() + ".requestBeanStore";
+
/**
*
*/
@@ -65,6 +65,15 @@
*/
public void beginSession(HttpSession session)
{
+ HttpPassThruSessionBeanStore beanStore = (HttpPassThruSessionBeanStore) lifecycle.getSessionContext().getBeanStore();
+ if (beanStore == null)
+ {
+ restoreSessionContext(session);
+ }
+ else
+ {
+ beanStore.attachToSession(session);
+ }
}
/**
@@ -74,11 +83,23 @@
*/
public void endSession(HttpSession session)
{
- ConversationManager conversationManager = conversationManager(session.getServletContext());
+ ServletConversationManager conversationManager = (ServletConversationManager) conversationManager(session.getServletContext());
if (lifecycle.getSessionContext().isActive())
{
- conversationManager.destroyAllConversations();
- lifecycle.endSession(session.getId(), lifecycle.getSessionContext().getBeanStore());
+ HttpPassThruSessionBeanStore beanStore = (HttpPassThruSessionBeanStore) lifecycle.getSessionContext().getBeanStore();
+ if (lifecycle.getRequestContext().isActive())
+ {
+ // Probably invalidated during request. This will be terminated
+ // at the end of the request.
+ beanStore.invalidate();
+ conversationManager.invalidateSession();
+ conversationManager.destroyAllConversations();
+ }
+ else
+ {
+ conversationManager.destroyAllConversations();
+ lifecycle.endSession(session.getId(), beanStore);
+ }
}
else if (lifecycle.getRequestContext().isActive())
{
@@ -89,14 +110,14 @@
else
{
BeanStore mockRequest = new ConcurrentHashMapBeanStore();
-
+
lifecycle.beginRequest("endSession-" + session.getId(), mockRequest);
BeanStore sessionBeanStore = restoreSessionContext(session);
conversationManager.destroyAllConversations();
lifecycle.endSession(session.getId(), sessionBeanStore);
lifecycle.endRequest("endSession-" + session.getId(), mockRequest);
}
-
+
}
/**
@@ -108,29 +129,29 @@
*/
protected BeanStore restoreSessionContext(HttpServletRequest request)
{
- BeanStore sessionBeanStore = new HttpRequestSessionBeanStore(request);
+ HttpPassThruSessionBeanStore sessionBeanStore = new HttpPassThruOnDemandSessionBeanStore(request);
HttpSession session = request.getSession(false);
lifecycle.restoreSession(session == null ? "Inactive session" : session.getId(), sessionBeanStore);
if (session != null)
{
+ sessionBeanStore.attachToSession(session);
httpSessionManager(session.getServletContext()).setSession(session);
}
return sessionBeanStore;
}
-
+
protected BeanStore restoreSessionContext(HttpSession session)
{
- BeanStore beanStore = new HttpSessionBeanStore(session);
+ HttpPassThruSessionBeanStore beanStore = new HttpPassThruSessionBeanStore();
+ beanStore.attachToSession(session);
lifecycle.restoreSession(session.getId(), beanStore);
httpSessionManager(session.getServletContext()).setSession(session);
return beanStore;
}
/**
- * Begins a HTTP request
+ * Begins a HTTP request Sets the session into the session context
*
- * Sets the session into the session context
- *
* @param request The request
*/
public void beginRequest(HttpServletRequest request)
@@ -160,6 +181,11 @@
}
lifecycle.endRequest(request.getRequestURI(), beanStore);
request.removeAttribute(REQUEST_ATTRIBUTE_NAME);
+ HttpPassThruSessionBeanStore sessionBeanStore = (HttpPassThruSessionBeanStore) lifecycle.getSessionContext().getBeanStore();
+ if ((sessionBeanStore != null) && (sessionBeanStore.isInvalidated()))
+ {
+ lifecycle.endSession(request.getRequestedSessionId(), sessionBeanStore);
+ }
lifecycle.getSessionContext().setActive(false);
lifecycle.getSessionContext().setBeanStore(null);
}
Modified: core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/InvalidateSessionTest.java
===================================================================
--- core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/InvalidateSessionTest.java 2010-01-31 19:33:56 UTC (rev 5688)
+++ core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/InvalidateSessionTest.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -31,6 +31,7 @@
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
+import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
@@ -41,7 +42,7 @@
*
*/
@Artifact(addCurrentPackage=false)
-(a)Classes({Storm.class})
+(a)Classes({Storm.class,SomeBean.class})
@IntegrationTest(runLocally=true)
@Resources({
@Resource(destination=WarArtifactDescriptor.WEB_XML_DESTINATION, source="web.xml"),
@@ -50,15 +51,23 @@
})
public class InvalidateSessionTest extends AbstractWeldTest
{
- @Test(description = "WELD-380")
+ @Test(description = "WELD-380, WELD-403")
public void testInvalidateSessionCalled() throws Exception
{
WebClient client = new WebClient();
- client.setThrowExceptionOnFailingStatusCode(false);
+ client.setThrowExceptionOnFailingStatusCode(true);
HtmlPage page = client.getPage(getPath("/storm.jsf"));
HtmlSubmitInput invalidateSessionButton = getFirstMatchingElement(page, HtmlSubmitInput.class, "invalidateSessionButton");
page = invalidateSessionButton.click();
+ HtmlInput inputField = getFirstMatchingElement(page, HtmlInput.class, "prop");
+ assert Storm.PROPERTY_VALUE.equals(inputField.getValueAttribute());
+
+ // Make another request to verify that the session bean value is not the
+ // one from the previous invalidated session.
+ page = client.getPage(getPath("/storm.jsf"));
+ inputField = getFirstMatchingElement(page, HtmlInput.class, "prop");
+ assert SomeBean.DEFAULT_PROPERTY_VALUE.equals(inputField.getValueAttribute());
}
protected <T> Set<T> getElements(HtmlElement rootElement, Class<T> elementClass)
Added: core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/SomeBean.java
===================================================================
--- core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/SomeBean.java (rev 0)
+++ core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/SomeBean.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -0,0 +1,23 @@
+package org.jboss.weld.tests.contexts.sessionInvalidation;
+
+import java.io.Serializable;
+import javax.enterprise.context.SessionScoped;
+import javax.inject.Named;
+
+@Named
+@SessionScoped
+public class SomeBean implements Serializable{
+ private static final long serialVersionUID = 5318736702438067705L;
+ public static final String DEFAULT_PROPERTY_VALUE = "default";
+
+ private String prop = DEFAULT_PROPERTY_VALUE;
+
+ public String getProp() {
+ return prop;
+ }
+
+ public void setProp(String prop) {
+ this.prop = prop;
+ }
+
+}
Property changes on: core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/SomeBean.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/Storm.java
===================================================================
--- core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/Storm.java 2010-01-31 19:33:56 UTC (rev 5688)
+++ core/trunk/tests/src/test/java/org/jboss/weld/tests/contexts/sessionInvalidation/Storm.java 2010-01-31 20:43:39 UTC (rev 5689)
@@ -25,9 +25,13 @@
{
@Inject HttpSession session;
+ @Inject SomeBean someBean;
+ public static final String PROPERTY_VALUE = "some value";
+
public String invalidateSession()
{
+ someBean.setProp(PROPERTY_VALUE);
session.invalidate();
return "success";
}
Modified: core/trunk/tests/src/test/resources/org/jboss/weld/tests/contexts/sessionInvalidation/storm.jsf
===================================================================
--- core/trunk/tests/src/test/resources/org/jboss/weld/tests/contexts/sessionInvalidation/storm.jsf 2010-01-31 19:33:56 UTC (rev 5688)
+++ core/trunk/tests/src/test/resources/org/jboss/weld/tests/contexts/sessionInvalidation/storm.jsf 2010-01-31 20:43:39 UTC (rev 5689)
@@ -14,6 +14,12 @@
</head>
<body>
<f:view>
+ <h:form>
+ <h:outputLabel value="Prop:" for="prop"/>
+ <h:inputText value="#{someBean.prop}" id="prop" />
+ <h:commandButton value="go!" id="go"/>
+ </h:form>
+ <hr/>
<h:form id="form">
<h:commandButton action="#{storm.invalidateSession}" value="Invalidate Session" id="invalidateSessionButton"/>
</h:form>