KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > jmx > adaptor > snmp > agent > SnmpAgentService


1 /*
2  * Copyright (c) 2003, Intracom S.A. - www.intracom.com
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * This package and its source code is available at www.jboss.org
19  */

20 package org.jboss.jmx.adaptor.snmp.agent;
21
22 import java.net.InetAddress JavaDoc;
23 import java.net.UnknownHostException JavaDoc;
24
25 import javax.management.Notification JavaDoc;
26 import javax.management.ObjectName JavaDoc;
27
28 import org.jboss.system.ListenerServiceMBeanSupport;
29 import org.jboss.system.server.ServerConfig;
30 import org.opennms.protocols.snmp.SnmpAgentSession;
31 import org.opennms.protocols.snmp.SnmpPeer;
32 import org.opennms.protocols.snmp.SnmpSMI;
33
34 /**
35  * <tt>SnmpAgentService</tt> is an MBean class implementing an SNMP agent.
36  *
37  * It allows to send V1 or V2 traps to one or more SNMP managers defined
38  * by their IP address, listening port number and expected SNMP version.
39  *
40  * It support mapping SNMP get/set requests JMX mbean attribute get/sets.
41  *
42  * @jmx:mbean
43  * extends="org.jboss.system.ListenerServiceMBean"
44  *
45  * @author <a HREF="mailto:spol@intracom.gr">Spyros Pollatos</a>
46  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
47  * @author <a HREF="mailto:krishnaraj@ieee.org">Krishnaraj S</a>
48  * @version $Revision: 44604 $
49  */

50 public class SnmpAgentService extends ListenerServiceMBeanSupport
51    implements SnmpAgentServiceMBean
52 {
53    /** Supported versions */
54    public static final int SNMPV1 = 1;
55    public static final int SNMPV2 = 2;
56     
57    /** Default communities */
58    public static final String JavaDoc DEFAULT_READ_COMMUNITY = "public";
59    public static final String JavaDoc DEFAULT_WRITE_COMMUNITY = "private";
60    
61    // Private data --------------------------------------------------
62

63    /** Time keeping*/
64    private Clock clock = null;
65    
66    /** Trap counter */
67    private Counter trapCounter = null;
68
69    /** Name of the file containing SNMP manager specifications */
70    private String JavaDoc managersResName = null;
71
72    /** Name of resource file containing notification to trap mappings */
73    private String JavaDoc notificationMapResName = null;
74    
75    /** Name of resource file containing get/set mappings */
76    private String JavaDoc requestHandlerResName = null;
77    
78    /** Name of the trap factory class to be utilised */
79    private String JavaDoc trapFactoryClassName = null;
80
81    /** Name of request handler implementation class */
82    private String JavaDoc requestHandlerClassName = null;
83
84    /** The SNMP read community to use */
85    private String JavaDoc readCommunity = DEFAULT_READ_COMMUNITY;
86    
87    /** The SNMP write community to use */
88    private String JavaDoc writeCommunity = DEFAULT_WRITE_COMMUNITY;
89    
90    /** Controls the request processing thread pool */
91    private int numberOfThreads = 1;
92    
93    /** Agent listening port */
94    private int port = 1161;
95    
96    /** Agent SNMP protocol version */
97    private int snmpVersion = SNMPV1;
98    
99    /** The interface to bind, useful for multi-homed hosts */
100    private InetAddress JavaDoc bindAddress;
101    
102    /** Name of the utilised timer MBean */
103    private ObjectName JavaDoc timerName = null;
104      
105    /** Heartbeat emission period (in seconds) and switch */
106    private int heartBeatPeriod = 60;
107    
108    /** Dynamic subscriptions flag */
109    private boolean dynamicSubscriptions = true;
110
111    /** Reference to heartbeat emission controller */
112    private Heartbeat heartbeat = null;
113
114    /** The trap emitting subsystem*/
115    private TrapEmitter trapEmitter = null;
116
117    /** the snmp agent session for handling get/set requests */
118    private SnmpAgentSession agentSession = null;
119    
120    /** the request handler instance handling get/set requests */
121    private RequestHandler requestHandler;
122    
123    // Constructors --------------------------------------------------
124

125    /**
126     * Default CTOR
127     */

128    public SnmpAgentService()
129    {
130       // empty
131
}
132    
133    // Attributes ----------------------------------------------------
134

135    /**
136     * Gets the heartbeat switch
137     *
138     * @jmx:managed-attribute
139     */

140    public int getHeartBeatPeriod()
141    {
142       return this.heartBeatPeriod;
143    }
144    
145    /**
146     * Sets the heartbeat period (in seconds) switch
147     *
148     * @jmx:managed-attribute
149     */

150    public void setHeartBeatPeriod(int heartBeatPeriod)
151    {
152       this.heartBeatPeriod = heartBeatPeriod;
153    }
154    
155    /**
156     * Returns the difference, measured in milliseconds, between the
157     * instantiation time and midnight, January 1, 1970 UTC.
158     *
159     * @jmx:managed-attribute
160     */

161    public long getInstantiationTime()
162    {
163       return this.clock.instantiationTime();
164    }
165     
166    /**
167     * Returns the up-time
168     *
169     * @jmx:managed-attribute
170     */

171    public long getUptime()
172    {
173       return this.clock.uptime();
174    }
175
176    /**
177     * Returns the current trap counter reading
178     *
179     * @jmx:managed-attribute
180     */

181    public long getTrapCount()
182    {
183       return this.trapCounter.peek();
184    }
185      
186    /**
187     * Sets the name of the file containing SNMP manager specifications
188     *
189     * @jmx:managed-attribute
190     */

191    public void setManagersResName(String JavaDoc managersResName)
192    {
193       this.managersResName = managersResName;
194    }
195
196    /**
197     * Gets the name of the file containing SNMP manager specifications
198     *
199     * @jmx:managed-attribute
200     */

201    public String JavaDoc getManagersResName()
202    {
203       return this.managersResName;
204    }
205
206    /**
207     * Sets the name of the file containing the notification/trap mappings
208     *
209     * @jmx:managed-attribute
210     */

211    public void setNotificationMapResName(String JavaDoc notificationMapResName)
212    {
213       this.notificationMapResName = notificationMapResName;
214    }
215     
216    /**
217     * Gets the name of the file containing the notification/trap mappings
218     *
219     * @jmx:managed-attribute
220     */

221    public String JavaDoc getNotificationMapResName()
222    {
223       return this.notificationMapResName;
224    }
225
226    /**
227     * Sets the utilised trap factory name
228     *
229     * @jmx:managed-attribute
230     */

231    public void setTrapFactoryClassName(String JavaDoc name)
232    {
233       this.trapFactoryClassName = name;
234    }
235     
236    /**
237     * Gets the utilised trap factory name
238     *
239     * @jmx:managed-attribute
240     */

241    public String JavaDoc getTrapFactoryClassName()
242    {
243       return this.trapFactoryClassName;
244    }
245     
246    /**
247     * Sets the utilised timer MBean name
248     *
249     * @jmx:managed-attribute
250     */

251    public void setTimerName(ObjectName JavaDoc timerName)
252    {
253       this.timerName = timerName;
254    }
255     
256    /**
257     * Gets the utilised timer MBean name
258     *
259     * @jmx:managed-attribute
260     */

261    public ObjectName JavaDoc getTimerName()
262    {
263       return this.timerName;
264    }
265
266    /**
267     * Sets the agent bind address
268     *
269     * @jmx:managed-attribute
270     */

271    public void setBindAddress(String JavaDoc bindAddress)
272       throws UnknownHostException JavaDoc
273    {
274       this.bindAddress = toInetAddress(bindAddress);
275    }
276    
277    /**
278     * Gets the agent bind address
279     *
280     * @jmx:managed-attribute
281     */

282    public String JavaDoc getBindAddress()
283    {
284       String JavaDoc address = null;
285       
286       if (this.bindAddress != null)
287          address = this.bindAddress.getHostAddress();
288       
289       return address;
290    }
291    
292    /**
293     * Sets the number of threads in the agent request processing thread pool
294     *
295     * @jmx:managed-attribute
296     */

297    public void setNumberOfThreads(int numberOfThreads)
298    {
299       if (numberOfThreads > 0 && numberOfThreads <= 12)
300       {
301          this.numberOfThreads = numberOfThreads;
302       }
303    }
304    
305    /**
306     * Gets the number of threads in the agent requests processing thread pool
307     *
308     * @jmx:managed-attribute
309     */

310    public int getNumberOfThreads()
311    {
312       return numberOfThreads;
313    }
314
315    /**
316     * Sets the agent listening port number
317     *
318     * @jmx:managed-attribute
319     */

320    public void setPort(int port)
321    {
322       if (port >= 0)
323       {
324          this.port = port;
325       }
326    }
327    
328    /**
329     * Gets the agent listening port number
330     *
331     * @jmx:managed-attribute
332     */

333    public int getPort()
334    {
335       return port;
336    }
337
338    /**
339     * Sets the snmp protocol version
340     *
341     * @jmx:managed-attribute
342     */

343    public void setSnmpVersion(int snmpVersion)
344    {
345       switch (snmpVersion)
346       {
347          case SNMPV2:
348             this.snmpVersion = SNMPV2;
349             break;
350             
351          default:
352             this.snmpVersion = SNMPV1;
353             break;
354       }
355    }
356    
357    /**
358     * Gets the snmp protocol version
359     *
360     * @jmx:managed-attribute
361     */

362    public int getSnmpVersion()
363    {
364       return snmpVersion;
365    }
366    
367    /**
368     * Sets the read community (no getter)
369     *
370     * @jmx:managed-attribute
371     */

372    public void setReadCommunity(String JavaDoc readCommunity)
373    {
374       if (readCommunity != null && readCommunity.length() > 0)
375       {
376          this.readCommunity = readCommunity;
377       }
378    }
379
380    /**
381     * Sets the write community (no getter)
382     * @jmx:managed-attribute
383     */

384    public void setWriteCommunity(String JavaDoc writeCommunity)
385    {
386       if (writeCommunity != null && writeCommunity.length() > 0)
387       {
388          this.writeCommunity = writeCommunity;
389       }
390    }
391    
392    /**
393     * Sets the RequestHandler implementation class
394     *
395     * @jmx:managed-attribute
396     */

397    public void setRequestHandlerClassName(String JavaDoc requestHandlerClassName)
398    {
399       this.requestHandlerClassName = requestHandlerClassName;
400    }
401    
402    /**
403     * Gets the RequestHandler implementation class
404     *
405     * @jmx:managed-attribute
406     */

407    public String JavaDoc getRequestHandlerClassName()
408    {
409       return requestHandlerClassName;
410    }
411
412    /**
413     * Sets the resource file name containing get/set mappings
414     *
415     * @jmx:managed-attribute
416     */

417    public void setRequestHandlerResName(String JavaDoc requestHandlerResName)
418    {
419       this.requestHandlerResName = requestHandlerResName;
420    }
421    
422    /**
423     * Gets the resource file name containing get/set mappings
424     *
425     * @jmx:managed-attribute
426     */

427    public String JavaDoc getRequestHandlerResName()
428    {
429       return requestHandlerResName;
430    }
431    
432    /**
433     * Enables/disables dynamic subscriptions
434     *
435     * @jmx:managed-attribute
436     */

437    public void setDynamicSubscriptions(boolean dynamicSubscriptions)
438    {
439       this.dynamicSubscriptions = dynamicSubscriptions;
440    }
441
442    /**
443     * Gets the dynamic subscriptions status
444     *
445     * @jmx:managed-attribute
446     */

447    public boolean getDynamicSubscriptions()
448    {
449       return this.dynamicSubscriptions;
450    }
451    
452    // Operations ----------------------------------------------------
453

454    /**
455     * Reconfigures the RequestHandler, reponsible for handling get requests etc.
456     *
457     * @jmx:managed-operation
458     */

459    public void reconfigureRequestHandler() throws Exception JavaDoc
460    {
461       if (requestHandler instanceof Reconfigurable)
462          ((Reconfigurable)requestHandler).reconfigure(getRequestHandlerResName());
463       else
464          throw new UnsupportedOperationException JavaDoc("Request handler is not Reconfigurable");
465    }
466    
467    // Lifecycle operations ------------------------------------------
468

469    /**
470     * Perform service start-up
471     */

472    protected void startService()
473       throws Exception JavaDoc
474    {
475       // initialize clock and trapCounter
476
this.clock = new Clock();
477       this.trapCounter = new Counter(0);
478       
479       // Notification subscription are handled by
480
// ListenerServiceMBeanSupport baseclass
481

482       log.debug("Instantiating trap emitter ...");
483       this.trapEmitter = new TrapEmitter(this.getTrapFactoryClassName(),
484                                          this.trapCounter,
485                                          this.clock,
486                                          this.getManagersResName(),
487                                          this.getNotificationMapResName());
488     
489       // Start trap emitter
490
log.debug("Starting trap emitter ...");
491       this.trapEmitter.start();
492
493       // Get the heartbeat going
494
this.heartbeat = new Heartbeat(this.getServer(),
495                                      this.getTimerName(),
496                                      this.getHeartBeatPeriod());
497                                      
498       log.debug("Starting heartbeat controller ...");
499       heartbeat.start();
500
501       // subscribe for notifications, with the option for dynamic subscriptions
502
super.subscribe(this.dynamicSubscriptions);
503
504       // initialise the snmp agent
505
log.debug("Starting snmp agent ...");
506       startAgent();
507       
508       log.info("SNMP agent going active");
509         
510       // Send the cold start!
511
this.sendNotification(new Notification JavaDoc(EventTypes.COLDSTART, this,
512                                              getNextNotificationSequenceNumber()));
513    }
514     
515    /**
516     * Perform service shutdown
517     */

518    protected void stopService()
519       throws Exception JavaDoc
520    {
521       // unsubscribe for notifications
522
super.unsubscribe();
523       
524       log.debug("Stopping heartbeat controller ...");
525       this.heartbeat.stop();
526       this.heartbeat = null; // gc
527

528       log.debug("Stopping trap emitter ...");
529       this.trapEmitter.stop();
530       this.trapEmitter = null;
531       
532       log.debug("Stopping snmp agent ...");
533       this.agentSession.close();
534       this.agentSession = null;
535       
536       log.info("SNMP agent stopped");
537    }
538    
539    // Notification handling -----------------------------------------
540

541    /**
542     * All notifications are intercepted here and are routed for emission.
543     */

544    public void handleNotification2(Notification JavaDoc n, Object JavaDoc handback)
545    {
546       if (log.isTraceEnabled()) {
547          log.trace("Received notification: <" + n + "> Payload " +
548                    "TS: <" + n.getTimeStamp() + "> " +
549                    "SN: <" + n.getSequenceNumber() + "> " +
550                    "T: <" + n.getType() + ">");
551       }
552       
553       try {
554          this.trapEmitter.send(n);
555       }
556       catch (Exception JavaDoc e) {
557          log.error("Sending trap", e);
558       }
559    }
560    
561    // Private -------------------------------------------------------
562

563    /**
564     * Start the embedded agent
565     */

566    private void startAgent()
567       throws Exception JavaDoc
568    {
569       // cater for possible global -b option, if no override has been specified
570
InetAddress JavaDoc address = this.bindAddress != null ? this.bindAddress :
571             toInetAddress(System.getProperty(ServerConfig.SERVER_BIND_ADDRESS));
572       
573       // the listening address
574
SnmpPeer peer = new SnmpPeer(address, this.port);
575       
576       // set community strings and protocol version
577
peer.getParameters().setReadCommunity(this.readCommunity);
578       peer.getParameters().setWriteCommunity(this.writeCommunity);
579       peer.getParameters().setVersion(this.snmpVersion == SNMPV2 ? SnmpSMI.SNMPV2 : SnmpSMI.SNMPV1);
580       
581       // Instantiate and initialize the RequestHandler implementation
582
requestHandler = (RequestHandler)Class.forName(
583          this.requestHandlerClassName, true, this.getClass().getClassLoader()).newInstance();
584       requestHandler.initialize(this.requestHandlerResName, this.getServer(), this.log, this.clock);
585       
586       // Instantiate the AgentSession with an optional thread pool
587
this.agentSession = this.numberOfThreads > 1
588          ? new SnmpAgentSession(requestHandler, peer, this.numberOfThreads)
589          : new SnmpAgentSession(requestHandler, peer);
590    }
591    
592    /**
593     * Safely convert a host string to InetAddress or null
594     */

595    private InetAddress JavaDoc toInetAddress(String JavaDoc host)
596       throws UnknownHostException JavaDoc
597    {
598       if (host == null || host.length() == 0)
599          return null;
600       else
601          return InetAddress.getByName(host);
602    }
603
604 }
605
Popular Tags