1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22 package org.jboss.web.tomcat.service.session;
23
24 import java.io.IOException;
25 import javax.servlet.ServletException;
26 import javax.transaction.TransactionManager;
27
28 import org.apache.catalina.Lifecycle;
29 import org.apache.catalina.LifecycleException;
30 import org.apache.catalina.LifecycleListener;
31 import org.apache.catalina.connector.Request;
32 import org.apache.catalina.connector.Response;
33 import org.apache.catalina.util.LifecycleSupport;
34 import org.apache.catalina.valves.ValveBase;
35 import org.jboss.logging.Logger;
36
37 /**
38 * This Valve handles batch replication mode. It uses the cache tm to performa batch replication.
39 *
40 * @author Ben Wang
41 * @version $Revision: 60079 $
42 */
43 public class BatchReplicationClusteredSessionValve extends ValveBase implements Lifecycle
44 {
45 private static Logger log_ = Logger.getLogger(BatchReplicationClusteredSessionValve.class);
46
47 // The info string for this Valve
48 private static final String info = "BatchReplicationClusteredSessionValve/1.0";
49
50 // Valve-lifecycle_ helper object
51 protected LifecycleSupport support = new LifecycleSupport(this);
52
53 protected JBossCacheManager manager_;
54
55 /**
56 * Create a new Valve.
57 *
58 */
59 public BatchReplicationClusteredSessionValve(AbstractJBossManager manager)
60 {
61 super();
62 manager_ = (JBossCacheManager)manager;
63 }
64
65 /**
66 * Get information about this Valve.
67 */
68 public String getInfo()
69 {
70 return info;
71 }
72
73 /**
74 * Valve-chain handler method.
75 * This method gets called when the request goes through the Valve-chain. Our session replication mechanism replicates the
76 * session after request got through the servlet code.
77 *
78 * @param request The request object associated with this request.
79 * @param response The response object associated with this request.
80 */
81 public void invoke(Request request, Response response) throws IOException, ServletException
82 {
83 // Note: we use specfically the tm in cache.
84 TransactionManager tm = manager_.getCacheService().getTransactionManager();
85 if(tm == null)
86 {
87 throw new RuntimeException("BatchReplicationClusteredSessionValve.invoke(): Obtain null tm");
88 }
89
90 // Before we start a tx, get the session. If this is a failover
91 // situation, this will cause data gravitation, which will occur
92 // thus outside of the scope of the tx we are about to start.
93 // JBossCacheManager will ensure the gravitation is in its own tx
94 request.getSession(false);
95
96 // Start a new transaction, we need transaction so all the replication are sent in batch.
97 try
98 {
99 tm.begin();
100
101 // let the servlet invocation go through
102 getNext().invoke(request, response);
103
104 log_.trace("Ready to commit batch replication for field level granularity");
105
106 tm.commit();
107 }
108 catch (Exception e)
109 {
110 try
111 {
112 tm.rollback();
113 }
114 catch (Exception exn)
115 {
116 log_.error("Caught exception rolling back transaction", exn);
117 }
118
119 // We will need to alert Tomcat of this exception.
120 if (e instanceof IOException)
121 throw (IOException) e;
122 if (e instanceof ServletException)
123 throw (ServletException) e;
124 if (e instanceof RuntimeException)
125 throw (RuntimeException) e;
126 throw new RuntimeException(e);
127 }
128 }
129
130 // Lifecylce-interface
131 public void addLifecycleListener(LifecycleListener listener)
132 {
133 support.addLifecycleListener(listener);
134 }
135
136 public void removeLifecycleListener(LifecycleListener listener)
137 {
138 support.removeLifecycleListener(listener);
139 }
140
141 public LifecycleListener[] findLifecycleListeners()
142 {
143 return support.findLifecycleListeners();
144 }
145
146 public void start() throws LifecycleException
147 {
148 support.fireLifecycleEvent(START_EVENT, this);
149 }
150
151 public void stop() throws LifecycleException
152 {
153 support.fireLifecycleEvent(STOP_EVENT, this);
154 }
155
156 }