Coverage Report - net.sf.snmpadaptor4j.SnmpAdaptor
 
Classes in this File Line Coverage Branch Coverage Complexity
SnmpAdaptor
100 %
190/190
100 %
80/80
2,469
 
 1  
 package net.sf.snmpadaptor4j;
 2  
 
 3  
 import java.net.URL;
 4  
 import java.util.ArrayList;
 5  
 import java.util.Collections;
 6  
 import java.util.HashMap;
 7  
 import java.util.List;
 8  
 import java.util.Map;
 9  
 import javax.management.MBeanAttributeInfo;
 10  
 import javax.management.MBeanConstructorInfo;
 11  
 import javax.management.MBeanInfo;
 12  
 import javax.management.MBeanNotificationInfo;
 13  
 import javax.management.MBeanOperationInfo;
 14  
 import javax.management.MBeanParameterInfo;
 15  
 import javax.management.MBeanServer;
 16  
 import javax.management.ObjectName;
 17  
 import javax.management.StandardMBean;
 18  
 import net.sf.snmpadaptor4j.api.SnmpApiFactory;
 19  
 import net.sf.snmpadaptor4j.api.SnmpDaemon;
 20  
 import net.sf.snmpadaptor4j.api.opennms.OpennmsSnmpApiFactory;
 21  
 import net.sf.snmpadaptor4j.config.XmlConfigParser;
 22  
 import net.sf.snmpadaptor4j.core.JmxListener;
 23  
 import net.sf.snmpadaptor4j.core.JmxNotificationManager;
 24  
 import net.sf.snmpadaptor4j.core.JmxSnmpMib;
 25  
 import net.sf.snmpadaptor4j.core.JvmSnmpMib;
 26  
 import net.sf.snmpadaptor4j.core.SystemSnmpMib;
 27  
 import net.sf.snmpadaptor4j.core.trap.SnmpManagers;
 28  
 import net.sf.snmpadaptor4j.mbean.SystemInfo;
 29  
 import org.apache.log4j.Logger;
 30  
 
 31  
 /**
 32  
  * <p>
 33  
  * snmpAdaptor4j is an adaptor for <a href="http://en.wikipedia.org/wiki/Java_Management_Extensions" target="_blank">Java Management eXtensions (JMX)</a> providing a
 34  
  * simple access to MBeans via the <a href="http://en.wikipedia.org/wiki/Simple_Network_Management_Protocol" target="_blank">SNMP</a> protocol. Thus, this adapter
 35  
  * you allow to connect most monitoring tools (like <a href="http://www.nagios.org/" target="_blank">Nagios</a> and <a href="http://www.cacti.net"
 36  
  * target="_blank">Cacti</a>) to your Java applications.
 37  
  * </p>
 38  
  * <p>
 39  
  * For each MBean, an XML mapping file allows to establish the relationships between attributes and the MIB of the SNMP adapter. No additional code is necessary to
 40  
  * integrate the MBeans in the SNMP protocol.
 41  
  * </p>
 42  
  * <p>
 43  
  * This adapter can work in a multi-applications environment (such as application servers).
 44  
  * </p>
 45  
  * <h4>Building of the mapping files</h4>
 46  
  * <p>
 47  
  * For each MBean of your project, create the mapping file in the <u>same package as the MBean</u>. For example:
 48  
  * </p>
 49  
  * <code>
 50  
  *        &lt;?xml version="1.0" encoding="utf-8"?&gt;<br>
 51  
  *        &lt;snmpAdaptor4j-mapping<br>
 52  
  *        &nbsp;&nbsp;&nbsp;&nbsp;xmlns="http://www.sf.net/snmpAdaptor4j/mapping/1.1"<br>
 53  
  *        &nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br>
 54  
  *        &nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation="http://www.sf.net/snmpAdaptor4j/mapping/1.1<br>
 55  
  *        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://snmpAdaptor4j.sourceforge.net/xsd/snmpAdaptor4j-mapping-1.1.xsd"&gt;<br><br>
 56  
  *        &nbsp;&nbsp;&lt;attributes&gt;<br>
 57  
  *        &nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute name="attributA" type="integer32" node="1" writable="true"/&gt;<br>
 58  
  *        &nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute name="attributB" type="counter64" node="2" writable="false"/&gt;<br>
 59  
  *        &nbsp;&nbsp;&nbsp;&nbsp;&lt;attribute name="attributC" type="gauge32" node="3" writable="false"/&gt;<br>
 60  
  *        &nbsp;&nbsp;&lt;/attributes&gt;<br><br>
 61  
  *        &lt;/snmpAdaptor4j-mapping&gt;
 62  
  *           </code>
 63  
  * <p>
 64  
  * Here, we map only MBean attributes by indicating the SNMP data type and the node constituting the OID (Object IDentifier). The mapping of MBean instances, is
 65  
  * generally put in the configuration file (see next chapter).
 66  
  * </p>
 67  
  * <h4>Building of the configuration file</h4>
 68  
  * <p>
 69  
  * Create the configuration file (one by application) like this:
 70  
  * </p>
 71  
  * <code>
 72  
  *        &lt;?xml version="1.0" encoding="utf-8"?&gt;<br>
 73  
  *        &lt;snmpAdaptor4j-config<br>
 74  
  *        &nbsp;&nbsp;&nbsp;&nbsp;xmlns="http://www.sf.net/snmpAdaptor4j/config/1.1"<br>
 75  
  *        &nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br>
 76  
  *        &nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation="http://www.sf.net/snmpAdaptor4j/config/1.1<br>
 77  
  *        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://snmpAdaptor4j.sourceforge.net/xsd/snmpAdaptor4j-config-1.1.xsd"&gt;<br><br>
 78  
  *        &nbsp;&nbsp;&lt;daemon address="127.0.0.1" port="161" version="2"&gt;<br>
 79  
  *        &nbsp;&nbsp;&nbsp;&nbsp;&lt;readCommunity&gt;public&lt;/readCommunity&gt;<br>
 80  
  *        &nbsp;&nbsp;&nbsp;&nbsp;&lt;writeCommunity&gt;private&lt;/writeCommunity&gt;<br>
 81  
  *        &nbsp;&nbsp;&lt;/daemon&gt;<br><br>
 82  
  *        &nbsp;&nbsp;&lt;roots default="1.3.6.1.4.1.99.12.8.1"/&gt;<br><br>
 83  
  *        &nbsp;&nbsp;&lt;mbeans&gt;<br>
 84  
  *        &nbsp;&nbsp;&nbsp;&nbsp;&lt;mbean name="fr.mydomain.myAppli:type=MyClass,name=objA" oid="1.1"/&gt;<br>
 85  
  *        &nbsp;&nbsp;&nbsp;&nbsp;&lt;mbean name="fr.mydomain.myAppli:type=MyClass,name=objB" oid="1.2"/&gt;<br>
 86  
  *        &nbsp;&nbsp;&lt;/mbeans&gt;<br><br>
 87  
  *        &lt;/snmpAdaptor4j-config&gt;
 88  
  *           </code>
 89  
  * <p>
 90  
  * Here, we define the OID for each instance of MBeans. The OID of an attribute, is built as follows:
 91  
  * </p>
 92  
  * <code>
 93  
  *           ${root}.${mbean oid}.${attribute node}.0
 94  
  *           </code>
 95  
  * <p>
 96  
  * For example, the <i>attributB</i> OID of first MBean will be <b>1.3.6.1.4.1.99.12.8.1.1.1.2.0</b>.
 97  
  * </p>
 98  
  * <h4>Registration and start of adaptor</h4>
 99  
  * <p>
 100  
  * Insert the following code to install the adapter inside JMX:
 101  
  * </p>
 102  
  * <code>
 103  
  *      URL url = getClass().getResource("/snmp.xml");<br>
 104  
  *      SnmpAdaptor adaptor = new SnmpAdaptor(url, true);<br>
 105  
  *      ObjectName name = new ObjectName("net.sf.snmpadaptor4j:adaptor=SnmpAdaptor");<br>
 106  
  *      ManagementFactory.getPlatformMBeanServer().registerMBean(adaptor, name);
 107  
  *           </code>
 108  
  * <p>
 109  
  * <i>snmp.xml</i> is the configuration file previously built.
 110  
  * </p>
 111  
  * <p>
 112  
  * Update the information about your system:
 113  
  * </p>
 114  
  * <code>
 115  
  *      adaptor.getSystemInfo().setSysName("MyApp");<br>
 116  
  *      adaptor.getSystemInfo().setSysDescr("This is a java application");<br>
 117  
  *      adaptor.getSystemInfo().setSysLocation("Web server at Montpellier (France)");<br>
 118  
  *      adaptor.getSystemInfo().setSysContact("root@mydomain.fr");
 119  
  * </code>
 120  
  * <p>
 121  
  * Start the adaptor:
 122  
  * </p>
 123  
  * <code>
 124  
  *      snmpAdaptor.start();
 125  
  * </code> <h4>Test</h4>
 126  
  * <p>
 127  
  * Install the <a href="http://www.net-snmp.org">Net-SNMP</a> commands and type:
 128  
  * </p>
 129  
  * <code>
 130  
  *           snmpwalk -v2c -Os -c public 127.0.0.1 .1
 131  
  *           </code>
 132  
  * <p>
 133  
  * You should see the attribute values of your MBean.
 134  
  * </p>
 135  
  * @author <a href="http://fr.linkedin.com/in/jpminetti/">Jean-Philippe MINETTI</a>
 136  
  */
 137  
 public class SnmpAdaptor
 138  
                 extends StandardMBean
 139  
                 implements SnmpConfiguration, SnmpAppContext, SnmpAdaptorMBean {
 140  
 
 141  
         /**
 142  
          * Logger.
 143  
          */
 144  33
         private final Logger logger = Logger.getLogger(SnmpAdaptor.class);
 145  
 
 146  
         /**
 147  
          * SNMP daemon.
 148  
          */
 149  
         private final SnmpDaemon daemon;
 150  
 
 151  
         /**
 152  
          * Informations on the system.
 153  
          */
 154  
         private final SystemInfo systemInfo;
 155  
 
 156  
         /**
 157  
          * Listening IP address of SNMP daemon (127.0.0.1 by default).
 158  
          */
 159  33
         private String listenerAddress = null;
 160  
 
 161  
         /**
 162  
          * UDP port of SNMP daemon (161 by default).
 163  
          */
 164  33
         private Integer listenerPort = null;
 165  
 
 166  
         /**
 167  
          * Protocol version of SNMP daemon (SNMP v2 by default).
 168  
          */
 169  33
         private Integer listenerSnmpVersion = null;
 170  
 
 171  
         /**
 172  
          * Read community of SNMP daemon ("public" by default).
 173  
          */
 174  33
         private String listenerReadCommunity = null;
 175  
 
 176  
         /**
 177  
          * Write community of SNMP daemon ("private" by default).
 178  
          */
 179  33
         private String listenerWriteCommunity = null;
 180  
 
 181  
         /**
 182  
          * List of managers where to send all notifications (SNMP traps).
 183  
          */
 184  33
         private final List<SnmpManagerConfiguration> managerList = new ArrayList<SnmpManagerConfiguration>();
 185  
 
 186  
         /**
 187  
          * Default root OID containing the attributes of the application.
 188  
          */
 189  
         private final String defaultRootOid;
 190  
 
 191  
         /**
 192  
          * Map of root OIDs where the attributes of the application will stay.
 193  
          */
 194  
         private final Map<String, String> rootOidMap;
 195  
 
 196  
         /**
 197  
          * Map of MBean OIDs.
 198  
          */
 199  
         private final Map<ObjectName, String> mBeanOidMap;
 200  
 
 201  
         /**
 202  
          * Application context map.
 203  
          */
 204  33
         protected final Map<ClassLoader, SnmpAppContext> appContextMap = new HashMap<ClassLoader, SnmpAppContext>();
 205  
 
 206  
         /**
 207  
          * SNMP managers on the network to which SNMP traps should be sent.
 208  
          */
 209  
         private final SnmpManagers snmpManagers;
 210  
 
 211  
         /**
 212  
          * <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB) for system attributes.
 213  
          */
 214  
         private final SystemSnmpMib systemMib;
 215  
 
 216  
         /**
 217  
          * <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB) for attributes of JVM.
 218  
          */
 219  
         private final JvmSnmpMib jvmMib;
 220  
 
 221  
         /**
 222  
          * Manager of JMX notifications.
 223  
          */
 224  
         private final JmxNotificationManager jmxNotificationManager;
 225  
 
 226  
         /**
 227  
          * Object designed to respond to each registration or deregistration of MBeans.
 228  
          */
 229  
         private final JmxListener jmxListener;
 230  
 
 231  
         /**
 232  
          * Constructor with a minimum of parameters.
 233  
          * <p>
 234  
          * Set <code>TRUE</code> to <code>classLoaderScope</code> for web applications: this avoids to publish MBeans of other applications of application server.
 235  
          * </p>
 236  
          * @param classLoaderScope <code>TRUE</code> for handle only MBeans created by the same {@link ClassLoader} that the SNMP adapter. <code>FALSE</code> for handle
 237  
          *            all MBeans of the JVM.
 238  
          * @throws Exception Exception if an error has occurred.
 239  
          */
 240  
         public SnmpAdaptor (final boolean classLoaderScope) throws Exception {
 241  1
                 this(null, null, null, classLoaderScope);
 242  1
         }
 243  
 
 244  
         /**
 245  
          * Constructor with an application context.
 246  
          * <p>
 247  
          * Set <code>TRUE</code> to <code>classLoaderScope</code> for web applications: this avoids to publish MBeans of other applications of application server.
 248  
          * </p>
 249  
          * @param appContext Application context.
 250  
          * @param classLoaderScope <code>TRUE</code> for handle only MBeans created by the same {@link ClassLoader} that the SNMP adapter. <code>FALSE</code> for handle
 251  
          *            all MBeans of the JVM.
 252  
          * @throws Exception Exception if an error has occurred.
 253  
          */
 254  
         public SnmpAdaptor (final SnmpAppContext appContext, final boolean classLoaderScope) throws Exception {
 255  1
                 this(null, appContext, null, classLoaderScope);
 256  1
         }
 257  
 
 258  
         /**
 259  
          * Constructor with an {@link URL} to SNMP configuration file (XML).
 260  
          * <p>
 261  
          * Set <code>TRUE</code> to <code>classLoaderScope</code> for web applications: this avoids to publish MBeans of other applications of application server.
 262  
          * </p>
 263  
          * @param url {@link URL} of SNMP configuration file (XML).
 264  
          * @param classLoaderScope <code>TRUE</code> for handle only MBeans created by the same {@link ClassLoader} that the SNMP adapter. <code>FALSE</code> for handle
 265  
          *            all MBeans of the JVM.
 266  
          * @throws Exception Exception if an error occurred.
 267  
          */
 268  
         public SnmpAdaptor (final URL url, final boolean classLoaderScope) throws Exception {
 269  1
                 this(url, null, classLoaderScope);
 270  1
         }
 271  
 
 272  
         /**
 273  
          * Constructor with an {@link URL} to SNMP configuration file (XML) and a {@link SystemInfo}.
 274  
          * <p>
 275  
          * Set <code>TRUE</code> to <code>classLoaderScope</code> for web applications: this avoids to publish MBeans of other applications of application server.
 276  
          * </p>
 277  
          * @param url {@link URL} of SNMP configuration file (XML).
 278  
          * @param systemInfo Informations on the system.
 279  
          * @param classLoaderScope <code>TRUE</code> for handle only MBeans created by the same {@link ClassLoader} that the SNMP adapter. <code>FALSE</code> for handle
 280  
          *            all MBeans of the JVM.
 281  
          * @throws Exception Exception if an error occurred.
 282  
          */
 283  
         public SnmpAdaptor (final URL url, final SystemInfo systemInfo, final boolean classLoaderScope) throws Exception {
 284  2
                 this(XmlConfigParser.newInstance(url), systemInfo, classLoaderScope);
 285  2
         }
 286  
 
 287  
         /**
 288  
          * Hidden constructor.
 289  
          * <p>
 290  
          * Set <code>TRUE</code> to <code>classLoaderScope</code> for web applications: this avoids to publish MBeans of other applications of application server.
 291  
          * </p>
 292  
          * @param xmlConfigParser Parser of SNMP configuration file (XML).
 293  
          * @param systemInfo Informations on the system.
 294  
          * @param classLoaderScope <code>TRUE</code> for handle only MBeans created by the same {@link ClassLoader} that the SNMP adapter. <code>FALSE</code> for handle
 295  
          *            all MBeans of the JVM.
 296  
          * @throws Exception Exception if an error has occurred.
 297  
          */
 298  
         private SnmpAdaptor (final XmlConfigParser xmlConfigParser, final SystemInfo systemInfo, final boolean classLoaderScope) throws Exception {
 299  2
                 this(xmlConfigParser, xmlConfigParser, systemInfo, classLoaderScope);
 300  2
         }
 301  
 
 302  
         /**
 303  
          * Constructor with all parameters.
 304  
          * <p>
 305  
          * Set <code>TRUE</code> to <code>classLoaderScope</code> for web applications: this avoids to publish MBeans of other applications of application server.
 306  
          * </p>
 307  
          * @param configuration SNMP configuration settings.
 308  
          * @param appContext Application context.
 309  
          * @param systemInfo Informations on the system.
 310  
          * @param classLoaderScope <code>TRUE</code> for handle only MBeans created by the same {@link ClassLoader} that the SNMP adapter. <code>FALSE</code> for handle
 311  
          *            all MBeans of the JVM.
 312  
          * @throws Exception Exception if an error has occurred.
 313  
          */
 314  
         public SnmpAdaptor (final SnmpConfiguration configuration, final SnmpAppContext appContext, final SystemInfo systemInfo, final boolean classLoaderScope)
 315  
                         throws Exception {
 316  7
                 super(SnmpAdaptorMBean.class);
 317  7
                 initializeMBeanDescriptions();
 318  7
                 this.defaultRootOid = ((appContext != null) && (appContext.getDefaultRootOid() != null) ? appContext.getDefaultRootOid() : "1.3.6.1.4.1.99.12.8.1");
 319  7
                 this.rootOidMap = Collections.unmodifiableMap(appContext != null ? appContext.getRootOidMap() : new HashMap<String, String>());
 320  7
                 this.mBeanOidMap = Collections.unmodifiableMap(appContext != null ? appContext.getMBeanOidMap() : new HashMap<ObjectName, String>());
 321  7
                 this.systemInfo = (systemInfo != null ? systemInfo : new SystemInfo());
 322  7
                 this.systemMib = new SystemSnmpMib(this, this.appContextMap, this.systemInfo);
 323  7
                 this.jvmMib = new JvmSnmpMib(this.systemMib);
 324  7
                 final JmxSnmpMib jmxSnmpMib = new JmxSnmpMib(this.jvmMib);
 325  7
                 final SnmpApiFactory apiFactory = new OpennmsSnmpApiFactory();
 326  7
                 this.snmpManagers = new SnmpManagers(apiFactory);
 327  7
                 this.jmxNotificationManager = new JmxNotificationManager(this.snmpManagers, this.systemInfo);
 328  7
                 this.jmxListener = new JmxListener(jmxSnmpMib, this.jmxNotificationManager, this, this.appContextMap, classLoaderScope);
 329  7
                 this.daemon = apiFactory.newSnmpDaemon(this, jmxSnmpMib);
 330  7
                 setListenerAddress(configuration != null ? configuration.getListenerAddress() : null);
 331  7
                 setListenerPort(configuration != null ? configuration.getListenerPort() : null);
 332  7
                 setListenerSnmpVersion(configuration != null ? configuration.getListenerSnmpVersion() : null);
 333  7
                 setListenerReadCommunity(configuration != null ? configuration.getListenerReadCommunity() : null);
 334  7
                 setListenerWriteCommunity(configuration != null ? configuration.getListenerWriteCommunity() : null);
 335  7
                 if ((configuration != null) && (configuration.getManagerList() != null)) {
 336  3
                         this.managerList.addAll(configuration.getManagerList());
 337  3
                         this.snmpManagers.initialize(this.managerList);
 338  
                 }
 339  7
         }
 340  
 
 341  
         /**
 342  
          * Hidden constructor (used for tests only).
 343  
          * <p>
 344  
          * Set <code>TRUE</code> to <code>classLoaderScope</code> for web applications: this avoids to publish MBeans of other applications of application server.
 345  
          * </p>
 346  
          * @param defaultRootOid Default root OID containing the attributes of the application.
 347  
          * @param configuration SNMP configuration settings.
 348  
          * @param classLoaderScope <code>TRUE</code> for handle only MBeans created by the same {@link ClassLoader} that the SNMP adapter. <code>FALSE</code> for handle
 349  
          *            all MBeans of the JVM.
 350  
          * @param systemMib <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB) for system attributes.
 351  
          * @param jvmMib <b>M</b>anagement <b>I</b>nformation <b>B</b>ase (MIB) for attributes of JVM.
 352  
          * @param jmxListener Object designed to respond to each registration or deregistration of MBeans.
 353  
          * @param jmxNotificationManager Manager of JMX notifications.
 354  
          * @param daemon SNMP daemon.
 355  
          * @throws Exception Exception if an error has occurred.
 356  
          */
 357  
         protected SnmpAdaptor (final String defaultRootOid, final SnmpConfiguration configuration, final boolean classLoaderScope, final SystemSnmpMib systemMib,
 358  
                         final JvmSnmpMib jvmMib, final JmxListener jmxListener, final JmxNotificationManager jmxNotificationManager, final SnmpDaemon daemon) throws Exception {
 359  26
                 super(SnmpAdaptorMBean.class);
 360  26
                 initializeMBeanDescriptions();
 361  26
                 this.defaultRootOid = defaultRootOid;
 362  26
                 this.rootOidMap = Collections.unmodifiableMap(new HashMap<String, String>());
 363  26
                 this.mBeanOidMap = Collections.unmodifiableMap(new HashMap<ObjectName, String>());
 364  26
                 this.systemInfo = new SystemInfo();
 365  26
                 this.systemMib = systemMib;
 366  26
                 this.jvmMib = jvmMib;
 367  26
                 this.snmpManagers = null;
 368  26
                 this.jmxNotificationManager = jmxNotificationManager;
 369  26
                 this.jmxListener = jmxListener;
 370  26
                 this.daemon = daemon;
 371  26
                 setListenerAddress(configuration != null ? configuration.getListenerAddress() : null);
 372  26
                 setListenerPort(configuration != null ? configuration.getListenerPort() : null);
 373  26
                 setListenerSnmpVersion(configuration != null ? configuration.getListenerSnmpVersion() : null);
 374  26
                 setListenerReadCommunity(configuration != null ? configuration.getListenerReadCommunity() : null);
 375  26
                 setListenerWriteCommunity(configuration != null ? configuration.getListenerWriteCommunity() : null);
 376  26
                 if ((configuration != null) && (configuration.getManagerList() != null)) {
 377  1
                         this.managerList.addAll(configuration.getManagerList());
 378  
                 }
 379  26
         }
 380  
 
 381  
         /**
 382  
          * Initializes all descriptions of MBean and its members.
 383  
          */
 384  
         private void initializeMBeanDescriptions () {
 385  
 
 386  
                 // Descriptions
 387  
                 final String classDescription = "JMX adaptor for SNMP protocol";
 388  
                 final String listenerAddressAttributeDescription = "Listening IP address of SNMP daemon";
 389  
                 final String listenerPortAttributeDescription = "Listening UDP port of SNMP daemon";
 390  
                 final String listenerSnmpVersionAttributeDescription = "Protocol version of SNMP daemon (1 or 2)";
 391  
                 final String listenerReadCommunityAttributeDescription = "Read community of SNMP daemon";
 392  
                 final String listenerWriteCommunityAttributeDescription = "Write community of SNMP daemon";
 393  
                 final String managerListAttributeDescription = "List of managers where to send all notifications (SNMP traps)";
 394  
                 final String startedAttributeDescription = "TRUE if the SNMP daemon is started";
 395  
                 final String addAppContextDescription = "Adds a new application context";
 396  
                 final String removeAppContextDescription = "Removes an application context";
 397  
                 final String startDescription = "Starts the SNMP daemon";
 398  
                 final String stopDescription = "Stops the SNMP daemon";
 399  
                 final String classLoaderParameterDescription = "Class loader of application";
 400  33
                 final String appContextParameterDescription = "Application context (any class that implements the interface " + SnmpAppContext.class.getName() + ")";
 401  
                 final String urlParameterDescription = "URL of SNMP configuration file (XML)";
 402  33
                 final String configurationParameterDescription = "SNMP configuration settings (any class that implements the interface " + SnmpConfiguration.class.getName()
 403  
                                 + ")";
 404  
                 final String systemInfoParameterDescription = "Informations on the Java application";
 405  
                 final String classLoaderScopeParameterDescription = "TRUE for handle only MBeans created by the same ClassLoader that the SNMP adapter - FALSE for handle all MBeans of the JVM (set TRUE to classLoaderScope for web applications: this avoids to publish MBeans of other applications of application server)";
 406  
 
 407  
                 // Parameter info
 408  33
                 final MBeanParameterInfo classLoaderParameter = new MBeanParameterInfo("classLoader", ClassLoader.class.getName(), classLoaderParameterDescription);
 409  
 
 410  33
                 final MBeanParameterInfo appContextParameter = new MBeanParameterInfo("appContext", SnmpAppContext.class.getName(), appContextParameterDescription);
 411  33
                 final MBeanParameterInfo urlParameter = new MBeanParameterInfo("url", URL.class.getName(), urlParameterDescription);
 412  33
                 final MBeanParameterInfo configurationParameter = new MBeanParameterInfo("configuration", SnmpConfiguration.class.getName(),
 413  
                                 configurationParameterDescription);
 414  33
                 final MBeanParameterInfo systemInfoParameter = new MBeanParameterInfo("systemInfo", SystemInfo.class.getName(), systemInfoParameterDescription);
 415  33
                 final MBeanParameterInfo classLoaderScopeParameter = new MBeanParameterInfo("classLoaderScope", boolean.class.getName(),
 416  
                                 classLoaderScopeParameterDescription);
 417  
 
 418  
                 // Operation info
 419  33
                 final MBeanOperationInfo addAppContextOperation = new MBeanOperationInfo("addAppContext", addAppContextDescription, new MBeanParameterInfo[] {
 420  
                                 classLoaderParameter, appContextParameter }, void.class.getName(), MBeanOperationInfo.ACTION);
 421  33
                 final MBeanOperationInfo removeAppContextOperation = new MBeanOperationInfo("removeAppContext", removeAppContextDescription,
 422  
                                 new MBeanParameterInfo[] { classLoaderParameter }, void.class.getName(), MBeanOperationInfo.ACTION);
 423  33
                 final MBeanOperationInfo startOperation = new MBeanOperationInfo("start", startDescription, new MBeanParameterInfo[] {}, void.class.getName(),
 424  
                                 MBeanOperationInfo.ACTION);
 425  33
                 final MBeanOperationInfo stopOperation = new MBeanOperationInfo("stop", stopDescription, new MBeanParameterInfo[] {}, void.class.getName(),
 426  
                                 MBeanOperationInfo.ACTION);
 427  33
                 final MBeanOperationInfo[] operations = new MBeanOperationInfo[] { addAppContextOperation, removeAppContextOperation, startOperation, stopOperation };
 428  
 
 429  
                 // Constructor info
 430  33
                 final MBeanConstructorInfo constructor1 = new MBeanConstructorInfo(getClass().getName(), "Constructor with only classLoaderScope parameter",
 431  
                                 new MBeanParameterInfo[] { classLoaderScopeParameter });
 432  33
                 final MBeanConstructorInfo constructor2 = new MBeanConstructorInfo(getClass().getName(), "Constructor with only appContext and classLoaderScope parameters",
 433  
                                 new MBeanParameterInfo[] { appContextParameter, classLoaderScopeParameter });
 434  33
                 final MBeanConstructorInfo constructor3 = new MBeanConstructorInfo(getClass().getName(), "Constructor with only url and classLoaderScope parameters",
 435  
                                 new MBeanParameterInfo[] { urlParameter, classLoaderScopeParameter });
 436  33
                 final MBeanConstructorInfo constructor4 = new MBeanConstructorInfo(getClass().getName(),
 437  
                                 "Constructor with only url, systemInfo and classLoaderScope parameters", new MBeanParameterInfo[] { urlParameter, systemInfoParameter,
 438  
                                                 classLoaderScopeParameter });
 439  33
                 final MBeanConstructorInfo constructor5 = new MBeanConstructorInfo(getClass().getName(),
 440  
                                 "Constructor with configuration, appContext, systemInfo and classLoaderScope parameters", new MBeanParameterInfo[] { configurationParameter,
 441  
                                                 appContextParameter, systemInfoParameter, classLoaderScopeParameter });
 442  33
                 final MBeanConstructorInfo[] constructors = new MBeanConstructorInfo[] { constructor1, constructor2, constructor3, constructor4, constructor5 };
 443  
 
 444  
                 // Attribute info
 445  33
                 final MBeanAttributeInfo listenerAddressAttribute = new MBeanAttributeInfo("ListenerAddress", String.class.getName(), listenerAddressAttributeDescription,
 446  
                                 true, true, false);
 447  33
                 final MBeanAttributeInfo listenerPortAttribute = new MBeanAttributeInfo("ListenerPort", Integer.class.getName(), listenerPortAttributeDescription, true,
 448  
                                 true, false);
 449  33
                 final MBeanAttributeInfo listenerSnmpVersionAttribute = new MBeanAttributeInfo("ListenerSnmpVersion", Integer.class.getName(),
 450  
                                 listenerSnmpVersionAttributeDescription, true, true, false);
 451  33
                 final MBeanAttributeInfo listenerReadCommunityAttribute = new MBeanAttributeInfo("ListenerReadCommunity", String.class.getName(),
 452  
                                 listenerReadCommunityAttributeDescription, true, true, false);
 453  33
                 final MBeanAttributeInfo listenerWriteCommunityAttribute = new MBeanAttributeInfo("ListenerWriteCommunity", String.class.getName(),
 454  
                                 listenerWriteCommunityAttributeDescription, true, true, false);
 455  33
                 final MBeanAttributeInfo managerListAttribute = new MBeanAttributeInfo("ManagerList", List.class.getName(), managerListAttributeDescription, true, true,
 456  
                                 false);
 457  33
                 final MBeanAttributeInfo startedAttribute = new MBeanAttributeInfo("Started", boolean.class.getName(), startedAttributeDescription, true, false, true);
 458  33
                 final MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[] { listenerAddressAttribute, listenerPortAttribute, listenerSnmpVersionAttribute,
 459  
                                 listenerReadCommunityAttribute, listenerWriteCommunityAttribute, managerListAttribute, startedAttribute };
 460  
 
 461  
                 // MBeanInfo
 462  33
                 final MBeanInfo mBeanInfo = new MBeanInfo(getClass().getName(), classDescription, attributes, constructors, operations, new MBeanNotificationInfo[] {},
 463  
                                 getMBeanInfo().getDescriptor());
 464  33
                 cacheMBeanInfo(mBeanInfo);
 465  
 
 466  33
         }
 467  
 
 468  
         /*
 469  
          * {@inheritDoc}
 470  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#addAppContext(java.lang.ClassLoader, net.sf.snmpadaptor4j.SnmpAppContext)
 471  
          */
 472  
         public void addAppContext (final ClassLoader classLoader, final SnmpAppContext appContext) {
 473  1
                 synchronized (this.appContextMap) {
 474  1
                         this.appContextMap.put(classLoader, appContext);
 475  1
                         this.systemMib.initSysObjectIDSet();
 476  1
                 }
 477  1
         }
 478  
 
 479  
         /*
 480  
          * {@inheritDoc}
 481  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#removeAppContext(java.lang.ClassLoader)
 482  
          */
 483  
         public void removeAppContext (final ClassLoader classLoader) {
 484  1
                 synchronized (this.appContextMap) {
 485  1
                         this.appContextMap.remove(classLoader);
 486  1
                         this.systemMib.initSysObjectIDSet();
 487  1
                 }
 488  1
         }
 489  
 
 490  
         /*
 491  
          * {@inheritDoc}
 492  
          * @see net.sf.snmpadaptor4j.api.SnmpDaemonConfiguration#getListenerAddress()
 493  
          */
 494  
         public final String getListenerAddress () {
 495  11
                 return this.listenerAddress;
 496  
         }
 497  
 
 498  
         /*
 499  
          * {@inheritDoc}
 500  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#setListenerAddress(java.lang.String)
 501  
          */
 502  
         public final void setListenerAddress (final String listenerAddress) {
 503  36
                 String newListenerAddress = formatAttribute(listenerAddress);
 504  36
                 if (newListenerAddress == null) {
 505  27
                         newListenerAddress = "localhost";
 506  
                 }
 507  36
                 if (this.listenerAddress != null ? !this.listenerAddress.equals(newListenerAddress) : true) {
 508  
                         try {
 509  35
                                 this.daemon.stop();
 510  34
                                 this.jmxNotificationManager.setEnabled(false);
 511  34
                                 this.listenerAddress = newListenerAddress;
 512  
                         }
 513  1
                         catch (final Throwable e) {
 514  1
                                 this.logger.error(e);
 515  34
                         }
 516  
                 }
 517  36
         }
 518  
 
 519  
         /*
 520  
          * {@inheritDoc}
 521  
          * @see net.sf.snmpadaptor4j.api.SnmpDaemonConfiguration#getListenerPort()
 522  
          */
 523  
         public final Integer getListenerPort () {
 524  11
                 return this.listenerPort;
 525  
         }
 526  
 
 527  
         /*
 528  
          * {@inheritDoc}
 529  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#setListenerPort(java.lang.Integer)
 530  
          */
 531  
         public final void setListenerPort (final Integer listenerPort) {
 532  36
                 final Integer newListenerPort = (listenerPort != null ? listenerPort : new Integer(161));
 533  36
                 if (this.listenerPort != null ? !this.listenerPort.equals(newListenerPort) : true) {
 534  
                         try {
 535  35
                                 this.daemon.stop();
 536  34
                                 this.jmxNotificationManager.setEnabled(false);
 537  34
                                 this.listenerPort = newListenerPort;
 538  
                         }
 539  1
                         catch (final Throwable e) {
 540  1
                                 this.logger.error(e);
 541  34
                         }
 542  
                 }
 543  36
         }
 544  
 
 545  
         /*
 546  
          * {@inheritDoc}
 547  
          * @see net.sf.snmpadaptor4j.api.SnmpDaemonConfiguration#getListenerSnmpVersion()
 548  
          */
 549  
         public final Integer getListenerSnmpVersion () {
 550  13
                 return this.listenerSnmpVersion;
 551  
         }
 552  
 
 553  
         /*
 554  
          * {@inheritDoc}
 555  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#setListenerSnmpVersion(java.lang.Integer)
 556  
          */
 557  
         public final void setListenerSnmpVersion (final Integer listenerSnmpVersion) {
 558  
                 Integer newListenerSnmpVersion;
 559  38
                 if ((listenerSnmpVersion == null) || (listenerSnmpVersion.intValue() < 1) || (listenerSnmpVersion.intValue() > 2)) {
 560  29
                         newListenerSnmpVersion = new Integer(2);
 561  
                 }
 562  
                 else {
 563  9
                         newListenerSnmpVersion = listenerSnmpVersion;
 564  
                 }
 565  38
                 if (this.listenerSnmpVersion != null ? !this.listenerSnmpVersion.equals(newListenerSnmpVersion) : true) {
 566  
                         try {
 567  37
                                 this.daemon.stop();
 568  36
                                 this.jmxNotificationManager.setEnabled(false);
 569  36
                                 this.listenerSnmpVersion = newListenerSnmpVersion;
 570  
                         }
 571  1
                         catch (final Throwable e) {
 572  1
                                 this.logger.error(e);
 573  36
                         }
 574  
                 }
 575  38
         }
 576  
 
 577  
         /*
 578  
          * {@inheritDoc}
 579  
          * @see net.sf.snmpadaptor4j.api.SnmpDaemonConfiguration#getListenerReadCommunity()
 580  
          */
 581  
         public final String getListenerReadCommunity () {
 582  11
                 return this.listenerReadCommunity;
 583  
         }
 584  
 
 585  
         /*
 586  
          * {@inheritDoc}
 587  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#setListenerReadCommunity(java.lang.String)
 588  
          */
 589  
         public final void setListenerReadCommunity (final String listenerReadCommunity) {
 590  36
                 String newListenerReadCommunity = formatAttribute(listenerReadCommunity);
 591  36
                 if (newListenerReadCommunity == null) {
 592  27
                         newListenerReadCommunity = "public";
 593  
                 }
 594  36
                 if (this.listenerReadCommunity != null ? !this.listenerReadCommunity.equals(newListenerReadCommunity) : true) {
 595  
                         try {
 596  35
                                 this.daemon.stop();
 597  34
                                 this.jmxNotificationManager.setEnabled(false);
 598  34
                                 this.listenerReadCommunity = newListenerReadCommunity;
 599  
                         }
 600  1
                         catch (final Throwable e) {
 601  1
                                 this.logger.error(e);
 602  34
                         }
 603  
                 }
 604  36
         }
 605  
 
 606  
         /*
 607  
          * {@inheritDoc}
 608  
          * @see net.sf.snmpadaptor4j.api.SnmpDaemonConfiguration#getListenerWriteCommunity()
 609  
          */
 610  
         public final String getListenerWriteCommunity () {
 611  11
                 return this.listenerWriteCommunity;
 612  
         }
 613  
 
 614  
         /*
 615  
          * {@inheritDoc}
 616  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#setListenerWriteCommunity(java.lang.String)
 617  
          */
 618  
         public final void setListenerWriteCommunity (final String listenerWriteCommunity) {
 619  36
                 String newListenerWriteCommunity = formatAttribute(listenerWriteCommunity);
 620  36
                 if (newListenerWriteCommunity == null) {
 621  27
                         newListenerWriteCommunity = "private";
 622  
                 }
 623  36
                 if (this.listenerWriteCommunity != null ? !this.listenerWriteCommunity.equals(newListenerWriteCommunity) : true) {
 624  
                         try {
 625  35
                                 this.daemon.stop();
 626  34
                                 this.jmxNotificationManager.setEnabled(false);
 627  34
                                 this.listenerWriteCommunity = newListenerWriteCommunity;
 628  
                         }
 629  1
                         catch (final Throwable e) {
 630  1
                                 this.logger.error(e);
 631  34
                         }
 632  
                 }
 633  36
         }
 634  
 
 635  
         /*
 636  
          * {@inheritDoc}
 637  
          * @see net.sf.snmpadaptor4j.SnmpConfiguration#getManagerList()
 638  
          */
 639  
         public final List<SnmpManagerConfiguration> getManagerList () {
 640  6
                 return Collections.unmodifiableList(this.managerList);
 641  
         }
 642  
 
 643  
         /*
 644  
          * {@inheritDoc}
 645  
          * @see net.sf.snmpadaptor4j.SnmpAppContext#getDefaultRootOid()
 646  
          */
 647  
         public final String getDefaultRootOid () {
 648  20
                 return this.defaultRootOid;
 649  
         }
 650  
 
 651  
         /*
 652  
          * {@inheritDoc}
 653  
          * @see net.sf.snmpadaptor4j.SnmpAppContext#getRootOidMap()
 654  
          */
 655  
         public final Map<String, String> getRootOidMap () {
 656  13
                 return this.rootOidMap;
 657  
         }
 658  
 
 659  
         /*
 660  
          * {@inheritDoc}
 661  
          * @see net.sf.snmpadaptor4j.SnmpAppContext#getMBeanOidMap()
 662  
          */
 663  
         public final Map<ObjectName, String> getMBeanOidMap () {
 664  6
                 return this.mBeanOidMap;
 665  
         }
 666  
 
 667  
         /*
 668  
          * {@inheritDoc}
 669  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#start()
 670  
          */
 671  
         public void start () throws Exception {
 672  2
                 this.daemon.start();
 673  2
                 if (!this.daemon.isStarted()) {
 674  1
                         throw new Exception("The SNMP daemon did not start");
 675  
                 }
 676  1
                 this.jmxNotificationManager.setEnabled(true);
 677  1
         }
 678  
 
 679  
         /*
 680  
          * {@inheritDoc}
 681  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#stop()
 682  
          */
 683  
         public void stop () throws Exception {
 684  2
                 this.daemon.stop();
 685  2
                 if (this.daemon.isStarted()) {
 686  1
                         throw new Exception("The SNMP daemon has not been stopped");
 687  
                 }
 688  1
                 this.jmxNotificationManager.setEnabled(false);
 689  1
         }
 690  
 
 691  
         /*
 692  
          * {@inheritDoc}
 693  
          * @see net.sf.snmpadaptor4j.SnmpAdaptorMBean#isStarted()
 694  
          */
 695  
         public final boolean isStarted () {
 696  1
                 return this.daemon.isStarted();
 697  
         }
 698  
 
 699  
         /**
 700  
          * Returns the informations on the system.
 701  
          * <p>
 702  
          * The returned object is a MBean. It is possible to register it in JMX.
 703  
          * </p>
 704  
          * @return Informations on the system.
 705  
          */
 706  
         public final SystemInfo getSystemInfo () {
 707  24
                 return this.systemInfo;
 708  
         }
 709  
 
 710  
         /**
 711  
          * Formats an attribute value.
 712  
          * @param value Value to format.
 713  
          * @return Value formatted.
 714  
          */
 715  
         protected static final String formatAttribute (final String value) {
 716  111
                 String result = value;
 717  111
                 if (result != null) {
 718  29
                         result = result.trim();
 719  29
                         if (result.length() == 0) {
 720  1
                                 result = null;
 721  
                         }
 722  
                 }
 723  111
                 return result;
 724  
         }
 725  
 
 726  
         /*
 727  
          * {@inheritDoc}
 728  
          * @see javax.management.StandardMBean#preRegister(javax.management.MBeanServer, javax.management.ObjectName)
 729  
          */
 730  
         @Override
 731  
         public ObjectName preRegister (final MBeanServer server, final ObjectName name) throws Exception {
 732  1
                 final ObjectName result = super.preRegister(server, name);
 733  1
                 this.jmxListener.open(server);
 734  1
                 this.jvmMib.open(server);
 735  1
                 return result;
 736  
         }
 737  
 
 738  
         /*
 739  
          * {@inheritDoc}
 740  
          * @see javax.management.StandardMBean#preDeregister()
 741  
          */
 742  
         @Override
 743  
         public void preDeregister () throws Exception {
 744  1
                 super.preDeregister();
 745  1
                 this.jmxListener.close();
 746  1
                 this.jvmMib.close();
 747  1
         }
 748  
 
 749  
         /*
 750  
          * {@inheritDoc}
 751  
          * @see java.lang.Object#toString()
 752  
          */
 753  
         @Override
 754  
         public String toString () {
 755  1
                 return "SnmpAdaptor[" + this.listenerAddress + ":" + this.listenerPort + "]";
 756  
         }
 757  
 
 758  
 }