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.catalina.mbeans;
19
20
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import javax.management.MBeanException;
24
25 import org.apache.catalina.Container;
26 import org.apache.catalina.ContainerEvent;
27 import org.apache.catalina.ContainerListener;
28 import org.apache.catalina.Context;
29 import org.apache.catalina.Engine;
30 import org.apache.catalina.Globals;
31 import org.apache.catalina.Host;
32 import org.apache.catalina.Lifecycle;
33 import org.apache.catalina.LifecycleEvent;
34 import org.apache.catalina.LifecycleListener;
35 import org.apache.catalina.Loader;
36 import org.apache.catalina.Manager;
37 import org.apache.catalina.Realm;
38 import org.apache.catalina.Server;
39 import org.apache.catalina.ServerFactory;
40 import org.apache.catalina.Service;
41 import org.apache.catalina.connector.Connector;
42 import org.apache.catalina.core.StandardContext;
43 import org.apache.catalina.core.StandardEngine;
44 import org.apache.catalina.core.StandardHost;
45 import org.apache.catalina.core.StandardServer;
46 import org.apache.catalina.core.StandardService;
47 import org.apache.catalina.deploy.ContextEnvironment;
48 import org.apache.catalina.deploy.ContextResource;
49 import org.apache.catalina.deploy.ContextResourceLink;
50 import org.apache.catalina.deploy.NamingResources;
51 import org.apache.juli.logging.Log;
52 import org.apache.juli.logging.LogFactory;
53
54
55 /**
56 * Implementation of <code>LifecycleListener</code> that
57 * instantiates the set of MBeans associated with the components of a
58 * running instance of Catalina.
59 *
60 * @author Craig R. McClanahan
61 * @author Amy Roh
62 * @version $Revision: 777611 $ $Date: 2009-05-22 18:41:15 +0200 (Fri, 22 May 2009) $
63 */
64
65 public class ServerLifecycleListener
66 implements ContainerListener, LifecycleListener, PropertyChangeListener {
67
68 private static Log log = LogFactory.getLog(ServerLifecycleListener.class);
69
70
71 // ------------------------------------------------------------- Properties
72
73
74 /**
75 * Semicolon separated list of paths containing MBean desciptor resources.
76 */
77 protected String descriptors = null;
78
79 public String getDescriptors() {
80 return (this.descriptors);
81 }
82
83 public void setDescriptors(String descriptors) {
84 this.descriptors = descriptors;
85 }
86
87
88 // ---------------------------------------------- ContainerListener Methods
89
90
91 /**
92 * Handle a <code>ContainerEvent</code> from one of the Containers we are
93 * interested in.
94 *
95 * @param event The event that has occurred
96 */
97 public void containerEvent(ContainerEvent event) {
98
99 try {
100 String type = event.getType();
101 if (Container.ADD_CHILD_EVENT.equals(type)) {
102 processContainerAddChild(event.getContainer(),
103 (Container) event.getData());
104 } else if (Container.REMOVE_CHILD_EVENT.equals(type)) {
105 processContainerRemoveChild(event.getContainer(),
106 (Container) event.getData());
107 }
108 } catch (Exception e) {
109 log.error("Exception processing event " + event, e);
110 }
111
112 }
113
114
115 // ---------------------------------------------- LifecycleListener Methods
116
117
118 /**
119 * Primary entry point for startup and shutdown events.
120 *
121 * @param event The event that has occurred
122 */
123 public void lifecycleEvent(LifecycleEvent event) {
124
125 Lifecycle lifecycle = event.getLifecycle();
126 if (Lifecycle.START_EVENT.equals(event.getType())) {
127
128 if (lifecycle instanceof Server) {
129 createMBeans();
130 }
131
132 // We are embedded.
133 if( lifecycle instanceof Service ) {
134 try {
135 MBeanFactory factory = new MBeanFactory();
136 createMBeans(factory);
137 createMBeans((Service)lifecycle);
138 } catch( Exception ex ) {
139 log.error("Create mbean factory");
140 }
141 }
142
143 /*
144 // Ignore events from StandardContext objects to avoid
145 // reregistering the context
146 if (lifecycle instanceof StandardContext)
147 return;
148 createMBeans();
149 */
150
151 } else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
152 try {
153 if (lifecycle instanceof Server) {
154 destroyMBeans((Server)lifecycle);
155 }
156 if (lifecycle instanceof Service) {
157 destroyMBeans((Service)lifecycle);
158 }
159 } catch (MBeanException t) {
160
161 Exception e = t.getTargetException();
162 if (e == null) {
163 e = t;
164 }
165 log.error("destroyMBeans: MBeanException", e);
166
167 } catch (Throwable t) {
168
169 log.error("destroyMBeans: Throwable", t);
170
171 }
172 // FIXME: RMI adaptor should be stopped; however, this is
173 // undocumented in MX4J, and reports exist in the MX4J bug DB that
174 // this doesn't work
175
176 }
177
178 if ((Context.RELOAD_EVENT.equals(event.getType()))
179 || (Lifecycle.START_EVENT.equals(event.getType()))) {
180
181 // Give context a new handle to the MBean server if the
182 // context has been reloaded since reloading causes the
183 // context to lose its previous handle to the server
184 if (lifecycle instanceof StandardContext) {
185 // If the context is privileged, give a reference to it
186 // in a servlet context attribute
187 StandardContext context = (StandardContext)lifecycle;
188 if (context.getPrivileged()) {
189 context.getServletContext().setAttribute
190 (Globals.MBEAN_REGISTRY_ATTR,
191 MBeanUtils.createRegistry());
192 context.getServletContext().setAttribute
193 (Globals.MBEAN_SERVER_ATTR,
194 MBeanUtils.createServer());
195 }
196 }
197
198 }
199
200 }
201
202
203 // ----------------------------------------- PropertyChangeListener Methods
204
205
206 /**
207 * Handle a <code>PropertyChangeEvent</code> from one of the Containers
208 * we are interested in.
209 *
210 * @param event The event that has occurred
211 */
212 public void propertyChange(PropertyChangeEvent event) {
213
214 if (event.getSource() instanceof Container) {
215 try {
216 processContainerPropertyChange((Container) event.getSource(),
217 event.getPropertyName(),
218 event.getOldValue(),
219 event.getNewValue());
220 } catch (Exception e) {
221 log.error("Exception handling Container property change", e);
222 }
223 }/* else if (event.getSource() instanceof DefaultContext) {
224 try {
225 processDefaultContextPropertyChange
226 ((DefaultContext) event.getSource(),
227 event.getPropertyName(),
228 event.getOldValue(),
229 event.getNewValue());
230 } catch (Exception e) {
231 log.error("Exception handling DefaultContext property change", e);
232 }
233 }*/ else if (event.getSource() instanceof NamingResources) {
234 try {
235 processNamingResourcesPropertyChange
236 ((NamingResources) event.getSource(),
237 event.getPropertyName(),
238 event.getOldValue(),
239 event.getNewValue());
240 } catch (Exception e) {
241 log.error("Exception handling NamingResources property change", e);
242 }
243 } else if (event.getSource() instanceof Server) {
244 try {
245 processServerPropertyChange((Server) event.getSource(),
246 event.getPropertyName(),
247 event.getOldValue(),
248 event.getNewValue());
249 } catch (Exception e) {
250 log.error("Exception handing Server property change", e);
251 }
252 } else if (event.getSource() instanceof Service) {
253 try {
254 processServicePropertyChange((Service) event.getSource(),
255 event.getPropertyName(),
256 event.getOldValue(),
257 event.getNewValue());
258 } catch (Exception e) {
259 log.error("Exception handing Service property change", e);
260 }
261 }
262
263 }
264
265
266 // ------------------------------------------------------ Protected Methods
267
268
269 /**
270 * Create the MBeans that correspond to every existing node of our tree.
271 */
272 protected void createMBeans() {
273
274 try {
275
276 MBeanFactory factory = new MBeanFactory();
277 createMBeans(factory);
278 createMBeans(ServerFactory.getServer());
279
280 } catch (MBeanException t) {
281
282 Exception e = t.getTargetException();
283 if (e == null)
284 e = t;
285 log.error("createMBeans: MBeanException", e);
286
287 } catch (Throwable t) {
288
289 log.error("createMBeans: Throwable", t);
290
291 }
292
293 }
294
295
296 /**
297 * Create the MBeans for the specified Connector and its nested components.
298 *
299 * @param connector Connector for which to create MBeans
300 *
301 * @exception Exception if an exception is thrown during MBean creation
302 */
303 protected void createMBeans(Connector connector) throws Exception {
304
305 // Create the MBean for the Connnector itself
306 // if (log.isDebugEnabled())
307 // log.debug("Creating MBean for Connector " + connector);
308 // MBeanUtils.createMBean(connector);
309
310 }
311
312
313 /**
314 * Create the MBeans for the specified Context and its nested components.
315 *
316 * @param context Context for which to create MBeans
317 *
318 * @exception Exception if an exception is thrown during MBean creation
319 */
320 protected void createMBeans(Context context) throws Exception {
321
322 // Create the MBean for the Context itself
323 // if (log.isDebugEnabled())
324 // log.debug("Creating MBean for Context " + context);
325 // MBeanUtils.createMBean(context);
326 context.addContainerListener(this);
327 if (context instanceof StandardContext) {
328 ((StandardContext) context).addPropertyChangeListener(this);
329 ((StandardContext) context).addLifecycleListener(this);
330 }
331
332 // If the context is privileged, give a reference to it
333 // in a servlet context attribute
334 if (context.getPrivileged()) {
335 context.getServletContext().setAttribute
336 (Globals.MBEAN_REGISTRY_ATTR,
337 MBeanUtils.createRegistry());
338 context.getServletContext().setAttribute
339 (Globals.MBEAN_SERVER_ATTR,
340 MBeanUtils.createServer());
341 }
342
343 // Create the MBeans for the associated nested components
344 Loader cLoader = context.getLoader();
345 if (cLoader != null) {
346 if (log.isDebugEnabled())
347 log.debug("Creating MBean for Loader " + cLoader);
348 //MBeanUtils.createMBean(cLoader);
349 }
350 Manager cManager = context.getManager();
351 if (cManager != null) {
352 if (log.isDebugEnabled())
353 log.debug("Creating MBean for Manager " + cManager);
354 //MBeanUtils.createMBean(cManager);
355 }
356 Realm hRealm = context.getParent().getRealm();
357 Realm cRealm = context.getRealm();
358 if ((cRealm != null) && (cRealm != hRealm)) {
359 if (log.isDebugEnabled())
360 log.debug("Creating MBean for Realm " + cRealm);
361 //MBeanUtils.createMBean(cRealm);
362 }
363
364 // Create the MBeans for the NamingResources (if any)
365 NamingResources resources = context.getNamingResources();
366 createMBeans(resources);
367
368 }
369
370
371 /**
372 * Create the MBeans for the specified ContextEnvironment entry.
373 *
374 * @param environment ContextEnvironment for which to create MBeans
375 *
376 * @exception Exception if an exception is thrown during MBean creation
377 */
378 protected void createMBeans(ContextEnvironment environment)
379 throws Exception {
380
381 // Create the MBean for the ContextEnvironment itself
382 if (log.isDebugEnabled()) {
383 log.debug("Creating MBean for ContextEnvironment " + environment);
384 }
385 MBeanUtils.createMBean(environment);
386
387 }
388
389
390 /**
391 * Create the MBeans for the specified ContextResource entry.
392 *
393 * @param resource ContextResource for which to create MBeans
394 *
395 * @exception Exception if an exception is thrown during MBean creation
396 */
397 protected void createMBeans(ContextResource resource)
398 throws Exception {
399
400 // Create the MBean for the ContextResource itself
401 if (log.isDebugEnabled()) {
402 log.debug("Creating MBean for ContextResource " + resource);
403 }
404 MBeanUtils.createMBean(resource);
405
406 }
407
408
409 /**
410 * Create the MBeans for the specified ContextResourceLink entry.
411 *
412 * @param resourceLink ContextResourceLink for which to create MBeans
413 *
414 * @exception Exception if an exception is thrown during MBean creation
415 */
416 protected void createMBeans(ContextResourceLink resourceLink)
417 throws Exception {
418
419 // Create the MBean for the ContextResourceLink itself
420 if (log.isDebugEnabled()) {
421 log.debug("Creating MBean for ContextResourceLink " + resourceLink);
422 }
423 MBeanUtils.createMBean(resourceLink);
424
425 }
426
427
428 /**
429 * Create the MBeans for the specified DefaultContext and its nested components.
430 *
431 * @param dcontext DefaultContext for which to create MBeans
432 *
433 * @exception Exception if an exception is thrown during MBean creation
434 */
435 /*
436 protected void createMBeans(DefaultContext dcontext) throws Exception {
437
438 // Create the MBean for the DefaultContext itself
439 if (log.isDebugEnabled())
440 log.debug("Creating MBean for DefaultContext " + dcontext);
441 MBeanUtils.createMBean(dcontext);
442
443 dcontext.addPropertyChangeListener(this);
444
445 // Create the MBeans for the associated nested components
446 Loader dLoader = dcontext.getLoader();
447 if (dLoader != null) {
448 if (log.isDebugEnabled())
449 log.debug("Creating MBean for Loader " + dLoader);
450 //MBeanUtils.createMBean(dLoader);
451 }
452
453 Manager dManager = dcontext.getManager();
454 if (dManager != null) {
455 if (log.isDebugEnabled())
456 log.debug("Creating MBean for Manager " + dManager);
457 //MBeanUtils.createMBean(dManager);
458 }
459
460 // Create the MBeans for the NamingResources (if any)
461 NamingResources resources = dcontext.getNamingResources();
462 createMBeans(resources);
463
464 }
465 */
466
467
468 /**
469 * Create the MBeans for the specified Engine and its nested components.
470 *
471 * @param engine Engine for which to create MBeans
472 *
473 * @exception Exception if an exception is thrown during MBean creation
474 */
475 protected void createMBeans(Engine engine) throws Exception {
476
477 // Create the MBean for the Engine itself
478 if (log.isDebugEnabled()) {
479 log.debug("Creating MBean for Engine " + engine);
480 }
481 //MBeanUtils.createMBean(engine);
482 engine.addContainerListener(this);
483 if (engine instanceof StandardEngine) {
484 ((StandardEngine) engine).addPropertyChangeListener(this);
485 }
486
487 // Create the MBeans for the associated nested components
488 Realm eRealm = engine.getRealm();
489 if (eRealm != null) {
490 if (log.isDebugEnabled())
491 log.debug("Creating MBean for Realm " + eRealm);
492 //MBeanUtils.createMBean(eRealm);
493 }
494
495 // Create the MBeans for each child Host
496 Container hosts[] = engine.findChildren();
497 for (int j = 0; j < hosts.length; j++) {
498 createMBeans((Host) hosts[j]);
499 }
500
501 }
502
503
504 /**
505 * Create the MBeans for the specified Host and its nested components.
506 *
507 * @param host Host for which to create MBeans
508 *
509 * @exception Exception if an exception is thrown during MBean creation
510 */
511 protected void createMBeans(Host host) throws Exception {
512
513 // Create the MBean for the Host itself
514 if (log.isDebugEnabled()) {
515 log.debug("Creating MBean for Host " + host);
516 }
517 //MBeanUtils.createMBean(host);
518 host.addContainerListener(this);
519 if (host instanceof StandardHost) {
520 ((StandardHost) host).addPropertyChangeListener(this);
521 }
522
523 // Create the MBeans for the associated nested components
524 Realm eRealm = host.getParent().getRealm();
525 Realm hRealm = host.getRealm();
526 if ((hRealm != null) && (hRealm != eRealm)) {
527 if (log.isDebugEnabled())
528 log.debug("Creating MBean for Realm " + hRealm);
529 //MBeanUtils.createMBean(hRealm);
530 }
531
532 // Create the MBeans for each child Context
533 Container contexts[] = host.findChildren();
534 for (int k = 0; k < contexts.length; k++) {
535 createMBeans((Context) contexts[k]);
536 }
537
538 }
539
540
541 /**
542 * Create the MBeans for MBeanFactory.
543 *
544 * @param factory MBeanFactory for which to create MBean
545 *
546 * @exception Exception if an exception is thrown during MBean creation
547 */
548 protected void createMBeans(MBeanFactory factory) throws Exception {
549
550 // Create the MBean for the MBeanFactory
551 if (log.isDebugEnabled())
552 log.debug("Creating MBean for MBeanFactory " + factory);
553 MBeanUtils.createMBean(factory);
554
555 }
556
557
558 /**
559 * Create the MBeans for the specified NamingResources and its
560 * nested components.
561 *
562 * @param resources NamingResources for which to create MBeans
563 */
564 protected void createMBeans(NamingResources resources) throws Exception {
565
566 // Create the MBean for the NamingResources itself
567 if (log.isDebugEnabled()) {
568 log.debug("Creating MBean for NamingResources " + resources);
569 }
570 MBeanUtils.createMBean(resources);
571 resources.addPropertyChangeListener(this);
572
573 // Create the MBeans for each child environment entry
574 ContextEnvironment environments[] = resources.findEnvironments();
575 for (int i = 0; i < environments.length; i++) {
576 createMBeans(environments[i]);
577 }
578
579 // Create the MBeans for each child resource entry
580 ContextResource cresources[] = resources.findResources();
581 for (int i = 0; i < cresources.length; i++) {
582 createMBeans(cresources[i]);
583 }
584
585 // Create the MBeans for each child resource link entry
586 ContextResourceLink cresourcelinks[] = resources.findResourceLinks();
587 for (int i = 0; i < cresourcelinks.length; i++) {
588 createMBeans(cresourcelinks[i]);
589 }
590
591 }
592
593
594 /**
595 * Create the MBeans for the specified Server and its nested components.
596 *
597 * @param server Server for which to create MBeans
598 *
599 * @exception Exception if an exception is thrown during MBean creation
600 */
601 protected void createMBeans(Server server) throws Exception {
602
603 // Create the MBean for the Server itself
604 if (log.isDebugEnabled())
605 log.debug("Creating MBean for Server " + server);
606 //MBeanUtils.createMBean(server);
607 if (server instanceof StandardServer) {
608 ((StandardServer) server).addPropertyChangeListener(this);
609 }
610
611 // Create the MBeans for the global NamingResources (if any)
612 NamingResources resources = server.getGlobalNamingResources();
613 if (resources != null) {
614 createMBeans(resources);
615 }
616
617 // Create the MBeans for each child Service
618 Service services[] = server.findServices();
619 for (int i = 0; i < services.length; i++) {
620 // FIXME - Warp object hierarchy not currently supported
621 if (services[i].getContainer().getClass().getName().equals
622 ("org.apache.catalina.connector.warp.WarpEngine")) {
623 if (log.isDebugEnabled()) {
624 log.debug("Skipping MBean for Service " + services[i]);
625 }
626 continue;
627 }
628 createMBeans(services[i]);
629 }
630
631 }
632
633
634 /**
635 * Create the MBeans for the specified Service and its nested components.
636 *
637 * @param service Service for which to create MBeans
638 *
639 * @exception Exception if an exception is thrown during MBean creation
640 */
641 protected void createMBeans(Service service) throws Exception {
642
643 if (service instanceof StandardService) {
644 ((StandardService) service).addPropertyChangeListener(this);
645 }
646
647 // Create the MBeans for the corresponding Connectors
648 Connector connectors[] = service.findConnectors();
649 for (int j = 0; j < connectors.length; j++) {
650 createMBeans(connectors[j]);
651 }
652
653 // Create the MBean for the associated Engine and friends
654 Engine engine = (Engine) service.getContainer();
655 if (engine != null) {
656 createMBeans(engine);
657 }
658
659 }
660
661
662
663
664 /**
665 * Deregister the MBeans for the specified Connector and its nested
666 * components.
667 *
668 * @param connector Connector for which to deregister MBeans
669 *
670 * @exception Exception if an exception is thrown during MBean destruction
671 */
672 protected void destroyMBeans(Connector connector, Service service)
673 throws Exception {
674
675 // deregister the MBean for the Connector itself
676 if (log.isDebugEnabled())
677 log.debug("Destroying MBean for Connector " + connector);
678 MBeanUtils.destroyMBean(connector, service);
679
680 }
681
682
683 /**
684 * Deregister the MBeans for the specified Context and its nested
685 * components.
686 *
687 * @param context Context for which to deregister MBeans
688 *
689 * @exception Exception if an exception is thrown during MBean destruction
690 */
691 protected void destroyMBeans(Context context) throws Exception {
692
693 // Deregister ourselves as a ContainerListener
694 context.removeContainerListener(this);
695
696 // Destroy the MBeans for the associated nested components
697 Realm hRealm = context.getParent().getRealm();
698 Realm cRealm = context.getRealm();
699 if ((cRealm != null) && (cRealm != hRealm)) {
700 if (log.isDebugEnabled())
701 log.debug("Destroying MBean for Realm " + cRealm);
702 //MBeanUtils.destroyMBean(cRealm);
703 }
704 Manager cManager = context.getManager();
705 if (cManager != null) {
706 if (log.isDebugEnabled())
707 log.debug("Destroying MBean for Manager " + cManager);
708 //MBeanUtils.destroyMBean(cManager);
709 }
710 Loader cLoader = context.getLoader();
711 if (cLoader != null) {
712 if (log.isDebugEnabled())
713 log.debug("Destroying MBean for Loader " + cLoader);
714 //MBeanUtils.destroyMBean(cLoader);
715 }
716
717 // Destroy the MBeans for the NamingResources (if any)
718 NamingResources resources = context.getNamingResources();
719 if (resources != null) {
720 destroyMBeans(resources);
721 }
722
723 // deregister the MBean for the Context itself
724 if (log.isDebugEnabled())
725 log.debug("Destroying MBean for Context " + context);
726 MBeanUtils.destroyMBean(context);
727 if (context instanceof StandardContext) {
728 ((StandardContext) context).
729 removePropertyChangeListener(this);
730 }
731
732 }
733
734
735 /**
736 * Deregister the MBeans for the specified ContextEnvironment entry.
737 *
738 * @param environment ContextEnvironment for which to destroy MBeans
739 *
740 * @exception Exception if an exception is thrown during MBean destruction
741 */
742 protected void destroyMBeans(ContextEnvironment environment)
743 throws Exception {
744
745 // Destroy the MBean for the ContextEnvironment itself
746 if (log.isDebugEnabled()) {
747 log.debug("Destroying MBean for ContextEnvironment " + environment);
748 }
749 MBeanUtils.destroyMBean(environment);
750
751 }
752
753
754 /**
755 * Deregister the MBeans for the specified ContextResource entry.
756 *
757 * @param resource ContextResource for which to destroy MBeans
758 *
759 * @exception Exception if an exception is thrown during MBean destruction
760 */
761 protected void destroyMBeans(ContextResource resource)
762 throws Exception {
763
764 // Destroy the MBean for the ContextResource itself
765 if (log.isDebugEnabled()) {
766 log.debug("Destroying MBean for ContextResource " + resource);
767 }
768 MBeanUtils.destroyMBean(resource);
769
770 }
771
772
773 /**
774 * Deregister the MBeans for the specified ContextResourceLink entry.
775 *
776 * @param resourceLink ContextResourceLink for which to destroy MBeans
777 *
778 * @exception Exception if an exception is thrown during MBean destruction
779 */
780 protected void destroyMBeans(ContextResourceLink resourceLink)
781 throws Exception {
782
783 // Destroy the MBean for the ContextResourceLink itself
784 if (log.isDebugEnabled()) {
785 log.debug("Destroying MBean for ContextResourceLink " + resourceLink);
786 }
787 MBeanUtils.destroyMBean(resourceLink);
788
789 }
790
791
792 /**
793 * Deregister the MBeans for the specified DefaultContext and its nested
794 * components.
795 *
796 * @param dcontext DefaultContext for which to deregister MBeans
797 *
798 * @exception Exception if an exception is thrown during MBean destruction
799 */
800 /*
801 protected void destroyMBeans(DefaultContext dcontext) throws Exception {
802
803 Manager dManager = dcontext.getManager();
804 if (dManager != null) {
805 if (log.isDebugEnabled())
806 log.debug("Destroying MBean for Manager " + dManager);
807 //MBeanUtils.destroyMBean(dManager);
808 }
809
810 Loader dLoader = dcontext.getLoader();
811 if (dLoader != null) {
812 if (log.isDebugEnabled())
813 log.debug("Destroying MBean for Loader " + dLoader);
814 //MBeanUtils.destroyMBean(dLoader);
815 }
816
817 // Destroy the MBeans for the NamingResources (if any)
818 NamingResources resources = dcontext.getNamingResources();
819 if (resources != null) {
820 destroyMBeans(resources);
821 }
822
823 // deregister the MBean for the DefaultContext itself
824 if (log.isDebugEnabled())
825 log.debug("Destroying MBean for Context " + dcontext);
826 MBeanUtils.destroyMBean(dcontext);
827 dcontext.removePropertyChangeListener(this);
828
829 }
830 */
831
832
833 /**
834 * Deregister the MBeans for the specified Engine and its nested
835 * components.
836 *
837 * @param engine Engine for which to destroy MBeans
838 *
839 * @exception Exception if an exception is thrown during MBean destruction
840 */
841 protected void destroyMBeans(Engine engine) throws Exception {
842
843 // Deregister ourselves as a ContainerListener
844 engine.removeContainerListener(this);
845
846 // Deregister the MBeans for each child Host
847 Container hosts[] = engine.findChildren();
848 for (int k = 0; k < hosts.length; k++) {
849 destroyMBeans((Host) hosts[k]);
850 }
851
852 // Deregister the MBeans for the associated nested components
853 Realm eRealm = engine.getRealm();
854 if (eRealm != null) {
855 if (log.isDebugEnabled())
856 log.debug("Destroying MBean for Realm " + eRealm);
857 //MBeanUtils.destroyMBean(eRealm);
858 }
859
860 // Deregister the MBean for the Engine itself
861 if (log.isDebugEnabled()) {
862 log.debug("Destroying MBean for Engine " + engine);
863 }
864 MBeanUtils.destroyMBean(engine);
865
866 }
867
868
869 /**
870 * Deregister the MBeans for the specified Host and its nested components.
871 *
872 * @param host Host for which to destroy MBeans
873 *
874 * @exception Exception if an exception is thrown during MBean destruction
875 */
876 protected void destroyMBeans(Host host) throws Exception {
877
878 // Deregister ourselves as a ContainerListener
879 host.removeContainerListener(this);
880
881 // Deregister the MBeans for each child Context
882 Container contexts[] = host.findChildren();
883 for (int k = 0; k < contexts.length; k++) {
884 destroyMBeans((Context) contexts[k]);
885 }
886
887
888 // Deregister the MBeans for the associated nested components
889 Realm eRealm = host.getParent().getRealm();
890 Realm hRealm = host.getRealm();
891 if ((hRealm != null) && (hRealm != eRealm)) {
892 if (log.isDebugEnabled())
893 log.debug("Destroying MBean for Realm " + hRealm);
894 //MBeanUtils.destroyMBean(hRealm);
895 }
896
897 // Deregister the MBean for the Host itself
898 if (log.isDebugEnabled()) {
899 log.debug("Destroying MBean for Host " + host);
900 }
901 MBeanUtils.destroyMBean(host);
902
903 }
904
905
906 /**
907 * Deregister the MBeans for the specified NamingResources and its
908 * nested components.
909 *
910 * @param resources NamingResources for which to destroy MBeans
911 *
912 * @exception Exception if an exception is thrown during MBean destruction
913 */
914 protected void destroyMBeans(NamingResources resources) throws Exception {
915
916 // Destroy the MBeans for each child resource entry
917 ContextResource cresources[] = resources.findResources();
918 for (int i = 0; i < cresources.length; i++) {
919 destroyMBeans(cresources[i]);
920 }
921
922 // Destroy the MBeans for each child resource link entry
923 ContextResourceLink cresourcelinks[] = resources.findResourceLinks();
924 for (int i = 0; i < cresourcelinks.length; i++) {
925 destroyMBeans(cresourcelinks[i]);
926 }
927
928 // Destroy the MBeans for each child environment entry
929 ContextEnvironment environments[] = resources.findEnvironments();
930 for (int i = 0; i < environments.length; i++) {
931 destroyMBeans(environments[i]);
932 }
933
934 // Destroy the MBean for the NamingResources itself
935 if (log.isDebugEnabled()) {
936 log.debug("Destroying MBean for NamingResources " + resources);
937 }
938 MBeanUtils.destroyMBean(resources);
939 resources.removePropertyChangeListener(this);
940
941 }
942
943
944 /**
945 * Deregister the MBeans for the specified Server and its related
946 * components.
947 *
948 * @param server Server for which to destroy MBeans
949 *
950 * @exception Exception if an exception is thrown during MBean destruction
951 */
952 protected void destroyMBeans(Server server) throws Exception {
953
954 // Destroy the MBeans for the global NamingResources (if any)
955 NamingResources resources = server.getGlobalNamingResources();
956 if (resources != null) {
957 destroyMBeans(resources);
958 }
959
960 // Destroy the MBeans for each child Service
961 Service services[] = server.findServices();
962 for (int i = 0; i < services.length; i++) {
963 // FIXME - Warp object hierarchy not currently supported
964 if (services[i].getContainer().getClass().getName().equals
965 ("org.apache.catalina.connector.warp.WarpEngine")) {
966 if (log.isDebugEnabled()) {
967 log.debug("Skipping MBean for Service " + services[i]);
968 }
969 continue;
970 }
971 destroyMBeans(services[i]);
972 }
973
974 // Destroy the MBean for the Server itself
975 if (log.isDebugEnabled()) {
976 log.debug("Destroying MBean for Server " + server);
977 }
978 MBeanUtils.destroyMBean(server);
979 if (server instanceof StandardServer) {
980 ((StandardServer) server).removePropertyChangeListener(this);
981 }
982
983 }
984
985
986 /**
987 * Deregister the MBeans for the specified Service and its nested
988 * components.
989 *
990 * @param service Service for which to destroy MBeans
991 *
992 * @exception Exception if an exception is thrown during MBean destruction
993 */
994 protected void destroyMBeans(Service service) throws Exception {
995
996 // Deregister the MBeans for the associated Engine
997 Engine engine = (Engine) service.getContainer();
998 if (engine != null) {
999 destroyMBeans(engine);
1000 }
1001
1002 // Deregister the MBeans for the corresponding Connectors
1003 Connector connectors[] = service.findConnectors();
1004 for (int j = 0; j < connectors.length; j++) {
1005 destroyMBeans(connectors[j], service);
1006 }
1007
1008 if (service instanceof StandardService) {
1009 ((StandardService) service).removePropertyChangeListener(this);
1010 }
1011
1012 }
1013
1014
1015 /**
1016 * Process the addition of a new child Container to a parent Container.
1017 *
1018 * @param parent Parent container
1019 * @param child Child container
1020 */
1021 protected void processContainerAddChild(Container parent,
1022 Container child) {
1023
1024 if (log.isDebugEnabled())
1025 log.debug("Process addChild[parent=" + parent + ",child=" + child + "]");
1026
1027 try {
1028 if (child instanceof Context) {
1029 createMBeans((Context) child);
1030 } else if (child instanceof Engine) {
1031 createMBeans((Engine) child);
1032 } else if (child instanceof Host) {
1033 createMBeans((Host) child);
1034 }
1035 } catch (MBeanException t) {
1036 Exception e = t.getTargetException();
1037 if (e == null)
1038 e = t;
1039 log.error("processContainerAddChild: MBeanException", e);
1040 } catch (Throwable t) {
1041 log.error("processContainerAddChild: Throwable", t);
1042 }
1043
1044 }
1045
1046
1047
1048
1049 /**
1050 * Process a property change event on a Container.
1051 *
1052 * @param container The container on which this event occurred
1053 * @param propertyName The name of the property that changed
1054 * @param oldValue The previous value (may be <code>null</code>)
1055 * @param newValue The new value (may be <code>null</code>)
1056 *
1057 * @exception Exception if an exception is thrown
1058 */
1059 protected void processContainerPropertyChange(Container container,
1060 String propertyName,
1061 Object oldValue,
1062 Object newValue)
1063 throws Exception {
1064
1065 if (log.isTraceEnabled()) {
1066 log.trace("propertyChange[container=" + container +
1067 ",propertyName=" + propertyName +
1068 ",oldValue=" + oldValue +
1069 ",newValue=" + newValue + "]");
1070 }
1071 if ("loader".equals(propertyName)) {
1072 if (oldValue != null) {
1073 if (log.isDebugEnabled()) {
1074 log.debug("Removing MBean for Loader " + oldValue);
1075 }
1076 MBeanUtils.destroyMBean((Loader) oldValue);
1077 }
1078 if (newValue != null) {
1079 if (log.isDebugEnabled()) {
1080 log.debug("Creating MBean for Loader " + newValue);
1081 }
1082 MBeanUtils.createMBean((Loader) newValue);
1083 }
1084 } else if ("logger".equals(propertyName)) {
1085 if (oldValue != null) {
1086 if (log.isDebugEnabled()) {
1087 log.debug("Removing MBean for Logger " + oldValue);
1088 }
1089 // MBeanUtils.destroyMBean((Logger) oldValue);
1090 }
1091 if (newValue != null) {
1092 if (log.isDebugEnabled()) {
1093 log.debug("Creating MBean for Logger " + newValue);
1094 }
1095 //MBeanUtils.createMBean((Logger) newValue);
1096 }
1097 } else if ("manager".equals(propertyName)) {
1098 if (oldValue != null) {
1099 if (log.isDebugEnabled()) {
1100 log.debug("Removing MBean for Manager " + oldValue);
1101 }
1102 //MBeanUtils.destroyMBean((Manager) oldValue);
1103 }
1104 if (newValue != null) {
1105 if (log.isDebugEnabled()) {
1106 log.debug("Creating MBean for Manager " + newValue);
1107 }
1108 //MBeanUtils.createMBean((Manager) newValue);
1109 }
1110 } else if ("realm".equals(propertyName)) {
1111 if (oldValue != null) {
1112 if (log.isDebugEnabled()) {
1113 log.debug("Removing MBean for Realm " + oldValue);
1114 }
1115 MBeanUtils.destroyMBean((Realm) oldValue);
1116 }
1117 if (newValue != null) {
1118 if (log.isDebugEnabled()) {
1119 log.debug("Creating MBean for Realm " + newValue);
1120 }
1121 //MBeanUtils.createMBean((Realm) newValue);
1122 }
1123 } else if ("service".equals(propertyName)) {
1124 if (oldValue != null) {
1125 destroyMBeans((Service) oldValue);
1126 }
1127 if (newValue != null) {
1128 createMBeans((Service) newValue);
1129 }
1130 }
1131
1132 }
1133
1134
1135 /**
1136 * Process a property change event on a DefaultContext.
1137 *
1138 * @param defaultContext The DefaultContext on which this event occurred
1139 * @param propertyName The name of the property that changed
1140 * @param oldValue The previous value (may be <code>null</code>)
1141 * @param newValue The new value (may be <code>null</code>)
1142 *
1143 * @exception Exception if an exception is thrown
1144 */
1145 /*
1146 protected void processDefaultContextPropertyChange(DefaultContext defaultContext,
1147 String propertyName,
1148 Object oldValue,
1149 Object newValue)
1150 throws Exception {
1151
1152 if (log.isTraceEnabled()) {
1153 log.trace("propertyChange[defaultContext=" + defaultContext +
1154 ",propertyName=" + propertyName +
1155 ",oldValue=" + oldValue +
1156 ",newValue=" + newValue + "]");
1157 }
1158 if ("loader".equals(propertyName)) {
1159 if (oldValue != null) {
1160 if (log.isDebugEnabled()) {
1161 log.debug("Removing MBean for Loader " + oldValue);
1162 }
1163 MBeanUtils.destroyMBean((Loader) oldValue);
1164 }
1165 if (newValue != null) {
1166 if (log.isDebugEnabled()) {
1167 log.debug("Creating MBean for Loader " + newValue);
1168 }
1169 MBeanUtils.createMBean((Loader) newValue);
1170 }
1171 } else if ("logger".equals(propertyName)) {
1172 if (oldValue != null) {
1173 if (log.isDebugEnabled()) {
1174 log.debug("Removing MBean for Logger " + oldValue);
1175 }
1176 //MBeanUtils.destroyMBean((Logger) oldValue);
1177 }
1178 if (newValue != null) {
1179 if (log.isDebugEnabled()) {
1180 log.debug("Creating MBean for Logger " + newValue);
1181 }
1182 //MBeanUtils.createMBean((Logger) newValue);
1183 }
1184 } else if ("manager".equals(propertyName)) {
1185 if (oldValue != null) {
1186 if (log.isDebugEnabled()) {
1187 log.debug("Removing MBean for Manager " + oldValue);
1188 }
1189 MBeanUtils.destroyMBean((Manager) oldValue);
1190 }
1191 if (newValue != null) {
1192 if (log.isDebugEnabled()) {
1193 log.debug("Creating MBean for Manager " + newValue);
1194 }
1195 MBeanUtils.createMBean((Manager) newValue);
1196 }
1197 } else if ("realm".equals(propertyName)) {
1198 if (oldValue != null) {
1199 // if (log.isDebugEnabled()) {
1200 // log.debug("Removing MBean for Realm " + oldValue);
1201 // }
1202 // //MBeanUtils.destroyMBean((Realm) oldValue);
1203 }
1204 if (newValue != null) {
1205 // if (log.isDebugEnabled()) {
1206 // log.debug("Creating MBean for Realm " + newValue);
1207 // }
1208 // //MBeanUtils.createMBean((Realm) newValue);
1209 }
1210 } else if ("service".equals(propertyName)) {
1211 if (oldValue != null) {
1212 destroyMBeans((Service) oldValue);
1213 }
1214 if (newValue != null) {
1215 createMBeans((Service) newValue);
1216 }
1217 }
1218
1219 }*/
1220
1221
1222 /**
1223 * Process the removal of a child Container from a parent Container.
1224 *
1225 * @param parent Parent container
1226 * @param child Child container
1227 */
1228 protected void processContainerRemoveChild(Container parent,
1229 Container child) {
1230
1231 if (log.isDebugEnabled())
1232 log.debug("Process removeChild[parent=" + parent + ",child=" +
1233 child + "]");
1234
1235 try {
1236 if (child instanceof Context) {
1237 Context context = (Context) child;
1238 if (context.getPrivileged()) {
1239 context.getServletContext().removeAttribute
1240 (Globals.MBEAN_REGISTRY_ATTR);
1241 context.getServletContext().removeAttribute
1242 (Globals.MBEAN_SERVER_ATTR);
1243 }
1244 if (log.isDebugEnabled())
1245 log.debug(" Removing MBean for Context " + context);
1246 destroyMBeans(context);
1247 if (context instanceof StandardContext) {
1248 ((StandardContext) context).
1249 removePropertyChangeListener(this);
1250 }
1251 } else if (child instanceof Host) {
1252 Host host = (Host) child;
1253 destroyMBeans(host);
1254 if (host instanceof StandardHost) {
1255 ((StandardHost) host).
1256 removePropertyChangeListener(this);
1257 }
1258 }
1259 } catch (MBeanException t) {
1260 Exception e = t.getTargetException();
1261 if (e == null)
1262 e = t;
1263 log.error("processContainerRemoveChild: MBeanException", e);
1264 } catch (Throwable t) {
1265 log.error("processContainerRemoveChild: Throwable", t);
1266 }
1267
1268 }
1269
1270
1271 /**
1272 * Process a property change event on a NamingResources.
1273 *
1274 * @param resources The global naming resources on which this
1275 * event occurred
1276 * @param propertyName The name of the property that changed
1277 * @param oldValue The previous value (may be <code>null</code>)
1278 * @param newValue The new value (may be <code>null</code>)
1279 *
1280 * @exception Exception if an exception is thrown
1281 */
1282 protected void processNamingResourcesPropertyChange
1283 (NamingResources resources, String propertyName,
1284 Object oldValue, Object newValue)
1285 throws Exception {
1286
1287 if (log.isTraceEnabled()) {
1288 log.trace("propertyChange[namingResources=" + resources +
1289 ",propertyName=" + propertyName +
1290 ",oldValue=" + oldValue +
1291 ",newValue=" + newValue + "]");
1292 }
1293
1294 // FIXME - Add other resource types when supported by admin tool
1295 if ("environment".equals(propertyName)) {
1296 if (oldValue != null) {
1297 destroyMBeans((ContextEnvironment) oldValue);
1298 }
1299 if (newValue != null) {
1300 createMBeans((ContextEnvironment) newValue);
1301 }
1302 } else if ("resource".equals(propertyName)) {
1303 if (oldValue != null) {
1304 destroyMBeans((ContextResource) oldValue);
1305 }
1306 if (newValue != null) {
1307 createMBeans((ContextResource) newValue);
1308 }
1309 } else if ("resourceLink".equals(propertyName)) {
1310 if (oldValue != null) {
1311 destroyMBeans((ContextResourceLink) oldValue);
1312 }
1313 if (newValue != null) {
1314 createMBeans((ContextResourceLink) newValue);
1315 }
1316 }
1317
1318 }
1319
1320
1321 /**
1322 * Process a property change event on a Server.
1323 *
1324 * @param server The server on which this event occurred
1325 * @param propertyName The name of the property that changed
1326 * @param oldValue The previous value (may be <code>null</code>)
1327 * @param newValue The new value (may be <code>null</code>)
1328 *
1329 * @exception Exception if an exception is thrown
1330 */
1331 protected void processServerPropertyChange(Server server,
1332 String propertyName,
1333 Object oldValue,
1334 Object newValue)
1335 throws Exception {
1336
1337 if (log.isTraceEnabled()) {
1338 log.trace("propertyChange[server=" + server +
1339 ",propertyName=" + propertyName +
1340 ",oldValue=" + oldValue +
1341 ",newValue=" + newValue + "]");
1342 }
1343 if ("globalNamingResources".equals(propertyName)) {
1344 if (oldValue != null) {
1345 destroyMBeans((NamingResources) oldValue);
1346 }
1347 if (newValue != null) {
1348 createMBeans((NamingResources) newValue);
1349 }
1350 } else if ("service".equals(propertyName)) {
1351 if (oldValue != null) {
1352 destroyMBeans((Service) oldValue);
1353 }
1354 if (newValue != null) {
1355 createMBeans((Service) newValue);
1356 }
1357 }
1358
1359 }
1360
1361
1362 /**
1363 * Process a property change event on a Service.
1364 *
1365 * @param service The service on which this event occurred
1366 * @param propertyName The name of the property that changed
1367 * @param oldValue The previous value (may be <code>null</code>)
1368 * @param newValue The new value (may be <code>null</code>)
1369 *
1370 * @exception Exception if an exception is thrown
1371 */
1372 protected void processServicePropertyChange(Service service,
1373 String propertyName,
1374 Object oldValue,
1375 Object newValue)
1376 throws Exception {
1377
1378 if (log.isTraceEnabled()) {
1379 log.trace("propertyChange[service=" + service +
1380 ",propertyName=" + propertyName +
1381 ",oldValue=" + oldValue +
1382 ",newValue=" + newValue + "]");
1383 }
1384 if ("connector".equals(propertyName)) {
1385 if (oldValue != null) {
1386 destroyMBeans((Connector) oldValue, service);
1387 }
1388 if (newValue != null) {
1389 createMBeans((Connector) newValue);
1390 }
1391 } else if ("container".equals(propertyName)) {
1392 if (oldValue != null) {
1393 destroyMBeans((Engine) oldValue);
1394 }
1395 if (newValue != null) {
1396 createMBeans((Engine) newValue);
1397 }
1398 }
1399
1400 }
1401
1402
1403 }