View Javadoc

1   /**
2    *
3    * Copyright 2003-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  
18  package org.apache.geronimo.system.jmx;
19  
20  import java.util.Iterator;
21  import javax.management.Attribute;
22  import javax.management.AttributeList;
23  import javax.management.AttributeNotFoundException;
24  import javax.management.DynamicMBean;
25  import javax.management.JMException;
26  import javax.management.ListenerNotFoundException;
27  import javax.management.MBeanInfo;
28  import javax.management.MBeanNotificationInfo;
29  import javax.management.Notification;
30  import javax.management.NotificationBroadcasterSupport;
31  import javax.management.NotificationEmitter;
32  import javax.management.NotificationFilter;
33  import javax.management.NotificationListener;
34  import javax.management.ObjectName;
35  import javax.management.ReflectionException;
36  import javax.management.MBeanRegistration;
37  import javax.management.MBeanServer;
38  
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.apache.geronimo.gbean.GOperationSignature;
42  import org.apache.geronimo.gbean.AbstractName;
43  import org.apache.geronimo.gbean.AbstractNameQuery;
44  import org.apache.geronimo.kernel.NoSuchAttributeException;
45  import org.apache.geronimo.kernel.NoSuchOperationException;
46  import org.apache.geronimo.kernel.Kernel;
47  import org.apache.geronimo.kernel.lifecycle.LifecycleListener;
48  import org.apache.geronimo.kernel.management.NotificationType;
49  
50  /**
51   * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $
52   */
53  public final class MBeanGBeanBridge implements MBeanRegistration, DynamicMBean, NotificationEmitter {
54      private static final Log log = LogFactory.getLog(MBeanGBeanBridge.class);
55  
56      /**
57       * The kernel
58       */
59      private final Kernel kernel;
60  
61      /**
62       * The unique name of this service.
63       */
64      private final AbstractName abstractName;
65      private final ObjectName objectName;
66      private final AbstractNameQuery pattern;
67  
68      /**
69       * The mbean info
70       */
71      private final MBeanInfo mbeanInfo;
72  
73      /**
74       * The broadcaster for notifications
75       */
76      private final NotificationBroadcasterSupport notificationBroadcaster = new NotificationBroadcasterSupport();
77      private final LifecycleBridge lifecycleBridge;
78  
79      public MBeanGBeanBridge(Kernel kernel, AbstractName abstractName, ObjectName objectName, MBeanInfo mbeanInfo) {
80          this.kernel = kernel;
81          this.abstractName = abstractName;
82          this.pattern = new AbstractNameQuery(abstractName);
83          this.mbeanInfo = mbeanInfo;
84          this.objectName = objectName;
85          lifecycleBridge = new LifecycleBridge(abstractName, objectName, notificationBroadcaster);
86      }
87  
88      public ObjectName getObjectName() {
89          return objectName;
90      }
91  
92      public ObjectName preRegister(MBeanServer mBeanServer, ObjectName objectName) throws Exception {
93          return objectName;
94      }
95  
96      public void postRegister(Boolean registrationDone) {
97          if (Boolean.TRUE.equals(registrationDone)) {
98              // fire the loaded event from the gbeanMBean.. it was already fired from the GBeanInstance when it was created
99              kernel.getLifecycleMonitor().addLifecycleListener(lifecycleBridge, pattern);
100             lifecycleBridge.loaded(abstractName);
101         }
102     }
103 
104     public void preDeregister() {
105         kernel.getLifecycleMonitor().removeLifecycleListener(lifecycleBridge);
106         lifecycleBridge.unloaded(abstractName);
107     }
108 
109     public void postDeregister() {
110     }
111 
112     public MBeanInfo getMBeanInfo() {
113         return mbeanInfo;
114     }
115 
116     public Object getAttribute(String attributeName) throws ReflectionException, AttributeNotFoundException {
117         try {
118             return kernel.getAttribute(abstractName, attributeName);
119         } catch (NoSuchAttributeException e) {
120             throw new AttributeNotFoundException(attributeName);
121         } catch (Exception e) {
122             throw new ReflectionException(e);
123         }
124     }
125 
126     public void setAttribute(Attribute attribute) throws ReflectionException, AttributeNotFoundException {
127         String attributeName = attribute.getName();
128         Object attributeValue = attribute.getValue();
129         try {
130             kernel.setAttribute(abstractName, attributeName, attributeValue);
131         } catch (NoSuchAttributeException e) {
132             throw new AttributeNotFoundException(attributeName);
133         } catch (Exception e) {
134             throw new ReflectionException(e);
135         }
136     }
137 
138     public AttributeList getAttributes(String[] attributes) {
139         AttributeList results = new AttributeList(attributes.length);
140         for (int i = 0; i < attributes.length; i++) {
141             String name = attributes[i];
142             try {
143                 Object value = getAttribute(name);
144                 results.add(new Attribute(name, value));
145             } catch (JMException e) {
146                 log.warn("Exception while getting attribute " + name, e);
147             }
148         }
149         return results;
150     }
151 
152     public AttributeList setAttributes(AttributeList attributes) {
153         AttributeList results = new AttributeList(attributes.size());
154         for (Iterator iterator = attributes.iterator(); iterator.hasNext();) {
155             Attribute attribute = (Attribute) iterator.next();
156             try {
157                 setAttribute(attribute);
158                 results.add(attribute);
159             } catch (JMException e) {
160                 log.warn("Exception while setting attribute " + attribute.getName(), e);
161             }
162         }
163         return results;
164     }
165 
166     public Object invoke(String operationName, Object[] arguments, String[] types) throws ReflectionException {
167         try {
168             return kernel.invoke(abstractName, operationName, arguments, types);
169         } catch (NoSuchOperationException e) {
170             throw new ReflectionException(new NoSuchMethodException(new GOperationSignature(operationName, types).toString()));
171         } catch (Exception e) {
172             throw new ReflectionException(e);
173         }
174     }
175 
176     public MBeanNotificationInfo[] getNotificationInfo() {
177         return new MBeanNotificationInfo[]{
178             new MBeanNotificationInfo(NotificationType.TYPES, "javax.management.Notification", "J2EE Notifications")
179         };
180     }
181 
182     public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) {
183         notificationBroadcaster.addNotificationListener(listener, filter, handback);
184     }
185 
186     public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
187         notificationBroadcaster.removeNotificationListener(listener);
188     }
189 
190     public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException {
191         notificationBroadcaster.removeNotificationListener(listener, filter, handback);
192     }
193 
194     public String toString() {
195         return abstractName.toString();
196     }
197 
198     private static class LifecycleBridge implements LifecycleListener {
199         /**
200          * Sequence number used for notifications
201          */
202         private long sequence;
203 
204         /**
205          * AbstractName of this MBean
206          */
207         private final AbstractName mbeanAbstractName;
208 
209         /**
210          * ObjectName of this MBean
211          */
212         private final ObjectName objectName;
213 
214         /**
215          * The notification broadcaster to use
216          */
217         private final NotificationBroadcasterSupport notificationBroadcaster;
218 
219         public LifecycleBridge(AbstractName mbeanAbstractName, ObjectName objectName, NotificationBroadcasterSupport notificationBroadcaster) {
220             this.mbeanAbstractName = mbeanAbstractName;
221             this.objectName = objectName;
222             this.notificationBroadcaster = notificationBroadcaster;
223         }
224 
225         public void loaded(AbstractName abstractName) {
226             if (mbeanAbstractName.equals(abstractName)) {
227                 notificationBroadcaster.sendNotification(new Notification(NotificationType.OBJECT_CREATED, objectName, nextSequence()));
228             }
229         }
230 
231         public void starting(AbstractName abstractName) {
232             if (mbeanAbstractName.equals(abstractName)) {
233                 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_STARTING, objectName, nextSequence()));
234             }
235         }
236 
237         public void running(AbstractName abstractName) {
238             if (mbeanAbstractName.equals(abstractName)) {
239                 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_RUNNING, objectName, nextSequence()));
240             }
241         }
242 
243         public void stopping(AbstractName abstractName) {
244             if (mbeanAbstractName.equals(abstractName)) {
245                 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_STOPPING, objectName, nextSequence()));
246             }
247         }
248 
249         public void stopped(AbstractName abstractName) {
250             if (mbeanAbstractName.equals(abstractName)) {
251                 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_STOPPED, objectName, nextSequence()));
252             }
253         }
254 
255         public void failed(AbstractName abstractName) {
256             if (mbeanAbstractName.equals(abstractName)) {
257                 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_FAILED, objectName, nextSequence()));
258             }
259         }
260 
261         public void unloaded(AbstractName abstractName) {
262             if (mbeanAbstractName.equals(abstractName)) {
263                 notificationBroadcaster.sendNotification(new Notification(NotificationType.OBJECT_DELETED, objectName, nextSequence()));
264             }
265         }
266 
267         public synchronized long nextSequence() {
268             return sequence++;
269         }
270     }
271 }