Coverage Report - net.sf.snmpadaptor4j.core.JmxNotificationManager
 
Classes in this File Line Coverage Branch Coverage Complexity
JmxNotificationManager
100 %
65/65
100 %
36/36
2,909
JmxNotificationManager$Listener
100 %
7/7
N/A
2,909
 
 1  
 package net.sf.snmpadaptor4j.core;
 2  
 
 3  
 import java.util.ArrayList;
 4  
 import java.util.HashMap;
 5  
 import java.util.List;
 6  
 import java.util.Map;
 7  
 import java.util.Map.Entry;
 8  
 import javax.management.MBeanServer;
 9  
 import javax.management.Notification;
 10  
 import javax.management.NotificationListener;
 11  
 import javax.management.ObjectName;
 12  
 import org.apache.log4j.Logger;
 13  
 import net.sf.snmpadaptor4j.core.mapping.SnmpTrapMapping;
 14  
 import net.sf.snmpadaptor4j.core.trap.SnmpManagers;
 15  
 import net.sf.snmpadaptor4j.core.trap.SnmpTrapBuilder;
 16  
 import net.sf.snmpadaptor4j.mbean.SystemInfo;
 17  
 import net.sf.snmpadaptor4j.object.SnmpTrap;
 18  
 
 19  
 /**
 20  
  * Object responsible of:
 21  
  * <ul>
 22  
  * <li>the conversion of JMX notifications to SNMP traps,</li>
 23  
  * <li>and the sending SNMP traps to SNMP managers.</li>
 24  
  * </ul>
 25  
  * @author <a href="http://fr.linkedin.com/in/jpminetti/">Jean-Philippe MINETTI</a>
 26  
  */
 27  
 public class JmxNotificationManager {
 28  
 
 29  
         /**
 30  
          * JMX notification listener.
 31  
          */
 32  
         protected final class Listener
 33  
                         implements NotificationListener {
 34  
 
 35  
                 /**
 36  
                  * Builder of SNMP traps from JMX notifications for an MBean.
 37  
                  */
 38  
                 protected final SnmpTrapBuilder trapBuilder;
 39  
 
 40  
                 /**
 41  
                  * Constructor.
 42  
                  * @param trapBuilder Builder of SNMP traps from JMX notifications for an MBean (must not be <code>NULL</code>).
 43  
                  */
 44  22
                 protected Listener (final SnmpTrapBuilder trapBuilder) {
 45  22
                         super();
 46  22
                         this.trapBuilder = trapBuilder;
 47  22
                 }
 48  
 
 49  
                 /*
 50  
                  * {@inheritDoc}
 51  
                  * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, java.lang.Object)
 52  
                  */
 53  
                 public void handleNotification (final Notification notification, final Object handback) {
 54  7
                         JmxNotificationManager.this.handleNotification(this.trapBuilder, notification);
 55  7
                 }
 56  
 
 57  
                 /*
 58  
                  * {@inheritDoc}
 59  
                  * @see java.lang.Object#toString()
 60  
                  */
 61  
                 @Override
 62  
                 public String toString () {
 63  1
                         return "Listener[trapBuilder=" + this.trapBuilder + "]";
 64  
                 }
 65  
 
 66  
         }
 67  
 
 68  
         /**
 69  
          * Logger.
 70  
          */
 71  26
         protected final Logger logger = Logger.getLogger(JmxNotificationManager.class);
 72  
 
 73  
         /**
 74  
          * SNMP managers on the network to which SNMP traps should be sent.
 75  
          */
 76  
         private final SnmpManagers managers;
 77  
 
 78  
         /**
 79  
          * Informations on the system.
 80  
          */
 81  
         private final SystemInfo systemInfo;
 82  
 
 83  
         /**
 84  
          * Map of JMX notification listener for each registered MBean.
 85  
          */
 86  26
         protected final Map<ObjectName, Listener> listenerMap = new HashMap<ObjectName, Listener>();
 87  
 
 88  
         /**
 89  
          * <code>TRUE</code> to handle notifications, otherwise <code>FALSE</code> to ignore.
 90  
          */
 91  26
         private boolean enabled = false;
 92  
 
 93  
         /**
 94  
          * Constructor.
 95  
          * @param managers SNMP managers on the network to which SNMP traps should be sent (must not be <code>NULL</code>).
 96  
          * @param systemInfo Informations on the system.
 97  
          */
 98  
         public JmxNotificationManager (final SnmpManagers managers, final SystemInfo systemInfo) {
 99  26
                 super();
 100  26
                 this.managers = managers;
 101  26
                 this.systemInfo = systemInfo;
 102  26
         }
 103  
 
 104  
         /**
 105  
          * Registers a notification listener used for send SNMP traps from the JMX notifications.
 106  
          * @param server JMX agent (must not be <code>NULL</code>).
 107  
          * @param mBeanName MBean name (must not be <code>NULL</code>).
 108  
          * @param trapMappingMap Map of mapping to build SNMP traps from the JMX notifications for each notification type (must not be <code>NULL</code>).
 109  
          */
 110  
         synchronized void register (final MBeanServer server, final ObjectName mBeanName, final Map<String, SnmpTrapMapping> trapMappingMap) {
 111  5
                 if (trapMappingMap.isEmpty()) {
 112  2
                         if (this.logger.isDebugEnabled()) {
 113  1
                                 this.logger.debug("None SNMP trap mapped for [" + mBeanName + "]");
 114  
                         }
 115  
                 }
 116  
                 else {
 117  3
                         if (this.logger.isInfoEnabled()) {
 118  2
                                 for (final Entry<String, SnmpTrapMapping> trapMappingEntry : trapMappingMap.entrySet()) {
 119  14
                                         this.logger.info("MBean notification registered at [" + mBeanName + "].[" + trapMappingEntry.getKey() + "] = " + trapMappingEntry.getValue());
 120  
                                 }
 121  
                         }
 122  3
                         final Listener listener = new Listener(new SnmpTrapBuilder(trapMappingMap, this.systemInfo));
 123  
                         try {
 124  3
                                 server.addNotificationListener(mBeanName, listener, null, null);
 125  2
                                 this.listenerMap.put(mBeanName, listener);
 126  
                         }
 127  1
                         catch (final Throwable e) {
 128  1
                                 this.logger.warn("Notifications issued in on [" + mBeanName + "] will not cause any SNMP trap sending", e);
 129  2
                         }
 130  
                 }
 131  5
         }
 132  
 
 133  
         /**
 134  
          * Unregisters all notification listeners used for send SNMP traps from the JMX notifications.
 135  
          * @param server JMX agent.
 136  
          */
 137  
         synchronized void unregisterAll (final MBeanServer server) {
 138  2
                 final List<ObjectName> mBeanNameList = new ArrayList<ObjectName>(this.listenerMap.keySet());
 139  2
                 for (final ObjectName mBeanName : mBeanNameList) {
 140  4
                         unregister(server, mBeanName);
 141  
                 }
 142  2
         }
 143  
 
 144  
         /**
 145  
          * Unregisters a notification listener used for send SNMP traps from the JMX notifications.
 146  
          * @param server JMX agent.
 147  
          * @param mBeanName MBean name.
 148  
          */
 149  
         synchronized void unregister (final MBeanServer server, final ObjectName mBeanName) {
 150  8
                 final Listener listener = this.listenerMap.get(mBeanName);
 151  8
                 if (listener != null) {
 152  7
                         if (this.logger.isInfoEnabled()) {
 153  4
                                 for (final String notificationType : listener.trapBuilder.getMappingMap().keySet()) {
 154  28
                                         this.logger.info("MBean notification unregistered at [" + mBeanName + "].[" + notificationType + "]");
 155  
                                 }
 156  
                         }
 157  
                         try {
 158  7
                                 if (server.isRegistered(mBeanName)) {
 159  5
                                         server.removeNotificationListener(mBeanName, listener);
 160  
                                 }
 161  
                                 else {
 162  2
                                         if (this.logger.isTraceEnabled()) {
 163  1
                                                 this.logger.trace("[" + mBeanName + "] already unregistered from JMX");
 164  
                                         }
 165  
                                 }
 166  6
                                 this.listenerMap.remove(mBeanName);
 167  
                         }
 168  1
                         catch (final Throwable e) {
 169  1
                                 this.logger.warn("An error occurred when unloading of [" + mBeanName + "] to support notifications", e);
 170  6
                         }
 171  
                 }
 172  8
         }
 173  
 
 174  
         /**
 175  
          * Returns <code>TRUE</code> to handle notifications, or <code>FALSE</code> to ignore.
 176  
          * @return <code>TRUE</code> to handle notifications.
 177  
          */
 178  
         public final boolean isEnabled () {
 179  7
                 return this.enabled;
 180  
         }
 181  
 
 182  
         /**
 183  
          * Sets <code>TRUE</code> to handle notifications, or <code>FALSE</code> to ignore.
 184  
          * @param enabled <code>TRUE</code> to handle notifications.
 185  
          */
 186  
         public void setEnabled (boolean enabled) {
 187  41
                 this.enabled = enabled;
 188  41
         }
 189  
 
 190  
         /**
 191  
          * Handles a JMX notification from an MBean.
 192  
          * @param trapBuilder Builder of SNMP traps from JMX notifications for an MBean.
 193  
          * @param notification JMX notification.
 194  
          */
 195  
         protected final void handleNotification (final SnmpTrapBuilder trapBuilder, final Notification notification) {
 196  7
                 if (this.enabled) {
 197  6
                         if (this.logger.isTraceEnabled()) {
 198  3
                                 this.logger.trace("JMX notification [" + notification.getSource() + "].[" + notification.getType() + "] received");
 199  3
                                 this.logger.trace("source           = " + notification.getSource());
 200  3
                                 this.logger.trace("sequenceNumber   = " + notification.getSequenceNumber());
 201  3
                                 this.logger.trace("timeStamp        = " + notification.getTimeStamp());
 202  3
                                 this.logger.trace("type             = " + notification.getType());
 203  3
                                 this.logger.trace("message          = " + notification.getMessage());
 204  3
                                 if (notification.getUserData() instanceof Map) {
 205  1
                                         for (final Entry<?, ?> entry : ((Map<?, ?>) (notification.getUserData())).entrySet()) {
 206  3
                                                 this.logger.trace("userData:        " + entry.getKey() + " = " + entry.getValue());
 207  
                                         }
 208  
                                 }
 209  
                                 else {
 210  2
                                         this.logger.trace("userData         = "
 211  
                                                         + (notification.getUserData() != null ? "(" + notification.getUserData().getClass().getName() + ")" : "") + notification.getUserData());
 212  
                                 }
 213  
                         }
 214  
                         try {
 215  6
                                 final SnmpTrap trap = trapBuilder.newTrap(notification);
 216  6
                                 if (trap == null) {
 217  2
                                         if (this.logger.isDebugEnabled()) {
 218  1
                                                 this.logger.debug("None SNMP trap to send for the JMX notification [" + notification.getSource() + "].[" + notification.getType() + "]");
 219  
                                         }
 220  
                                 }
 221  
                                 else {
 222  4
                                         if (this.logger.isDebugEnabled()) {
 223  2
                                                 this.logger.debug("Notification [" + notification.getSource() + "].[" + notification.getType() + "] = " + trap);
 224  
                                         }
 225  4
                                         this.managers.send(trap);
 226  
                                 }
 227  
                         }
 228  2
                         catch (final Throwable e) {
 229  2
                                 this.logger.error("Unable to handle the notification " + notification + " for send a SNMP trap", e);
 230  4
                         }
 231  
                 }
 232  7
         }
 233  
 
 234  
         /*
 235  
          * {@inheritDoc}
 236  
          * @see java.lang.Object#toString()
 237  
          */
 238  
         @Override
 239  
         public final String toString () {
 240  1
                 return "JmxNotificationManager[managers=" + this.managers + "; systemInfo=" + this.systemInfo + "; listenerMap=" + this.listenerMap + "]";
 241  
         }
 242  
 
 243  
 }