001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.catalina.ha.session;
019:
020: import java.io.IOException;
021:
022: import org.apache.catalina.Container;
023: import org.apache.catalina.Context;
024: import org.apache.catalina.Engine;
025: import org.apache.catalina.LifecycleException;
026: import org.apache.catalina.Session;
027: import org.apache.catalina.ha.ClusterMessage;
028: import org.apache.catalina.core.StandardEngine;
029: import org.apache.catalina.ha.*;
030:
031: /**
032: * Receive SessionID cluster change from other backup node after primary session
033: * node is failed.
034: *
035: * @author Peter Rossbach
036: * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
037: */
038: public class JvmRouteSessionIDBinderListener extends ClusterListener {
039:
040: /**
041: * The descriptive information about this implementation.
042: */
043: protected static final String info = "org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener/1.1";
044:
045: //--Instance Variables--------------------------------------
046:
047: protected boolean started = false;
048:
049: /**
050: * number of session that goes to this cluster node
051: */
052: private long numberOfSessions = 0;
053:
054: //--Constructor---------------------------------------------
055:
056: public JvmRouteSessionIDBinderListener() {
057: }
058:
059: //--Logic---------------------------------------------------
060:
061: /**
062: * Return descriptive information about this implementation.
063: */
064: public String getInfo() {
065:
066: return (info);
067:
068: }
069:
070: /**
071: * @return Returns the numberOfSessions.
072: */
073: public long getNumberOfSessions() {
074: return numberOfSessions;
075: }
076:
077: /**
078: * Add this Mover as Cluster Listener ( receiver)
079: *
080: * @throws LifecycleException
081: */
082: public void start() throws LifecycleException {
083: if (started)
084: return;
085: getCluster().addClusterListener(this );
086: started = true;
087: if (log.isInfoEnabled())
088: log.info(sm.getString("jvmRoute.clusterListener.started"));
089: }
090:
091: /**
092: * Remove this from Cluster Listener
093: *
094: * @throws LifecycleException
095: */
096: public void stop() throws LifecycleException {
097: started = false;
098: getCluster().removeClusterListener(this );
099: if (log.isInfoEnabled())
100: log.info(sm.getString("jvmRoute.clusterListener.stopped"));
101: }
102:
103: /**
104: * Callback from the cluster, when a message is received, The cluster will
105: * broadcast it invoking the messageReceived on the receiver.
106: *
107: * @param msg
108: * ClusterMessage - the message received from the cluster
109: */
110: public void messageReceived(ClusterMessage msg) {
111: if (msg instanceof SessionIDMessage && msg != null) {
112: SessionIDMessage sessionmsg = (SessionIDMessage) msg;
113: if (log.isDebugEnabled())
114: log.debug(sm.getString(
115: "jvmRoute.receiveMessage.sessionIDChanged",
116: sessionmsg.getOrignalSessionID(), sessionmsg
117: .getBackupSessionID(), sessionmsg
118: .getContextPath()));
119: Container container = getCluster().getContainer();
120: Container host = null;
121: if (container instanceof Engine) {
122: host = container.findChild(sessionmsg.getHost());
123: } else {
124: host = container;
125: }
126: if (host != null) {
127: Context context = (Context) host.findChild(sessionmsg
128: .getContextPath());
129: if (context != null) {
130: try {
131: Session session = context.getManager()
132: .findSession(
133: sessionmsg
134: .getOrignalSessionID());
135: if (session != null) {
136: session.setId(sessionmsg
137: .getBackupSessionID());
138: } else if (log.isInfoEnabled())
139: log.info(sm.getString(
140: "jvmRoute.lostSession", sessionmsg
141: .getOrignalSessionID(),
142: sessionmsg.getContextPath()));
143: } catch (IOException e) {
144: log.error(e);
145: }
146:
147: } else if (log.isErrorEnabled())
148: log.error(sm.getString("jvmRoute.contextNotFound",
149: sessionmsg.getContextPath(),
150: ((StandardEngine) host.getParent())
151: .getJvmRoute()));
152: } else if (log.isErrorEnabled())
153: log.error(sm.getString("jvmRoute.hostNotFound",
154: sessionmsg.getContextPath()));
155: }
156: return;
157: }
158:
159: /**
160: * Accept only SessionIDMessages
161: *
162: * @param msg
163: * ClusterMessage
164: * @return boolean - returns true to indicate that messageReceived should be
165: * invoked. If false is returned, the messageReceived method will
166: * not be invoked.
167: */
168: public boolean accept(ClusterMessage msg) {
169: return (msg instanceof SessionIDMessage);
170: }
171: }
|