View Javadoc

1   /**
2    *
3    * Copyright 2004 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  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  package org.apache.geronimo.system.jmx;
18  
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.Map;
22  import java.util.Set;
23  import java.util.Collections;
24  import javax.management.InstanceAlreadyExistsException;
25  import javax.management.InstanceNotFoundException;
26  import javax.management.JMException;
27  import javax.management.JMRuntimeException;
28  import javax.management.MBeanInfo;
29  import javax.management.MBeanServer;
30  import javax.management.ObjectName;
31  
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  import org.apache.geronimo.gbean.GBeanLifecycle;
35  import org.apache.geronimo.gbean.GBeanInfo;
36  import org.apache.geronimo.gbean.GBeanInfoBuilder;
37  import org.apache.geronimo.gbean.AbstractName;
38  import org.apache.geronimo.gbean.AbstractNameQuery;
39  import org.apache.geronimo.kernel.GBeanNotFoundException;
40  import org.apache.geronimo.kernel.Kernel;
41  import org.apache.geronimo.kernel.lifecycle.LifecycleAdapter;
42  
43  /**
44   * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $
45   */
46  public class MBeanServerKernelBridge implements GBeanLifecycle {
47      private static final Log log = LogFactory.getLog(MBeanServerKernelBridge.class);
48      private static final AbstractNameQuery ALL = new AbstractNameQuery(null, Collections.EMPTY_MAP, Collections.EMPTY_SET);
49  
50      private final HashMap registry = new HashMap();
51      private final Kernel kernel;
52      private final MBeanServer mbeanServer;
53  
54      // todo remove this as soon as Geronimo supports factory beans    
55      public MBeanServerKernelBridge(Kernel kernel, MBeanServerReference mbeanServerReference) {
56          this(kernel, mbeanServerReference.getMBeanServer());
57      }
58  
59      public MBeanServerKernelBridge(Kernel kernel, MBeanServer mbeanServer) {
60          this.kernel = kernel;
61          this.mbeanServer = mbeanServer;
62      }
63  
64      public void doStart() {
65          kernel.getLifecycleMonitor().addLifecycleListener(new GBeanRegistrationListener(), ALL);
66  
67          Set allNames = kernel.listGBeans(ALL);
68          for (Iterator iterator = allNames.iterator(); iterator.hasNext();) {
69              AbstractName abstractName = (AbstractName) iterator.next();
70              register(abstractName);
71          }
72      }
73  
74      public void doFail() {
75          doStop();
76      }
77  
78      public void doStop() {
79          // unregister all of our GBeans from the MBeanServer
80          Map beans;
81          synchronized (this) {
82              beans = new HashMap(registry);
83              registry.clear();
84          }
85          for (Iterator i = beans.values().iterator(); i.hasNext();) {
86              MBeanGBeanBridge mbeanGBeanBridge = (MBeanGBeanBridge) i.next();
87              ObjectName objectName = mbeanGBeanBridge.getObjectName();
88              try {
89                  mbeanServer.unregisterMBean(objectName);
90              } catch (Exception e) {
91                  // ignore
92              }
93          }
94      }
95  
96      private void register(AbstractName abstractName) {
97          try {
98              MBeanGBeanBridge mbeanGBeanBridge;
99              synchronized (this) {
100                 if (registry.containsKey(abstractName)) {
101                     return;
102                 }
103                 MBeanInfo mbeanInfo = JMXUtil.toMBeanInfo(kernel.getGBeanInfo(abstractName));
104                 mbeanGBeanBridge = new MBeanGBeanBridge(kernel, abstractName, abstractName.getObjectName(), mbeanInfo);
105                 registry.put(abstractName, mbeanGBeanBridge);
106             }
107             mbeanServer.registerMBean(mbeanGBeanBridge, mbeanGBeanBridge.getObjectName());
108         } catch (GBeanNotFoundException e) {
109             // ignore - gbean already unregistered
110         } catch (InstanceAlreadyExistsException e) {
111             // ignore - gbean already has an mbean shadow object
112         } catch (Exception e) {
113             log.warn("Unable to register MBean shadow object for GBean", unwrapJMException(e));
114         }
115     }
116 
117     private void unregister(AbstractName abstractName) {
118         MBeanGBeanBridge mbeanGBeanBridge;
119         synchronized (this) {
120             mbeanGBeanBridge = (MBeanGBeanBridge) registry.remove(abstractName);
121         }
122 
123         if (mbeanGBeanBridge != null) {
124             try {
125                 mbeanServer.unregisterMBean(mbeanGBeanBridge.getObjectName());
126             } catch (InstanceNotFoundException e) {
127                 // ignore - something else may have unregistered us
128                 // if there truely is no GBean then we will catch it below whwn we call the superclass
129             } catch (Exception e) {
130                 log.warn("Unable to unregister MBean shadow object for GBean", unwrapJMException(e));
131             }
132         }
133     }
134 
135     private Throwable unwrapJMException(Throwable cause) {
136         while ((cause instanceof JMException || cause instanceof JMRuntimeException) && cause.getCause() != null) {
137             cause = cause.getCause();
138         }
139         return cause;
140     }
141 
142     private class GBeanRegistrationListener extends LifecycleAdapter {
143         public void loaded(AbstractName abstractName) {
144             register(abstractName);
145         }
146 
147         public void unloaded(AbstractName abstractName) {
148             unregister(abstractName);
149         }
150     }
151 
152     public static final GBeanInfo GBEAN_INFO;
153 
154     static {
155         GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(MBeanServerKernelBridge.class);
156         infoFactory.addAttribute("kernel", Kernel.class, false);
157         infoFactory.addReference("MBeanServerReference", MBeanServerReference.class);
158         infoFactory.setConstructor(new String[]{"kernel", "MBeanServerReference"});
159         GBEAN_INFO = infoFactory.getBeanInfo();
160     }
161 
162     public static GBeanInfo getGBeanInfo() {
163         return GBEAN_INFO;
164     }
165 }