KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > cluster > tcp > ReplicationValve


1 /*
2  * Copyright 1999,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.catalina.cluster.tcp;
18
19
20
21
22
23 import java.io.IOException JavaDoc;
24
25 import javax.servlet.ServletException JavaDoc;
26 import javax.servlet.http.HttpSession JavaDoc;
27
28 import org.apache.catalina.Manager;
29 import org.apache.catalina.Session;
30 import org.apache.catalina.cluster.CatalinaCluster;
31 import org.apache.catalina.cluster.ClusterManager;
32 import org.apache.catalina.cluster.ClusterMessage;
33 import org.apache.catalina.cluster.ClusterSession;
34 import org.apache.catalina.connector.Request;
35 import org.apache.catalina.connector.Response;
36 import org.apache.catalina.util.StringManager;
37 import org.apache.catalina.valves.Constants;
38 import org.apache.catalina.valves.ValveBase;
39
40 /**
41  * <p>Implementation of a Valve that logs interesting contents from the
42  * specified Request (before processing) and the corresponding Response
43  * (after processing). It is especially useful in debugging problems
44  * related to headers and cookies.</p>
45  *
46  * <p>This Valve may be attached to any Container, depending on the granularity
47  * of the logging you wish to perform.</p>
48  *
49  * <p>primaryIndicator=true, then the request attribute <i>org.apache.catalina.cluster.tcp.isPrimarySession.</i>
50  * is set true, when request processing is at sessions primary node.
51  * </p>
52  *
53  * @author Craig R. McClanahan
54  * @author Filip Hanik
55  * @author Peter Rossbach
56  * @version $Revision: 1.17 $ $Date: 2005/02/11 19:45:18 $
57  */

58
59 public class ReplicationValve
60     extends ValveBase {
61     private static org.apache.commons.logging.Log log =
62         org.apache.commons.logging.LogFactory.getLog( ReplicationValve.class );
63
64     // ----------------------------------------------------- Instance Variables
65

66
67     /**
68      * The descriptive information related to this implementation.
69      */

70     private static final String JavaDoc info =
71         "org.apache.catalina.cluster.tcp.ReplicationValve/1.1";
72
73
74     /**
75      * The StringManager for this package.
76      */

77     protected static StringManager sm =
78         StringManager.getManager(Constants.Package);
79
80     /**
81      * holds file endings to not call for like images and others
82      */

83     protected java.util.regex.Pattern JavaDoc[] reqFilters = new java.util.regex.Pattern JavaDoc[0];
84     protected String JavaDoc filter ;
85
86     protected long totalRequestTime=0;
87     protected long totalSendTime=0;
88     protected long nrOfRequests =0;
89     protected long lastSendTime =0;
90
91     protected boolean primaryIndicator = false ;
92
93     protected String JavaDoc primaryIndicatorName = "org.apache.catalina.cluster.tcp.isPrimarySession";
94    
95     // ------------------------------------------------------------- Properties
96

97     public ReplicationValve() {
98     }
99     /**
100      * Return descriptive information about this Valve implementation.
101      */

102     public String JavaDoc getInfo() {
103
104         return (info);
105
106     }
107
108     // --------------------------------------------------------- Public Methods
109

110     protected synchronized void addClusterSendTime(long requestTime, long clusterTime) {
111         totalSendTime+=clusterTime;
112         totalRequestTime+=requestTime;
113         nrOfRequests++;
114         if ( (nrOfRequests % 100) == 0 ) {
115             if(log.isInfoEnabled()) {
116                  log.info("Average request time="+(totalRequestTime/nrOfRequests)+" ms for "+
117                           "Cluster overhead time="+(totalSendTime/nrOfRequests)+" ms for "+
118                            nrOfRequests+" requests (Request="+totalRequestTime+"ms Cluster="+totalSendTime+"ms).");
119             }
120             lastSendTime=System.currentTimeMillis();
121         }//end if
122
}
123
124
125     /**
126      * Log the interesting request parameters, invoke the next Valve in the
127      * sequence, and log the interesting response parameters.
128      *
129      * @param request The servlet request to be processed
130      * @param response The servlet response to be created
131      * @param context The valve context used to invoke the next valve
132      * in the current processing pipeline
133      *
134      * @exception IOException if an input/output error occurs
135      * @exception ServletException if a servlet error occurs
136      */

137     public void invoke(Request request, Response response)
138         throws IOException JavaDoc, ServletException JavaDoc
139     {
140         long totalstart = System.currentTimeMillis();
141         //this happens before the request
142
//long _debugstart = System.currentTimeMillis();
143
if (primaryIndicator)
144             createPrimaryIndicator( request) ;
145         getNext().invoke(request, response);
146         //System.out.println("[DEBUG] Regular invoke took="+(System.currentTimeMillis()-_debugstart)+" ms.");
147
//this happens after the request
148
try
149         {
150             long start = System.currentTimeMillis();
151             HttpSession JavaDoc session = request.getSession(false);
152             
153             if (!( request.getContext().getManager() instanceof ClusterManager) ) return;
154             
155             ClusterManager manager = (ClusterManager)request.getContext().getManager();
156             CatalinaCluster cluster = (CatalinaCluster)getContainer().getCluster();
157             if ( cluster == null ) {
158                 if(log.isWarnEnabled())
159                     log.warn("No cluster configured for this request.");
160                 return;
161             }
162             //first check for session invalidations
163
String JavaDoc[] invalidIds=manager.getInvalidatedSessions();
164             if ( invalidIds.length > 0 ) {
165                 for ( int i=0;i<invalidIds.length; i++ ) {
166                     try {
167                         ClusterMessage imsg = manager.requestCompleted(invalidIds[i]);
168                         if (imsg != null)
169                             cluster.send(imsg);
170                     }catch ( Exception JavaDoc x ) {
171                         log.error("Unable to send session invalid message over cluster.",x);
172                     }
173                 }
174             }
175
176             String JavaDoc id = null;
177             if ( session != null )
178                 id = session.getId();
179             else
180                 return;
181
182             if ( id == null )
183                 return;
184
185             if ( (request.getContext().getManager()==null) ||
186                  (!(request.getContext().getManager() instanceof ClusterManager)))
187                 return;
188
189
190
191             String JavaDoc uri = request.getDecodedRequestURI();
192             boolean filterfound = false;
193
194             for ( int i=0; (i<reqFilters.length) && (!filterfound); i++ )
195             {
196                 java.util.regex.Matcher JavaDoc matcher = reqFilters[i].matcher(uri);
197                 filterfound = matcher.matches();
198             }//for
199
if ( filterfound )
200                 return;
201
202             if(log.isDebugEnabled())
203                 log.debug("Invoking replication request on "+uri);
204
205             
206             ClusterMessage msg = manager.requestCompleted(id);
207
208             if ( msg == null ) return;
209
210             cluster.send(msg);
211             long stop = System.currentTimeMillis();
212             addClusterSendTime(stop-totalstart,stop-start);
213
214         }catch (Exception JavaDoc x)
215         {
216             log.error("Unable to perform replication request.",x);
217         }
218     }
219
220     /**
221      * Mark Request that processed at primary node with attribute
222      * primaryIndicatorName
223      *
224      * @param request
225      * @throws IOException
226      */

227     protected void createPrimaryIndicator(Request request) throws IOException JavaDoc {
228         String JavaDoc id = request.getRequestedSessionId();
229         if ((id != null) && (id.length() > 0)) {
230             Manager manager = request.getContext().getManager();
231             Session JavaDoc session = manager.findSession(id);
232             if (session instanceof ClusterSession) {
233                 ClusterSession cses = (ClusterSession) session;
234                 if (cses != null) {
235                     Boolean JavaDoc isPrimary = new Boolean JavaDoc(cses.isPrimarySession());
236                     if (log.isDebugEnabled())
237                         log.debug("Primarity of session " + id
238                                 + " in request attribute "
239                                 + primaryIndicatorName + " is " + isPrimary);
240                     request.setAttribute(primaryIndicatorName, isPrimary);
241                 }
242             } else {
243                 if (log.isDebugEnabled()) {
244                     if (session != null) {
245                         log.debug("Found session " + id
246                                 + " but it is not a ClusterSession.");
247                     } else {
248                         log.debug("Requested session " + id + " is invalid.");
249                     }
250                 }
251             }
252         }
253     }
254     
255     /**
256      * Return a String rendering of this object.
257      */

258     public String JavaDoc toString() {
259
260         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("ReplicationValve[");
261         if (container != null)
262             sb.append(container.getName());
263         sb.append("]");
264         return (sb.toString());
265
266     }
267
268     /**
269      * @param filter The filter to set.
270      */

271     public void setFilter(String JavaDoc filter)
272     {
273         if(log.isDebugEnabled())
274              log.debug("Loading request filters="+filter);
275         this.filter = filter ;
276         java.util.StringTokenizer JavaDoc t = new java.util.StringTokenizer JavaDoc(filter,";");
277         this.reqFilters = new java.util.regex.Pattern JavaDoc[t.countTokens()];
278         int i = 0;
279         while ( t.hasMoreTokens() )
280         {
281             String JavaDoc s = t.nextToken();
282             if(log.isDebugEnabled())
283                  log.debug("Request filter="+s);
284             try
285             {
286                 reqFilters[i++] = java.util.regex.Pattern.compile(s);
287             }catch ( Exception JavaDoc x )
288             {
289                 log.error("Unable to compile filter "+s,x);
290             }
291         }
292     }
293
294     /**
295      * @return Returns the filter
296      */

297     public String JavaDoc getFilter() {
298        return filter ;
299     }
300
301     /**
302      * @return Returns the primaryIndicator.
303      */

304     public boolean isPrimaryIndicator() {
305         return primaryIndicator;
306     }
307     /**
308      * @param primaryIndicator The primaryIndicator to set.
309      */

310     public void setPrimaryIndicator(boolean primaryIndicator) {
311         this.primaryIndicator = primaryIndicator;
312     }
313     /**
314      * @return Returns the primaryIndicatorName.
315      */

316     public String JavaDoc getPrimaryIndicatorName() {
317         return primaryIndicatorName;
318     }
319     /**
320      * @param primaryIndicatorName The primaryIndicatorName to set.
321      */

322     public void setPrimaryIndicatorName(String JavaDoc primaryIndicatorName) {
323         this.primaryIndicatorName = primaryIndicatorName;
324     }
325 }
326
Popular Tags