1 package org.oddjob.jmx.server; 2 3 import java.rmi.RemoteException ; 4 import java.util.Iterator ; 5 6 import javax.management.Attribute ; 7 import javax.management.AttributeList ; 8 import javax.management.DynamicMBean ; 9 import javax.management.JMException ; 10 import javax.management.MBeanException ; 11 import javax.management.MBeanInfo ; 12 import javax.management.MBeanNotificationInfo ; 13 import javax.management.Notification ; 14 import javax.management.NotificationBroadcasterSupport ; 15 import javax.management.ObjectName ; 16 import javax.management.ReflectionException ; 17 18 import org.apache.log4j.Logger; 19 import org.oddjob.jmx.SharedConstants; 20 import org.oddjob.jmx.Utils; 21 22 35 36 public class OddjobMBean extends NotificationBroadcasterSupport implements 37 DynamicMBean { 38 private static final Logger logger = Logger.getLogger(OddjobMBean.class); 39 40 public static final String RESYNC_PREFIX = "resync."; 41 42 43 public static final String RESYNC_STARTED_NOTIF_TYPE 44 = RESYNC_PREFIX + "org.oddjob.resyncstarted"; 45 46 47 public static final String RESYNC_FINISHED_NOTIF_TYPE 48 = RESYNC_PREFIX + "org.oddjob.resyncfinished"; 49 50 51 private final Object node; 52 53 54 private final ServerContext srvcon; 55 56 57 private int sequenceNumber = 0; 58 59 60 private final OddjobMBeanFactory factory; 61 62 63 private final InterfaceManager iManager; 64 65 66 private final Object resyncLock = new Object (); 67 68 78 public OddjobMBean(Object node, OddjobMBeanFactory factory, 79 ServerContext srvcon) { 80 if (node == null) { 81 throw new NullPointerException ("Component must not be null"); 82 } 83 if (srvcon == null) { 84 throw new NullPointerException ("Server Context must not be null"); 85 } 86 this.node = node; 87 this.factory = factory; 88 this.srvcon = srvcon; 89 90 InterfaceManagerFactory imf = srvcon.getInterfaceManagerFactory(); 91 iManager = imf.create(node, this); 92 } 93 94 98 public Object getAttribute(String attribute) 99 throws ReflectionException , MBeanException { 100 logger.debug("getAttribute(" + attribute + ")"); 101 return invoke("get", new Object [] { attribute }, 102 new String [] { String .class.getName() }); 103 } 104 105 109 public void setAttribute(Attribute attribute) 110 throws ReflectionException , MBeanException { 111 logger.debug("setAttribute(" + attribute.getName() + ")"); 112 invoke("set", new Object [] { attribute.getClass(), attribute.getValue() }, 113 new String [] { String .class.getName(), Object .class.getName() }); 114 } 115 116 120 public AttributeList getAttributes(String [] attributes) { 121 AttributeList al = new AttributeList (); 122 for (int i = 0; i < attributes.length; ++i) { 123 String attribute = attributes[i]; 124 Attribute attr; 125 try { 126 attr = new Attribute (attribute, getAttribute(attribute)); 127 al.add(attr); 128 } catch (ReflectionException e) { 129 logger.debug(e); 130 } catch (MBeanException e) { 131 logger.debug(e); 132 } 133 } 134 return al; 135 } 136 137 141 public AttributeList setAttributes(AttributeList attributes) { 142 AttributeList al = new AttributeList (); 143 for (Iterator it = attributes.iterator(); it.hasNext();) { 144 Attribute attribute = (Attribute ) it.next(); 145 try { 146 setAttribute(attribute); 147 al.add(attribute); 148 } catch (ReflectionException e) { 149 logger.debug(e); 150 } catch (MBeanException e) { 151 logger.debug(e); 152 } 153 } 154 return al; 155 } 156 157 162 static String methodDescription(final String actionName, String [] signature) { 163 StringBuffer buf = new StringBuffer (); 165 buf.append(actionName); 166 buf.append('('); 167 for (int j = 0; j < signature.length; ++j) { 168 buf.append(j== 0 ? "" : ", "); 169 buf.append(signature[j]); 170 } 171 buf.append(")"); 172 return buf.toString(); 173 } 174 175 179 public Object invoke(final String actionName, final Object [] params, String [] signature) 180 throws MBeanException , ReflectionException { 181 String methodDescription = methodDescription(actionName, signature); 182 if (logger.isDebugEnabled()) { 183 logger.debug("Invoking [" + 184 methodDescription + "] on [" + node + "]"); 185 } 186 187 189 if (SharedConstants.RETRIEVE_LOG_EVENTS_METHOD.equals(actionName) 190 && signature.length == 2 191 && Long .class.getName().equals(signature[0]) 192 && Integer .class.getName().equals(signature[1])) { 193 return LogArchiverHelper.retrieveLogEvents(node, srvcon, 194 (Long )params[0], (Integer )params[1]); 195 } 196 else if (SharedConstants.RETRIEVE_CONSOLE_EVENTS_METHOD.equals(actionName) && signature.length == 2 197 && Long .class.getName().equals(signature[0]) 198 && Integer .class.getName().equals(signature[1])) { 199 return LogArchiverHelper.retrieveConsoleEvents(node, srvcon, 200 (Long )params[0], (Integer )params[1]); 201 } 202 203 205 Object [] imported = null; 207 imported = Utils.importResolve(params, srvcon.getComponentRegistry()); 208 Object result = iManager.invoke(actionName, imported, signature); 209 return Utils.export(result); 210 } 211 212 216 public MBeanInfo getMBeanInfo() { 217 return iManager.getMBeanInfo(); 218 } 219 220 226 public int getNextNotificationNumber() { 227 synchronized(resyncLock) { 228 return sequenceNumber++; 229 } 230 } 231 232 239 void resync() { 240 synchronized (resyncLock) { 241 logger.debug("resync Started"); 242 Notification notification = new Notification ( 243 RESYNC_STARTED_NOTIF_TYPE, OddjobMBean.this, 244 sequenceNumber++); 245 sendNotification(notification); 246 debugSentNotification(notification); 247 Notification [] notifications = iManager.getLastNotifications(); 248 for (int i = 0; i < notifications.length; ++i) { 249 Notification oldNot = notifications[i]; 250 Notification newNot = new Notification ( 251 RESYNC_PREFIX + oldNot.getType(), 252 oldNot.getSource(), 253 sequenceNumber++, 254 oldNot.getTimeStamp(), 255 oldNot.getMessage()); 256 newNot.setUserData(oldNot.getUserData()); 257 sendNotification(newNot); 258 debugSentNotification(newNot); 259 } 260 notification = new Notification (RESYNC_FINISHED_NOTIF_TYPE, 261 OddjobMBean.this, sequenceNumber++); 262 sendNotification(notification); 263 debugSentNotification(notification); 264 logger.debug("resync Finished"); 265 } 266 } 267 268 private static void debugSentNotification(Notification notification) { 269 if (!logger.isDebugEnabled()) { 270 return; 271 } 272 logger.debug("Sent notification [" + notification.getType() 273 + "] sequence [" + notification.getSequenceNumber() + "]"); 274 } 275 276 279 ServerInfo serverSideInfo() { 280 return new ServerInfo( 281 srvcon.getId(), 282 srvcon.getUrl(), 283 LogArchiverHelper.consoleId(node, srvcon), 284 iManager.interfaces(), 285 srvcon.isRegistryOwner(), 286 srvcon.getChildId()); 287 } 288 289 292 void destroy() { 293 logger.debug("Destroying OddjobMBean for [" + node + "]"); 294 iManager.destroy(); 295 } 296 297 301 public MBeanNotificationInfo [] getNotificationInfo() { 302 return iManager.getMBeanInfo().getNotifications(); 303 } 304 305 311 public void runSynchronized(Runnable runnable) { 312 synchronized (resyncLock) { 313 runnable.run(); 314 } 315 } 316 317 323 public ObjectName addChild(Object child, ServerContext childContext) { 324 ObjectName childName = null; 325 try { 326 childName = factory.createMBeanFor(child, childContext); 327 } catch (JMException ex) { 328 logger.error("Failed to add child MBean", ex); 329 } 330 return childName; 331 } 332 333 338 public void removeChild(ObjectName childName) { 339 try { 340 factory.destroy(childName); 341 } catch (JMException ex) { 342 logger.error("Failed to remove child MBean", ex); 343 } 344 } 345 346 351 public ServerContext getContext() { 352 return srvcon; 353 } 354 355 } | Popular Tags |