From cda54b4e8935bf7b27ea71db328881192d466c2c Mon Sep 17 00:00:00 2001 From: kfujino Date: Wed, 16 Jun 2010 11:01:45 +0000 Subject: [PATCH] Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=49445 The change in session ID is notified to other node. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@955190 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/catalina/ha/session/DeltaManager.java | 109 ++++++++++++++++++++- .../catalina/ha/session/LocalStrings.properties | 1 + .../apache/catalina/ha/session/SessionMessage.java | 18 ++-- .../catalina/ha/session/SessionMessageImpl.java | 7 +- .../catalina/ha/session/mbeans-descriptors.xml | 10 ++ 5 files changed, 130 insertions(+), 15 deletions(-) diff --git a/java/org/apache/catalina/ha/session/DeltaManager.java b/java/org/apache/catalina/ha/session/DeltaManager.java index 9216120ac..cc5e27832 100644 --- a/java/org/apache/catalina/ha/session/DeltaManager.java +++ b/java/org/apache/catalina/ha/session/DeltaManager.java @@ -125,22 +125,23 @@ public class DeltaManager extends ClusterManagerBase{ private long sessionReplaceCounter = 0 ; long processingTime = 0; private long counterReceive_EVT_GET_ALL_SESSIONS = 0 ; - private long counterSend_EVT_ALL_SESSION_DATA = 0 ; private long counterReceive_EVT_ALL_SESSION_DATA = 0 ; private long counterReceive_EVT_SESSION_CREATED = 0 ; private long counterReceive_EVT_SESSION_EXPIRED = 0; private long counterReceive_EVT_SESSION_ACCESSED = 0 ; private long counterReceive_EVT_SESSION_DELTA = 0; + private int counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE = 0 ; + private long counterReceive_EVT_CHANGE_SESSION_ID = 0 ; private long counterSend_EVT_GET_ALL_SESSIONS = 0 ; + private long counterSend_EVT_ALL_SESSION_DATA = 0 ; private long counterSend_EVT_SESSION_CREATED = 0; private long counterSend_EVT_SESSION_DELTA = 0 ; private long counterSend_EVT_SESSION_ACCESSED = 0; private long counterSend_EVT_SESSION_EXPIRED = 0; private int counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE = 0 ; - private int counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE = 0 ; + private long counterSend_EVT_CHANGE_SESSION_ID = 0; private int counterNoStateTransfered = 0 ; - // ------------------------------------------------------------- Constructor public DeltaManager() { super(); @@ -218,7 +219,14 @@ public class DeltaManager extends ClusterManagerBase{ public int getCounterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE() { return counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE; } - + + /** + * @return Returns the counterSend_EVT_CHANGE_SESSION_ID. + */ + public long getCounterSend_EVT_CHANGE_SESSION_ID() { + return counterSend_EVT_CHANGE_SESSION_ID; + } + /** * @return Returns the counterReceive_EVT_ALL_SESSION_DATA. */ @@ -268,6 +276,13 @@ public class DeltaManager extends ClusterManagerBase{ public int getCounterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE() { return counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE; } + + /** + * @return Returns the counterReceive_EVT_CHANGE_SESSION_ID. + */ + public long getCounterReceive_EVT_CHANGE_SESSION_ID() { + return counterReceive_EVT_CHANGE_SESSION_ID; + } /** * @return Returns the processingTime. @@ -603,6 +618,65 @@ public class DeltaManager extends ClusterManagerBase{ } /** + * Change the session ID of the current session to a new randomly generated + * session ID. + * + * @param session The session to change the session ID for + */ + @Override + public void changeSessionId(Session session) { + changeSessionId(session, true); + } + + public void changeSessionId(Session session, boolean notify) { + // original sessionID + String orgSessionID = session.getId(); + super.changeSessionId(session); + if (notify) { + // changed sessionID + String newSessionID = session.getId(); + try { + // serialize sessionID + byte[] data = serializeSessionId(newSessionID); + // notify change sessionID + SessionMessage msg = new SessionMessageImpl(getName(), + SessionMessage.EVT_CHANGE_SESSION_ID, data, + orgSessionID, orgSessionID + "-" + + System.currentTimeMillis()); + counterSend_EVT_CHANGE_SESSION_ID++; + send(msg); + } catch (IOException e) { + log.error(sm.getString("deltaManager.unableSerializeSessionID", + newSessionID), e); + } + } + } + + /** + * serialize sessionID + * @throws IOException if an input/output error occurs + */ + protected byte[] serializeSessionId(String sessionId) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeUTF(sessionId); + oos.flush(); + oos.close(); + return bos.toByteArray(); + } + + /** + * Load sessionID + * @throws IOException if an input/output error occurs + */ + protected String deserializeSessionId(byte[] data) throws IOException { + ReplicationStream ois = getReplicationStream(data); + String sessionId = ois.readUTF(); + ois.close(); + return sessionId; + } + + /** * Load Deltarequest from external node * Load the Class at container classloader * @see DeltaRequest#readExternal(java.io.ObjectInput) @@ -1031,7 +1105,8 @@ public class DeltaManager extends ClusterManagerBase{ case SessionMessage.EVT_SESSION_CREATED: case SessionMessage.EVT_SESSION_EXPIRED: case SessionMessage.EVT_SESSION_ACCESSED: - case SessionMessage.EVT_SESSION_DELTA: { + case SessionMessage.EVT_SESSION_DELTA: + case SessionMessage.EVT_CHANGE_SESSION_ID: { synchronized(receivedMessageQueue) { if(receiverQueue) { receivedMessageQueue.add(msg); @@ -1169,6 +1244,7 @@ public class DeltaManager extends ClusterManagerBase{ counterReceive_EVT_SESSION_DELTA = 0 ; counterReceive_EVT_SESSION_EXPIRED = 0 ; counterReceive_EVT_ALL_SESSION_TRANSFERCOMPLETE = 0; + counterReceive_EVT_CHANGE_SESSION_ID = 0; counterSend_EVT_ALL_SESSION_DATA = 0; counterSend_EVT_GET_ALL_SESSIONS = 0; counterSend_EVT_SESSION_ACCESSED = 0 ; @@ -1176,6 +1252,7 @@ public class DeltaManager extends ClusterManagerBase{ counterSend_EVT_SESSION_DELTA = 0 ; counterSend_EVT_SESSION_EXPIRED = 0 ; counterSend_EVT_ALL_SESSION_TRANSFERCOMPLETE = 0; + counterSend_EVT_CHANGE_SESSION_ID = 0; } @@ -1313,6 +1390,10 @@ public class DeltaManager extends ClusterManagerBase{ handleSESSION_DELTA(msg,sender); break; } + case SessionMessage.EVT_CHANGE_SESSION_ID: { + handleCHANGE_SESSION_ID(msg,sender); + break; + } default: { //we didn't recognize the message type, do nothing break; @@ -1481,6 +1562,24 @@ public class DeltaManager extends ClusterManagerBase{ cluster.send(newmsg, sender); } + /** + * handle receive change sessionID at other node + * @param msg + * @param sender + * @throws IOException + */ + protected void handleCHANGE_SESSION_ID(SessionMessage msg,Member sender) throws IOException { + counterReceive_EVT_CHANGE_SESSION_ID++; + DeltaSession session = (DeltaSession) findSession(msg.getSessionID()); + String newSessionID = deserializeSessionId(msg.getSession()); + session.setPrimarySession(false); + if(notifySessionListenersOnReplication) { + session.setId(newSessionID); + } else { + session.setIdInternal(newSessionID); + add(session); + } + } /** * send a block of session to sender diff --git a/java/org/apache/catalina/ha/session/LocalStrings.properties b/java/org/apache/catalina/ha/session/LocalStrings.properties index ca587ef09..c986d9775 100644 --- a/java/org/apache/catalina/ha/session/LocalStrings.properties +++ b/java/org/apache/catalina/ha/session/LocalStrings.properties @@ -55,6 +55,7 @@ deltaManager.startClustering=Starting clustering manager at {0} deltaManager.stopped=Manager [{0}] is stopping deltaManager.unloading.ioe=IOException while saving persisted sessions: {0} deltaManager.waitForSessionState=Manager [{0}], requesting session state from {1}. This operation will timeout if no session state has been received within {2} seconds. +deltaManager.unableSerializeSessionID =Unable to serialize sessionID [{0}] deltaRequest.showPrincipal=Principal [{0}] is set to session {1} deltaRequest.wrongPrincipalClass=DeltaManager only support GenericPrincipal. Your realm used principal class {0}. deltaSession.notifying=Notifying cluster of expiration primary={0} sessionId [{1}] diff --git a/java/org/apache/catalina/ha/session/SessionMessage.java b/java/org/apache/catalina/ha/session/SessionMessage.java index 340865729..2fb1af2e0 100644 --- a/java/org/apache/catalina/ha/session/SessionMessage.java +++ b/java/org/apache/catalina/ha/session/SessionMessage.java @@ -26,15 +26,13 @@ import org.apache.catalina.ha.ClusterMessage; * The following events are currently available: * * */ @@ -78,7 +76,11 @@ public interface SessionMessage extends ClusterMessage, java.io.Serializable * When a session state is complete transferred, this is the event. */ public static final int EVT_ALL_SESSION_TRANSFERCOMPLETE = 14; - + + /** + * Event type used when a sessionID has been changed. + */ + public static final int EVT_CHANGE_SESSION_ID = 15; public String getContextName(); diff --git a/java/org/apache/catalina/ha/session/SessionMessageImpl.java b/java/org/apache/catalina/ha/session/SessionMessageImpl.java index 587598295..20a717511 100644 --- a/java/org/apache/catalina/ha/session/SessionMessageImpl.java +++ b/java/org/apache/catalina/ha/session/SessionMessageImpl.java @@ -69,8 +69,8 @@ public class SessionMessageImpl extends ClusterMessageBase implements SessionMes * The parameters: sessionID must be set.
* EVT_SESSION_ACCESSED
* The parameters: sessionID must be set.
- * EVT_SESSION_EXPIRED_XXXX
- * The parameters: sessionID must be set.
+ * EVT_GET_ALL_SESSIONS
+ * get all sessions from from one of the nodes.
* EVT_SESSION_DELTA
* Send attribute delta (add,update,remove attribute or principal, ...).
* EVT_ALL_SESSION_DATA
@@ -78,6 +78,8 @@ public class SessionMessageImpl extends ClusterMessageBase implements SessionMes * EVT_ALL_SESSION_TRANSFERCOMPLETE
* send that all session state information are transfered * after GET_ALL_SESSION received from this sender.
+ * EVT_CHANGE_SESSION_ID
+ * send original sessionID and new sessionID.
* @param contextName - the name of the context (application * @param eventtype - one of the 8 event type defined in this class * @param session - the serialized byte array of the session itself @@ -141,6 +143,7 @@ public class SessionMessageImpl extends ClusterMessageBase implements SessionMes case EVT_SESSION_DELTA : return "SESSION-DELTA"; case EVT_ALL_SESSION_DATA : return "ALL-SESSION-DATA"; case EVT_ALL_SESSION_TRANSFERCOMPLETE : return "SESSION-STATE-TRANSFERED"; + case EVT_CHANGE_SESSION_ID : return "SESSION-ID-CHANGED"; default : return "UNKNOWN-EVENT-TYPE"; } } diff --git a/java/org/apache/catalina/ha/session/mbeans-descriptors.xml b/java/org/apache/catalina/ha/session/mbeans-descriptors.xml index cdb28f8ba..d2168acd6 100644 --- a/java/org/apache/catalina/ha/session/mbeans-descriptors.xml +++ b/java/org/apache/catalina/ha/session/mbeans-descriptors.xml @@ -139,6 +139,11 @@ type="long" writeable="false"/> + + -- 2.11.0