Java Dynamic Management Kit 4.1 Tutorial

Sending Traps

Agents can send unsolicited event reports to management application by using traps. The SNMP protocol adaptor can send both v1 and v2 traps, the difference being in the format of the corresponding PDU. Traps in the SNMP specification are not acknowledged by the management application, so agents do not know if traps are received.

Inform requests are acknowledged event reports, but they are sent by entities acting in a manager role, according to RFC 1905. Therefore, the SNMP inform requests are implemented in the SNMP manager API of the Java Management extensions: see "The Inform Request Example" for more information.

Our 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: an 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 12-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;
    }

    // Create the variable bindings to send in the trap
    Vector varBindList = new Vector();

    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();
    }
}

As 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.

In order to simulate a live 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 number of the table entry can be modified through the MBean's attributes.


Example 12-3 The Thread of the Link Trap Generator

public void run() {
    int remainingTraps = nbTraps;
    while ((nbTraps == -1) || (remainingTraps > 0)) {
        try {
            sleep(interval);
        } catch (Exception e) {
            e.printStackTrace();
        }
        triggerTrap();
        remainingTraps--;
    }
}

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

To run the trap generator, the example application instantiates and registers a LinkTrapGenerator MBean. During its registration, this MBean starts the thread, sending a trap every two seconds by default.


Example 12-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=LinkTrapGenerator,ifIndex=" + ifIndex);
LinkTrapGenerator trapGenerator = new LinkTrapGenerator(nbTraps);
server.registerMBean(trapGenerator, trapGeneratorObjName);
[...]

trapGenerator.start();

Specifying the Trap Destination

There are several methods in the SNMP protocol adaptor for sending traps to remote managers. They differ in their method signatures, depending upon whether or not you need to specify the destination host. When no host is specified, the SNMP protocol adaptor relies on the trap group definition in access control lists (ACL), as described below.

In all cases, traps are sent to the port specified by the current value of the TrapPort attribute on 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.

Using an ACL Trap Group

This is the method that was used in Example 12-2 to send traps, along with its v2 equivalent (see the Javadoc API for a description of the parameters):

Using these methods, you must first define the trap group in an access control list. See "Access Control Lists (ACL)" for a formal definition of the trap group and instructions for defining the ACL file when starting the agent. By default, these lists are file-based, but you may implement other mechanisms, as described in "Custom Access Control".

In this example we provide the following template file:


Example 12-5 Trap Group of the jdmk.acl File

acl = {
  ...
}

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

The trap group lists all of the hosts to which the SNMP protocol adaptor 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 definition will receive the trap in a PDU 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 using the ACL mechanism.


Given this definition, traps will be sent to a host called yourmanager, and the community string of the trap PDU would contain the value public. By adding community definitions to this file, you can specify all hosts which will receive traps along with the community string for each host or group of hosts.

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

Specifying the Hostname Directly

The other two methods of the SNMP protocol adaptor, one for each trap version, let you send a trap to a specified recipient:

In both cases, these methods take an address and a community string, in addition to the version-specific trap information. The address is an InetAddress object which is usually instantiated by its static methods getLocalHost or getByName. The latter method returns a valid InetAddress object when given a string representing a hostname or IP address.

The cs parameter is the community string, a name that the agent and manager exchange to help identify one another. The string given will be used as the community when sending the trap PDU.

Either one of these methods sends a trap to a single manager using a single community string. The ACL trap group mechanism is better suited to sending traps to multiple managers, though it requires the setup of a trap group. Note that even if a trap group is in use, the two methods above only send one trap to the specified host address.

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. You then have two options for launching the simple agent:

In these commands, nbTraps is the number of traps that the agent will send. Set it to a small integer to avoid too much output. If you omit this parameter, traps will be sent continuously.

If you don't have an SNMP manager or a second host, don't copy the ACL file or specify it as a property. 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.

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 finished 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.