001 /**
002 *
003 * Copyright 2003-2004 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.system.jmx;
018
019 import java.io.ObjectInputStream;
020 import java.util.HashSet;
021 import java.util.Iterator;
022 import java.util.Set;
023 import java.util.HashMap;
024 import java.util.Collections;
025 import java.util.LinkedHashSet;
026 import javax.management.Attribute;
027 import javax.management.AttributeList;
028 import javax.management.AttributeNotFoundException;
029 import javax.management.InstanceAlreadyExistsException;
030 import javax.management.InstanceNotFoundException;
031 import javax.management.ListenerNotFoundException;
032 import javax.management.MBeanException;
033 import javax.management.MBeanInfo;
034 import javax.management.MBeanRegistrationException;
035 import javax.management.MBeanServer;
036 import javax.management.NotCompliantMBeanException;
037 import javax.management.NotificationFilter;
038 import javax.management.NotificationListener;
039 import javax.management.ObjectInstance;
040 import javax.management.ObjectName;
041 import javax.management.OperationsException;
042 import javax.management.QueryExp;
043 import javax.management.ReflectionException;
044 import javax.management.MalformedObjectNameException;
045 import javax.management.loading.ClassLoaderRepository;
046
047 import org.apache.geronimo.gbean.GBeanInfo;
048 import org.apache.geronimo.gbean.AbstractNameQuery;
049 import org.apache.geronimo.gbean.AbstractName;
050 import org.apache.geronimo.kernel.GBeanNotFoundException;
051 import org.apache.geronimo.kernel.InternalKernelException;
052 import org.apache.geronimo.kernel.NoSuchAttributeException;
053 import org.apache.geronimo.kernel.NoSuchOperationException;
054 import org.apache.geronimo.kernel.Kernel;
055 import org.apache.geronimo.kernel.lifecycle.LifecycleAdapter;
056
057 /**
058 * A fake MBeanServer that delegates to a Kernel.
059 * @version $Rev: 396619 $ $Date: 2006-04-24 10:44:00 -0700 (Mon, 24 Apr 2006) $
060 */
061 public class KernelMBeanServer implements MBeanServer {
062 private static final AbstractNameQuery ALL = new AbstractNameQuery(null, Collections.EMPTY_MAP, Collections.EMPTY_SET);
063
064 private final HashMap objetNameToAbstractName = new HashMap();
065 private final Kernel kernel;
066
067 public KernelMBeanServer(Kernel kernel) {
068 this.kernel = kernel;
069 }
070
071 public void doStart() {
072 kernel.getLifecycleMonitor().addLifecycleListener(new GBeanRegistrationListener(), ALL);
073
074 Set allNames = kernel.listGBeans(ALL);
075 for (Iterator iterator = allNames.iterator(); iterator.hasNext();) {
076 AbstractName abstractName = (AbstractName) iterator.next();
077 register(abstractName);
078 }
079 }
080
081 public synchronized AbstractName getAbstractNameFor(ObjectName objectName) {
082 return (AbstractName) objetNameToAbstractName.get(objectName);
083 }
084
085 private synchronized void register(AbstractName abstractName) {
086 objetNameToAbstractName.put(abstractName.getObjectName(), abstractName);
087 }
088
089 private synchronized void unregister(AbstractName abstractName) {
090 objetNameToAbstractName.remove(abstractName.getObjectName());
091 }
092
093 public void doFail() {
094 doStop();
095 }
096
097 public synchronized void doStop() {
098 objetNameToAbstractName.clear();
099 }
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 }