package org.jboss.jmx.adaptor.snmp.agent;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import org.jboss.system.ListenerServiceMBeanSupport;
import org.jboss.system.server.ServerConfig;
import org.opennms.protocols.snmp.SnmpAgentSession;
import org.opennms.protocols.snmp.SnmpPeer;
import org.opennms.protocols.snmp.SnmpSMI;
public class SnmpAgentService
extends ListenerServiceMBeanSupport
implements NotificationListener, SnmpAgentServiceMBean
{
public static final int SNMPV1 = 1;
public static final int SNMPV2 = 2;
public static final String DEFAULT_READ_COMMUNITY = "public";
public static final String DEFAULT_WRITE_COMMUNITY = "private";
private Clock clock = null;
private Counter trapCounter = null;
private String managersResName = null;
private String notificationMapResName = null;
private String requestHandlerResName = null;
private String trapFactoryClassName = null;
private String requestHandlerClassName = null;
private String readCommunity = DEFAULT_READ_COMMUNITY;
private String writeCommunity = DEFAULT_WRITE_COMMUNITY;
private int numberOfThreads = 1;
private int port = 1161;
private int snmpVersion = SNMPV1;
private InetAddress bindAddress;
private ObjectName timerName = null;
private int heartBeatPeriod = 60;
private boolean dynamicSubscriptions = true;
private Heartbeat heartbeat = null;
private TrapEmitter trapEmitter = null;
private SnmpAgentSession agentSession = null;
public SnmpAgentService()
{
}
public int getHeartBeatPeriod()
{
return this.heartBeatPeriod;
}
public void setHeartBeatPeriod(int heartBeatPeriod)
{
this.heartBeatPeriod = heartBeatPeriod;
}
public long getInstantiationTime()
{
return this.clock.instantiationTime();
}
public long getUptime()
{
return this.clock.uptime();
}
public long getTrapCount()
{
return this.trapCounter.peek();
}
public void setManagersResName(String managersResName)
{
this.managersResName = managersResName;
}
public String getManagersResName()
{
return this.managersResName;
}
public void setNotificationMapResName(String notificationMapResName)
{
this.notificationMapResName = notificationMapResName;
}
public String getNotificationMapResName()
{
return this.notificationMapResName;
}
public void setTrapFactoryClassName(String name)
{
this.trapFactoryClassName = name;
}
public String getTrapFactoryClassName()
{
return this.trapFactoryClassName;
}
public void setTimerName(ObjectName timerName)
{
this.timerName = timerName;
}
public ObjectName getTimerName()
{
return this.timerName;
}
public void setBindAddress(String bindAddress)
throws UnknownHostException
{
this.bindAddress = toInetAddress(bindAddress);
}
public String getBindAddress()
{
String address = null;
if (this.bindAddress != null)
address = this.bindAddress.getHostAddress();
return address;
}
public void setNumberOfThreads(int numberOfThreads)
{
if (numberOfThreads > 0 && numberOfThreads <= 12)
{
this.numberOfThreads = numberOfThreads;
}
}
public int getNumberOfThreads()
{
return numberOfThreads;
}
public void setPort(int port)
{
if (port >= 0)
{
this.port = port;
}
}
public int getPort()
{
return port;
}
public void setSnmpVersion(int snmpVersion)
{
switch (snmpVersion)
{
case SNMPV2:
this.snmpVersion = SNMPV2;
break;
default:
this.snmpVersion = SNMPV1;
break;
}
}
public int getSnmpVersion()
{
return snmpVersion;
}
public void setReadCommunity(String readCommunity)
{
if (readCommunity != null && readCommunity.length() > 0)
{
this.readCommunity = readCommunity;
}
}
public void setWriteCommunity(String writeCommunity)
{
if (writeCommunity != null && writeCommunity.length() > 0)
{
this.writeCommunity = writeCommunity;
}
}
public void setRequestHandlerClassName(String requestHandlerClassName)
{
this.requestHandlerClassName = requestHandlerClassName;
}
public String getRequestHandlerClassName()
{
return requestHandlerClassName;
}
public void setRequestHandlerResName(String requestHandlerResName)
{
this.requestHandlerResName = requestHandlerResName;
}
public String getRequestHandlerResName()
{
return requestHandlerResName;
}
public void setDynamicSubscriptions(boolean dynamicSubscriptions)
{
this.dynamicSubscriptions = dynamicSubscriptions;
}
public boolean getDynamicSubscriptions()
{
return this.dynamicSubscriptions;
}
protected void startService()
throws Exception
{
this.clock = new Clock();
this.trapCounter = new Counter(0);
log.debug("Instantiating trap emitter ...");
this.trapEmitter = new TrapEmitter(this.getTrapFactoryClassName(),
this.trapCounter,
this.clock,
this.getManagersResName(),
this.getNotificationMapResName());
log.debug("Starting trap emitter ...");
this.trapEmitter.start();
this.heartbeat = new Heartbeat(this.getServer(),
this.getTimerName(),
this.getHeartBeatPeriod());
log.debug("Starting heartbeat controller ...");
heartbeat.start();
super.subscribe(this.dynamicSubscriptions);
log.debug("Starting snmp agent ...");
startAgent();
log.info("SNMP agent going active");
this.sendNotification(new Notification(EventTypes.COLDSTART, this,
getNextNotificationSequenceNumber()));
}
protected void stopService()
throws Exception
{
super.unsubscribe();
log.debug("Stopping heartbeat controller ...");
this.heartbeat.stop();
this.heartbeat = null;
log.debug("Stopping trap emitter ...");
this.trapEmitter.stop();
this.trapEmitter = null;
log.debug("Stopping snmp agent ...");
this.agentSession.close();
this.agentSession = null;
log.info("SNMP agent stopped");
}
public void handleNotification2(Notification n, Object handback)
{
if (log.isDebugEnabled()) {
log.debug("Received notification: <" + n + "> Payload " +
"TS: <" + n.getTimeStamp() + "> " +
"SN: <" + n.getSequenceNumber() + "> " +
"T: <" + n.getType() + ">");
}
try {
this.trapEmitter.send(n);
}
catch (Exception e) {
log.error("Sending trap", e);
}
}
private void startAgent()
throws Exception
{
InetAddress address = this.bindAddress != null ? this.bindAddress :
toInetAddress(System.getProperty(ServerConfig.SERVER_BIND_ADDRESS));
SnmpPeer peer = new SnmpPeer(address, this.port);
peer.getParameters().setReadCommunity(this.readCommunity);
peer.getParameters().setWriteCommunity(this.writeCommunity);
peer.getParameters().setVersion(this.snmpVersion == SNMPV2 ? SnmpSMI.SNMPV2 : SnmpSMI.SNMPV1);
RequestHandler handler = (RequestHandler)Class.forName(
this.requestHandlerClassName, true, this.getClass().getClassLoader()).newInstance();
handler.initialize(this.requestHandlerResName, this.getServer(), this.log, this.clock);
this.agentSession = this.numberOfThreads > 1
? new SnmpAgentSession(handler, peer, this.numberOfThreads)
: new SnmpAgentSession(handler, peer);
}
private InetAddress toInetAddress(String host)
throws UnknownHostException
{
if (host == null || host.length() == 0)
return null;
else
return InetAddress.getByName(host);
}
}