package org.jboss.jmx.adaptor.snmp.agent;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.management.Notification;
import org.jboss.jmx.adaptor.snmp.config.manager.Manager;
import org.jboss.logging.Logger;
import org.jboss.system.server.ServerConfig;
import org.jboss.xml.binding.MappingObjectModelFactory;
import org.jboss.xml.binding.Unmarshaller;
import org.opennms.protocols.snmp.SnmpIPAddress;
import org.opennms.protocols.snmp.SnmpPduPacket;
import org.opennms.protocols.snmp.SnmpPduTrap;
public class TrapEmitter
{
private static final Logger log = Logger.getLogger(TrapEmitter.class);
private TrapFactory trapFactory = null;
private String trapFactoryClassName = null;
private String managersResName = null;
private String notificationMapResName = null;
private Counter trapCount = null;
private Clock uptime = null;
private Set managers = Collections.synchronizedSet(new HashSet());
public TrapEmitter(String trapFactoryClassName,
Counter trapCount,
Clock uptime,
String managersResName,
String notificationMapResName)
{
this.trapFactoryClassName = trapFactoryClassName;
this.trapCount = trapCount;
this.uptime = uptime;
this.managersResName = managersResName;
this.notificationMapResName = notificationMapResName;
}
public void start()
throws Exception
{
load();
this.trapFactory = (TrapFactory) Class.forName(this.trapFactoryClassName,
true,
this.getClass().getClassLoader()).newInstance();
this.trapFactory.set(this.notificationMapResName,
this.uptime,
this.trapCount);
this.trapFactory.start();
}
public void stop()
throws Exception
{
synchronized(this.managers) {
Iterator i = this.managers.iterator();
while (i.hasNext()) {
ManagerRecord s = (ManagerRecord)i.next();
s.closeSession();
}
this.managers.clear();
}
}
public void send(Notification n)
throws Exception
{
synchronized(this.trapFactory) {
if(this.trapFactory == null) {
log.error("Received notifications before trap factory set. Discarding.");
return;
}
}
SnmpPduTrap v1TrapPdu = null;
SnmpPduPacket v2TrapPdu = null;
synchronized(this.managers) {
Iterator i = this.managers.iterator();
while (i.hasNext()) {
ManagerRecord s = (ManagerRecord)i.next();
try {
switch (s.getVersion()) {
case SnmpAgentService.SNMPV1:
if (v1TrapPdu == null)
v1TrapPdu = this.trapFactory.generateV1Trap(n);
v1TrapPdu.setAgentAddress(new SnmpIPAddress(s.getLocalAddress()));
this.trapCount.advance();
s.getSession().send(v1TrapPdu);
break;
case SnmpAgentService.SNMPV2:
if (v2TrapPdu == null)
v2TrapPdu = this.trapFactory.generateV2Trap(n);
this.trapCount.advance();
s.getSession().send(v2TrapPdu);
break;
default:
log.error("Skipping session: Unknown SNMP version found");
}
}
catch(MappingFailedException e) {
log.error("Translating notification - " + e.getMessage());
}
catch(Exception e) {
log.error("SNMP send error for " +
s.getAddress().toString() + ":" +
s.getPort() + ": <" + e +
">");
}
}
}
}
private void load() throws Exception
{
log.debug("Reading resource: '" + this.managersResName + "'");
MappingObjectModelFactory momf = new MappingObjectModelFactory();
momf.mapElementToClass("manager-list", ArrayList.class);
momf.mapElementToClass("manager", Manager.class);
ArrayList managerList = null;
InputStream is = null;
try
{
is = this.getClass().getResourceAsStream(this.managersResName);
Unmarshaller unmarshaller = new Unmarshaller();
managerList = (ArrayList)unmarshaller.unmarshal(is, momf, null);
}
catch (Exception e)
{
log.error("Accessing resource '" + managersResName + "'");
throw e;
}
finally
{
if (is != null)
{
is.close();
}
}
log.debug("Found " + managerList.size() + " monitoring managers");
for (Iterator i = managerList.iterator(); i.hasNext(); )
{
Manager m = (Manager)i.next();
try
{
ManagerRecord mr = new ManagerRecord(
InetAddress.getByName(m.getAddress()),
m.getPort(),
toInetAddressWithDefaultBinding(m.getLocalAddress()),
m.getLocalPort(),
m.getVersion()
);
if (this.managers.add(mr) == false)
{
log.warn("Ignoring duplicate manager: " + m);
}
else
{
mr.openSession();
}
}
catch (Exception e)
{
log.warn("Error enabling monitoring manager: " + m, e);
}
}
}
private InetAddress toInetAddressWithDefaultBinding(String host)
throws UnknownHostException
{
if (host == null || host.length() == 0) {
String defaultBindAddress = System.getProperty(ServerConfig.SERVER_BIND_ADDRESS);
if (defaultBindAddress != null && !defaultBindAddress.equals("0.0.0.0"))
return InetAddress.getByName(defaultBindAddress);
else
return InetAddress.getLocalHost();
}
else
return InetAddress.getByName(host);
}
}