KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > server > hmux > HmuxDispatchRequest


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.server.hmux;
31
32 import com.caucho.log.Log;
33 import com.caucho.server.cluster.Cluster;
34 import com.caucho.server.cluster.ClusterPort;
35 import com.caucho.server.cluster.ClusterServer;
36 import com.caucho.server.cluster.Server;
37 import com.caucho.server.host.Host;
38 import com.caucho.server.webapp.WebApp;
39 import com.caucho.server.webapp.WebAppController;
40 import com.caucho.util.*;
41 import com.caucho.vfs.ReadStream;
42 import com.caucho.vfs.WriteStream;
43
44 import java.io.IOException JavaDoc;
45 import java.util.ArrayList JavaDoc;
46 import java.util.logging.Level JavaDoc;
47 import java.util.logging.Logger JavaDoc;
48
49 /**
50  * Handles the filter mapping (config) requests from a remote dispatcher.
51  */

52 public class HmuxDispatchRequest {
53   private static final Logger JavaDoc log = Log.open(HmuxDispatchRequest.class);
54
55   // other, specialized protocols
56
public static final int HMUX_HOST = 'h';
57   public static final int HMUX_QUERY_ALL = 'q';
58   public static final int HMUX_QUERY_URL = 'r';
59   public static final int HMUX_QUERY_SERVER = 's';
60   public static final int HMUX_WEB_APP = 'a';
61   public static final int HMUX_MATCH = 'm';
62   public static final int HMUX_IGNORE = 'i';
63   public static final int HMUX_ETAG = 'e';
64   public static final int HMUX_NO_CHANGE = 'n';
65   public static final int HMUX_CLUSTER = 'c';
66   public static final int HMUX_SRUN = 's';
67   public static final int HMUX_SRUN_BACKUP = 'b';
68
69   private CharBuffer _cb = new CharBuffer();
70
71   private HmuxRequest _request;
72   private Server _server;
73
74   private int _srunIndex;
75
76   public HmuxDispatchRequest(HmuxRequest request)
77   {
78     _request = request;
79
80     _server = (Server) request.getDispatchServer();
81   }
82
83   /**
84    * Handles a new request. Initializes the protocol handler and
85    * the request streams.
86    *
87    * <p>Note: ClientDisconnectException must be rethrown to
88    * the caller.
89    */

90   public boolean handleRequest(ReadStream is, WriteStream os)
91     throws IOException JavaDoc
92   {
93     CharBuffer cb = _cb;
94     boolean isLoggable = log.isLoggable(Level.FINE);
95     int code;
96     int len;
97     String JavaDoc host = "";
98     String JavaDoc etag = null;
99
100     while (true) {
101       code = is.read();
102
103       switch (code) {
104       case -1:
105         if (isLoggable)
106           log.fine(dbgId() + "end of file");
107         return false;
108
109       case HmuxRequest.HMUX_QUIT:
110         if (isLoggable)
111           log.fine(dbgId() + (char) code + ": end of request");
112         return true;
113
114       case HmuxRequest.HMUX_EXIT:
115         if (isLoggable)
116           log.fine(dbgId() + (char) code + ": end of socket");
117
118         return false;
119
120       case HMUX_ETAG:
121         len = (is.read() << 8) + is.read();
122     _cb.clear();
123     is.readAll(_cb, len);
124     etag = _cb.toString();
125
126     if (isLoggable)
127       log.fine(dbgId() + "etag: " + etag);
128         break;
129
130       case HMUX_HOST:
131         len = (is.read() << 8) + is.read();
132     _cb.clear();
133     is.readAll(_cb, len);
134     host = _cb.toString();
135
136     if (isLoggable)
137       log.fine(dbgId() + "host: " + host);
138         break;
139
140       case HMUX_QUERY_ALL:
141         len = (is.read() << 8) + is.read();
142     _cb.clear();
143     is.readAll(_cb, len);
144
145     if (isLoggable)
146       log.fine(dbgId() + "query: " + _cb);
147
148         queryAll(os, host, _cb.toString(), etag);
149         break;
150
151     /*
152       case HMUX_QUERY_SERVER:
153         len = (is.read() << 8) + is.read();
154     _cb.clear();
155     is.readAll(_cb, len);
156
157     if (isLoggable)
158       log.fine(dbgId() + "query-server: " + _cb);
159
160         queryCluster(os, host, _cb.toString());
161         break;
162     */

163         
164       default:
165         len = (is.read() << 8) + is.read();
166
167     if (isLoggable)
168       log.fine(dbgId() + (char) code + " " + len + " (dispatch)");
169     is.skip(len);
170     break;
171       }
172     }
173
174     // _filter.setClientClosed(true);
175

176     // return false;
177
}
178   
179   /**
180    * Returns the url.
181    */

182   private void queryAll(WriteStream os, String JavaDoc hostName,
183             String JavaDoc url, String JavaDoc etag)
184     throws IOException JavaDoc
185   {
186     int channel = 2;
187     boolean isLoggable = log.isLoggable(Level.FINE);
188     
189     os.write(HmuxRequest.HMUX_CHANNEL);
190     os.write(channel >> 8);
191     os.write(channel);
192
193     Host host = _server.getHost(hostName, 80);
194     if (host == null) {
195       writeString(os, HmuxRequest.HMUX_HEADER, "check-interval");
196       writeString(os, HmuxRequest.HMUX_STRING,
197           String.valueOf(_server.getDependencyCheckInterval() / 1000));
198       writeString(os, HMUX_WEB_APP, "");
199
200       if (isLoggable)
201     log.fine(dbgId() + "host '" + host + "' not configured");
202       return;
203     }
204     else if (! host.isActive()) {
205       if (etag == null) {
206     // take control until more information is known
207
writeString(os, HMUX_WEB_APP, "");
208     writeString(os, HMUX_MATCH, "/*");
209       }
210       else {
211     sendQuery(null, host, hostName, url);
212
213     writeString(os, HMUX_NO_CHANGE, "");
214       }
215
216       if (isLoggable)
217     log.fine(dbgId() + "host '" + host + "' not active");
218       return;
219     }
220
221     if (host.getConfigETag() == null)
222       sendQuery(null, host, hostName, url);
223
224     if (etag == null) {
225     }
226     else if (etag.equals(host.getConfigETag())) {
227       if (isLoggable)
228     log.fine(dbgId() + "host '" + host + "' no change");
229       
230       writeString(os, HMUX_NO_CHANGE, "");
231       return;
232     }
233     else {
234       if (isLoggable)
235     log.fine(dbgId() + "host '" + host + "' changed");
236     }
237     
238     sendQuery(os, host, hostName, url);
239   }
240
241   /**
242    * Writes the host data, returning the crc
243    */

244   private void sendQuery(WriteStream os, Host host,
245              String JavaDoc hostName, String JavaDoc url)
246     throws IOException JavaDoc
247   {
248     boolean isLoggable = log.isLoggable(Level.FINE);
249     
250     long crc64 = 0;
251
252     if (! Alarm.isTest())
253       crc64 = Crc64.generate(crc64, com.caucho.Version.FULL_VERSION);
254     
255     queryServer(os);
256     
257     writeString(os, HMUX_HOST, host.getHostName());
258
259     if (hostName.equals(host.getHostName())) {
260       crc64 = queryCluster(os, host, crc64);
261       
262       WebAppController controller = host.findByURI(url);
263       if (controller != null) {
264     try {
265       controller.request();
266     } catch (Throwable JavaDoc e) {
267       log.log(Level.WARNING, e.toString(), e);
268     }
269       }
270
271       ArrayList JavaDoc<WebAppController> appList = host.getWebAppList();
272
273       for (int i = 0; i < appList.size(); i++) {
274     WebAppController appEntry = appList.get(i);
275
276     if (appEntry.getParent() != null &&
277         appEntry.getParent().isDynamicDeploy()) {
278       continue;
279     }
280     
281     writeString(os, HMUX_WEB_APP, appEntry.getContextPath());
282     if (isLoggable)
283       log.fine(dbgId() + "web-app '" + appEntry.getContextPath() + "'");
284
285     crc64 = Crc64.generate(crc64, appEntry.getContextPath());
286
287     WebApp app = appEntry.getWebApp();
288
289     if (appEntry.isDynamicDeploy()) {
290       writeString(os, HMUX_MATCH, "/*");
291     
292       crc64 = Crc64.generate(crc64, "/*");
293       
294       if (isLoggable)
295         log.fine(dbgId() + "dynamic '" + appEntry.getContextPath() + "'");
296     }
297     else if (app == null || ! app.isActive()) {
298       if (isLoggable)
299         log.fine(dbgId() + "not active '" + appEntry.getContextPath() + "'");
300       
301       writeString(os, HMUX_NO_CHANGE, "");
302     }
303     else {
304       if (isLoggable)
305         log.fine(dbgId() + "active '" + appEntry.getContextPath() + "'");
306       ArrayList JavaDoc<String JavaDoc> patternList = app.getServletMappingPatterns();
307
308       for (int j = 0; patternList != null && j < patternList.size(); j++) {
309         String JavaDoc pattern = patternList.get(j);
310
311         writeString(os, HMUX_MATCH, pattern);
312       
313         crc64 = Crc64.generate(crc64, pattern);
314       }
315       
316       patternList = app.getServletIgnoreMappingPatterns();
317
318       for (int j = 0; patternList != null && j < patternList.size(); j++) {
319         String JavaDoc pattern = patternList.get(j);
320
321         writeString(os, HMUX_IGNORE, pattern);
322       
323         crc64 = Crc64.generate(crc64, "i");
324         crc64 = Crc64.generate(crc64, pattern);
325       }
326     }
327       }
328
329       CharBuffer cb = new CharBuffer();
330       Base64.encode(cb, crc64);
331       String JavaDoc newETag = cb.close();
332       host.setConfigETag(newETag);
333     }
334     
335     writeString(os, HMUX_ETAG, host.getConfigETag());
336   }
337   
338   /**
339    * Queries the cluster.
340    */

341   private long queryCluster(WriteStream os, Host host, long crc64)
342     throws IOException JavaDoc
343   {
344     /*
345     int channel = 2;
346     
347     os.write(HmuxRequest.HMUX_CHANNEL);
348     os.write(channel >> 8);
349     os.write(channel);
350     */

351
352     Cluster cluster = host.getCluster();
353
354     if (cluster == null)
355       return 0;
356
357     writeString(os, HMUX_CLUSTER, cluster.getId());
358
359     crc64 = Crc64.generate(crc64, cluster.getId());
360
361     writeString(os, HmuxRequest.HMUX_HEADER, "live-time");
362     writeString(os, HmuxRequest.HMUX_STRING, "" + (cluster.getClientMaxIdleTime() / 1000));
363
364     writeString(os, HmuxRequest.HMUX_HEADER, "dead-time");
365     writeString(os, HmuxRequest.HMUX_STRING, "" + (cluster.getClientFailRecoverTime() / 1000));
366
367     ClusterServer []servers = cluster.getServerList();
368
369     for (int i = 0; i < servers.length; i++) {
370       ClusterServer server = servers[i];
371
372       if (server != null && server.getClusterPort() != null) {
373     ClusterPort port = server.getClusterPort();
374     
375     String JavaDoc srunHost = port.getAddress() + ":" + port.getPort();
376
377     /*
378     if (server.isBackup())
379       writeString(os, HMUX_SRUN_BACKUP, srunHost);
380     else
381     */

382     writeString(os, HMUX_SRUN, srunHost);
383       
384     crc64 = Crc64.generate(crc64, srunHost);
385       }
386     }
387
388     return crc64;
389   }
390   
391   /**
392    * Queries the cluster.
393    */

394   private void queryServer(WriteStream os)
395     throws IOException JavaDoc
396   {
397     writeString(os, HmuxRequest.HMUX_HEADER, "check-interval");
398     writeString(os, HmuxRequest.HMUX_STRING,
399         String.valueOf(_server.getDependencyCheckInterval() / 1000));
400     
401     writeString(os, HmuxRequest.HMUX_HEADER, "cookie");
402     writeString(os, HmuxRequest.HMUX_STRING,
403         _server.getSessionCookie());
404     writeString(os, HmuxRequest.HMUX_HEADER, "ssl-cookie");
405     writeString(os, HmuxRequest.HMUX_STRING,
406         _server.getSSLSessionCookie());
407     writeString(os, HmuxRequest.HMUX_HEADER, "session-url-prefix");
408     writeString(os, HmuxRequest.HMUX_STRING,
409         _server.getSessionURLPrefix());
410     writeString(os, HmuxRequest.HMUX_HEADER, "alt-session-url-prefix");
411     writeString(os, HmuxRequest.HMUX_STRING,
412         _server.getAlternateSessionURLPrefix());
413
414     if (_server.getConnectionErrorPage() != null) {
415       writeString(os, HmuxRequest.HMUX_HEADER, "connection-error-page");
416       writeString(os, HmuxRequest.HMUX_STRING,
417           _server.getConnectionErrorPage());
418     }
419   }
420
421   void writeString(WriteStream os, int code, String JavaDoc value)
422     throws IOException JavaDoc
423   {
424     if (os == null)
425       return;
426     
427     if (value == null)
428       value = "";
429     
430     int len = value.length();
431
432     os.write(code);
433     os.write(len >> 8);
434     os.write(len);
435     os.print(value);
436     
437     if (log.isLoggable(Level.FINE))
438       log.fine(dbgId() + (char)code + " " + value);
439   }
440
441   void writeString(WriteStream os, int code, CharBuffer value)
442     throws IOException JavaDoc
443   {
444     if (os == null)
445       return;
446     
447     int len = value.length();
448
449     os.write(code);
450     os.write(len >> 8);
451     os.write(len);
452     os.print(value);
453     
454     if (log.isLoggable(Level.FINE))
455       log.fine(dbgId() + (char)code + " " + value);
456   }
457
458   private String JavaDoc dbgId()
459   {
460     return _request.dbgId();
461   }
462 }
463
Popular Tags