Home Implementation Testing Add-Ons > disman API > Smurf > JAX > Schedule-MIB > Tcl Engine > Policy Mgmt Documentation Download Mailinglist People |
The Jasmin Project
Adding WWW-MIB AgentX Sub-Agent Support to Jigsaw
This is an example on how to use the JAX package. It describes the measures necessary to add an SNMP interface to an existing Java application by talking AgentX to a master SNMP agent. The application used in this example is the Jigsaw web server. It has been extended to export some of the Objects defined in RFC 2594 known as the WWW-MIB. While writing this example the UCD-SNMP served as the master agent, but JAX should work with any other AgentX enabled SNMP agent. Preliminaries
The WWW-MIB: Brief OverviewThe WWW-MIB was designed to monitor WWW-services. There are two compliance statements in the MIB definition. The full compliance contains separate tables for all incoming and outgoing requests and for all incoming and outgoing responses and a bucket mechanism to keep detailed statistics about the biggest and most frequently accessed documents. An agent with minimal compliance just has to implement a table of the services and a short summary table. Of course, both are also required for full compliance. In this example we decided to concentrate on the minimal conformance especially to avoid a complex bucket handling. The code is intended to serve as an example and therefore we strive for easy understanding and simplicity, but we also included three additional tables that contain the last documents and the types of requests and responses along with their number, size and timestamps. In order to support this subset of the WWW-MIB the Agent has to keep the following information:
Generating the Java FilesWe use smidump to generate 33 Java class files for the MIB objects in the WWW-MIB:
% smidump -f jax WWW-MIB
As already stated, we do not intend to make a full conforming agent. So we only need fifteen of the files which are used to implement five tables of the WWW-MIB:
The classes that represent an entire table are called
Interfacing with the Jigsaw Code Base
Now lets take a look at the Jigsaw code base to find out where to start the AgentX-threads and gather the information we need.
In Jigsaw the class
The AgentX main object runs in a separate thread
and the
Of course, before calling the
Note that there are two instances of the public void start () throws ServerHandlerInitException { if (!isAClone) { if (jaxMain == null) { jaxMain = new JigAgentX(); jaxMain.start(); } // ... } serviceId = jaxMain.addService(port); }
To distinguish between normal requests and those for the jigadmin
service every public void log (Client client , Request request, Reply reply , int nbytes , long duration) { if ( logger != null ) logger.log (request, reply, nbytes, duration); synchronized (jaxMain) { jaxMain.updateMIB(serviceId, client, request, reply, nbytes, duration); } statistics.updateStatistics(client, request, reply, nbytes, duration); } Implementing the WWW-MIB Objects
The AgentX main class
The table objects of the classes public class JigAgentX extends Thread { // ... public synchronized void updateMIB (int service, Client client, Request request, Reply reply, int nbytes, long duration) // ... public int addService(long port) // ... public void run () { // ... // create the AgentX session connection = new AgentXConnection(host, port); session = new AgentXSession(); connection.openSession(session); // create the MIB tables wstab = new WwwServiceTable(); sumTab = new WwwSummaryTable(); lastTab = new WwwDocLastNTable(); reqTab = new WwwRequestInTable(); replyTab = new WwwResponseOutTable(); // register tables with session object session.addGroup(wstab); session.addGroup(sumTab); session.addGroup(lastTab); session.addGroup(reqTab); session.addGroup(replyTab); // register subtree with master agent registration = new AgentXRegistration(new AgentXOID(value)); session.register(registration); // run until we get interrupted try { while(true) Thread.sleep(90000); } catch (InterruptedException e) {} // ... } }
The The Table of Services
In the public WwwServiceEntryImpl(long wwwServiceIndex, long port) { super(wwwServiceIndex); long tcpOid[] = {1,3,6,1,2,1,27,4,port}; wwwServiceDescription = ((wwwServiceIndex == 1 ) ? System.getProperty("jax.jigadminDesc") : System.getProperty("jax.jigsawDesc") ).getBytes(); wwwServiceContact = (System.getProperty("jax.serviceContact") ).getBytes(); wwwServiceProtocol = new AgentXOID(tcpOid); try { wwwServiceName = ("" + InetAddress.getLocalHost()).getBytes(); } catch (UnknownHostException e) { wwwServiceName = ("Unknown Host").getBytes(); } wwwServiceType = 2; byte timeStamp[] = Util.getTimeStamp(); wwwServiceStartTime = timeStamp; wwwServiceOperStatus = 2; wwwServiceLastChange = timeStamp; }
Strings are passed to the JAX-methods as
The public class Util { public static byte[] getTimeStamp() { char sign = '+'; GregorianCalendar now = new GregorianCalendar(); int offset = (now.getTimeZone()).getRawOffset() / 1000; if (offset < 0) { offset = (-1) * offset; sign = '-'; } return makeDateAndTime(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH), now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE), now.get(Calendar.SECOND), 0, // no deci seconds sign, (offset / 60), (offset % 60) ); } public static byte[] makeDateAndTime(int year, int month, int day, int hour, int min, int sec, int decSec, char directionFromUTC, int hoursFromUTC, int minutesFromUTC) { byte out[] = new byte[11]; out[0] = (byte) (year / 256); out[1] = (byte) (year % 256); out[2] = (byte) (month + 1); out[3] = (byte) day; out[4] = (byte) hour; out[5] = (byte) min; out[6] = (byte) sec; out[7] = (byte) decSec; out[8] = (byte) directionFromUTC; out[9] = (byte) hoursFromUTC; out[10] = (byte) minutesFromUTC; return out; } }
New entries in the public int addService(long port) { WwwServiceEntryImpl wsent; WwwSummaryEntryImpl sumEnt; wsent = new WwwServiceEntryImpl(serviceId, port); sumEnt = new WwwSummaryEntryImpl(serviceId); // add both entries to the global table instances in this object wstab.addEntry(wsent); sumTab.addEntry(sumEnt); return serviceId++; } The Table that Summarizes Service Activity
In the public void addInRequest(long size) { wwwSummaryInBytes += size; wwwSummaryInRequests++; } public void addOutResponses(long size) { wwwSummaryOutBytes += size; wwwSummaryOutResponses++; }
To avoid updating the values of public long get_wwwSummaryInLowBytes() { return (wwwSummaryInBytes % (((long) 1) << 32)); }
Both private void updateSummaryTable(int service, long reqLength, long replLength) { // find the summary entry of this service in Vector WwwSummaryEntryImpl sumEnt = null; Enumeration enum = sumTab.elements(); for(int k = 0; enum.hasMoreElements(); k++) { sumEnt = (WwwSummaryEntryImpl) enum.nextElement(); if (service == sumEnt.get_wwwServiceIndex()) break; } // add summary information if (sumEnt != null) { sumEnt.addInRequest(reqLength); sumEnt.addOutResponses(replLength); } }
In turn, public synchronized void updateMIB(int service, Client client, Request request, Reply reply, int nbytes, long duration) { long requestLength = (request.hasContentLength() ? request.getContentLength() : (request.getURLPath()).length()); updateDocLastNTable(service, request.getURLPath(), request.getMethod(), reply.getStatus(), reply.getReason(), nbytes); updateSummaryTable(service, requestLength, nbytes); updateRequestTable(service, request.getMethod(), requestLength); updateResponseTable(service, reply.getStatus(), nbytes); } The Table of Incoming Requests
The public void updateRequestType(long count, long inBytes) { wwwRequestInBytes = inBytes; wwwRequestInRequests = count; wwwRequestInLastTime = Util.getTimeStamp(); }
New rows are inserted into the table each time a new request is
encountered. Again private void updateRequestTable(int service, String index, long size) { WwwRequestInEntryImpl row = null; int k = 0; Enumeration enum = reqTab.elements(); // check for an existing entry with same request type for (k = 0; enum.hasMoreElements(); k++) { row = (WwwRequestInEntryImpl) enum.nextElement(); if (service == row.get_wwwServiceIndex() && index.equals(new String(row.get_wwwRequestInIndex()))) break; } if (k == reqTab.size()) { row = new WwwRequestInEntryImpl(service, index); reqTab.addEntry(row); } row.updateRequestType(row.get_wwwRequestInRequests() + 1, size); } The Table of Outgoing Responses
Like for the private void updateResponseTable(int service, int index, long size) { WwwResponseOutEntryImpl row = null; int k = 0; Enumeration enum = replyTab.elements(); // check for an existing entry with same request type for (k = 0; enum.hasMoreElements(); k++) { row = (WwwResponseOutEntryImpl) enum.nextElement(); if (service == row.get_wwwServiceIndex() && index == row.get_wwwResponseOutIndex()) break; } if (k == replyTab.size()) { row = new WwwResponseOutEntryImpl(service, index); replyTab.addEntry(row); } row.updateResponseType(row.get_wwwResponseOutResponses() + 1, size); }
Similarly public void updateResponseType(long count, long outBytes) { wwwResponseOutBytes = outBytes; wwwResponseOutResponses = count; wwwResponseOutLastTime = Util.getTimeStamp(); } The Table of the Last Documents that were Requested
The public void setDocInfo(String name, String reqType, int resType, String state, long size) { wwwDocLastNName = name.getBytes(); wwwDocLastNBytes = size; wwwDocLastNResponseType = resType; wwwDocLastNRequestType = reqType.getBytes(); wwwDocLastNStatusMsg = state.getBytes(); wwwDocLastNTimeStamp = Util.getTimeStamp(); }
private void updateDocLastNTable(int service, String url, String reqType, int status, String reason, long size) { // add a new line to the DocLastNTable of this Service WwwDocLastNEntryImpl ent = new WwwDocLastNEntryImpl(service, nextDocIndex++); ent.setDocInfo(url, reqType, status, reason, size); lastTab.addEntry(ent); // remove superfluous entries in DocLastNTable if (lastTab.size() > max_n) { Enumeration all = lastTab.elements(); for (int k = lastTab.size() - max_n; k > 0 && all.hasMoreElements(); k--) { ent = (WwwDocLastNEntryImpl) all.nextElement(); lastTab.removeEntry(ent); } } }
The first index of the
© 2000 TU Braunschweig, NEC C&C Europe -
Wed Sep 5 12:55:04 2001
|