KickJava   Java API By Example, From Geeks To Geeks.

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


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.io.InputStream JavaDoc;
23 import java.net.InetAddress JavaDoc;
24 import java.net.UnknownHostException JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.Set JavaDoc;
30
31 import javax.management.Notification JavaDoc;
32
33 import org.jboss.jmx.adaptor.snmp.config.manager.Manager;
34 import org.jboss.logging.Logger;
35 import org.jboss.system.server.ServerConfig;
36 import org.jboss.xb.binding.MappingObjectModelFactory;
37 import org.jboss.xb.binding.Unmarshaller;
38 import org.jboss.xb.binding.UnmarshallerFactory;
39 import org.opennms.protocols.snmp.SnmpIPAddress;
40 import org.opennms.protocols.snmp.SnmpPduPacket;
41 import org.opennms.protocols.snmp.SnmpPduTrap;
42
43 /**
44  * <tt>TrapEmitter</tt> is a class that manages SNMP trap emission.
45  *
46  * Currently, it allows to send V1 or V2 traps to one or more subscribed SNMP
47  * managers defined by their IP address, listening port number and expected
48  * SNMP version.
49  *
50  * @version $Revision: 44604 $
51  *
52  * @author <a HREF="mailto:spol@intracom.gr">Spyros Pollatos</a>
53  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
54 **/

55 public class TrapEmitter
56 {
57    /** The logger object */
58    private static final Logger log = Logger.getLogger(TrapEmitter.class);
59    
60    /** Reference to the utilised trap factory*/
61    private TrapFactory trapFactory = null;
62    
63    /** The actual trap factory to instantiate */
64    private String JavaDoc trapFactoryClassName = null;
65
66    /** The managers resource name */
67    private String JavaDoc managersResName = null;
68    
69    /** The notification map resource name */
70    private String JavaDoc notificationMapResName = null;
71    
72    /** Provides trap count */
73    private Counter trapCount = null;
74    
75    /** Uptime clock */
76    private Clock uptime = null;
77    
78    /** Holds the manager subscriptions. Accessed through synch'd wrapper */
79    private Set JavaDoc managers = Collections.synchronizedSet(new HashSet JavaDoc());
80     
81    /**
82     * Builds a TrapEmitter object for sending SNMP V1 or V2 traps. <P>
83    **/

84    public TrapEmitter(String JavaDoc trapFactoryClassName,
85                       Counter trapCount,
86                       Clock uptime,
87                       String JavaDoc managersResName,
88                       String JavaDoc notificationMapResName)
89    {
90       this.trapFactoryClassName = trapFactoryClassName;
91       this.trapCount = trapCount;
92       this.uptime = uptime;
93       this.managersResName = managersResName;
94       this.notificationMapResName = notificationMapResName;
95    }
96     
97    /**
98     * Complete emitter initialisation
99    **/

100    public void start()
101       throws Exception JavaDoc
102    {
103       // Load persisted manager subscriptions
104
load();
105       
106       // Instantiate the trap factory
107
this.trapFactory = (TrapFactory) Class.forName(this.trapFactoryClassName,
108                                                      true,
109                                                      this.getClass().getClassLoader()).newInstance();
110       
111       // Initialise
112
this.trapFactory.set(this.notificationMapResName,
113                            this.uptime,
114                            this.trapCount);
115       
116       // Start the trap factory
117
this.trapFactory.start();
118    }
119     
120    /**
121     * Perform shutdown
122    **/

123    public void stop()
124       throws Exception JavaDoc
125    {
126       synchronized(this.managers) {
127
128          // Recycle open sessions to managers
129
Iterator JavaDoc i = this.managers.iterator();
130          
131          while (i.hasNext()) {
132             ManagerRecord s = (ManagerRecord)i.next();
133             s.closeSession();
134          }
135             
136          // Drop all held manager records
137
this.managers.clear();
138       }
139    }
140     
141    /**
142     * Intercepts the notification and after translating it to a trap sends it
143     * along.
144     *
145     * @param n notification to be sent
146     * @throws Exception if an error occurs during the preparation or
147     * sending of the trap
148    **/

149    public void send(Notification JavaDoc n)
150       throws Exception JavaDoc
151    {
152       // Beeing paranoid
153
synchronized(this.trapFactory) {
154          if(this.trapFactory == null) {
155             log.error("Received notifications before trap factory set. Discarding.");
156             return;
157          }
158       }
159            
160       // Cache the translated notification
161
SnmpPduTrap v1TrapPdu = null;
162       SnmpPduPacket v2TrapPdu = null;
163        
164       // Send trap. Synchronise on the subscription collection while
165
// iterating
166
synchronized(this.managers) {
167             
168          // Iterate over sessions and emit the trap on each one
169
Iterator JavaDoc i = this.managers.iterator();
170          while (i.hasNext()) {
171             ManagerRecord s = (ManagerRecord)i.next();
172
173             try {
174                switch (s.getVersion()) {
175                   case SnmpAgentService.SNMPV1:
176                      if (v1TrapPdu == null)
177                         v1TrapPdu = this.trapFactory.generateV1Trap(n);
178                      
179                      // fix the agent ip in the trap depending on which local address is bound
180
v1TrapPdu.setAgentAddress(new SnmpIPAddress(s.getLocalAddress()));
181                             
182                      // Advance the trap counter
183
this.trapCount.advance();
184                             
185                      // Send
186
s.getSession().send(v1TrapPdu);
187                      break;
188                   
189                   case SnmpAgentService.SNMPV2:
190                      if (v2TrapPdu == null)
191                         v2TrapPdu = this.trapFactory.generateV2Trap(n);
192                      
193                      // Advance the trap counter
194
this.trapCount.advance();
195                             
196                      // Send
197
s.getSession().send(v2TrapPdu);
198                      break;
199                      
200                   default:
201                      log.error("Skipping session: Unknown SNMP version found");
202                }
203             }
204             catch(MappingFailedException e) {
205               log.error("Translating notification - " + e.getMessage());
206             }
207             catch(Exception JavaDoc e) {
208               log.error("SNMP send error for " +
209                         s.getAddress().toString() + ":" +
210                         s.getPort() + ": <" + e +
211                         ">");
212             }
213          }
214       }
215    }
216
217    /**
218     * Load manager subscriptions
219    **/

220    private void load() throws Exception JavaDoc
221    {
222       log.debug("Reading resource: '" + this.managersResName + "'");
223       
224       // configure ObjectModelFactory for mapping XML to POJOs
225
// we'll be simply getting an ArrayList of Manager objects
226
MappingObjectModelFactory momf = new MappingObjectModelFactory();
227       momf.mapElementToClass("manager-list", ArrayList JavaDoc.class);
228       momf.mapElementToClass("manager", Manager.class);
229
230       ArrayList JavaDoc managerList = null;
231       InputStream JavaDoc is = null;
232       try
233       {
234          // locate managers.xml
235
is = this.getClass().getResourceAsStream(this.managersResName);
236          
237          // create unmarshaller
238
Unmarshaller unmarshaller = UnmarshallerFactory.newInstance()
239                .newUnmarshaller();
240          
241          // let JBossXB do it's magic using the MappingObjectModelFactory
242
managerList = (ArrayList JavaDoc)unmarshaller.unmarshal(is, momf, null);
243       }
244       catch (Exception JavaDoc e)
245       {
246          log.error("Accessing resource '" + managersResName + "'");
247          throw e;
248       }
249       finally
250       {
251          if (is != null)
252          {
253             // close the XML stream
254
is.close();
255          }
256       }
257       log.debug("Found " + managerList.size() + " monitoring managers");
258         
259       for (Iterator JavaDoc i = managerList.iterator(); i.hasNext(); )
260       {
261          // Read the monitoring manager's particulars
262
Manager m = (Manager)i.next();
263
264          try
265          {
266             // Create a record of the manager's interest
267
ManagerRecord mr = new ManagerRecord(
268                     InetAddress.getByName(m.getAddress()),
269                     m.getPort(),
270                     toInetAddressWithDefaultBinding(m.getLocalAddress()),
271                     m.getLocalPort(),
272                     m.getVersion()
273                 );
274                 
275             // Add the record to the list of monitoring managers. If
276
// successfull open the session to the manager as well.
277
if (this.managers.add(mr) == false)
278             {
279                log.warn("Ignoring duplicate manager: " + m);
280             }
281             else
282             {
283                // Open the session to the manager
284
mr.openSession();
285             }
286          }
287          catch (Exception JavaDoc e)
288          {
289             log.warn("Error enabling monitoring manager: " + m, e);
290          }
291       }
292    }
293
294    /**
295     * cater for possible global -b option, if no override has been specified
296     */

297    private InetAddress JavaDoc toInetAddressWithDefaultBinding(String JavaDoc host)
298       throws UnknownHostException JavaDoc
299    {
300       if (host == null || host.length() == 0) {
301          
302          String JavaDoc defaultBindAddress = System.getProperty(ServerConfig.SERVER_BIND_ADDRESS);
303          if (defaultBindAddress != null && !defaultBindAddress.equals("0.0.0.0"))
304             return InetAddress.getByName(defaultBindAddress);
305          else
306             return InetAddress.getLocalHost();
307       }
308       else
309          return InetAddress.getByName(host);
310    }
311    
312 } // class TrapEmitter
313
Popular Tags