1 9 package org.jboss.mx.remoting; 10 11 import java.lang.reflect.InvocationTargetException ; 12 import java.lang.reflect.Method ; 13 import java.lang.reflect.UndeclaredThrowableException ; 14 import java.util.Map ; 15 import javax.management.Attribute ; 16 import javax.management.AttributeList ; 17 import javax.management.MBeanException ; 18 import javax.management.MBeanServer ; 19 import javax.management.NotificationFilter ; 20 import javax.management.ObjectName ; 21 import org.jboss.logging.Logger; 22 import org.jboss.remoting.InvocationRequest; 23 import org.jboss.remoting.callback.InvokerCallbackHandler; 24 import org.jboss.remoting.InvokerLocator; 25 import org.jboss.remoting.ServerInvocationHandler; 26 import org.jboss.remoting.ServerInvoker; 27 import org.jboss.remoting.ident.Identity; 28 import org.jboss.remoting.invocation.NameBasedInvocation; 29 30 37 public class JMXSubsystemInvocationHandler implements ServerInvocationHandler 38 { 39 private static final Logger log = Logger.getLogger(JMXSubsystemInvocationHandler.class); 40 private MBeanServer server; 41 private MBeanNotificationCache notificationCache; 42 private ServerInvoker invoker; 43 private Identity identity; 44 45 private static Method getObjectInstance; 46 private static Method isRegistered; 47 private static Method getAttribute; 48 private static Method getAttributes; 49 private static Method setAttribute; 50 private static Method setAttributes; 51 private static Method invoke; 52 private static Method getMBeanInfo; 53 54 static 55 { 56 try 57 { 58 Class LObject = (new Object [0]).getClass(); 59 Class LString = (new String [0]).getClass(); 60 61 Class [] Sig_ObjectName = 62 new Class []{ObjectName .class}; 63 Class [] Sig_ObjectName_String = 64 new Class []{ObjectName .class, String .class}; 65 Class [] Sig_ObjectName_LString = 66 new Class []{ObjectName .class, LString}; 67 Class [] Sig_ObjectName_Attribute = 68 new Class []{ObjectName .class, Attribute .class}; 69 Class [] Sig_ObjectName_AttributeList = 70 new Class []{ObjectName .class, AttributeList .class}; 71 Class [] Sig_ObjectName_String_LObject_LString = 72 new Class []{ObjectName .class, String .class, LObject, LString}; 73 74 getObjectInstance = MBeanServer .class.getMethod("getObjectInstance", Sig_ObjectName); 75 isRegistered = MBeanServer .class.getMethod("isRegistered", Sig_ObjectName); 76 getAttribute = MBeanServer .class.getMethod("getAttribute", Sig_ObjectName_String); 77 getAttributes = MBeanServer .class.getMethod("getAttributes", Sig_ObjectName_LString); 78 setAttribute = MBeanServer .class.getMethod("setAttribute", Sig_ObjectName_Attribute); 79 setAttributes = MBeanServer .class.getMethod("setAttributes", Sig_ObjectName_AttributeList); 80 invoke = MBeanServer .class.getMethod("invoke", Sig_ObjectName_String_LObject_LString); 81 getMBeanInfo = MBeanServer .class.getMethod("getMBeanInfo", Sig_ObjectName); 82 } 83 catch(Exception e) 84 { 85 throw new RuntimeException ("Error resolving methods", e); 86 } 87 } 88 89 public JMXSubsystemInvocationHandler() 90 { 91 super(); 92 } 93 94 99 public void setInvoker(ServerInvoker invoker) 100 { 101 this.invoker = invoker; 102 } 103 104 109 public void setMBeanServer(MBeanServer server) 110 { 111 this.server = server; 112 identity = Identity.get(server); 113 MBeanTransportPreference.setLocalServer(server, identity); 115 if(log.isTraceEnabled()) 116 { 117 log.trace("setMBeanServer called with: " + server + " with identity: " + identity); 118 } 119 } 120 121 125 public synchronized void destroy() 126 { 127 if(notificationCache != null) 128 { 129 notificationCache.destroy(); 130 notificationCache = null; 131 } 132 } 133 134 protected void finalize() throws Throwable 135 { 136 destroy(); 137 super.finalize(); 138 } 139 140 146 private void storeNotifications(String sessionId, Map payload) 147 { 148 NotificationQueue q = (notificationCache == null) ? null : notificationCache.getNotifications(sessionId); 149 if(q != null) 150 { 151 payload.put("notifications", q); 152 } 153 } 154 155 public Object invoke(InvocationRequest invocation) 156 throws Throwable 157 { 158 if(this.server == null) 159 { 160 throw new IllegalStateException ("invoke called prior to mbean server being set"); 161 } 162 try 163 { 164 NameBasedInvocation nbi = (NameBasedInvocation) invocation.getParameter(); 165 String methodName = nbi.getMethodName(); 166 Object args [] = nbi.getParameters(); 167 String signature [] = nbi.getSignature(); 168 String sessionId = invocation.getSessionId(); 169 170 if(methodName.equals("$GetNotifications$")) { 173 return new Boolean (true); 180 } 181 if(methodName.equals("$NOTIFICATIONS$")) { 183 NotificationQueue queue = (NotificationQueue) args[0]; 185 MBeanServerClientInvokerProxy p = MBeanServerClientInvokerProxy.get(queue.getSessionID()); 186 if(p != null) 187 { 188 if(log.isTraceEnabled()) 189 { 190 log.trace("received remote notifications for JMX id: " + queue.getSessionID() + ", queue: " + queue); 191 } 192 p.deliverNotifications(queue, true); 193 } 194 else 195 { 196 log.warn("couldn't find a client invoker proxy for mbean serverid: " + queue.getSessionID() + ", dropping notifications [" + queue + "]"); 197 } 198 return null; 199 } 200 if(methodName.equals("addNotificationListener") && signature.length == 4) 202 { 203 handleAddNotificationListener(invocation.getLocator(), sessionId, (ObjectName ) args[0], (NotificationFilter ) args[2], args[3]); 205 return null; 206 } 207 else if(methodName.equals("removeNotificationListener") && signature.length == 3) 208 { 209 handleRemoveNotificationListener(invocation.getLocator(), sessionId, (ObjectName ) args[0], args[2]); 211 return null; 212 } 213 Object _args[] = (args == null && signature != null) ? new Object [signature.length] : args; 214 Method method = getMethod(methodName, signature); 216 return method.invoke(server, _args); 218 } 219 catch(Throwable ex) 220 { 221 if(ex instanceof UndeclaredThrowableException ) 222 { 223 UndeclaredThrowableException ut = (UndeclaredThrowableException ) ex; 224 Throwable ute = ut.getUndeclaredThrowable(); 225 if(ute instanceof Exception ) 226 { 227 throw new MBeanException ((Exception ) ute, ut.getUndeclaredThrowable().getMessage()); 228 } 229 else 230 { 231 throw new MBeanException (new Exception (ute.getMessage()), ute.getMessage()); 232 } 233 } 234 if(ex instanceof InvocationTargetException ) 235 { 236 throw ((InvocationTargetException ) ex).getTargetException(); 237 } 238 throw ex; 239 } 240 finally 241 { 242 if(notificationCache != null) 246 { 247 storeNotifications(invocation.getSessionId(), invocation.getReturnPayload()); 248 } 249 } 250 } 251 252 private synchronized void handleAddNotificationListener(InvokerLocator locator, String sessionId, ObjectName objName, NotificationFilter filter, Object handback) 253 throws Throwable 254 { 255 if(notificationCache == null) 256 { 257 notificationCache = new MBeanNotificationCache(invoker, server); 258 } 259 notificationCache.addNotificationListener(locator, sessionId, objName, filter, handback); 260 } 261 262 private synchronized void handleRemoveNotificationListener(InvokerLocator locator, String sessionId, ObjectName objName, Object key) 263 throws Throwable 264 { 265 if(notificationCache == null) 266 { 267 return; 268 } 269 notificationCache.removeNotificationListener(locator, sessionId, objName, key); 270 } 271 272 280 private Method getMethod(String methodName, String sig[]) 281 throws Throwable 282 { 283 if(methodName.equals("invoke")) 284 { 285 return invoke; 286 } 287 else if(methodName.equals("getAttribute")) 288 { 289 return getAttribute; 290 } 291 else if(methodName.equals("setAttribute")) 292 { 293 return setAttribute; 294 } 295 else if(methodName.equals("getAttributes")) 296 { 297 return getAttributes; 298 } 299 else if(methodName.equals("setAttributes")) 300 { 301 return setAttributes; 302 } 303 else if(methodName.equals("setAttributes")) 304 { 305 return setAttributes; 306 } 307 else if(methodName.equals("getMBeanInfo")) 308 { 309 return getMBeanInfo; 310 } 311 else if(methodName.equals("getObjectInstance")) 312 { 313 return getObjectInstance; 314 } 315 else if(methodName.equals("isRegistered")) 316 { 317 return isRegistered; 318 } 319 320 Class [] params = null; 321 if(sig != null) 322 { 323 params = new Class [sig.length]; 324 for(int i = 0; i < sig.length; ++i) 325 { 326 params[i] = Class.forName(sig[i]); 327 } 328 } 329 return MBeanServer .class.getMethod(methodName, params); 330 } 331 332 public void addListener(InvokerCallbackHandler callbackHandler) 336 { 337 } 339 340 public void removeListener(InvokerCallbackHandler callbackHandler) 341 { 342 } 344 } 345 | Popular Tags |