Java Dynamic Management Kit 5.1 Tutorial

18.1 Simple SNMP Tables

SNMP allows for the structuring of Management Information Base (MIB) variables into logical tables, in which the variables are organized into rows and columns. Java DMK allows for the dynamic addition of rows to the tables that conform to the RowStatus convention defined by SNMPv2. Java DMK also allows you to change the values of existing rows. An example of the use of tables in the Java DMK SNMP API is found in the directory examplesDir/current/Snmp/Rowstatus.

This example shows how to create rows remotely in an SNMP agent from an SNMP manager application, in tables that follow the RowStatus convention. It does this by enabling remote entry creation in the tables and by sending the appropriate requests to create or destroy rows in the table. The RowStatus example also shows how to replace the generated skeletons for SNMP groups, tables, and entries with your own customized classes, so that the customized entry class is instantiated when a remote SNMP manager requests the creation of a row in a table managed by a RowStatus variable.

This example is built around a small SNMP MIB called DEMO-MIB which contains one group, Demo, and one table, TableDemoTable. Before you can proceed with the example, you need to generate this MIB and its associated classes, by using the mibgen compiler supplied with Java DMK. For details of the mibgen compiler, see the Java Dynamic Management Kit 5.1 Tools Reference Guide.

To Generate the DEMO-MIB

The example MIB is contained in the configuration file mib_demo.txt, which is found in examplesDir/current/Snmp/Rowstatus. You should run the example from within this directory.

  1. Ensure that your PATH environment variable knows where to find mibgen.

    In a default installation, mibgen is found in installDir/bin.

  2. Run the mibgen compiler.


    $ mibgen -d . mib_demo.txt
    

    You see that mibgen has generated the following Java classes.

    • Demo, which implements the Demo group.

    • DemoEntry, which defines an MBean that provides variables to serve as entries in the table, and specifies the operations that can be performed on this MBean.

    • DemoEntryMBean, which represents the remote management interface for the DemoEntry MBean.

    • DemoEntryMeta, which constructs the SNMP metadata for the DemoEntry MBean.

    • DemoMBean, which represents the remote management interface for the Demo MBean.

    • DemoMeta, which constructs the SNMP metadata for the DemoEntry MBean.

    • DEMO_MIB, which defines the behavior of this SNMP MIB.

    • DEMO_MIBOidTable, which contains the metadata definitions for DEMO-MIB.

    • DemoTableMeta, which constructs the metadata definitions for the SNMP table.

    • EnumDemoTableRowStatus, which provides an enumerated integer value that informs you of the status of a table row.

    • TableDemoTable, which constructs the SNMP table, making each row from DemoEntry objects using SNMP SET operations, and then registers the rows in the Java DMK MBean server.

To be able to modify the classes dynamically, we must take the classes generated by the mibgen compiler and extend them accordingly in a series of custom classes. These customized classes are provided in the examplesDir/current/Snmp/Rowstatus directory.


Example 18–1 Adding Entries to Tables

public class TableDemoTableImpl extends TableDemoTable {
    public TableDemoTableImpl(SnmpMib myMib, DemoImpl myGroup) {
        super(myMib);
	       this.myGroup = myGroup;
    }
    public TableDemoTableImpl(SnmpMib myMib, MBeanServer server, 
			      DemoImpl myGroup) {
       super(myMib,server);
	       this.myGroup = myGroup;
    }

    public void removeEntryCb(int pos, SnmpOid row, ObjectName name,
                Object entry, SnmpMibTable meta)
            throws SnmpStatusException {
       super.removeEntryCb(pos,row,name,entry,meta);
	      myGroup.removeRowCb();
    }
    public void addEntryCb(int pos, SnmpOid row, ObjectName name, 
			         Object entry, SnmpMibTable meta) 
	          throws SnmpStatusException {
	      super.addEntryCb(pos,row,name,entry,meta);
	      myGroup.addRowCb();
    }
    public Object createDemoEntryMBean(SnmpMibSubRequest req,
                SnmpOid rowOid, int depth, ObjectName entryObjName,
                SnmpMibTable meta, Integer  aDemoTableIndex)
            throws SnmpStatusException  {

        DemoEntryImpl entry = new DemoEntryImpl(theMib);
        entry.DemoTableIndex = aDemoTableIndex;
        return entry;
    }
    private DemoImpl myGroup;

}

The TableDemoTableImpl class shown in Example 18–1 subclasses the TableDemoTable class generated by mibgen from the mib_demo.txt file. It customizes the SnmpTableSupport addEntryCb and removeEntryCb methods, adding new functionality not originally provided by TableDemoTable. The addEntryCb and removeEntryCb callback methods are called from the SNMP runtime when a row is added to or removed from the table. The removedRowCb and addRowCb methods are callback methods that maintain a local row counter, DemoInteger. However, the fact that they maintain a row counter is merely for the sake of this example. The addEntryCb and removeEntryCb callback methods could perform any operation the developer chooses to implement, such as emitting notifications, for example.

The most important method of the TableDemoTableImpl class is createDemoEntryMBean. The createDemoEntryMBean method inTableDemoTableImpl overrides the one defined by TableDemoTable to implement DemoEntryImpl instead of the skeletal DemoEntry.

The DemoImpl group, shown in Example 18–2, overrides the constructors defined by the Demo group, to allow remote creation of rows in a DemoTable.


Example 18–2 Permitting Remote Creation of Rows

public class DemoImpl extends Demo {
    public DemoImpl(SnmpMib myMib) {
	       super(myMib);
		    DemoTable = new TableDemoTableImpl(myMib, this);
       DemoTable.setCreationEnabled(true);
    }
    public DemoImpl(SnmpMib myMib, MBeanServer server) {
	        super(myMib,server);
        DemoTable = new TableDemoTableImpl(myMib, server, this);
	        DemoTable.setCreationEnabled(true);
    }
    public void addRowCb() {
	        DemoInteger = new Integer(DemoInteger.intValue() + 1);
    }
    public void removeRowCb() {
	        DemoInteger =  new Integer(DemoInteger.intValue() - 1);
    }
}

As you can see, as well as setting the SnmpTableSupport method setCreationEnabled value to true, DemoImpl defines the addRowCb and removeRowCb callback methods called by TableDemoTableImpl. For each row added or deleted, addRowCb and removeRowCb update the value of the DemoInteger counter accordingly. DemoInteger is defined by the Demo class, and counts the number of entries in the demoTable.


Example 18–3 Adding and Deleting Rows from a Remote SNMP Manager

public class Manager {

[...]
        try {
            SnmpOidTableSupport oidTable = new DEMO_MIBOidTable();
            SnmpOid.setSnmpOidTable(oidTable);
            [..]
            EnumRowStatus   createAndGo = new EnumRowStatus("createAndGo");
            EnumRowStatus   destroy     = new EnumRowStatus("destroy");
            
            SnmpVarBindList setList1 = 
                new SnmpVarBindList("Manager SET varbind list");
            SnmpVarBind stringRow1 = 
                new SnmpVarBind(new SnmpOid("demoTableString.1"),
                                new SnmpString("This is row 1"));
            SnmpVarBind statusRow1 = 
                new SnmpVarBind(new SnmpOid("demoTableRowStatus.1"),
                                createAndGo.toSnmpValue());

            setList1.addVarBind(stringRow1);
            setList1.addVarBind(statusRow1);
            
            request = session.snmpSetRequest(null, setList1);
            completed = request.waitForCompletion(10000);
            [...]
            result = request.getResponseVarBindList();
      
            SnmpVarBindList getList = 
                new SnmpVarBindList("Manager GET varbind list");
            getList.addVarBind("demoInteger.0");
            getList.addVarBind("demoTableString.1");
            getList.addVarBind("demoTableRowStatus.1");
            request = session.snmpGetRequest(null, getList);
            completed = request.waitForCompletion(10000);
            [...]
            result = request.getResponseVarBindList();

            SnmpVarBindList setList2 = 
                new SnmpVarBindList("Manager SET varbind list");
            SnmpVarBind statusRow2 = 
                new SnmpVarBind(new SnmpOid("demoTableRowStatus.1"),
                                destroy.toSnmpValue());

            setList2.addVarBind(statusRow2);
            request = session.snmpSetRequest(null, setList2);
            completed = request.waitForCompletion(10000);
            [...]
            result = request.getResponseVarBindList();
            request = session.snmpGetRequest(null, getList);
            completed = request.waitForCompletion(10000);
            result = request.getResponseVarBindList();
            [...]
            session.destroySession();
            java.lang.System.exit(0);
        }
        [...]
    }

The Manager begins by loading the DEMO_MIBOidTable table created by mibgen. After setting up the SNMP peer, session and parameters, the Manager defines the creation and deletion of rows. The table in this example supports the RowStatus variable. The values for columns can be changed by sending SNMP set requests to the index of the row that is to be added or removed. Setting the value of the column that contains the RowStatus variable to createAndGo creates and activates a row for which a value is provided by the set request. Setting the value of the RowStatus column of an existing row you want to delete to destroy, deletes that row.

To Run the SNMP Table RowStatus Example

As stated in To Generate the DEMO-MIB, you must have run mibgen on the mib_demo.txt file before proceeding with this example. Run the example inside the examplesDir/current/Snmp/Rowstatus directory.

  1. Compile the Java classes.


    $ javac -d . *.java
    
  2. Start the Agent.

    Make sure that no agents are already running before you start the Agent.


    $ java Agent
    

    You see confirmation of the creation of the HTML adaptor on port 8082 and the SNMP adaptor on port 8085, and the addition of the DEMO-MIB to the MBean server. You can perform management operations on the Agent using the HTML adaptor, by loading the URL http://localhost:8082/ in a browser.

  3. In another terminal, start the Manager.


    $ java Manager agent-hostname 8085
    

    Where agent-hostname is the name of the machine where the Agent is running. 8085 represents the port number on which the SNMP adaptor is running.

    When you start the Manager, you will be prompted to press Enter to perform the get and set operations to add and delete rows from the demoTable.