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 }