KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > coyote > ajp > AjpAprProtocol


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

17
18 package org.apache.coyote.ajp;
19
20 import java.net.InetAddress JavaDoc;
21 import java.net.URLEncoder JavaDoc;
22 import java.util.Hashtable JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.concurrent.Executor JavaDoc;
25
26 import javax.management.MBeanRegistration JavaDoc;
27 import javax.management.MBeanServer JavaDoc;
28 import javax.management.ObjectName JavaDoc;
29
30 import org.apache.coyote.ActionCode;
31 import org.apache.coyote.ActionHook;
32 import org.apache.coyote.Adapter;
33 import org.apache.coyote.ProtocolHandler;
34 import org.apache.coyote.RequestGroupInfo;
35 import org.apache.coyote.RequestInfo;
36 import org.apache.tomcat.util.modeler.Registry;
37 import org.apache.tomcat.util.net.AprEndpoint;
38 import org.apache.tomcat.util.net.SocketStatus;
39 import org.apache.tomcat.util.net.AprEndpoint.Handler;
40 import org.apache.tomcat.util.res.StringManager;
41
42
43 /**
44  * Abstract the protocol implementation, including threading, etc.
45  * Processor is single threaded and specific to stream-based protocols,
46  * will not fit Jk protocols like JNI.
47  *
48  * @author Remy Maucherat
49  * @author Costin Manolache
50  */

51 public class AjpAprProtocol
52     implements ProtocolHandler, MBeanRegistration JavaDoc {
53     
54     
55     protected static org.apache.commons.logging.Log log =
56         org.apache.commons.logging.LogFactory.getLog(AjpAprProtocol.class);
57
58     /**
59      * The string manager for this package.
60      */

61     protected static StringManager sm =
62         StringManager.getManager(Constants.Package);
63
64
65     // ------------------------------------------------------------ Constructor
66

67
68     public AjpAprProtocol() {
69         cHandler = new AjpConnectionHandler(this);
70         setSoLinger(Constants.DEFAULT_CONNECTION_LINGER);
71         setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT);
72         //setServerSoTimeout(Constants.DEFAULT_SERVER_SOCKET_TIMEOUT);
73
setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY);
74     }
75
76     
77     // ----------------------------------------------------- Instance Variables
78

79
80     protected ObjectName JavaDoc tpOname;
81     
82     
83     protected ObjectName JavaDoc rgOname;
84
85
86     /**
87      * Associated APR endpoint.
88      */

89     protected AprEndpoint ep = new AprEndpoint();
90
91
92     /**
93      * Configuration attributes.
94      */

95     protected Hashtable JavaDoc attributes = new Hashtable JavaDoc();
96
97
98     /**
99      * Should authentication be done in the native webserver layer,
100      * or in the Servlet container ?
101      */

102     protected boolean tomcatAuthentication = true;
103
104
105     /**
106      * Required secret.
107      */

108     protected String JavaDoc requiredSecret = null;
109
110
111     /**
112      * AJP packet size.
113      */

114     protected int packetSize = Constants.MAX_PACKET_SIZE;
115
116     
117     /**
118      * Adapter which will process the requests recieved by this endpoint.
119      */

120     private Adapter adapter;
121     
122     
123     /**
124      * Connection handler for AJP.
125      */

126     private AjpConnectionHandler cHandler;
127
128
129     // --------------------------------------------------------- Public Methods
130

131
132     /**
133      * Pass config info
134      */

135     public void setAttribute(String JavaDoc name, Object JavaDoc value) {
136         if (log.isTraceEnabled()) {
137             log.trace(sm.getString("ajpprotocol.setattribute", name, value));
138         }
139         attributes.put(name, value);
140     }
141
142     public Object JavaDoc getAttribute(String JavaDoc key) {
143         if (log.isTraceEnabled()) {
144             log.trace(sm.getString("ajpprotocol.getattribute", key));
145         }
146         return attributes.get(key);
147     }
148
149
150     public Iterator JavaDoc getAttributeNames() {
151         return attributes.keySet().iterator();
152     }
153
154
155     /**
156      * Set a property.
157      */

158     public void setProperty(String JavaDoc name, String JavaDoc value) {
159         setAttribute(name, value);
160     }
161
162
163     /**
164      * Get a property
165      */

166     public String JavaDoc getProperty(String JavaDoc name) {
167         return (String JavaDoc) getAttribute(name);
168     }
169
170
171     /**
172      * The adapter, used to call the connector
173      */

174     public void setAdapter(Adapter adapter) {
175         this.adapter = adapter;
176     }
177
178
179     public Adapter getAdapter() {
180         return adapter;
181     }
182
183
184     /** Start the protocol
185      */

186     public void init() throws Exception JavaDoc {
187         ep.setName(getName());
188         ep.setHandler(cHandler);
189         ep.setUseSendfile(false);
190
191         try {
192             ep.init();
193         } catch (Exception JavaDoc ex) {
194             log.error(sm.getString("ajpprotocol.endpoint.initerror"), ex);
195             throw ex;
196         }
197         if (log.isInfoEnabled()) {
198             log.info(sm.getString("ajpprotocol.init", getName()));
199         }
200     }
201
202
203     public void start() throws Exception JavaDoc {
204         if (this.domain != null ) {
205             try {
206                 tpOname = new ObjectName JavaDoc
207                     (domain + ":" + "type=ThreadPool,name=" + getName());
208                 Registry.getRegistry(null, null)
209                     .registerComponent(ep, tpOname, null );
210             } catch (Exception JavaDoc e) {
211                 log.error("Can't register threadpool" );
212             }
213             rgOname = new ObjectName JavaDoc
214                 (domain + ":type=GlobalRequestProcessor,name=" + getName());
215             Registry.getRegistry(null, null).registerComponent
216                 (cHandler.global, rgOname, null);
217         }
218
219         try {
220             ep.start();
221         } catch (Exception JavaDoc ex) {
222             log.error(sm.getString("ajpprotocol.endpoint.starterror"), ex);
223             throw ex;
224         }
225         if (log.isInfoEnabled())
226             log.info(sm.getString("ajpprotocol.start", getName()));
227     }
228
229     public void pause() throws Exception JavaDoc {
230         try {
231             ep.pause();
232         } catch (Exception JavaDoc ex) {
233             log.error(sm.getString("ajpprotocol.endpoint.pauseerror"), ex);
234             throw ex;
235         }
236         if (log.isInfoEnabled())
237             log.info(sm.getString("ajpprotocol.pause", getName()));
238     }
239
240     public void resume() throws Exception JavaDoc {
241         try {
242             ep.resume();
243         } catch (Exception JavaDoc ex) {
244             log.error(sm.getString("ajpprotocol.endpoint.resumeerror"), ex);
245             throw ex;
246         }
247         if (log.isInfoEnabled())
248             log.info(sm.getString("ajpprotocol.resume", getName()));
249     }
250
251     public void destroy() throws Exception JavaDoc {
252         if (log.isInfoEnabled())
253             log.info(sm.getString("ajpprotocol.stop", getName()));
254         ep.destroy();
255         if (tpOname!=null)
256             Registry.getRegistry(null, null).unregisterComponent(tpOname);
257         if (rgOname != null)
258             Registry.getRegistry(null, null).unregisterComponent(rgOname);
259     }
260
261
262     // *
263
public Executor JavaDoc getExecutor() {
264         return ep.getExecutor();
265     }
266     
267     // *
268
public void setExecutor(Executor JavaDoc executor) {
269         ep.setExecutor(executor);
270     }
271     
272     public int getMaxThreads() {
273         return ep.getMaxThreads();
274     }
275
276     public void setMaxThreads(int maxThreads) {
277         ep.setMaxThreads(maxThreads);
278         setAttribute("maxThreads", "" + maxThreads);
279     }
280
281     public void setThreadPriority(int threadPriority) {
282         ep.setThreadPriority(threadPriority);
283         setAttribute("threadPriority", "" + threadPriority);
284     }
285     
286     public int getThreadPriority() {
287         return ep.getThreadPriority();
288     }
289     
290
291     public int getBacklog() {
292         return ep.getBacklog();
293     }
294
295
296     public void setBacklog( int i ) {
297         ep.setBacklog(i);
298         setAttribute("backlog", "" + i);
299     }
300
301
302     public int getPort() {
303         return ep.getPort();
304     }
305
306
307     public void setPort( int port ) {
308         ep.setPort(port);
309         setAttribute("port", "" + port);
310     }
311
312
313     public boolean getUseSendfile() {
314         return ep.getUseSendfile();
315     }
316
317
318     public void setUseSendfile(boolean useSendfile) {
319         // No sendfile for AJP
320
}
321
322
323     public InetAddress JavaDoc getAddress() {
324         return ep.getAddress();
325     }
326
327
328     public void setAddress(InetAddress JavaDoc ia) {
329         ep.setAddress(ia);
330         setAttribute("address", "" + ia);
331     }
332
333
334     public String JavaDoc getName() {
335         String JavaDoc encodedAddr = "";
336         if (getAddress() != null) {
337             encodedAddr = "" + getAddress();
338             if (encodedAddr.startsWith("/"))
339                 encodedAddr = encodedAddr.substring(1);
340             encodedAddr = URLEncoder.encode(encodedAddr) + "-";
341         }
342         return ("ajp-" + encodedAddr + ep.getPort());
343     }
344
345
346     public boolean getTcpNoDelay() {
347         return ep.getTcpNoDelay();
348     }
349
350
351     public void setTcpNoDelay(boolean b) {
352         ep.setTcpNoDelay(b);
353         setAttribute("tcpNoDelay", "" + b);
354     }
355
356
357     public boolean getTomcatAuthentication() {
358         return tomcatAuthentication;
359     }
360
361
362     public void setTomcatAuthentication(boolean tomcatAuthentication) {
363         this.tomcatAuthentication = tomcatAuthentication;
364     }
365
366
367     public int getFirstReadTimeout() {
368         return ep.getFirstReadTimeout();
369     }
370
371
372     public void setFirstReadTimeout(int i) {
373         ep.setFirstReadTimeout(i);
374         setAttribute("firstReadTimeout", "" + i);
375     }
376
377
378     public int getPollTime() {
379         return ep.getPollTime();
380     }
381
382
383     public void setPollTime(int i) {
384         ep.setPollTime(i);
385         setAttribute("pollTime", "" + i);
386     }
387
388
389     public void setPollerSize(int i) {
390         ep.setPollerSize(i);
391         setAttribute("pollerSize", "" + i);
392     }
393
394
395     public int getPollerSize() {
396         return ep.getPollerSize();
397     }
398
399
400     public int getSoLinger() {
401         return ep.getSoLinger();
402     }
403
404
405     public void setSoLinger(int i) {
406         ep.setSoLinger(i);
407         setAttribute("soLinger", "" + i);
408     }
409
410
411     public int getSoTimeout() {
412         return ep.getSoTimeout();
413     }
414
415
416     public void setSoTimeout( int i ) {
417         ep.setSoTimeout(i);
418         setAttribute("soTimeout", "" + i);
419     }
420
421     
422     public void setRequiredSecret(String JavaDoc requiredSecret) {
423         this.requiredSecret = requiredSecret;
424     }
425     
426     
427     public int getPacketSize() {
428         return packetSize;
429     }
430
431
432     public void setPacketSize(int i) {
433         packetSize = i;
434     }
435
436     
437     // -------------------------------------- AjpConnectionHandler Inner Class
438

439
440     protected static class AjpConnectionHandler implements Handler {
441         protected AjpAprProtocol proto;
442         protected static int count = 0;
443         protected RequestGroupInfo global=new RequestGroupInfo();
444         protected ThreadLocal JavaDoc<AjpAprProcessor> localProcessor = new ThreadLocal JavaDoc<AjpAprProcessor>();
445
446         public AjpConnectionHandler(AjpAprProtocol proto) {
447             this.proto = proto;
448         }
449
450         // FIXME: Support for this could be added in AJP as well
451
public SocketState event(long socket, SocketStatus status) {
452             return SocketState.CLOSED;
453         }
454         
455         public SocketState process(long socket) {
456             AjpAprProcessor processor = null;
457             try {
458                 processor = localProcessor.get();
459                 if (processor == null) {
460                     processor = new AjpAprProcessor(proto.packetSize, proto.ep);
461                     processor.setAdapter(proto.adapter);
462                     processor.setTomcatAuthentication(proto.tomcatAuthentication);
463                     processor.setRequiredSecret(proto.requiredSecret);
464                     localProcessor.set(processor);
465                     if (proto.getDomain() != null) {
466                         synchronized (this) {
467                             try {
468                                 RequestInfo rp = processor.getRequest().getRequestProcessor();
469                                 rp.setGlobalProcessor(global);
470                                 ObjectName JavaDoc rpName = new ObjectName JavaDoc
471                                     (proto.getDomain() + ":type=RequestProcessor,worker="
472                                         + proto.getName() + ",name=AjpRequest" + count++ );
473                                 Registry.getRegistry(null, null)
474                                     .registerComponent(rp, rpName, null);
475                             } catch (Exception JavaDoc ex) {
476                                 log.warn(sm.getString("ajpprotocol.request.register"));
477                             }
478                         }
479                     }
480                 }
481
482                 if (processor instanceof ActionHook) {
483                     ((ActionHook) processor).action(ActionCode.ACTION_START, null);
484                 }
485
486                 if (processor.process(socket)) {
487                     return SocketState.OPEN;
488                 } else {
489                     return SocketState.CLOSED;
490                 }
491
492             } catch(java.net.SocketException JavaDoc e) {
493                 // SocketExceptions are normal
494
AjpAprProtocol.log.debug
495                     (sm.getString
496                      ("ajpprotocol.proto.socketexception.debug"), e);
497             } catch (java.io.IOException JavaDoc e) {
498                 // IOExceptions are normal
499
AjpAprProtocol.log.debug
500                     (sm.getString
501                      ("ajpprotocol.proto.ioexception.debug"), e);
502             }
503             // Future developers: if you discover any other
504
// rare-but-nonfatal exceptions, catch them here, and log as
505
// above.
506
catch (Throwable JavaDoc e) {
507                 // any other exception or error is odd. Here we log it
508
// with "ERROR" level, so it will show up even on
509
// less-than-verbose logs.
510
AjpAprProtocol.log.error
511                     (sm.getString("ajpprotocol.proto.error"), e);
512             } finally {
513                 if (processor instanceof ActionHook) {
514                     ((ActionHook) processor).action(ActionCode.ACTION_STOP, null);
515                 }
516             }
517             return SocketState.CLOSED;
518         }
519     }
520
521
522     // -------------------- Various implementation classes --------------------
523

524
525     protected String JavaDoc domain;
526     protected ObjectName JavaDoc oname;
527     protected MBeanServer JavaDoc mserver;
528
529     public ObjectName JavaDoc getObjectName() {
530         return oname;
531     }
532
533     public String JavaDoc getDomain() {
534         return domain;
535     }
536
537     public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server,
538                                   ObjectName JavaDoc name) throws Exception JavaDoc {
539         oname=name;
540         mserver=server;
541         domain=name.getDomain();
542         return name;
543     }
544
545     public void postRegister(Boolean JavaDoc registrationDone) {
546     }
547
548     public void preDeregister() throws Exception JavaDoc {
549     }
550
551     public void postDeregister() {
552     }
553     
554  
555 }
556
Popular Tags