RESOLVED - issue SWF-378: Session binding conversation containers cannot be used in a cluster

http://opensource.atlassian.com/projects/spring/browse/SWF-378
This commit is contained in:
Keith Donald
2007-08-15 17:29:49 +00:00
parent f8265e4fbe
commit c2e0e1e7d8
3 changed files with 32 additions and 9 deletions

View File

@@ -13,6 +13,7 @@ Package org.springframework.webflow.engine
Package org.springframework.webflow.execution
* Made the Event class non-final to allow for extension (SWF-330).
* Now allow multiple conversation containers per session in a manner that supports use in a cluster (SWF-378).
Changes in version 1.0.4 (13.06.2007)
-------------------------------------

View File

@@ -24,7 +24,6 @@ import org.springframework.webflow.conversation.ConversationId;
import org.springframework.webflow.conversation.ConversationManager;
import org.springframework.webflow.conversation.ConversationParameters;
import org.springframework.webflow.core.collection.SharedAttributeMap;
import org.springframework.webflow.util.RandomGuid;
import org.springframework.webflow.util.RandomGuidUidGenerator;
import org.springframework.webflow.util.UidGenerator;
@@ -44,10 +43,14 @@ public class SessionBindingConversationManager implements ConversationManager {
private static final Log logger = LogFactory.getLog(SessionBindingConversationManager.class);
/**
* Generate a unique key for the session attribute holding the conversation container managed by this conversation
* manager.
* The name of the session attribute that will hold the conversation container used by this conversation manager.
*
* To support multiple independent conversation containers in the same web application, for example, for use with
* multiple flow executors each configured with their own session-binding conversation manager, set this field's
* value to something unique.
* @see #setSessionKey(String)
*/
private final String sessionKey = "webflow.conversation.container." + new RandomGuid().toString();
private String sessionKey = "webflow.conversationContainer";
/**
* The conversation uid generation strategy to use.
@@ -62,7 +65,6 @@ public class SessionBindingConversationManager implements ConversationManager {
/**
* Returns the used generator for conversation ids. Defaults to {@link RandomGuidUidGenerator}.
* @since 1.0.1
*/
public UidGenerator getConversationIdGenerator() {
return conversationIdGenerator;
@@ -77,7 +79,6 @@ public class SessionBindingConversationManager implements ConversationManager {
/**
* Returns the maximum number of allowed concurrent conversations. The default is 5.
* @since 1.0.1
*/
public int getMaxConversations() {
return maxConversations;
@@ -91,14 +92,23 @@ public class SessionBindingConversationManager implements ConversationManager {
}
/**
* Returns the key this conversation manager uses to store conversation data in the session. The key is unique for
* this conversation manager instance.
* Returns the key this conversation manager uses to store conversation data in the session.
* @return the session key
*/
public String getSessionKey() {
return sessionKey;
}
/**
* Sets the key this conversation manager uses to store conversation data in the session. If multiple session
* binding conversation managers are used in the same web application to back independent flow executors, this value
* should be unique among them.
* @param sessionKey the session key
*/
public void setSessionKey(String sessionKey) {
this.sessionKey = sessionKey;
}
public Conversation beginConversation(ConversationParameters conversationParameters) throws ConversationException {
ConversationId conversationId = new SimpleConversationId(conversationIdGenerator.generateUid());
if (logger.isDebugEnabled()) {

View File

@@ -87,11 +87,15 @@ public class SessionBindingConversationManagerTests extends TestCase {
conversation.putAttribute("testAttribute", "testValue");
ConversationId conversationId = conversation.getId();
ExternalContextHolder.setExternalContext(null);
// simulate write out of session
byte[] passiveSession = passivate(externalContext.getSessionMap());
// simulate start-up of server
conversationManager = new SessionBindingConversationManager();
String id = conversationId.toString();
conversationId = conversationManager.parseConversationId(id);
// simulate restore of session
externalContext.setSessionMap(activate(passiveSession));
ExternalContextHolder.setExternalContext(externalContext);
Conversation conversation2 = conversationManager.getConversation(conversationId);
@@ -125,6 +129,14 @@ public class SessionBindingConversationManagerTests extends TestCase {
assertNotNull(conversationManager.getConversation(conversation3.getId()));
}
public void testCustomSessionKey() {
conversationManager.setSessionKey("foo");
MockExternalContext context = new MockExternalContext();
ExternalContextHolder.setExternalContext(context);
conversationManager.beginConversation(new ConversationParameters("test", "test", "test"));
assertNotNull(context.getSessionMap().get("foo"));
}
private byte[] passivate(SharedAttributeMap session) throws Exception {
// session is serialized out
ByteArrayOutputStream bout = new ByteArrayOutputStream();
@@ -138,4 +150,4 @@ public class SessionBindingConversationManagerTests extends TestCase {
return (SharedAttributeMap) new ObjectInputStream(new ByteArrayInputStream(sessionData)).readObject();
}
}
}