Java Dynamic Management Kit 4.0 Tutorial

Sending Traps

The simple SNMP agent application also demonstrates how the agent can send traps. The customized class IfEntryImpl in the example directory extends the IfEntry class generated by mibgen in order to provide a method that switches the IfOperStatus variable and sends a trap. This is an example of customization of the generated code: some agent-side entity will switch the operation status, the MIB variable will be updated and a trap will be sent to SNMP managers.

The IfEntryImpl.java file provided in the example directory contains the code for sending the trap through the SNMP adaptor.


Example 7-2 Sending a Trap in the IfEntryImpl Class

public void switchifOperStatus() {
    // implements the switch and then calls sendTrap indirectly
    [...]
}

// Method called after the variable has been switched
// Should be called with generic==2 (up) or 3 (down or testing)
public void sendTrap(int generic) {

    SnmpAdaptorServer snmpAdaptor = null;

    // Retrieve the reference of the SNMP protocol adaptor through
    // the static method of the Agent or StandAloneSnmpAgent class
    snmpAdaptor = Agent.getSnmpAdaptor();
    if (snmpAdaptor == null) {
        snmpAdaptor = StandAloneSnmpAgent.getSnmpAdaptor();
    }
    if (snmpAdaptor == null) {
        return;
    }

    Vector varBindList = new Vector();

    // IfIndex is the index of the current If table entry
    SnmpOid oid1 = new SnmpOid("1.3.6.1.2.1.2.2.1.1." + IfIndex);
    SnmpInt value1 = new SnmpInt(IfIndex);
    SnmpVarBind varBind1 = new SnmpVarBind(oid1, (SnmpValue) value1);

    varBindList.addElement(varBind1);

    try {
        snmpAdaptor.sendV1Trap(generic, 0, varBindList);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Since the sendTrap method runs in a different thread, it needs to get a reference to the SNMP adaptor instance. Here we call the static methods of our two possible agent implementations. This code is specific to these agents and is only an example of how to retrieve this information.

Since our example has no real operation status, we invent the LinkTrapGenerator class which will switch the status periodically. It is an MBean which contains a thread which loops endlessly. The interval period between traps and the index of the table entry can be modified through the MBean's attributes.


Example 7-3 The Thread of the Link Trap Generator

public void run() {
    while (true) {
        try {
            sleep(interval);
        } catch (Exception e) {
            e.printStackTrace();
        }
        sendTrap();
    }
}

public void sendTrap() {
    // get the entry whose status we will switch
    IfEntryImpl ifEntryImpl = InterfacesImpl.find(ifIndex);
    if (ifEntryImpl == null) {
        errors++;
        return;
    }
    ifEntryImpl.switchifOperStatus();
    successes++;
}

To start the trap generator, the example application creates a LinkTrapGenerator MBean. During its registration, the MBean starts the thread, sending a trap every two seconds by default.


Example 7-4 Starting the Trap Generator Example

// Create a LinkTrapGenerator (specify the ifIndex in the object name)
//
String trapGeneratorClass = "LinkTrapGenerator";
int ifIndex = 1;
trapGeneratorObjName = new ObjectName("trapGenerator:class=" +
    trapGeneratorClass + ",ifIndex=" + ifIndex);
server.createMBean(trapGeneratorClass, trapGeneratorObjName);

In order for an SNMP adaptor to send traps to remote managers, you must define the trap group in the access control list (ACL) file. This group of community definitions lists all of the hosts to which the agent will send every trap. A community definition associates a community name with a list of hosts specified either by their hostname or by their IP address. All hosts in a community will receive the trap in a packet identified by the community name.


Note -

Since access control and trap recipients share the same file, you must fully define the access control when you want to send traps.


See "Access Control Lists (ACL)" for a formal definition of the trap group and instructions for defining the ACL file when starting the agent. In this example we provide the following template:


Example 7-5 Sample jdmk.acl File

acl = {
 {
 communities = public
 access = read-only
 managers = yourmanager
 }
 {
 communities = private
 access = read-write
 managers = yourmanager
 } 
} 

trap = {
  {
  trap-community = public
  hosts = yourmanager
  }
}

Traps are sent to the port specified by the TrapPort attribute of the SnmpAdaptorServer MBean. In our simple agent, we set the trap port to 8086, but this can be changed at any time by a custom MIB implementation or a management application.

If the ACL file is not defined, or if the trap group is empty, the default behavior of the SNMP adaptor is to send a trap to the localhost.

Traps in the Agent Example

Before launching the SNMP agent again, edit the jdmk.acl file to replace the occurrences of yourmanager with the name of a host running an SNMP manager. Then copy this file to the configuration directory:


$ cp jdmk.acl installDir/SUNWjdmk/jdmk4.0/JDKversion/etc/conf

If you don't have an SNMP manager or a second host, don't copy the ACL file. In the absence of the trap-community definitions, the traps will be addressed to the trap port on the local host. And even if no manager is running, we can still see the agent sending the traps. See "SNMP Trap Handler" in the SNMP manager topic for details about receiving traps.

Then launch the simple agent example again:


$ java -classpath classpath Agent
Interacting with the Trap Generator
  1. Access this agent's HTML adaptor by pointing a web browser to the following URL: http://localhost:8082/. Click on the class=LinkTrapGenerator,ifIndex=1 MBean in the trapGenerator domain.

    Through the HTML adaptor, you can see the MBean representing the trap generator object. You can modify its attributes to change the table entry that it operates on and to change the interval between traps.

  2. Change the trap interval to 10000 so that traps are sent every 10 seconds.

  3. Go back to the agent view and click on the ifEntry.ifIndex=1 MBean in the ifTable domain. Set the reload period to 10, and click the "Reload" button.

    You should see the effect of the trap generator which is to switch the value of the IfOperStatus variable. It is our implementation of the table entry which sends a trap when this status is changed.

  4. Go back to the agent view and click on the name=Snmp MBean in the RFC1213_MIB domain. Scroll down to see the SnmpOutPkts and SnmpOutTraps variables.

    These variables should be the only non zero values, if no manager has connected to the SNMP agent. The Snmp group shows information about the SNMP adaptor, and we can see how many traps have been sent since the agent was launched.

  5. Type "Control-C" when you are done interacting with the agent.

The LinkTrapGenerator MBean is not manageable through the SNMP adaptor because it is not part of any MIB. It is an example of another MBean providing some control of the SNMP agent, and this control can be exercised by other managers connecting through other protocols. This shows that designing an SNMP agent application involves both the implementation of the MIB functionality and, if desired, the implementation of other dynamic controls afforded by the JMX architecture and the services of the Java Dynamic Management Kit.