/*_############################################################################
_##
_## SNMP4J-AgentX - TestSubagent.java
_##
_## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
_##
_## This program is free software; you can redistribute it and/or modify
_## it under the terms of the GNU General Public License version 2 as
_## published by the Free Software Foundation.
_##
_## This program is distributed in the hope that it will be useful,
_## but WITHOUT ANY WARRANTY; without even the implied warranty of
_## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
_## GNU General Public License for more details.
_##
_## You should have received a copy of the GNU General Public License
_## along with this program; if not, write to the Free Software
_## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
_## MA 02110-1301 USA
_##
_##########################################################################*/
package org.snmp4j.agent.agentx.subagent.test;
import org.snmp4j.agent.agentx.subagent.AgentXSubagent;
import org.snmp4j.smi.OID;
import org.snmp4j.agent.agentx.AgentX;
import org.snmp4j.smi.OctetString;
import org.snmp4j.agent.agentx.AgentXMessageDispatcherImpl;
import org.snmp4j.agent.agentx.AgentXMessageDispatcher;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.agent.agentx.AgentXSession;
import org.snmp4j.agent.DefaultMOServer;
import org.snmp4j.agent.MOServer;
import org.snmp4j.agent.DuplicateRegistrationException;
import org.apache.log4j.BasicConfigurator;
import org.snmp4j.log.LogFactory;
import org.snmp4j.log.Log4jLogFactory;
import org.snmp4j.agent.agentx.AgentXProtocol;
import java.io.*;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.ConnectionOrientedTransportMapping;
import org.snmp4j.transport.TransportStateListener;
import org.snmp4j.transport.TransportStateEvent;
import java.util.List;
import org.snmp4j.log.LogAdapter;
import org.snmp4j.agent.mo.MOFactory;
import org.snmp4j.agent.mo.DefaultMOFactory;
import org.snmp4j.util.ThreadPool;
import org.snmp4j.agent.mo.snmp4j.Snmp4jConfigMib;
import org.snmp4j.agent.mo.snmp4j.Snmp4jLogMib;
import org.snmp4j.agent.mo.snmp.SNMPv2MIB.SysUpTimeImpl;
import org.snmp4j.agent.mo.snmp.SysUpTime;
import org.snmp4j.smi.TimeTicks;
/**
* The <code>TestSubagent</code> is an example implementation of a simple
* AgentX subagent with shared tables and multi context registration.
*
* @author Frank Fock
* @version 1.0
*/
public class TestSubagent implements Runnable, TransportStateListener {
static {
LogFactory.setLogFactory(new Log4jLogFactory());
}
private static final LogAdapter LOGGER =
LogFactory.getLogger(TestSubagent.class);
public static final OID SUBAGENT_ID = new OID();
private AgentXSubagent subagent;
private AgentX agentX;
private AgentXMessageDispatcher dispatcher;
private Address masterAddress;
private Address localAddress;
private AgentXSession session;
private int sessionID = 0;
private MOServer server;
private AgentppTestMib agentppTestMib;
private Snmp4jConfigMib snmp4jConfigMib;
private Snmp4jLogMib snmp4jLogMib;
private SysUpTimeImpl sessionContextUpTime = new SysUpTimeImpl();
public TestSubagent(Address masterAddress, Address localAddress) {
this.masterAddress = masterAddress;
this.localAddress = localAddress;
this.dispatcher = new AgentXMessageDispatcherImpl();
this.agentX = new AgentX(dispatcher);
server = new DefaultMOServer();
server.addContext(new OctetString());
this.subagent =
new AgentXSubagent(agentX, SUBAGENT_ID,
new OctetString("AgentX4J Test agent"));
this.subagent.setThreadPool(ThreadPool.create("AgentXSubAgent", 3));
this.subagent.addMOServer(server);
}
public static void main(String[] args) {
BasicConfigurator.configure();
Address masterAddress = new TcpAddress(args[0]);
TestSubagent testsubagent =
new TestSubagent(masterAddress, new TcpAddress());
testsubagent.run();
try {
Thread.sleep(100000000);
}
catch (InterruptedException iex) {
iex.printStackTrace();
}
}
protected void register() throws DuplicateRegistrationException {
MOFactory factory = AgentppTestMib.getSharedTableFactory();
DefaultMOFactory.addSNMPv2TCs(factory);
agentppTestMib = new AgentppTestMib(factory);
agentppTestMib.registerMOs(server, null);
}
protected void unregisterSessionDependent() {
if (session != null) {
OctetString sessionContext = getSessionContext(session.getSessionID());
server.removeContext(sessionContext);
if (snmp4jConfigMib != null) {
snmp4jConfigMib.unregisterMOs(server, sessionContext);
}
if (snmp4jLogMib != null) {
snmp4jLogMib.unregisterMOs(server, sessionContext);
}
}
}
protected void registerSessionDependent()
throws DuplicateRegistrationException
{
OctetString sessionContext = getSessionContext(session.getSessionID());
server.addContext(sessionContext);
snmp4jConfigMib = new Snmp4jConfigMib(sessionContextUpTime);
snmp4jConfigMib.registerMOs(server, sessionContext);
snmp4jLogMib = new Snmp4jLogMib();
snmp4jLogMib.registerMOs(server, sessionContext);
}
private static OctetString getSessionContext(int sessionID) {
return new OctetString("session="+sessionID);
}
public void run() {
try {
Runtime.getRuntime().addShutdownHook(new AgentShutdown());
register();
unregisterSessionDependent();
session = new AgentXSession(++sessionID);
int status = subagent.connect(masterAddress, localAddress, session);
if (status == AgentXProtocol.AGENTX_SUCCESS) {
subagent.addAgentCaps(session, new OctetString(),
new OID("1.3.6.1.4.1.4976.10.1.1.100.4.1"),
new OctetString("AgentX-Test-Subagent"));
registerSessionDependent();
List failed = subagent.registerRegions(session, new OctetString());
if (failed.size() > 0) {
LOGGER.warn("Failed to register to following objects at master:"+
failed);
}
TimeTicks upTime = new TimeTicks();
subagent.registerRegions(session,
getSessionContext(session.getSessionID()),
upTime);
sessionContextUpTime.setValue(upTime);
subagent.setPingDelay(30);
subagent.notify(null, SnmpConstants.warmStart,
new VariableBinding[] {
new VariableBinding(SnmpConstants.sysDescr,
new OctetString("SNMP4J-AgentX Test-Subagent")) });
((ConnectionOrientedTransportMapping)session.getPeer().getTransport()).
addTransportStateListener(this);
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
public void connectionStateChanged(final TransportStateEvent change) {
if (change.getNewState() ==
TransportStateEvent.STATE_DISCONNECTED_REMOTELY) {
// remove session dependent registrations
// try to reconnect
Thread t = new Thread(new Runnable() {
public void run() {
Address addr = change.getPeerAddress();
// try to reconnect ten times if we have been disconnected remotely
for (int i=0; i<10; i++) {
try {
Thread.sleep(5000);
if (subagent.connect(addr, localAddress, session) ==
AgentXProtocol.AGENTX_SUCCESS) {
// if connected register our MIB objects
try {
registerSessionDependent();
}
catch (DuplicateRegistrationException ex1) {
ex1.printStackTrace();
}
subagent.registerRegions(session, new OctetString());
server.addContext(getSessionContext(session.getSessionID()));
TimeTicks upTime = new TimeTicks();
subagent.registerRegions(session,
getSessionContext(session.getSessionID()),
upTime);
sessionContextUpTime.setValue(upTime);
break;
}
}
catch (IOException ex) {
ex.printStackTrace();
}
catch (InterruptedException ex) {
break;
}
}
}
});
t.start();
}
}
/**
* The <code>AgentShutdown</code> is being executed when the agent is about
* to be shut down (e.g. terminated by SIGTERM/Ctrl-C). Its purpose is to
* send an AgentX Close PDU to the master agent to gracefully unregister
* the current session.
*
* @author Frank Fock
* @version 1.0
*/
class AgentShutdown extends Thread {
public void run() {
try {
subagent.close(session, AgentXProtocol.REASON_SHUTDOWN);
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
|