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.http11;
19
20 import java.net.InetAddress;
21 import java.net.URLEncoder;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.concurrent.ConcurrentHashMap;
25 import java.util.concurrent.ConcurrentLinkedQueue;
26 import java.util.concurrent.Executor;
27 import java.util.concurrent.atomic.AtomicInteger;
28 import java.util.concurrent.atomic.AtomicLong;
29
30 import javax.management.MBeanRegistration;
31 import javax.management.MBeanServer;
32 import javax.management.ObjectName;
33
34 import org.apache.coyote.ActionCode;
35 import org.apache.coyote.ActionHook;
36 import org.apache.coyote.Adapter;
37 import org.apache.coyote.ProtocolHandler;
38 import org.apache.coyote.RequestGroupInfo;
39 import org.apache.coyote.RequestInfo;
40 import org.apache.tomcat.util.modeler.Registry;
41 import org.apache.tomcat.util.net.AprEndpoint;
42 import org.apache.tomcat.util.net.SocketStatus;
43 import org.apache.tomcat.util.net.AprEndpoint.Handler;
44 import org.apache.tomcat.util.res.StringManager;
45
46
47 /**
48 * Abstract the protocol implementation, including threading, etc.
49 * Processor is single threaded and specific to stream-based protocols,
50 * will not fit Jk protocols like JNI.
51 *
52 * @author Remy Maucherat
53 * @author Costin Manolache
54 */
55 public class Http11AprProtocol implements ProtocolHandler, MBeanRegistration {
56
57 protected static org.apache.juli.logging.Log log =
58 org.apache.juli.logging.LogFactory.getLog(Http11AprProtocol.class);
59
60 /**
61 * The string manager for this package.
62 */
63 protected static StringManager sm =
64 StringManager.getManager(Constants.Package);
65
66 public Http11AprProtocol() {
67 setSoLinger(Constants.DEFAULT_CONNECTION_LINGER);
68 setSoTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT);
69 //setServerSoTimeout(Constants.DEFAULT_SERVER_SOCKET_TIMEOUT);
70 setTcpNoDelay(Constants.DEFAULT_TCP_NO_DELAY);
71 }
72
73 /** Pass config info
74 */
75 public void setAttribute( String name, Object value ) {
76 if( log.isTraceEnabled())
77 log.trace(sm.getString("http11protocol.setattribute", name, value));
78
79 attributes.put(name, value);
80 }
81
82 public Object getAttribute( String key ) {
83 if( log.isTraceEnabled())
84 log.trace(sm.getString("http11protocol.getattribute", key));
85 return attributes.get(key);
86 }
87
88 public Iterator getAttributeNames() {
89 return attributes.keySet().iterator();
90 }
91
92 /**
93 * The adapter, used to call the connector.
94 */
95 protected Adapter adapter;
96 public void setAdapter(Adapter adapter) { this.adapter = adapter; }
97 public Adapter getAdapter() { return adapter; }
98
99
100 /** Start the protocol
101 */
102 public void init() throws Exception {
103 endpoint.setName(getName());
104 endpoint.setHandler(cHandler);
105
106 try {
107 endpoint.init();
108 } catch (Exception ex) {
109 log.error(sm.getString("http11protocol.endpoint.initerror"), ex);
110 throw ex;
111 }
112 if(log.isInfoEnabled())
113 log.info(sm.getString("http11protocol.init", getName()));
114
115 }
116
117 ObjectName tpOname;
118 ObjectName rgOname;
119
120 public void start() throws Exception {
121 if( this.domain != null ) {
122 try {
123 tpOname=new ObjectName
124 (domain + ":" + "type=ThreadPool,name=" + getName());
125 Registry.getRegistry(null, null)
126 .registerComponent(endpoint, tpOname, null );
127 } catch (Exception e) {
128 log.error("Can't register threadpool" );
129 }
130 rgOname=new ObjectName
131 (domain + ":type=GlobalRequestProcessor,name=" + getName());
132 Registry.getRegistry(null, null).registerComponent
133 ( cHandler.global, rgOname, null );
134 }
135
136 try {
137 endpoint.start();
138 } catch (Exception ex) {
139 log.error(sm.getString("http11protocol.endpoint.starterror"), ex);
140 throw ex;
141 }
142 if(log.isInfoEnabled())
143 log.info(sm.getString("http11protocol.start", getName()));
144 }
145
146 public void pause() throws Exception {
147 try {
148 endpoint.pause();
149 } catch (Exception ex) {
150 log.error(sm.getString("http11protocol.endpoint.pauseerror"), ex);
151 throw ex;
152 }
153 if(log.isInfoEnabled())
154 log.info(sm.getString("http11protocol.pause", getName()));
155 }
156
157 public void resume() throws Exception {
158 try {
159 endpoint.resume();
160 } catch (Exception ex) {
161 log.error(sm.getString("http11protocol.endpoint.resumeerror"), ex);
162 throw ex;
163 }
164 if(log.isInfoEnabled())
165 log.info(sm.getString("http11protocol.resume", getName()));
166 }
167
168 public void destroy() throws Exception {
169 if(log.isInfoEnabled())
170 log.info(sm.getString("http11protocol.stop", getName()));
171 endpoint.destroy();
172 if( tpOname!=null )
173 Registry.getRegistry(null, null).unregisterComponent(tpOname);
174 if( rgOname != null )
175 Registry.getRegistry(null, null).unregisterComponent(rgOname);
176 }
177
178 public String getName() {
179 String encodedAddr = "";
180 if (getAddress() != null) {
181 encodedAddr = "" + getAddress();
182 if (encodedAddr.startsWith("/"))
183 encodedAddr = encodedAddr.substring(1);
184 encodedAddr = URLEncoder.encode(encodedAddr) + "-";
185 }
186 return ("http-" + encodedAddr + endpoint.getPort());
187 }
188
189 protected AprEndpoint endpoint=new AprEndpoint();
190
191 protected HashMap<String, Object> attributes = new HashMap<String, Object>();
192
193 private Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this);
194
195 /**
196 * Processor cache.
197 */
198 protected int processorCache = -1;
199 public int getProcessorCache() { return this.processorCache; }
200 public void setProcessorCache(int processorCache) { this.processorCache = processorCache; }
201
202 public Executor getExecutor() { return endpoint.getExecutor(); }
203 public void setExecutor(Executor executor) { endpoint.setExecutor(executor); }
204
205 public int getMaxThreads() { return endpoint.getMaxThreads(); }
206 public void setMaxThreads(int maxThreads) { endpoint.setMaxThreads(maxThreads); }
207
208 public int getThreadPriority() { return endpoint.getThreadPriority(); }
209 public void setThreadPriority(int threadPriority) { endpoint.setThreadPriority(threadPriority); }
210
211 public int getBacklog() { return endpoint.getBacklog(); }
212 public void setBacklog(int backlog) { endpoint.setBacklog(backlog); }
213
214 public int getPort() { return endpoint.getPort(); }
215 public void setPort(int port) { endpoint.setPort(port); }
216
217 public InetAddress getAddress() { return endpoint.getAddress(); }
218 public void setAddress(InetAddress ia) { endpoint.setAddress(ia); }
219
220 public boolean getTcpNoDelay() { return endpoint.getTcpNoDelay(); }
221 public void setTcpNoDelay(boolean tcpNoDelay) { endpoint.setTcpNoDelay(tcpNoDelay); }
222
223 public int getSoLinger() { return endpoint.getSoLinger(); }
224 public void setSoLinger(int soLinger) { endpoint.setSoLinger(soLinger); }
225
226 public int getSoTimeout() { return endpoint.getSoTimeout(); }
227 public void setSoTimeout(int soTimeout) { endpoint.setSoTimeout(soTimeout); }
228
229 /**
230 * The number of seconds Tomcat will wait for a subsequent request
231 * before closing the connection.
232 */
233 public int getKeepAliveTimeout() { return endpoint.getKeepAliveTimeout(); }
234 public void setKeepAliveTimeout(int timeout) { endpoint.setKeepAliveTimeout(timeout); }
235
236 public boolean getUseSendfile() { return endpoint.getUseSendfile(); }
237 public void setUseSendfile(boolean useSendfile) { endpoint.setUseSendfile(useSendfile); }
238
239 public int getPollTime() { return endpoint.getPollTime(); }
240 public void setPollTime(int pollTime) { endpoint.setPollTime(pollTime); }
241
242 public void setPollerSize(int pollerSize) { endpoint.setPollerSize(pollerSize); }
243 public int getPollerSize() { return endpoint.getPollerSize(); }
244
245 public int getSendfileSize() { return endpoint.getSendfileSize(); }
246 public void setSendfileSize(int sendfileSize) { endpoint.setSendfileSize(sendfileSize); }
247
248 protected int socketBuffer = 9000;
249 public int getSocketBuffer() { return socketBuffer; }
250 public void setSocketBuffer(int socketBuffer) { this.socketBuffer = socketBuffer; }
251
252 /**
253 * Maximum size of the post which will be saved when processing certain
254 * requests, such as a POST.
255 */
256 protected int maxSavePostSize = 4 * 1024;
257 public int getMaxSavePostSize() { return maxSavePostSize; }
258 public void setMaxSavePostSize(int valueI) { maxSavePostSize = valueI; }
259
260 // HTTP
261 /**
262 * Maximum size of the HTTP message header.
263 */
264 protected int maxHttpHeaderSize = 8 * 1024;
265 public int getMaxHttpHeaderSize() { return maxHttpHeaderSize; }
266 public void setMaxHttpHeaderSize(int valueI) { maxHttpHeaderSize = valueI; }
267
268
269 // HTTP
270 /**
271 * If true, the regular socket timeout will be used for the full duration
272 * of the connection.
273 */
274 protected boolean disableUploadTimeout = true;
275 public boolean getDisableUploadTimeout() { return disableUploadTimeout; }
276 public void setDisableUploadTimeout(boolean isDisabled) { disableUploadTimeout = isDisabled; }
277
278 // HTTP
279 /**
280 * Integrated compression support.
281 */
282 protected String compression = "off";
283 public String getCompression() { return compression; }
284 public void setCompression(String valueS) { compression = valueS; }
285
286
287 // HTTP
288 protected String noCompressionUserAgents = null;
289 public String getNoCompressionUserAgents() { return noCompressionUserAgents; }
290 public void setNoCompressionUserAgents(String valueS) { noCompressionUserAgents = valueS; }
291
292
293 // HTTP
294 protected String compressableMimeTypes = "text/html,text/xml,text/plain";
295 public String getCompressableMimeType() { return compressableMimeTypes; }
296 public void setCompressableMimeType(String valueS) { compressableMimeTypes = valueS; }
297
298
299 // HTTP
300 protected int compressionMinSize = 2048;
301 public int getCompressionMinSize() { return compressionMinSize; }
302 public void setCompressionMinSize(int valueI) { compressionMinSize = valueI; }
303
304
305 // HTTP
306 /**
307 * User agents regular expressions which should be restricted to HTTP/1.0 support.
308 */
309 protected String restrictedUserAgents = null;
310 public String getRestrictedUserAgents() { return restrictedUserAgents; }
311 public void setRestrictedUserAgents(String valueS) { restrictedUserAgents = valueS; }
312
313
314 protected String protocol = null;
315 public String getProtocol() { return protocol; }
316 public void setProtocol(String protocol) { setSecure(true); this.protocol = protocol; }
317
318 /**
319 * Maximum number of requests which can be performed over a keepalive
320 * connection. The default is the same as for Apache HTTP Server.
321 */
322 protected int maxKeepAliveRequests = 100;
323 public int getMaxKeepAliveRequests() { return maxKeepAliveRequests; }
324 public void setMaxKeepAliveRequests(int mkar) { maxKeepAliveRequests = mkar; }
325
326 /**
327 * Return the Keep-Alive policy for the connection.
328 */
329 public boolean getKeepAlive() {
330 return ((maxKeepAliveRequests != 0) && (maxKeepAliveRequests != 1));
331 }
332
333 /**
334 * Set the keep-alive policy for this connection.
335 */
336 public void setKeepAlive(boolean keepAlive) {
337 if (!keepAlive) {
338 setMaxKeepAliveRequests(1);
339 }
340 }
341
342 /**
343 * Server header.
344 */
345 protected String server;
346 public void setServer( String server ) { this.server = server; }
347 public String getServer() { return server; }
348
349 /**
350 * This timeout represents the socket timeout which will be used while
351 * the adapter execution is in progress, unless disableUploadTimeout
352 * is set to true. The default is the same as for Apache HTTP Server
353 * (300 000 milliseconds).
354 */
355 protected int timeout = 300000;
356 public int getTimeout() { return timeout; }
357 public void setTimeout(int timeout) { this.timeout = timeout; }
358
359 /**
360 * This field indicates if the protocol is secure from the perspective of
361 * the client (= https is used).
362 */
363 protected boolean secure;
364 public boolean getSecure() { return secure; }
365 public void setSecure(boolean b) { secure = b; }
366
367 // -------------------- SSL related properties --------------------
368
369 /**
370 * SSL engine.
371 */
372 public boolean isSSLEnabled() { return endpoint.isSSLEnabled(); }
373 public void setSSLEnabled(boolean SSLEnabled) { endpoint.setSSLEnabled(SSLEnabled); }
374
375
376 /**
377 * SSL protocol.
378 */
379 public String getSSLProtocol() { return endpoint.getSSLProtocol(); }
380 public void setSSLProtocol(String SSLProtocol) { endpoint.setSSLProtocol(SSLProtocol); }
381
382
383 /**
384 * SSL password (if a cert is encrypted, and no password has been provided, a callback
385 * will ask for a password).
386 */
387 public String getSSLPassword() { return endpoint.getSSLPassword(); }
388 public void setSSLPassword(String SSLPassword) { endpoint.setSSLPassword(SSLPassword); }
389
390
391 /**
392 * SSL cipher suite.
393 */
394 public String getSSLCipherSuite() { return endpoint.getSSLCipherSuite(); }
395 public void setSSLCipherSuite(String SSLCipherSuite) { endpoint.setSSLCipherSuite(SSLCipherSuite); }
396
397
398 /**
399 * SSL certificate file.
400 */
401 public String getSSLCertificateFile() { return endpoint.getSSLCertificateFile(); }
402 public void setSSLCertificateFile(String SSLCertificateFile) { endpoint.setSSLCertificateFile(SSLCertificateFile); }
403
404
405 /**
406 * SSL certificate key file.
407 */
408 public String getSSLCertificateKeyFile() { return endpoint.getSSLCertificateKeyFile(); }
409 public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { endpoint.setSSLCertificateKeyFile(SSLCertificateKeyFile); }
410
411
412 /**
413 * SSL certificate chain file.
414 */
415 public String getSSLCertificateChainFile() { return endpoint.getSSLCertificateChainFile(); }
416 public void setSSLCertificateChainFile(String SSLCertificateChainFile) { endpoint.setSSLCertificateChainFile(SSLCertificateChainFile); }
417
418
419 /**
420 * SSL CA certificate path.
421 */
422 public String getSSLCACertificatePath() { return endpoint.getSSLCACertificatePath(); }
423 public void setSSLCACertificatePath(String SSLCACertificatePath) { endpoint.setSSLCACertificatePath(SSLCACertificatePath); }
424
425
426 /**
427 * SSL CA certificate file.
428 */
429 public String getSSLCACertificateFile() { return endpoint.getSSLCACertificateFile(); }
430 public void setSSLCACertificateFile(String SSLCACertificateFile) { endpoint.setSSLCACertificateFile(SSLCACertificateFile); }
431
432
433 /**
434 * SSL CA revocation path.
435 */
436 public String getSSLCARevocationPath() { return endpoint.getSSLCARevocationPath(); }
437 public void setSSLCARevocationPath(String SSLCARevocationPath) { endpoint.setSSLCARevocationPath(SSLCARevocationPath); }
438
439
440 /**
441 * SSL CA revocation file.
442 */
443 public String getSSLCARevocationFile() { return endpoint.getSSLCARevocationFile(); }
444 public void setSSLCARevocationFile(String SSLCARevocationFile) { endpoint.setSSLCARevocationFile(SSLCARevocationFile); }
445
446
447 /**
448 * SSL verify client.
449 */
450 public String getSSLVerifyClient() { return endpoint.getSSLVerifyClient(); }
451 public void setSSLVerifyClient(String SSLVerifyClient) { endpoint.setSSLVerifyClient(SSLVerifyClient); }
452
453
454 /**
455 * SSL verify depth.
456 */
457 public int getSSLVerifyDepth() { return endpoint.getSSLVerifyDepth(); }
458 public void setSSLVerifyDepth(int SSLVerifyDepth) { endpoint.setSSLVerifyDepth(SSLVerifyDepth); }
459
460 // -------------------- Connection handler --------------------
461
462 static class Http11ConnectionHandler implements Handler {
463
464 protected Http11AprProtocol proto;
465 protected AtomicLong registerCount = new AtomicLong(0);
466 protected RequestGroupInfo global = new RequestGroupInfo();
467
468 protected ConcurrentHashMap<Long, Http11AprProcessor> connections =
469 new ConcurrentHashMap<Long, Http11AprProcessor>();
470 protected ConcurrentLinkedQueue<Http11AprProcessor> recycledProcessors =
471 new ConcurrentLinkedQueue<Http11AprProcessor>() {
472 protected AtomicInteger size = new AtomicInteger(0);
473 public boolean offer(Http11AprProcessor processor) {
474 boolean offer = (proto.processorCache == -1) ? true : (size.get() < proto.processorCache);
475 //avoid over growing our cache or add after we have stopped
476 boolean result = false;
477 if ( offer ) {
478 result = super.offer(processor);
479 if ( result ) {
480 size.incrementAndGet();
481 }
482 }
483 if (!result) unregister(processor);
484 return result;
485 }
486
487 public Http11AprProcessor poll() {
488 Http11AprProcessor result = super.poll();
489 if ( result != null ) {
490 size.decrementAndGet();
491 }
492 return result;
493 }
494
495 public void clear() {
496 Http11AprProcessor next = poll();
497 while ( next != null ) {
498 unregister(next);
499 next = poll();
500 }
501 super.clear();
502 size.set(0);
503 }
504 };
505
506
507 Http11ConnectionHandler(Http11AprProtocol proto) {
508 this.proto = proto;
509 }
510
511 public SocketState event(long socket, SocketStatus status) {
512 Http11AprProcessor result = connections.get(socket);
513
514 SocketState state = SocketState.CLOSED;
515 if (result != null) {
516 // Call the appropriate event
517 try {
518 state = result.event(status);
519 } catch (java.net.SocketException e) {
520 // SocketExceptions are normal
521 Http11AprProtocol.log.debug
522 (sm.getString
523 ("http11protocol.proto.socketexception.debug"), e);
524 } catch (java.io.IOException e) {
525 // IOExceptions are normal
526 Http11AprProtocol.log.debug
527 (sm.getString
528 ("http11protocol.proto.ioexception.debug"), e);
529 }
530 // Future developers: if you discover any other
531 // rare-but-nonfatal exceptions, catch them here, and log as
532 // above.
533 catch (Throwable e) {
534 // any other exception or error is odd. Here we log it
535 // with "ERROR" level, so it will show up even on
536 // less-than-verbose logs.
537 Http11AprProtocol.log.error
538 (sm.getString("http11protocol.proto.error"), e);
539 } finally {
540 if (state != SocketState.LONG) {
541 connections.remove(socket);
542 recycledProcessors.offer(result);
543 if (state == SocketState.OPEN) {
544 proto.endpoint.getPoller().add(socket);
545 }
546 } else {
547 proto.endpoint.getCometPoller().add(socket);
548 }
549 }
550 }
551 return state;
552 }
553
554 public SocketState process(long socket) {
555 Http11AprProcessor processor = recycledProcessors.poll();
556 try {
557 if (processor == null) {
558 processor = createProcessor();
559 }
560
561 if (processor instanceof ActionHook) {
562 ((ActionHook) processor).action(ActionCode.ACTION_START, null);
563 }
564
565 SocketState state = processor.process(socket);
566 if (state == SocketState.LONG) {
567 // Associate the connection with the processor. The next request
568 // processed by this thread will use either a new or a recycled
569 // processor.
570 connections.put(socket, processor);
571 proto.endpoint.getCometPoller().add(socket);
572 } else {
573 recycledProcessors.offer(processor);
574 }
575 return state;
576
577 } catch (java.net.SocketException e) {
578 // SocketExceptions are normal
579 Http11AprProtocol.log.debug
580 (sm.getString
581 ("http11protocol.proto.socketexception.debug"), e);
582 } catch (java.io.IOException e) {
583 // IOExceptions are normal
584 Http11AprProtocol.log.debug
585 (sm.getString
586 ("http11protocol.proto.ioexception.debug"), e);
587 }
588 // Future developers: if you discover any other
589 // rare-but-nonfatal exceptions, catch them here, and log as
590 // above.
591 catch (Throwable e) {
592 // any other exception or error is odd. Here we log it
593 // with "ERROR" level, so it will show up even on
594 // less-than-verbose logs.
595 Http11AprProtocol.log.error
596 (sm.getString("http11protocol.proto.error"), e);
597 }
598 recycledProcessors.offer(processor);
599 return SocketState.CLOSED;
600 }
601
602 protected Http11AprProcessor createProcessor() {
603 Http11AprProcessor processor =
604 new Http11AprProcessor(proto.maxHttpHeaderSize, proto.endpoint);
605 processor.setAdapter(proto.adapter);
606 processor.setMaxKeepAliveRequests(proto.maxKeepAliveRequests);
607 processor.setTimeout(proto.timeout);
608 processor.setDisableUploadTimeout(proto.disableUploadTimeout);
609 processor.setCompressionMinSize(proto.compressionMinSize);
610 processor.setCompression(proto.compression);
611 processor.setNoCompressionUserAgents(proto.noCompressionUserAgents);
612 processor.setCompressableMimeTypes(proto.compressableMimeTypes);
613 processor.setRestrictedUserAgents(proto.restrictedUserAgents);
614 processor.setSocketBuffer(proto.socketBuffer);
615 processor.setMaxSavePostSize(proto.maxSavePostSize);
616 processor.setServer(proto.server);
617 register(processor);
618 return processor;
619 }
620
621 protected void register(Http11AprProcessor processor) {
622 if (proto.getDomain() != null) {
623 synchronized (this) {
624 try {
625 long count = registerCount.incrementAndGet();
626 RequestInfo rp = processor.getRequest().getRequestProcessor();
627 rp.setGlobalProcessor(global);
628 ObjectName rpName = new ObjectName
629 (proto.getDomain() + ":type=RequestProcessor,worker="
630 + proto.getName() + ",name=HttpRequest" + count);
631 if (log.isDebugEnabled()) {
632 log.debug("Register " + rpName);
633 }
634 Registry.getRegistry(null, null).registerComponent(rp, rpName, null);
635 rp.setRpName(rpName);
636 } catch (Exception e) {
637 log.warn("Error registering request");
638 }
639 }
640 }
641 }
642
643 protected void unregister(Http11AprProcessor processor) {
644 if (proto.getDomain() != null) {
645 synchronized (this) {
646 try {
647 RequestInfo rp = processor.getRequest().getRequestProcessor();
648 rp.setGlobalProcessor(null);
649 ObjectName rpName = rp.getRpName();
650 if (log.isDebugEnabled()) {
651 log.debug("Unregister " + rpName);
652 }
653 Registry.getRegistry(null, null).unregisterComponent(rpName);
654 rp.setRpName(null);
655 } catch (Exception e) {
656 log.warn("Error unregistering request", e);
657 }
658 }
659 }
660 }
661
662 }
663
664 // -------------------- Various implementation classes --------------------
665
666 protected String domain;
667 protected ObjectName oname;
668 protected MBeanServer mserver;
669
670 public ObjectName getObjectName() {
671 return oname;
672 }
673
674 public String getDomain() {
675 return domain;
676 }
677
678 public ObjectName preRegister(MBeanServer server,
679 ObjectName name) throws Exception {
680 oname=name;
681 mserver=server;
682 domain=name.getDomain();
683 return name;
684 }
685
686 public void postRegister(Boolean registrationDone) {
687 }
688
689 public void preDeregister() throws Exception {
690 }
691
692 public void postDeregister() {
693 }
694 }