[SNMP4J] Unnecessary SNMP retries after a response has been received ?

k j janssk1 at hotmail.com
Sun Mar 5 19:06:41 CET 2006


A small program to show the behaviour:

import junit.framework.TestCase;
import org.snmp4j.*;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.log.Log4jLogFactory;
import org.snmp4j.log.LogFactory;
import org.snmp4j.mp.MPv1;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.DefaultPDUFactory;

import javax.resource.ResourceException;
import java.io.IOException;
import java.net.InetAddress;

public class Snmp4JTest extends TestCase {

    private static final OctetString HELLO = new OctetString("hello");

    /**
     * Sends one get request to a daemon. Daemon reacts with a delay of 1.5 
seconds. Client
     * is configured with retry 9 (just to show the issue) and timeout 1 
second.
     * The test shows that as soon as one retry is send, all retries are 
send, even if the
     * response is received after the first retry.
     */
    public void testSnmp4jRetryBehavior() throws ResourceException, 
IOException, InterruptedException {

        LogFactory.setLogFactory(new Log4jLogFactory());
        int freePort = 23454;

        //INIT server
        UdpAddress udpAddress = new 
UdpAddress(InetAddress.getByName("127.0.0.1"), freePort);
        DefaultUdpTransportMapping defaultUdpTransportMapping = new 
DefaultUdpTransportMapping(udpAddress);
        Snmp daemon = new Snmp(defaultUdpTransportMapping);
        final MyCommandResponder myCommandResponder = new 
MyCommandResponder();
        myCommandResponder.setSleepBeforeSendingResponse(1500);//force one 
retry..

        daemon.addCommandResponder(myCommandResponder);
        daemon.listen();

        try {

            //INIT client
            DefaultPDUFactory factory = new DefaultPDUFactory();
            MessageDispatcher mtDispatcher = new MessageDispatcherImpl();
            mtDispatcher.addMessageProcessingModel(new MPv1());
            Snmp snmpClient = new Snmp(mtDispatcher, new 
DefaultUdpTransportMapping());
            snmpClient.listen();

            //Create Request
            Target target = new CommunityTarget(udpAddress, new 
OctetString("public"));
            target.setRetries(9);
            target.setTimeout(1000);
            PDU pdu = factory.createPDU(target);
            pdu.setType(PDU.GET);
            pdu.addAll(new VariableBinding[]{new VariableBinding(new 
OID("1.2"))});

            // Send the request
            ResponseEvent event = snmpClient.send(pdu, target);
            PDU response = event.getResponse();
            assertEquals(HELLO, response.get(0).getVariable());
            System.out.println("Received response: " + response);
            Thread.sleep(12000);//sleep for a while..
        } finally {
            daemon.close();
        }

        //server should have received only two requests (request + one 
retry)
        assertEquals(2, myCommandResponder.getProcessCount());

    }

    private class MyCommandResponder implements CommandResponder {
        private long m_sleepBeforeSendingResponse = 0;
        private int m_processCount;

        public MyCommandResponder(){
        }

        public void setSleepBeforeSendingResponse(long 
sleepBeforeSendingResponse) {
            m_sleepBeforeSendingResponse = sleepBeforeSendingResponse;
        }

        public int getProcessCount() {
            return m_processCount;
        }

        public void processPdu(CommandResponderEvent vEvent) {
            PDU pdu = vEvent.getPDU();
            int pduType = pdu.getType();
            System.out.println("Process PDU: " + pdu);
            if (pduType == PDU.GET) {
                m_processCount++;
                ((VariableBinding) 
pdu.getVariableBindings().get(0)).setVariable(HELLO);
            }
            try {
                Thread.sleep(m_sleepBeforeSendingResponse);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            pdu.setErrorIndex(0);
            pdu.setErrorStatus(0);
            pdu.setType(PDU.RESPONSE);
            try {
                
vEvent.getMessageDispatcher().returnResponsePdu(vEvent.getMessageProcessingModel(),
                        vEvent.getSecurityModel(), vEvent.getSecurityName(),
                        vEvent.getSecurityLevel(), pdu, 
vEvent.getMaxSizeResponsePDU(), vEvent.getStateReference(),
                        null);
            } catch (MessageException e) {
                throw new RuntimeException(e);
            }
        }
    }
}





More information about the SNMP4J mailing list