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  package org.apache.geronimo.system.jmx;
18  
19  import java.io.ObjectInputStream;
20  import java.util.HashSet;
21  import java.util.Iterator;
22  import java.util.Set;
23  import java.util.HashMap;
24  import java.util.Collections;
25  import java.util.LinkedHashSet;
26  import javax.management.Attribute;
27  import javax.management.AttributeList;
28  import javax.management.AttributeNotFoundException;
29  import javax.management.InstanceAlreadyExistsException;
30  import javax.management.InstanceNotFoundException;
31  import javax.management.ListenerNotFoundException;
32  import javax.management.MBeanException;
33  import javax.management.MBeanInfo;
34  import javax.management.MBeanRegistrationException;
35  import javax.management.MBeanServer;
36  import javax.management.NotCompliantMBeanException;
37  import javax.management.NotificationFilter;
38  import javax.management.NotificationListener;
39  import javax.management.ObjectInstance;
40  import javax.management.ObjectName;
41  import javax.management.OperationsException;
42  import javax.management.QueryExp;
43  import javax.management.ReflectionException;
44  import javax.management.MalformedObjectNameException;
45  import javax.management.loading.ClassLoaderRepository;
46  
47  import org.apache.geronimo.gbean.GBeanInfo;
48  import org.apache.geronimo.gbean.AbstractNameQuery;
49  import org.apache.geronimo.gbean.AbstractName;
50  import org.apache.geronimo.kernel.GBeanNotFoundException;
51  import org.apache.geronimo.kernel.InternalKernelException;
52  import org.apache.geronimo.kernel.NoSuchAttributeException;
53  import org.apache.geronimo.kernel.NoSuchOperationException;
54  import org.apache.geronimo.kernel.Kernel;
55  import org.apache.geronimo.kernel.lifecycle.LifecycleAdapter;
56  
57  /**
58   * A fake MBeanServer that delegates to a Kernel.
59   * @version $Rev: 396619 $ $Date: 2006-04-24 10:44:00 -0700 (Mon, 24 Apr 2006) $
60   */
61  public class KernelMBeanServer implements MBeanServer {
62      private static final AbstractNameQuery ALL = new AbstractNameQuery(null, Collections.EMPTY_MAP, Collections.EMPTY_SET);
63  
64      private final HashMap objetNameToAbstractName = new HashMap();
65      private final Kernel kernel;
66  
67      public KernelMBeanServer(Kernel kernel) {
68          this.kernel = kernel;
69      }
70  
71      public void doStart() {
72          kernel.getLifecycleMonitor().addLifecycleListener(new GBeanRegistrationListener(), ALL);
73  
74          Set allNames = kernel.listGBeans(ALL);
75          for (Iterator iterator = allNames.iterator(); iterator.hasNext();) {
76              AbstractName abstractName = (AbstractName) iterator.next();
77              register(abstractName);
78          }
79      }
80  
81      public synchronized AbstractName getAbstractNameFor(ObjectName objectName) {
82          return (AbstractName) objetNameToAbstractName.get(objectName);
83      }
84  
85      private synchronized void register(AbstractName abstractName) {
86          objetNameToAbstractName.put(abstractName.getObjectName(), abstractName);
87      }
88  
89      private synchronized void unregister(AbstractName abstractName) {
90          objetNameToAbstractName.remove(abstractName.getObjectName());
91      }
92  
93      public void doFail() {
94          doStop();
95      }
96  
97      public synchronized void doStop() {
98          objetNameToAbstractName.clear();
99      }
100 
101     private class GBeanRegistrationListener extends LifecycleAdapter {
102         public void loaded(AbstractName abstractName) {
103             register(abstractName);
104         }
105 
106         public void unloaded(AbstractName abstractName) {
107             unregister(abstractName);
108         }
109     }
110 
111     public AbstractName toAbstractName(ObjectName objectName) throws InstanceNotFoundException{
112         AbstractName abstractName = getAbstractNameFor(objectName);
113         if (abstractName == null) {
114             throw new InstanceNotFoundException(objectName.getCanonicalName());
115         }
116         return abstractName;
117     }
118 
119     public Object getAttribute(ObjectName name, String attribute) throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException {
120         AbstractName abstractName = toAbstractName(name);
121         try {
122             return kernel.getAttribute(abstractName, attribute);
123         } catch (NoSuchAttributeException e) {
124             throw new AttributeNotFoundException(attribute);
125         } catch (GBeanNotFoundException e) {
126             throw new InstanceNotFoundException(name.getCanonicalName());
127         } catch (InternalKernelException e) {
128             throw new MBeanException(unwrapInternalKernelException(e));
129         } catch (Exception e) {
130             throw new MBeanException(e);
131         }
132     }
133 
134     public AttributeList getAttributes(ObjectName name, String[] attributes) throws InstanceNotFoundException, ReflectionException {
135         AbstractName abstractName = toAbstractName(name);
136         AttributeList attributeList = new AttributeList(attributes.length);
137         for (int i = 0; i < attributes.length; i++) {
138             String attribute = attributes[i];
139             try {
140                 Object value = kernel.getAttribute(abstractName, attribute);
141                 attributeList.add(i, new Attribute(attribute, value));
142             } catch (NoSuchAttributeException e) {
143                 // ignored - caller will simply find no value
144             } catch (GBeanNotFoundException e) {
145                 throw new InstanceNotFoundException(name.getCanonicalName());
146             } catch (InternalKernelException e) {
147                 throw new ReflectionException(unwrapInternalKernelException(e));
148             } catch (Exception e) {
149                 // ignored - caller will simply find no value
150             }
151         }
152         return attributeList;
153     }
154 
155     public String getDefaultDomain() {
156         return kernel.getKernelName();
157     }
158 
159     public Integer getMBeanCount() {
160         return new Integer(kernel.listGBeans((AbstractNameQuery)null).size());
161     }
162 
163     public MBeanInfo getMBeanInfo(ObjectName name) throws InstanceNotFoundException, ReflectionException {
164         AbstractName abstractName = toAbstractName(name);
165         GBeanInfo gbeanInfo;
166         try {
167             gbeanInfo = kernel.getGBeanInfo(abstractName);
168         } catch (GBeanNotFoundException e) {
169             throw new InstanceNotFoundException(name.getCanonicalName());
170         } catch (InternalKernelException e) {
171             throw new ReflectionException(unwrapInternalKernelException(e));
172         }
173         return JMXUtil.toMBeanInfo(gbeanInfo);
174     }
175 
176     public Object invoke(ObjectName name, String operationName, Object[] params, String[] signature) throws InstanceNotFoundException, MBeanException, ReflectionException {
177         AbstractName abstractName = toAbstractName(name);
178         try {
179             return kernel.invoke(abstractName, operationName, params, signature);
180         } catch (NoSuchOperationException e) {
181             throw new ReflectionException(new NoSuchMethodException(e.getMessage()));
182         } catch (GBeanNotFoundException e) {
183             if(name.equals(e.getGBeanName())) {
184                 throw new InstanceNotFoundException(name.getCanonicalName());
185             }
186             throw new MBeanException(e);
187         } catch (InternalKernelException e) {
188             throw new MBeanException(unwrapInternalKernelException(e));
189         } catch (Exception e) {
190             throw new MBeanException(e);
191         }
192     }
193 
194     public boolean isRegistered(ObjectName name) {
195         AbstractName abstractName = getAbstractNameFor(name);
196         if (abstractName == null) {
197             return false;
198         }
199         return kernel.isLoaded(abstractName);
200     }
201 
202     public Set queryNames(ObjectName pattern, QueryExp query) {
203         // normalize the name
204         if (pattern != null && pattern.getDomain().length() == 0) {
205             try {
206                 pattern = new ObjectName(kernel.getKernelName(), pattern.getKeyPropertyList());
207             } catch (MalformedObjectNameException e) {
208                 throw new AssertionError(e);
209             }
210         }
211 
212         Set names;
213         synchronized (this) {
214             names = new LinkedHashSet(objetNameToAbstractName.keySet());
215         }
216 
217         // fairly dumb implementation that iterates the list of all registered GBeans
218         Set result = new HashSet(names.size());
219         for (Iterator iterator = names.iterator(); iterator.hasNext();) {
220             ObjectName name = (ObjectName) iterator.next();
221             if (pattern == null || pattern.apply(name)) {
222                 if (query != null) {
223                     query.setMBeanServer(this);
224 
225                     try {
226                         if (query.apply(name)) {
227                             result.add(name);
228                         }
229                     } catch (Exception e) {
230                         // reject any name that threw an exception
231                     }
232                 } else {
233                     result.add(name);
234                 }
235             }
236         }
237 
238         return result;
239     }
240 
241     public Set queryMBeans(ObjectName pattern, QueryExp query) {
242         Set names = queryNames(pattern, query);
243         Set objectInstances = new HashSet(names.size());
244         for (Iterator iterator = names.iterator(); iterator.hasNext();) {
245             ObjectName name = (ObjectName) iterator.next();
246             try {
247                 objectInstances.add(getObjectInstance(name));
248             } catch (InstanceNotFoundException e) {
249                 // ignore
250             }
251         }
252         return objectInstances;
253     }
254 
255     public void setAttribute(ObjectName name, Attribute attribute) throws InstanceNotFoundException, AttributeNotFoundException, MBeanException {
256         AbstractName abstractName = toAbstractName(name);
257         String attributeName = attribute.getName();
258         Object attributeValue = attribute.getValue();
259         try {
260             kernel.setAttribute(abstractName, attributeName, attributeValue);
261         } catch (NoSuchAttributeException e) {
262             throw new AttributeNotFoundException(attributeName);
263         } catch (GBeanNotFoundException e) {
264             throw new InstanceNotFoundException(name.getCanonicalName());
265         } catch (InternalKernelException e) {
266             throw new MBeanException(unwrapInternalKernelException(e));
267         } catch (Exception e) {
268             throw new MBeanException(e);
269         }
270     }
271 
272     public AttributeList setAttributes(ObjectName name, AttributeList attributes) throws InstanceNotFoundException, ReflectionException {
273         AbstractName abstractName = toAbstractName(name);
274         AttributeList set = new AttributeList(attributes.size());
275         for (Iterator iterator = attributes.iterator(); iterator.hasNext();) {
276             Attribute attribute = (Attribute) iterator.next();
277             String attributeName = attribute.getName();
278             Object attributeValue = attribute.getValue();
279             try {
280                 kernel.setAttribute(abstractName, attributeName, attributeValue);
281                 set.add(attribute);
282             } catch (NoSuchAttributeException e) {
283                 // ignored - caller will see value was not set because this attribute will not be in the attribute list
284             } catch (GBeanNotFoundException e) {
285                 throw new InstanceNotFoundException(name.getCanonicalName());
286             } catch (InternalKernelException e) {
287                 throw new ReflectionException(unwrapInternalKernelException(e));
288             } catch (Exception e) {
289                 // ignored - caller will see value was not set because this attribute will not be in the attribute list
290             }
291         }
292         return set;
293     }
294 
295     public String[] getDomains() {
296         Set domains = new HashSet();
297         Set names = kernel.listGBeans((AbstractNameQuery)null);
298         for (Iterator iterator = names.iterator(); iterator.hasNext();) {
299             ObjectName objectName = (ObjectName) iterator.next();
300             domains.add(objectName.getDomain());
301         }
302         return (String[]) domains.toArray(new String[domains.size()]);
303     }
304 
305     public ObjectInstance getObjectInstance(ObjectName objectName) throws InstanceNotFoundException {
306         AbstractName abstractName = toAbstractName(objectName);
307         try {
308             GBeanInfo gbeanInfo = kernel.getGBeanInfo(abstractName);
309             return new ObjectInstance(objectName, gbeanInfo.getClassName());
310         } catch (GBeanNotFoundException e) {
311             throw new InstanceNotFoundException(objectName.getCanonicalName());
312         }
313     }
314 
315     public ClassLoader getClassLoaderFor(ObjectName objectName) throws InstanceNotFoundException {
316         AbstractName abstractName = toAbstractName(objectName);
317         try {
318             return kernel.getClassLoaderFor(abstractName);
319         } catch (GBeanNotFoundException e) {
320             throw new InstanceNotFoundException(objectName.getCanonicalName());
321         }
322     }
323 
324     private static Exception unwrapInternalKernelException(InternalKernelException e) {
325         if (e.getCause() instanceof Exception) {
326             return (Exception) e.getCause();
327         }
328         return e;
329     }
330 
331     //////////////////////////////////////////////
332     //
333     // NOT ALLOWED
334     //
335     //////////////////////////////////////////////
336 
337     public void addNotificationListener(ObjectName objectName, NotificationListener notificationListener, NotificationFilter notificationFilter, Object o) throws InstanceNotFoundException {
338         throw new SecurityException("Operation not allowed");
339     }
340 
341     public void addNotificationListener(ObjectName objectName, ObjectName objectName1, NotificationFilter notificationFilter, Object o) throws InstanceNotFoundException {
342         throw new SecurityException("Operation not allowed");
343     }
344 
345     public void removeNotificationListener(ObjectName objectName, ObjectName objectName1) throws InstanceNotFoundException, ListenerNotFoundException {
346         throw new SecurityException("Operation not allowed");
347     }
348 
349     public void removeNotificationListener(ObjectName objectName, NotificationListener notificationListener) throws InstanceNotFoundException, ListenerNotFoundException {
350         throw new SecurityException("Operation not allowed");
351     }
352 
353     public void removeNotificationListener(ObjectName objectName, ObjectName objectName1, NotificationFilter notificationFilter, Object o) throws InstanceNotFoundException, ListenerNotFoundException {
354         throw new SecurityException("Operation not allowed");
355     }
356 
357     public void removeNotificationListener(ObjectName objectName, NotificationListener notificationListener, NotificationFilter notificationFilter, Object o) throws InstanceNotFoundException, ListenerNotFoundException {
358         throw new SecurityException("Operation not allowed");
359     }
360 
361     public boolean isInstanceOf(ObjectName objectName, String s) throws InstanceNotFoundException {
362         throw new SecurityException("Operation not allowed");
363     }
364 
365     public ObjectInstance createMBean(String s, ObjectName objectName) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException {
366         throw new SecurityException("Operation not allowed");
367     }
368 
369     public ObjectInstance createMBean(String s, ObjectName objectName, ObjectName objectName1) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException {
370         throw new SecurityException("Operation not allowed");
371     }
372 
373     public ObjectInstance createMBean(String s, ObjectName objectName, Object[] objects, String[] strings) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException {
374         throw new SecurityException("Operation not allowed");
375     }
376 
377     public ObjectInstance createMBean(String s, ObjectName objectName, ObjectName objectName1, Object[] objects, String[] strings) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException {
378         throw new SecurityException("Operation not allowed");
379     }
380 
381     public Object instantiate(String s) throws ReflectionException, MBeanException {
382         throw new SecurityException("Operation not allowed");
383     }
384 
385     public Object instantiate(String s, ObjectName objectName) throws ReflectionException, MBeanException, InstanceNotFoundException {
386         throw new SecurityException("Operation not allowed");
387     }
388 
389     public Object instantiate(String s, Object[] objects, String[] strings) throws ReflectionException, MBeanException {
390         throw new SecurityException("Operation not allowed");
391     }
392 
393     public Object instantiate(String s, ObjectName objectName, Object[] objects, String[] strings) throws ReflectionException, MBeanException, InstanceNotFoundException {
394         throw new SecurityException("Operation not allowed");
395     }
396 
397     public ObjectInstance registerMBean(Object o, ObjectName objectName) throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
398         throw new SecurityException("Operation not allowed");
399     }
400 
401     public ObjectInputStream deserialize(String s, ObjectName objectName, byte[] bytes) throws InstanceNotFoundException, OperationsException, ReflectionException {
402         throw new SecurityException("Operation not allowed");
403     }
404 
405     public ObjectInputStream deserialize(String s, byte[] bytes) throws OperationsException, ReflectionException {
406         throw new SecurityException("Operation not allowed");
407     }
408 
409     public ObjectInputStream deserialize(ObjectName objectName, byte[] bytes) throws InstanceNotFoundException, OperationsException {
410         throw new SecurityException("Operation not allowed");
411     }
412 
413     public ClassLoader getClassLoader(ObjectName objectName) throws InstanceNotFoundException {
414         throw new SecurityException("Operation not allowed");
415     }
416 
417     public ClassLoaderRepository getClassLoaderRepository() {
418         return new ClassLoaderRepository() {
419             public Class loadClass(String className) throws ClassNotFoundException {
420                 throw new ClassNotFoundException(className);
421             }
422 
423             public Class loadClassWithout(ClassLoader loader, String className) throws ClassNotFoundException {
424                 throw new ClassNotFoundException(className);
425             }
426 
427             public Class loadClassBefore(ClassLoader loader, String className) throws ClassNotFoundException {
428                 throw new ClassNotFoundException(className);
429             }
430         };
431     }
432 
433     public void unregisterMBean(ObjectName objectName) throws InstanceNotFoundException, MBeanRegistrationException {
434         throw new SecurityException("Operation not allowed");
435     }
436 }