001: /*_############################################################################
002: _##
003: _## SNMP4J-AgentX - TestSubagent.java
004: _##
005: _## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
006: _##
007: _## This program is free software; you can redistribute it and/or modify
008: _## it under the terms of the GNU General Public License version 2 as
009: _## published by the Free Software Foundation.
010: _##
011: _## This program is distributed in the hope that it will be useful,
012: _## but WITHOUT ANY WARRANTY; without even the implied warranty of
013: _## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: _## GNU General Public License for more details.
015: _##
016: _## You should have received a copy of the GNU General Public License
017: _## along with this program; if not, write to the Free Software
018: _## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
019: _## MA 02110-1301 USA
020: _##
021: _##########################################################################*/
022:
023: package org.snmp4j.agent.agentx.subagent.test;
024:
025: import org.snmp4j.agent.agentx.subagent.AgentXSubagent;
026: import org.snmp4j.smi.OID;
027: import org.snmp4j.agent.agentx.AgentX;
028: import org.snmp4j.smi.OctetString;
029: import org.snmp4j.agent.agentx.AgentXMessageDispatcherImpl;
030: import org.snmp4j.agent.agentx.AgentXMessageDispatcher;
031: import org.snmp4j.smi.Address;
032: import org.snmp4j.smi.TcpAddress;
033: import org.snmp4j.agent.agentx.AgentXSession;
034: import org.snmp4j.agent.DefaultMOServer;
035: import org.snmp4j.agent.MOServer;
036: import org.snmp4j.agent.DuplicateRegistrationException;
037: import org.apache.log4j.BasicConfigurator;
038: import org.snmp4j.log.LogFactory;
039: import org.snmp4j.log.Log4jLogFactory;
040: import org.snmp4j.agent.agentx.AgentXProtocol;
041: import java.io.*;
042: import org.snmp4j.mp.SnmpConstants;
043: import org.snmp4j.smi.VariableBinding;
044: import org.snmp4j.transport.ConnectionOrientedTransportMapping;
045: import org.snmp4j.transport.TransportStateListener;
046: import org.snmp4j.transport.TransportStateEvent;
047: import java.util.List;
048: import org.snmp4j.log.LogAdapter;
049: import org.snmp4j.agent.mo.MOFactory;
050: import org.snmp4j.agent.mo.DefaultMOFactory;
051: import org.snmp4j.util.ThreadPool;
052: import org.snmp4j.agent.mo.snmp4j.Snmp4jConfigMib;
053: import org.snmp4j.agent.mo.snmp4j.Snmp4jLogMib;
054: import org.snmp4j.agent.mo.snmp.SNMPv2MIB.SysUpTimeImpl;
055: import org.snmp4j.agent.mo.snmp.SysUpTime;
056: import org.snmp4j.smi.TimeTicks;
057:
058: /**
059: * The <code>TestSubagent</code> is an example implementation of a simple
060: * AgentX subagent with shared tables and multi context registration.
061: *
062: * @author Frank Fock
063: * @version 1.0
064: */
065: public class TestSubagent implements Runnable, TransportStateListener {
066:
067: static {
068: LogFactory.setLogFactory(new Log4jLogFactory());
069: }
070:
071: private static final LogAdapter LOGGER = LogFactory
072: .getLogger(TestSubagent.class);
073:
074: public static final OID SUBAGENT_ID = new OID();
075:
076: private AgentXSubagent subagent;
077: private AgentX agentX;
078: private AgentXMessageDispatcher dispatcher;
079: private Address masterAddress;
080: private Address localAddress;
081: private AgentXSession session;
082: private int sessionID = 0;
083:
084: private MOServer server;
085: private AgentppTestMib agentppTestMib;
086: private Snmp4jConfigMib snmp4jConfigMib;
087: private Snmp4jLogMib snmp4jLogMib;
088:
089: private SysUpTimeImpl sessionContextUpTime = new SysUpTimeImpl();
090:
091: public TestSubagent(Address masterAddress, Address localAddress) {
092: this .masterAddress = masterAddress;
093: this .localAddress = localAddress;
094: this .dispatcher = new AgentXMessageDispatcherImpl();
095: this .agentX = new AgentX(dispatcher);
096: server = new DefaultMOServer();
097: server.addContext(new OctetString());
098: this .subagent = new AgentXSubagent(agentX, SUBAGENT_ID,
099: new OctetString("AgentX4J Test agent"));
100: this .subagent.setThreadPool(ThreadPool.create("AgentXSubAgent",
101: 3));
102: this .subagent.addMOServer(server);
103: }
104:
105: public static void main(String[] args) {
106: BasicConfigurator.configure();
107: Address masterAddress = new TcpAddress(args[0]);
108: TestSubagent testsubagent = new TestSubagent(masterAddress,
109: new TcpAddress());
110: testsubagent.run();
111: try {
112: Thread.sleep(100000000);
113: } catch (InterruptedException iex) {
114: iex.printStackTrace();
115: }
116: }
117:
118: protected void register() throws DuplicateRegistrationException {
119: MOFactory factory = AgentppTestMib.getSharedTableFactory();
120: DefaultMOFactory.addSNMPv2TCs(factory);
121: agentppTestMib = new AgentppTestMib(factory);
122: agentppTestMib.registerMOs(server, null);
123: }
124:
125: protected void unregisterSessionDependent() {
126: if (session != null) {
127: OctetString sessionContext = getSessionContext(session
128: .getSessionID());
129: server.removeContext(sessionContext);
130: if (snmp4jConfigMib != null) {
131: snmp4jConfigMib.unregisterMOs(server, sessionContext);
132: }
133: if (snmp4jLogMib != null) {
134: snmp4jLogMib.unregisterMOs(server, sessionContext);
135: }
136: }
137: }
138:
139: protected void registerSessionDependent()
140: throws DuplicateRegistrationException {
141: OctetString sessionContext = getSessionContext(session
142: .getSessionID());
143: server.addContext(sessionContext);
144: snmp4jConfigMib = new Snmp4jConfigMib(sessionContextUpTime);
145: snmp4jConfigMib.registerMOs(server, sessionContext);
146: snmp4jLogMib = new Snmp4jLogMib();
147: snmp4jLogMib.registerMOs(server, sessionContext);
148: }
149:
150: private static OctetString getSessionContext(int sessionID) {
151: return new OctetString("session=" + sessionID);
152: }
153:
154: public void run() {
155: try {
156: Runtime.getRuntime().addShutdownHook(new AgentShutdown());
157: register();
158: unregisterSessionDependent();
159: session = new AgentXSession(++sessionID);
160: int status = subagent.connect(masterAddress, localAddress,
161: session);
162: if (status == AgentXProtocol.AGENTX_SUCCESS) {
163: subagent.addAgentCaps(session, new OctetString(),
164: new OID("1.3.6.1.4.1.4976.10.1.1.100.4.1"),
165: new OctetString("AgentX-Test-Subagent"));
166: registerSessionDependent();
167: List failed = subagent.registerRegions(session,
168: new OctetString());
169: if (failed.size() > 0) {
170: LOGGER
171: .warn("Failed to register to following objects at master:"
172: + failed);
173: }
174: TimeTicks upTime = new TimeTicks();
175: subagent.registerRegions(session,
176: getSessionContext(session.getSessionID()),
177: upTime);
178: sessionContextUpTime.setValue(upTime);
179: subagent.setPingDelay(30);
180: subagent
181: .notify(
182: null,
183: SnmpConstants.warmStart,
184: new VariableBinding[] { new VariableBinding(
185: SnmpConstants.sysDescr,
186: new OctetString(
187: "SNMP4J-AgentX Test-Subagent")) });
188: ((ConnectionOrientedTransportMapping) session.getPeer()
189: .getTransport())
190: .addTransportStateListener(this );
191: }
192: } catch (Exception ex) {
193: ex.printStackTrace();
194: }
195: }
196:
197: public void connectionStateChanged(final TransportStateEvent change) {
198: if (change.getNewState() == TransportStateEvent.STATE_DISCONNECTED_REMOTELY) {
199: // remove session dependent registrations
200: // try to reconnect
201: Thread t = new Thread(new Runnable() {
202: public void run() {
203: Address addr = change.getPeerAddress();
204: // try to reconnect ten times if we have been disconnected remotely
205: for (int i = 0; i < 10; i++) {
206: try {
207: Thread.sleep(5000);
208: if (subagent.connect(addr, localAddress,
209: session) == AgentXProtocol.AGENTX_SUCCESS) {
210: // if connected register our MIB objects
211: try {
212: registerSessionDependent();
213: } catch (DuplicateRegistrationException ex1) {
214: ex1.printStackTrace();
215: }
216: subagent.registerRegions(session,
217: new OctetString());
218: server
219: .addContext(getSessionContext(session
220: .getSessionID()));
221: TimeTicks upTime = new TimeTicks();
222: subagent.registerRegions(session,
223: getSessionContext(session
224: .getSessionID()),
225: upTime);
226: sessionContextUpTime.setValue(upTime);
227: break;
228: }
229: } catch (IOException ex) {
230: ex.printStackTrace();
231: } catch (InterruptedException ex) {
232: break;
233: }
234: }
235: }
236: });
237: t.start();
238: }
239: }
240:
241: /**
242: * The <code>AgentShutdown</code> is being executed when the agent is about
243: * to be shut down (e.g. terminated by SIGTERM/Ctrl-C). Its purpose is to
244: * send an AgentX Close PDU to the master agent to gracefully unregister
245: * the current session.
246: *
247: * @author Frank Fock
248: * @version 1.0
249: */
250: class AgentShutdown extends Thread {
251: public void run() {
252: try {
253: subagent.close(session, AgentXProtocol.REASON_SHUTDOWN);
254: } catch (IOException ex) {
255: ex.printStackTrace();
256: }
257: }
258: }
259: }
|