Multi Threaded Trap Receiver using SNMP4J
The entry briefly touched upon creating a multithreaded Trap receiver using SNMP4J. This is based on example shipped with SNMP4J
Pre-requisite
- SNMP4J
- Log4j
Structure
For complete source have a look at the class org.snmp4j.test. MultiThreadedTrapReceiver.java shipped with SNMP4J distribution
Logical structure of the program
- Create Socket for accepting Traps
- Create a Thread pool to process PDU’s
- Process the Traps
Let’s get into the code
Lets address the Listener creation steps
threadPool = ThreadPool.create("Trap", 2); dispatcher = MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl()); "udp:0.0.0.0/162")); TransportMapping transport; if (listenAddress instanceof UdpAddress) { transport = new DefaultUdpTransportMapping((UdpAddress)listenAddress); } else { transport = new DefaultTcpTransportMapping((TcpAddress)listenAddress); } snmp = new Snmp(dispatcher, transport); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1()); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c()); snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3()); USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0); SecurityModels.getInstance().addSecurityModel(usm); snmp.listen(); }
Here we see that we have created Transport mapping to Listener on port 162. Next we add all three Message processing models, so that we can process Traps received from all three versions of SNMP (V1, V2C and V3). For SNMPv3, we add a Security model.
That’s it done. We listen and process the traps.
The default implementation of processPdu() in this class, just dumps some statistics on the output.
Customization’s
Let’s see what all can we do with this default example
- Set only the SNMP version you want to support
- Customize the Security Model for SNMP V3
- The whole logic lies on processPDU(). You can take complete control of how to process the message and subsequent processing of the message like dumping it to database etc.

Yeah that’s great – multi-threaded. You should point out though that if you want to guarantee processing of the traps in the order they were received (for example, if you are monitoring transitions in state which is what Traps are all about…), this approach is not recommended. Why? Because, when processing the traps via a threadpool or similar concurrent fashion, you cannot guarantee they will be processed in the order they were received. Rather, we would only be assuming they will be processed in the order they are received due to the length of time between each trap being received being large enough under normal operation such that the probability of processing the second trap before the first becomes almost nill. However this is still only an assumption. When freak network behavior occurs, as is common during large outages when floods of traps are being generated, this assumption often leads to unpredictable results (and at a moment when the network needs the solution to be most accurate..).
Hi,
Below is my complete code. I am able to receive the traps with security level “NOAUTH_NOPRIV” but I do not get any trap in case of “AUTH_NOPRIV” and “AUTH_PRIV” security level. Assist me in case something is missed..
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Vector;
import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.AuthMD5;
import org.snmp4j.security.PrivDES;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
public class SnmpServer implements CommandResponder {
private MultiThreadedMessageDispatcher dispatcher;
private Snmp snmp = null;
private Address listenAddress;
private ThreadPool threadPool;
private void init() throws UnknownHostException, IOException {
threadPool = ThreadPool.create(“Trap”, 2);
dispatcher = new MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl());
listenAddress = new UdpAddress(“localhost/162″);
TransportMapping transport;
transport = new DefaultUdpTransportMapping((UdpAddress) listenAddress);
snmp = new Snmp(dispatcher, transport);
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
final USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
final String userName = “anuj”;
final String authenticationPwd = “temptemptemptemp”;
final String privacyPwd = “temptemptemptemp”;
final byte[] localEngineId = MPv3.createLocalEngineID();
//Add user to the USM
snmp.getUSM().addUser(
new OctetString(userName),
new OctetString(localEngineId),
new UsmUser(new OctetString(userName), AuthMD5.ID, new OctetString(authenticationPwd), PrivDES.ID,
new OctetString(privacyPwd), new OctetString(localEngineId)));
snmp.listen();
}
public void run() {
try {
init();
snmp.addCommandResponder(this);
} catch (final Exception ex) {
ex.printStackTrace();
}
}
@Override
public synchronized void processPdu(final CommandResponderEvent respEvnt) {
if (respEvnt != null && respEvnt.getPDU() != null) {
final Vector recVBs = respEvnt.getPDU().getVariableBindings();
for (int i = 0; i < recVBs.size(); i++) {
final VariableBinding recVB = recVBs.elementAt(i);
System.out.println(recVB.getOid() + " : " + recVB.getVariable());
}
}
}
public static void main(final String[] args) {
final SnmpServer server = new SnmpServer();
server.run();
}
}
Thanks
Anuj
@Anuj – I am afraid I dont have a solution for you. This is with SNMPv3 and its been very very long since I worked with SNMP.
I agree. If ordered processing is a need, then we need something like OrderedThreadPoolExecutor http://mina.apache.org/report/trunk/xref/org/apache/mina/filter/executor/OrderedThreadPoolExecutor.html