Java Dynamic Management Kit 4.2 Tutorial

The SNMP Proxy Implementation

The SNMP proxy is an extension of the abstract SnmpMibAgent which implements all of its abstract methods and can be instantiated. The proxy implements a synchronous SNMP manager that forwards the requests to the sub-agent. It does some error fixing for SNMPv2 requests but doesn't claim to be extensive. The SNMP proxy implementation is only provided as an example and Sun Microsystems makes no claim as to its suitability for any particular usage.


Note -

The implementation of the example proxy does not support the getBulk request nor the check method.


Before it is used, the proxy must be initialized with the hostname and port of the sub-agent. It uses this information to create the corresponding SNMP parameter object and SNMP peer object. It then creates three SNMP sessions:


Example 19-3 Internal Initialization of the SNMP Proxy

public void initializeProxy(String h, int p,
                            String strOid, String name)
    throws UnknownHostException, SnmpStatusException {
	
    host = h;
    port = p;
    oid = strOid;
    mibName = name;
	
    // Initialization for SNMP v1 protocol.
    //
    SnmpParameters paramsV1 = new SnmpParameters("public", "private");
    paramsV1.setProtocolVersion(SnmpDefinitions.snmpVersionOne);
    SnmpPeer peerV1 = new SnmpPeer(host, port);
    peerV1.setSnmpParam(paramsV1);
    sessionV1 = new SnmpSession("SnmpMibAgentImpl session V1");
    sessionV1.setDefaultPeer(peerV1);

    // Using SNMP v1 protocol, errors are not fixed and
    // forwarded to the manager
    sessionV1.snmpOptions.setPduFixedOnError(false);

    // Initialization for SNMP v2 protocol.
    //
    SnmpParameters paramsV2 = new SnmpParameters("public", "private");
    paramsV2.setProtocolVersion(SnmpDefinitions.snmpVersionTwo);
    SnmpPeer peerV2 = new SnmpPeer(host, port);
    peerV2.setSnmpParam(paramsV2);
    // If we get an error, we don't retry the request using SNMP v2,
    // but we try the request using SNMP v1
    peerV2.setMaxRetries(0);
    sessionV2 = new SnmpSession("SnmpMibAgentImpl session V2");
    sessionV2.setDefaultPeer(peerV2);
    // Using SNMP v2 protocol, the error is fixed
    //
    sessionV2.snmpOptions.setPduFixedOnError(true);

    // Initialization for SNMP v2 protocol simulated
    // using SNMP v1 protocol
    //
    sessionV2WithV1 = new SnmpSession("SnmpMibAgentImpl session V2 with V1");
    sessionV2WithV1.setDefaultPeer(peerV1);
    // Simulating SNMP v2 with SNMP v1 protocol, the error is fixed.
    //
    sessionV2WithV1.snmpOptions.setPduFixedOnError(true);
}

The proxy exposes the public methods for handling requests, and then implements this algorithm for reducing errors by internal methods. Roughly, the proxy must determine the version of the incoming request and handle it as promised. Version 1 requests that timeout or fail are dropped, and v2 requests that timeout or fail are retried as v1 requests. Here we only show the code for implementing the get method.


Example 19-4 Implementing a get Request in the Proxy

// the exposed method
public void get(SnmpMibRequest inRequest) throws SnmpStatusException {
			  	  	  
    java.lang.System.out.println(
        "Proxy: Sending get request to SNMP sub-agent on " + 
            host + " using port " + port);

    // Get the protocol version
    final int version = inRequest.getVersion();

    // Request using SNMP v1 protocol
    if (version == SnmpDefinitions.snmpVersionOne) {
        get(inRequest, version, sessionV1);
    }

    // Request using SNMP v2 protocol.
    if (version == SnmpDefinitions.snmpVersionTwo) {
        get(inRequest, version, sessionV2);
    }
}

// the internal implementation
private void get(SnmpMibRequest inRequest, int version, SnmpSession session)
    throws SnmpStatusException {
	
    // Construction of the SnmpVarBindList for the request.
    final SnmpVarbindList varbindlist = 
        new SnmpVarbindList("SnmpMibAgentImpl varbind list",
                             inRequest.getSubList() );

    SnmpRequest request = null;
    try {
        request = session.snmpGet(null, varbindlist);
    } 
    catch (SnmpStatusException e) {
        throw new SnmpStatusException(SnmpDefinitions.snmpRspGenErr, 0);
    }
    java.lang.System.out.println("\nRequest:\n" + request.toString());
	
    boolean completed = request.waitForCompletion(10000);
    if (completed == false) {

        // If the completion failed using SNMP v1, we give up
        if (version == SnmpDefinitions.snmpVersionOne) {
            java.lang.System.out.println(
                "\nRequest timed out: check reachability of sub-agent.");
            return;
        }

        // If the completion failed using SNMP v2, we try again using v1

        if (version == SnmpDefinitions.snmpVersionTwo) {
            get(inRequest, SnmpDefinitions.snmpVersionOne, sessionV2WithV1);
            return;
        }
    }

    // Check the request result
    int errorStatus = request.getErrorStatus();
    int errorIndex = request.getErrorIndex() + 1;
    if (errorStatus != SnmpDefinitions.snmpRspNoError) {

        // If there is an error status using v1, we throw an exception
        if (version == SnmpDefinitions.snmpVersionOne) {
            throw new SnmpStatusException(errorStatus, errorIndex);
        }
        // If there is an error status using v2, we try again using v1
        if (version == SnmpDefinitions.snmpVersionTwo) {
            get(inRequest, SnmpDefinitions.snmpVersionOne, sessionV2WithV1);
            return;
        }
    }
    // Get and display the returned values
    final SnmpVarbindList result = request.getResponseVarBindList();
    java.lang.System.out.println("\nResult: \n" + 
                                 result.varBindListToString());

    // Update the list parameter with the result
    // The varbinds in the result list are expected to be in the same
    // order as in the request, so we can safely loop sequentially
    // over both lists.
    Enumeration l = list.elements();
    for (Enumeration e = result.elements(); e.hasMoreElements();) {
        SnmpVarBind varres = (SnmpVarBind) e.nextElement();
        SnmpVarBind varbind = (SnmpVarBind) l.nextElement();
        varbind.value = varres.value;
    }
}

The complete list of methods that a proxy must implement are the same as for MIB MBeans represented by instances of the SnmpMib class: