The asynchronous SNMP manager lets you handle more requests in the same amount of time because the manager is not blocked waiting for responses. Instead it creates a request handler object which runs as a separate thread and processes several responses concurrently. Otherwise, the initialization of peers, parameters, sessions and options is identical to that of a synchronous manager.
In this example application, we also demonstrate how to implement and enable a trap listener for the traps sent by the agent. First we need to instantiate an SnmpEventReportDispatcher object. Then we add our listener implementation through its addEventReportListener method, and finally we start its thread. Trap listeners can be implemented in any manager using the SNMP manager API, not only asynchronous managers.
// read the command line parameters String host = argv[0]; String port = argv[1]; // Use the OidTable generated by migen when compiling MIB II. SnmpOidTableSupport oidTable = new RFC1213_MIBOidTable(); // Sample use of the OidTable. SnmpOidRecord record = oidTable.resolveVarName("udpLocalPort"); java.lang.System.out.println( "AsyncManager::main: variable = " + record.getName() + " oid = " + record.getOid() + " type = " + record.getType()); // Initialize the SNMP Manager API. SnmpOid.setSnmpOidTable(oidTable); // Create an SnmpPeer object for representing the agent SnmpPeer agent = new SnmpPeer(host, Integer.parseInt(port)); // Create parameters for communicating with the agent SnmpParameters params = new SnmpParameters("public", "private"); agent.setSnmpParam(params); // Build the session and assign its default peer SnmpSession session = new SnmpSession("AsyncManager session"); session.setDefaultPeer(agent); // Create a listener and dispatcher for SNMP traps: // SnmpEventReportDispatcher will run as a thread and // listens for traps in UDP port = agent port + 1 SnmpEventReportDispatcher trapAgent = new SnmpEventReportDispatcher(Integer.parseInt(port)+1); // TrapListenerImpl will receive a callback // when a valid trap PDU is received. trapAgent.addEventReportListener(new TrapListenerImpl()); new Thread(trapAgent).start(); // Build the list of variables to query SnmpVarbindList list = new SnmpVarbindList("AsyncManager varbind list"); list.addVariable("sysDescr.0"); // Create a simple implementation of an SnmpHandler. AsyncRspHandler handler = new AsyncRspHandler(); // Make the SNMP walk request with our handler SnmpRequest request = session.snmpWalkUntil( handler, list, new SnmpOid("sysServices")); // Here you could do whatever processing you need. // In the context of the example, we are just going to wait // 5 seconds so that we can receive trap PDUs. Thread.sleep(5000); // Here the handle should have resume the activity of the thread // so the request is over java.lang.System.out.println("done"); // End the session properly and we're done. // session.destroySession(); java.lang.System.exit(0); |
In this example, the manager performs an snmpWalkUntil request which will give a response for each variable that it gets. The response handler will be called every time to process the response.
A trap handler for the SNMP manager is an object that implements the SnmpEventReportListener interface in the javax.management.snmp.manager package. When this object is bound as a listener of an SnmpEventReportDispatcher object, its methods will be called to handle trap PDUs.
The interface defines two methods, one for processing SNMPv1 traps and the other for SNMPv2 traps. Trap PDUs have already been decoded by the dispatcher: the v1 handler must process an SnmpPduTrap object, and the v2 handler must process an SnmpPduRequest object representing a trap. In our implementation, we are only interested in v1 traps, and we just print out the trap information fields.
public class TrapListenerImpl implements SnmpEventReportListener { public void processSnmpTrapV1(SnmpPduTrap trap) { java.lang.System.out.println( "NOTE: TrapListenerImpl received trap :"); java.lang.System.out.println( "\tGeneric " + trap.genericTrap); java.lang.System.out.println( "\tSpecific " + trap.specificTrap); java.lang.System.out.println( "\tTimeStamp " + trap.timeStamp); java.lang.System.out.println( "\tAgent address " + trap.agentAddr.stringValue()); } public void processSnmpTrapV2(SnmpPduRequest trap) { java.lang.System.out.println("NOTE: Trap V2 ignored"); } } |
A request handler for an asynchronous manager is an implementation of the SnmpHandler interface. When a handler object is associated with a request, its methods are called when the agent returns an answer or fails to return an answer. In these methods, you implement whatever actions you wish for processing the results of a request.
The timeout used by the request handler is the one specified by the SnmpPeer object representing the agent. The handler is also called to process any errors caused by the request in the session. This insures that the manager application is never interrupted after issue a request.
public class AsyncRspHandler implements SnmpHandler { // Empty constructor public AsyncRspHandler() { } // Called when the agent responds to a request public void processSnmpPollData( SnmpRequest request, int errStatus, int errIndex, SnmpVarbindList vblist) { java.lang.System.out.println( "Processing response: " + request.toString()); java.lang.System.out.println( "errStatus = " + SnmpRequest.snmpErrorToString(errStatus) + " errIndex = " + errIndex); // Check if a result is available. if (request.getRequestStatus() == SnmpRequest.stResultsAvailable) { // Extract the result for display SnmpVarbindList result = request.getResponseVbList(); java.lang.System.out.println( "Result = " + result.vbListToString()); } } // Called when the agent fails to respond to a request public void processSnmpPollTimeout(SnmpRequest request) { java.lang.System.out.println( "Request timed out: " + request.toString()); if (request.getRequestStatus() == SnmpRequest.stResultsAvailable) { // The result is empty and will display an error message SnmpVarbindList result = request.getResponseVbList(); java.lang.System.out.println( "Result = " + result.vbListToString()); } } // Called when there is an error in the session public void processSnmpInternalError(SnmpRequest request, String errmsg) { java.lang.System.out.println( "Session error: " + request.toString()); java.lang.System.out.println("Error is: " + errmsg); } } |
These example applications do not cover the security features in the SNMP manager. However, security can be implemented at the message level with a custom PDU factory, in the same way that it is for SNMP agents (see "Message-Level Security"). The hook for using your own implementation of the PDU factory is the setPduFactory method of an SnmpPeer instance.
Message-level security can be implemented in this manner in both synchronous and asynchronous managers. See the Java Management Extensions SNMP Manager API document and its Javadoc API for more details.
If you have not done so already, launch the simple SNMP agent in examplesDir/Snmp/Agent, after making sure that no other agent is running on port 8085. The manager also requires the same OID table description that we generated for the synchronous manager. See "Running the SimpleManager Example" for instructions to do this.
Here we give commands for launching the agent and manager from the same terminal window running the Korn shell. On the Windows NT platform, you will have to launch each application in a separate window. We redirect the output messages since this agent sends traps periodically.
$ cd examplesDir/Snmp/Agent $ java -classpath classpath Agent > Agent.out & |
Now we can launch the manager application to connect to this agent. If you wish to run the manager on a different host, replace localhost with the name of the machine where you launched the agent.
$ cd examplesDir/Snmp/Manager $ java -classpath classpath AsyncManager localhost 8085 |
You should then see the output of the SnmpWalkUntil request: the response handler method is called for each variable that is returned. Since this manager also has a trap listener running in a different thread, the output may be interspersed with trap reports.
When you are done with the agent, don't forget to stop it with the following commands:
$ fg java [...] Agent > agent.out <Control-C> ^C$ rm examplesDir/Snmp/Agent/agent.out |