Overview
SnmpHibernate is a MIB/Object Mapping framework inspired by Hibernate Project(O/R Mapping framework). It will release EMS/NMS developer from coding tedious SNMP Client code.
Tell Something about the history of the project. I have been developing EMS/NMS products for about 4 years, and most of the products are based on SNMP protocol. I meet many different and proprietary Framework to ease the SNMP client side development, but I am not satisfied with them still. When I using the Hibernate (www.hibernate.org) to code O/R mapping someday, I am very impressed by its simplicity. I decided to use the same architecture to implement MIB/Object mapping for I find a mib table is the same to a database table, and then the project is born in one weekend:)
The project location: SnmpHibernate on Sourceforge
The SNMP Client API we used: SNMP4J project.
License of the project: Apache 2.0 License(Same to SNMP4J project)
Examples
The most efficient way to introduce something is to show samples.
Get/Set MIB2.System Scalars:
1. Write the SystemInfo class and annotate properties of the class with MIB defination.
import java.io.Serializable;
import net.sourceforge.snmphibernate.api.SmiType;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType.Access;
public class SystemInfo implements Serializable {
@MibObjectType(oid = "1.3.6.1.2.1.1.1.0", smiType = SmiType.DISPLAY_STRING, access = Access.READ)
public String sysDesc;
@MibObjectType(oid = "1.3.6.1.2.1.1.2.0", smiType = SmiType.OID, access = Access.READ)
public String sysObjectID;
@MibObjectType(oid = "1.3.6.1.2.1.1.3.0", smiType = SmiType.TIMETICKS, access = Access.READ)
public long sysUpTime;
@MibObjectType(oid = "1.3.6.1.2.1.1.4.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
public String sysContact;
@MibObjectType(oid = "1.3.6.1.2.1.1.5.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
public String sysName;
@MibObjectType(oid = "1.3.6.1.2.1.1.6.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
public String sysLocation;
public String getSysContact() {
return sysContact;
}
public void setSysContact(String sysContact) {
this.sysContact = sysContact;
}
public String getSysDesc() {
return sysDesc;
}
public void setSysDesc(String sysDesc) {
this.sysDesc = sysDesc;
}
public String getSysLocation() {
return sysLocation;
}
public void setSysLocation(String sysLocation) {
this.sysLocation = sysLocation;
}
public String getSysName() {
return sysName;
}
public void setSysName(String sysName) {
this.sysName = sysName;
}
public String getSysObjectID() {
return sysObjectID;
}
public void setSysObjectID(String sysObjectID) {
this.sysObjectID = sysObjectID;
}
public long getSysUpTime() {
return sysUpTime;
}
public void setSysUpTime(long sysUpTime) {
this.sysUpTime = sysUpTime;
}
}
2. Create the ISnmpSession API, and execute Get/Set operation.
ISnmpSession session = null;
try {
ISnmpClientFacade facade = new Snmp4JClientFacade();
ISnmpSessionFactory sessionFactory = facade.getSnmpSessionFactory();
ISnmpTargetFactory targetFactory = facade.getSnmpTargetFactory();
session = sessionFactory.newSnmpSession(targetFactory.newSnmpTarget("127.0.0.1", 161));
SystemInfo sysMIB = session.get(SystemInfo.class);
sysMIB.setSysContact("ery.lee@gmail.com");
session.set(sysMIB);
} finally {
if(session != null) session.close();
}
Get IfTable
1. Write the IfEntry class first
import java.io.Serializable;
import net.sourceforge.snmphibernate.api.SmiType;
import net.sourceforge.snmphibernate.api.annotation.MibIndex;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType;
import net.sourceforge.snmphibernate.api.annotation.MibTable;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType.Access;
@MibTable
public class IfEntry implements Serializable {
@MibIndex(no = 0, length = 1)
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.1", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifIndex;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.2", smiType = SmiType.DISPLAY_STRING, access = Access.READ)
public String ifDescr;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.3", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifType;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.4", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifMtu;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.5", smiType = SmiType.GAUGE32, access = Access.READ)
public long ifSpeed;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.6", smiType = SmiType.OCTET_STRING, access = Access.READ)
public byte[] ifPhysAddress;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.7", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifAdminStatus;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.8", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifOperStatus;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.9", smiType = SmiType.TIMETICKS, access = Access.READ)
public long ifLastChange;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.10", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInOctets;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.11", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInUcastPkts;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.12", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInNUcastPkts;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.13", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInDiscards;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.14", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInErrors;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.15", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInUnknownProtos;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.16", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutOctets;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.17", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutUcastPkts;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.18", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutNUcastPkts;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.19", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutDiscards;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.20", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutErrors;
public IfEntry() {}
public IfEntry(int index) {
this.ifIndex = index;
}
public boolean isLoopback() {
return ifType == 24;
}
public int getIfAdminStatus() {
return ifAdminStatus;
}
public void setIfAdminStatus(int ifAdminStatus) {
this.ifAdminStatus = ifAdminStatus;
}
public String getIfDescr() {
return ifDescr;
}
public void setIfDescr(String ifDescr) {
this.ifDescr = ifDescr;
}
public int getIfIndex() {
return ifIndex;
}
public void setIfIndex(int ifIndex) {
this.ifIndex = ifIndex;
}
public long getIfInDiscards() {
return ifInDiscards;
}
public void setIfInDiscards(long ifInDiscards) {
this.ifInDiscards = ifInDiscards;
}
public long getIfInErrors() {
return ifInErrors;
}
public void setIfInErrors(long ifInErrors) {
this.ifInErrors = ifInErrors;
}
public long getIfInNUcastPkts() {
return ifInNUcastPkts;
}
public void setIfInNUcastPkts(long ifInNUcastPkts) {
this.ifInNUcastPkts = ifInNUcastPkts;
}
public long getIfInOctets() {
return ifInOctets;
}
public void setIfInOctets(long ifInOctets) {
this.ifInOctets = ifInOctets;
}
public long getIfInUcastPkts() {
return ifInUcastPkts;
}
public void setIfInUcastPkts(long ifInUcastPkts) {
this.ifInUcastPkts = ifInUcastPkts;
}
public long getIfInUnknownProtos() {
return ifInUnknownProtos;
}
public void setIfInUnknownProtos(long ifInUnknownProtos) {
this.ifInUnknownProtos = ifInUnknownProtos;
}
public long getIfLastChange() {
return ifLastChange;
}
public void setIfLastChange(long ifLastChange) {
this.ifLastChange = ifLastChange;
}
public int getIfMtu() {
return ifMtu;
}
public void setIfMtu(int ifMtu) {
this.ifMtu = ifMtu;
}
public int getIfOperStatus() {
return ifOperStatus;
}
public void setIfOperStatus(int ifOperStatus) {
this.ifOperStatus = ifOperStatus;
}
public long getIfOutDiscards() {
return ifOutDiscards;
}
public void setIfOutDiscards(long ifOutDiscards) {
this.ifOutDiscards = ifOutDiscards;
}
public long getIfOutErrors() {
return ifOutErrors;
}
public void setIfOutErrors(long ifOutErrors) {
this.ifOutErrors = ifOutErrors;
}
public long getIfOutNUcastPkts() {
return ifOutNUcastPkts;
}
public void setIfOutNUcastPkts(long ifOutNUcastPkts) {
this.ifOutNUcastPkts = ifOutNUcastPkts;
}
public long getIfOutOctets() {
return ifOutOctets;
}
public void setIfOutOctets(long ifOutOctets) {
this.ifOutOctets = ifOutOctets;
}
public long getIfOutUcastPkts() {
return ifOutUcastPkts;
}
public void setIfOutUcastPkts(long ifOutUcastPkts) {
this.ifOutUcastPkts = ifOutUcastPkts;
}
public byte[] getIfPhysAddress() {
return ifPhysAddress;
}
public void setIfPhysAddress(byte[] ifPhysAddress) {
this.ifPhysAddress = ifPhysAddress;
}
public long getIfSpeed() {
return ifSpeed;
}
public void setIfSpeed(long ifSpeed) {
this.ifSpeed = ifSpeed;
}
public int getIfType() {
return ifType;
}
public void setIfType(int ifType) {
this.ifType = ifType;
}
}
2. Get "IfTable",
ISnmpSession session = null;
try {
ISnmpClientFacade facade = new Snmp4JClientFacade();
ISnmpSessionFactory sessionFactory = facade.getSnmpSessionFactory();
ISnmpTargetFactory targetFactory = facade.getSnmpTargetFactory();
ISnmpSession session = sessionFactory.newSnmpSession(targetFactory.newSnmpTarget("127.0.0.1", 161));
//Get the whole table
List<IfEntry> list = session.getTable(IfEntry.class);
//Get the one interface entry by index
IfEntry entry = session.getByIndex(IfEntry.class, 1);
//Only get the "ifDescr" property of one entry.
IfEntry entryWithDescr = session.getByIndex(IfEntry.class, 1, new String[] { "ifDescr" });
System.out.println(entryWithDescr.getIfDescr());
} finally {
if(session != null) session.close();
}
Code Structure
There are two binary jars:
The API jar: net.sourceforge.snmphibernate.api_1.1.0.jar
The SNMP4J implementation jar: net.sourceforge.snmphibernate.impl.snmp4j_1.1.0.jar
Your code should only depend on the API jar.
API Introduction
All API interfaces are defined in the package "net.sourceforge.snmphibernate.api" package. Introduce the important ones below.
ISnmpClientFacade: Facade of the whole SnmpHibernate framework.
//Create SNMP Session Factory.
ISnmpSessionFactory getSnmpSessionFactory();
//Create SNMP Target Factory.
ISnmpTargetFactory getSnmpTargetFactory();
ISnmpSessionFactory: Factory of ISnmpSession
//Create a SNMP Session.
ISnmpSession newSnmpSession(ISnmpTarget target) throws IOException;
ISnmpTargetFactory: Factory of ISnmpTarget
//Create a SNMP Target by Ip
ISnmpTarget newSnmpTarget(String ip);
//Create a SNMP Target by Ip and port.
ISnmpTarget newSnmpTarget(String ip, int port);
ISnmpTarget: A SNMP Agent hosted on the managed device.
//SNMP protocol version enums
int V1 = 0;
int V2C = 1;
int V3 = 3;
//Get SNMP Read Community.
String getCommunity();
//Set SNMP read community.
void setCommunity(String community);
//Get IP of the managed device.
String getIp();
//Set IP of the managed device.
void setIp(String ip);
//Get SNMP Port, default is 161
int getPort();
//Set SNMP Port, default is 161
void setPort(int port);
//Get SNMP protocol version the agent supports.
int getVersion();
//Set SNMP protocol version the agent supports.
void setVersion(int version);
//Get SNMP write community.
String getWriteCommunity();
//Set SNMP write community.
void setWriteCommunity(String writeCommunity);
ISnmpSession: Core API of SnmpHiberate that is used to execute SNMP operations.
/**
* Get scalar group.
*
* @param scalarClass class of the Java Value Object that represents one scalar group.
*
* @return Return an instance of the class.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> T get(Class<T> scalarClass) throws IOException,
SnmpException, SnmpAnnotationException;
/**
* Get specified fields of a scalar group.
*
* @param scalarClass class of the Java Value Object that represents one scalar group.
* @param fields specified fields of the scalar object.
* @return Return an instance of the class that only has the specified attributes
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> T get(Class<T> scalarClass, String[] fields)
throws IOException, SnmpException, SnmpAnnotationException;
/**
* Get a whole mib table.
*
* @param entryClass Class of the Java Value Object that represents one mib entry.
*
* @return a list of instances of the class.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> List<T> getTable(Class<T> entryClass) throws IOException,
SnmpException, SnmpAnnotationException;
/**
* Get a mib entry by index.
*
* @param entryClass Class of the Java Value Object that represents one mib entry.
* @param indices If there is only one index, this param is the just the object;
* if there are multiple indices, this param is an array.
*
* @return a mib entry with whole properties.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> T getByIndex(Class<T> entryClass, Serializable indices)
throws IOException, SnmpException, SnmpAnnotationException;
/**
* Get specified fields of a mib entry by index.
*
* @param entryClass Class of the Java Value Object that represents one mib entry.
* @param indices If there is only one index, this param is the just the object;
* if there are multiple indices, this param is an array.
* @param fileds specified fields of the mib entry object.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> T getByIndex(Class<T> entryClass, Serializable indices, String[] fields)
throws IOException, SnmpException, SnmpAnnotationException;
/**
* Set a scalar group or a mib entry.
*
* @param object a Java Value Object represents a scalar group or a mib entry.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
void set(Object object) throws IOException,
SnmpException, SnmpAnnotationException;
/**
* Create a mib entry.
*
* @param entry a mib entry.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
void create(Object entry) throws IOException,
SnmpException, SnmpAnnotationException;
/**
* Delete a mib entry.
*
* @param entry
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
void delete(Object entry) throws IOException,
SnmpException, SnmpAnnotationException;
Annotation Introduction
Mapping Java Value Object to MIB
SnmpHibernate uses Java Annotation to mapping a property of a Java Value Object to a MIB Object-Type. For examle, the "System" class is mapping to "iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1)" scalar group.
Sytem.java:
import java.io.Serializable;
import net.sourceforge.snmphibernate.api.SmiType;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType.Access;
public class System implements Serializable {
@MibObjectType(oid = "1.3.6.1.2.1.1.1.0", smiType = SmiType.DISPLAY_STRING, access = Access.READ)
private String sysDesc;
@MibObjectType(oid = "1.3.6.1.2.1.1.2.0", smiType = SmiType.OID, access = Access.READ)
private String sysObjectID;
@MibObjectType(oid = "1.3.6.1.2.1.1.3.0", smiType = SmiType.TIMETICKS, access = Access.READ)
private long sysUpTime;
@MibObjectType(oid = "1.3.6.1.2.1.1.4.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
private String sysContact;
@MibObjectType(oid = "1.3.6.1.2.1.1.5.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
private String sysName;
@MibObjectType(oid = "1.3.6.1.2.1.1.6.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
private String sysLocation;
//don't list the get/set methods here
}
The "@MibObjectType" annotates a class property with MIB defination.
The "IfEntry" class is mapping to "iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).interfaces(2).ifTable(2)" below,
IfEntry.java
import java.io.Serializable;
import net.sourceforge.snmphibernate.api.SmiType;
import net.sourceforge.snmphibernate.api.annotation.MibIndex;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType;
import net.sourceforge.snmphibernate.api.annotation.MibTable;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType.Access;
@MibTable
public class IfEntry implements Serializable {
@MibIndex(no = 0, length = 1)
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.1", smiType = SmiType.INTEGER32, access = Access.READ)
private int ifIndex;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.2", smiType = SmiType.DISPLAY_STRING, access = Access.READ)
private String ifDescr;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.3", smiType = SmiType.INTEGER32, access = Access.READ)
private int ifType;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.4", smiType = SmiType.INTEGER32, access = Access.READ)
private int ifMtu;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.5", smiType = SmiType.GAUGE32, access = Access.READ)
private long ifSpeed;
//don't list other properties.
}
"@MibTable" annotatation tags a class as a MIB table.
"@MibIndex" annotates a property as a MIB table index.
MibObjectType: Annotation for mapping a property to a Object-Type of MIB.
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD })
public @interface MibObjectType {
public enum Access { READ, WRITE, CREATE }
String oid();
SmiType smiType();
Access access();
}
MibTable: Annotation for mapping a class to a row of MIB table.
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.TYPE })
public @interface MibTable {
}
MibIndex:Annotation for mapping a property to an index of MIB table
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD })
public @interface MibIndex {
public static final int VARSTR_WITH_LENGTH = -1;
public static final int VARSTR_WITHOUT_LENGTH = -2;
int no(); // index no, 0 start.
int length(); // length of the index
}
RowStatus: Annotation for mapping the delete/create operations to RowStatus values.
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.TYPE })
public @interface RowStatus {
String oid();
int delete() default 6;
int create() default 4;
}
Released as OSGi bundle
For I used SnmpHibernate in our product as OSGi bundle, I put the OSGi "Manifest.MF" in the released jars and u could use them on OSGi platform directly. Sample code below introduce the usage on OSGi:
public Activate implements BundleActivator {
public void start(BundleContext context) throws Exception {
ServiceReference sRef= context.getServiceReference(ISnmpClientFacade.class.getName());
ISnmpClientFacade scFacade = context.getService(sRef);
// then u could inject the fadade to anywhere that need it.
}
public void stop(BundleContext context) throws Exception {
}
}
Advantages
Simplicity: Is it the most simple solution for MIB/Object mapping in the world?
Serializable: Serialize the Java Value Object to anywhere, for example, from Server to client.
To-Do List
Support XML/MIB mapping directly.
Feed new requirements from users.
Contribution
I hope someone could help me provide an implementation based on WestHawk SNMP protocol stack.
Contact
ery.lee@gmail.com
SnmpHibernate is a MIB/Object Mapping framework inspired by Hibernate Project(O/R Mapping framework). It will release EMS/NMS developer from coding tedious SNMP Client code.
Tell Something about the history of the project. I have been developing EMS/NMS products for about 4 years, and most of the products are based on SNMP protocol. I meet many different and proprietary Framework to ease the SNMP client side development, but I am not satisfied with them still. When I using the Hibernate (www.hibernate.org) to code O/R mapping someday, I am very impressed by its simplicity. I decided to use the same architecture to implement MIB/Object mapping for I find a mib table is the same to a database table, and then the project is born in one weekend:)
The project location: SnmpHibernate on Sourceforge
The SNMP Client API we used: SNMP4J project.
License of the project: Apache 2.0 License(Same to SNMP4J project)
Examples
The most efficient way to introduce something is to show samples.
Get/Set MIB2.System Scalars:
1. Write the SystemInfo class and annotate properties of the class with MIB defination.
import java.io.Serializable;
import net.sourceforge.snmphibernate.api.SmiType;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType.Access;
public class SystemInfo implements Serializable {
@MibObjectType(oid = "1.3.6.1.2.1.1.1.0", smiType = SmiType.DISPLAY_STRING, access = Access.READ)
public String sysDesc;
@MibObjectType(oid = "1.3.6.1.2.1.1.2.0", smiType = SmiType.OID, access = Access.READ)
public String sysObjectID;
@MibObjectType(oid = "1.3.6.1.2.1.1.3.0", smiType = SmiType.TIMETICKS, access = Access.READ)
public long sysUpTime;
@MibObjectType(oid = "1.3.6.1.2.1.1.4.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
public String sysContact;
@MibObjectType(oid = "1.3.6.1.2.1.1.5.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
public String sysName;
@MibObjectType(oid = "1.3.6.1.2.1.1.6.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
public String sysLocation;
public String getSysContact() {
return sysContact;
}
public void setSysContact(String sysContact) {
this.sysContact = sysContact;
}
public String getSysDesc() {
return sysDesc;
}
public void setSysDesc(String sysDesc) {
this.sysDesc = sysDesc;
}
public String getSysLocation() {
return sysLocation;
}
public void setSysLocation(String sysLocation) {
this.sysLocation = sysLocation;
}
public String getSysName() {
return sysName;
}
public void setSysName(String sysName) {
this.sysName = sysName;
}
public String getSysObjectID() {
return sysObjectID;
}
public void setSysObjectID(String sysObjectID) {
this.sysObjectID = sysObjectID;
}
public long getSysUpTime() {
return sysUpTime;
}
public void setSysUpTime(long sysUpTime) {
this.sysUpTime = sysUpTime;
}
}
2. Create the ISnmpSession API, and execute Get/Set operation.
ISnmpSession session = null;
try {
ISnmpClientFacade facade = new Snmp4JClientFacade();
ISnmpSessionFactory sessionFactory = facade.getSnmpSessionFactory();
ISnmpTargetFactory targetFactory = facade.getSnmpTargetFactory();
session = sessionFactory.newSnmpSession(targetFactory.newSnmpTarget("127.0.0.1", 161));
SystemInfo sysMIB = session.get(SystemInfo.class);
sysMIB.setSysContact("ery.lee@gmail.com");
session.set(sysMIB);
} finally {
if(session != null) session.close();
}
Get IfTable
1. Write the IfEntry class first
import java.io.Serializable;
import net.sourceforge.snmphibernate.api.SmiType;
import net.sourceforge.snmphibernate.api.annotation.MibIndex;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType;
import net.sourceforge.snmphibernate.api.annotation.MibTable;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType.Access;
@MibTable
public class IfEntry implements Serializable {
@MibIndex(no = 0, length = 1)
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.1", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifIndex;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.2", smiType = SmiType.DISPLAY_STRING, access = Access.READ)
public String ifDescr;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.3", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifType;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.4", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifMtu;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.5", smiType = SmiType.GAUGE32, access = Access.READ)
public long ifSpeed;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.6", smiType = SmiType.OCTET_STRING, access = Access.READ)
public byte[] ifPhysAddress;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.7", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifAdminStatus;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.8", smiType = SmiType.INTEGER32, access = Access.READ)
public int ifOperStatus;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.9", smiType = SmiType.TIMETICKS, access = Access.READ)
public long ifLastChange;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.10", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInOctets;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.11", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInUcastPkts;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.12", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInNUcastPkts;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.13", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInDiscards;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.14", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInErrors;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.15", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifInUnknownProtos;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.16", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutOctets;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.17", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutUcastPkts;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.18", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutNUcastPkts;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.19", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutDiscards;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.20", smiType = SmiType.COUNTER32, access = Access.READ)
public long ifOutErrors;
public IfEntry() {}
public IfEntry(int index) {
this.ifIndex = index;
}
public boolean isLoopback() {
return ifType == 24;
}
public int getIfAdminStatus() {
return ifAdminStatus;
}
public void setIfAdminStatus(int ifAdminStatus) {
this.ifAdminStatus = ifAdminStatus;
}
public String getIfDescr() {
return ifDescr;
}
public void setIfDescr(String ifDescr) {
this.ifDescr = ifDescr;
}
public int getIfIndex() {
return ifIndex;
}
public void setIfIndex(int ifIndex) {
this.ifIndex = ifIndex;
}
public long getIfInDiscards() {
return ifInDiscards;
}
public void setIfInDiscards(long ifInDiscards) {
this.ifInDiscards = ifInDiscards;
}
public long getIfInErrors() {
return ifInErrors;
}
public void setIfInErrors(long ifInErrors) {
this.ifInErrors = ifInErrors;
}
public long getIfInNUcastPkts() {
return ifInNUcastPkts;
}
public void setIfInNUcastPkts(long ifInNUcastPkts) {
this.ifInNUcastPkts = ifInNUcastPkts;
}
public long getIfInOctets() {
return ifInOctets;
}
public void setIfInOctets(long ifInOctets) {
this.ifInOctets = ifInOctets;
}
public long getIfInUcastPkts() {
return ifInUcastPkts;
}
public void setIfInUcastPkts(long ifInUcastPkts) {
this.ifInUcastPkts = ifInUcastPkts;
}
public long getIfInUnknownProtos() {
return ifInUnknownProtos;
}
public void setIfInUnknownProtos(long ifInUnknownProtos) {
this.ifInUnknownProtos = ifInUnknownProtos;
}
public long getIfLastChange() {
return ifLastChange;
}
public void setIfLastChange(long ifLastChange) {
this.ifLastChange = ifLastChange;
}
public int getIfMtu() {
return ifMtu;
}
public void setIfMtu(int ifMtu) {
this.ifMtu = ifMtu;
}
public int getIfOperStatus() {
return ifOperStatus;
}
public void setIfOperStatus(int ifOperStatus) {
this.ifOperStatus = ifOperStatus;
}
public long getIfOutDiscards() {
return ifOutDiscards;
}
public void setIfOutDiscards(long ifOutDiscards) {
this.ifOutDiscards = ifOutDiscards;
}
public long getIfOutErrors() {
return ifOutErrors;
}
public void setIfOutErrors(long ifOutErrors) {
this.ifOutErrors = ifOutErrors;
}
public long getIfOutNUcastPkts() {
return ifOutNUcastPkts;
}
public void setIfOutNUcastPkts(long ifOutNUcastPkts) {
this.ifOutNUcastPkts = ifOutNUcastPkts;
}
public long getIfOutOctets() {
return ifOutOctets;
}
public void setIfOutOctets(long ifOutOctets) {
this.ifOutOctets = ifOutOctets;
}
public long getIfOutUcastPkts() {
return ifOutUcastPkts;
}
public void setIfOutUcastPkts(long ifOutUcastPkts) {
this.ifOutUcastPkts = ifOutUcastPkts;
}
public byte[] getIfPhysAddress() {
return ifPhysAddress;
}
public void setIfPhysAddress(byte[] ifPhysAddress) {
this.ifPhysAddress = ifPhysAddress;
}
public long getIfSpeed() {
return ifSpeed;
}
public void setIfSpeed(long ifSpeed) {
this.ifSpeed = ifSpeed;
}
public int getIfType() {
return ifType;
}
public void setIfType(int ifType) {
this.ifType = ifType;
}
}
2. Get "IfTable",
ISnmpSession session = null;
try {
ISnmpClientFacade facade = new Snmp4JClientFacade();
ISnmpSessionFactory sessionFactory = facade.getSnmpSessionFactory();
ISnmpTargetFactory targetFactory = facade.getSnmpTargetFactory();
ISnmpSession session = sessionFactory.newSnmpSession(targetFactory.newSnmpTarget("127.0.0.1", 161));
//Get the whole table
List<IfEntry> list = session.getTable(IfEntry.class);
//Get the one interface entry by index
IfEntry entry = session.getByIndex(IfEntry.class, 1);
//Only get the "ifDescr" property of one entry.
IfEntry entryWithDescr = session.getByIndex(IfEntry.class, 1, new String[] { "ifDescr" });
System.out.println(entryWithDescr.getIfDescr());
} finally {
if(session != null) session.close();
}
Code Structure
There are two binary jars:
The API jar: net.sourceforge.snmphibernate.api_1.1.0.jar
The SNMP4J implementation jar: net.sourceforge.snmphibernate.impl.snmp4j_1.1.0.jar
Your code should only depend on the API jar.
API Introduction
All API interfaces are defined in the package "net.sourceforge.snmphibernate.api" package. Introduce the important ones below.
ISnmpClientFacade: Facade of the whole SnmpHibernate framework.
//Create SNMP Session Factory.
ISnmpSessionFactory getSnmpSessionFactory();
//Create SNMP Target Factory.
ISnmpTargetFactory getSnmpTargetFactory();
ISnmpSessionFactory: Factory of ISnmpSession
//Create a SNMP Session.
ISnmpSession newSnmpSession(ISnmpTarget target) throws IOException;
ISnmpTargetFactory: Factory of ISnmpTarget
//Create a SNMP Target by Ip
ISnmpTarget newSnmpTarget(String ip);
//Create a SNMP Target by Ip and port.
ISnmpTarget newSnmpTarget(String ip, int port);
ISnmpTarget: A SNMP Agent hosted on the managed device.
//SNMP protocol version enums
int V1 = 0;
int V2C = 1;
int V3 = 3;
//Get SNMP Read Community.
String getCommunity();
//Set SNMP read community.
void setCommunity(String community);
//Get IP of the managed device.
String getIp();
//Set IP of the managed device.
void setIp(String ip);
//Get SNMP Port, default is 161
int getPort();
//Set SNMP Port, default is 161
void setPort(int port);
//Get SNMP protocol version the agent supports.
int getVersion();
//Set SNMP protocol version the agent supports.
void setVersion(int version);
//Get SNMP write community.
String getWriteCommunity();
//Set SNMP write community.
void setWriteCommunity(String writeCommunity);
ISnmpSession: Core API of SnmpHiberate that is used to execute SNMP operations.
/**
* Get scalar group.
*
* @param scalarClass class of the Java Value Object that represents one scalar group.
*
* @return Return an instance of the class.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> T get(Class<T> scalarClass) throws IOException,
SnmpException, SnmpAnnotationException;
/**
* Get specified fields of a scalar group.
*
* @param scalarClass class of the Java Value Object that represents one scalar group.
* @param fields specified fields of the scalar object.
* @return Return an instance of the class that only has the specified attributes
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> T get(Class<T> scalarClass, String[] fields)
throws IOException, SnmpException, SnmpAnnotationException;
/**
* Get a whole mib table.
*
* @param entryClass Class of the Java Value Object that represents one mib entry.
*
* @return a list of instances of the class.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> List<T> getTable(Class<T> entryClass) throws IOException,
SnmpException, SnmpAnnotationException;
/**
* Get a mib entry by index.
*
* @param entryClass Class of the Java Value Object that represents one mib entry.
* @param indices If there is only one index, this param is the just the object;
* if there are multiple indices, this param is an array.
*
* @return a mib entry with whole properties.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> T getByIndex(Class<T> entryClass, Serializable indices)
throws IOException, SnmpException, SnmpAnnotationException;
/**
* Get specified fields of a mib entry by index.
*
* @param entryClass Class of the Java Value Object that represents one mib entry.
* @param indices If there is only one index, this param is the just the object;
* if there are multiple indices, this param is an array.
* @param fileds specified fields of the mib entry object.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
<T> T getByIndex(Class<T> entryClass, Serializable indices, String[] fields)
throws IOException, SnmpException, SnmpAnnotationException;
/**
* Set a scalar group or a mib entry.
*
* @param object a Java Value Object represents a scalar group or a mib entry.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
void set(Object object) throws IOException,
SnmpException, SnmpAnnotationException;
/**
* Create a mib entry.
*
* @param entry a mib entry.
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
void create(Object entry) throws IOException,
SnmpException, SnmpAnnotationException;
/**
* Delete a mib entry.
*
* @param entry
*
* @throws IOException When IO errors occured while communicating.
* @throws SnmpException When SNMP errors occured.
* @throws SnmpAnnotationException Annotaction Error for your Java Value Object.
*/
void delete(Object entry) throws IOException,
SnmpException, SnmpAnnotationException;
Annotation Introduction
Mapping Java Value Object to MIB
SnmpHibernate uses Java Annotation to mapping a property of a Java Value Object to a MIB Object-Type. For examle, the "System" class is mapping to "iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).system(1)" scalar group.
Sytem.java:
import java.io.Serializable;
import net.sourceforge.snmphibernate.api.SmiType;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType.Access;
public class System implements Serializable {
@MibObjectType(oid = "1.3.6.1.2.1.1.1.0", smiType = SmiType.DISPLAY_STRING, access = Access.READ)
private String sysDesc;
@MibObjectType(oid = "1.3.6.1.2.1.1.2.0", smiType = SmiType.OID, access = Access.READ)
private String sysObjectID;
@MibObjectType(oid = "1.3.6.1.2.1.1.3.0", smiType = SmiType.TIMETICKS, access = Access.READ)
private long sysUpTime;
@MibObjectType(oid = "1.3.6.1.2.1.1.4.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
private String sysContact;
@MibObjectType(oid = "1.3.6.1.2.1.1.5.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
private String sysName;
@MibObjectType(oid = "1.3.6.1.2.1.1.6.0", smiType = SmiType.DISPLAY_STRING, access = Access.WRITE)
private String sysLocation;
//don't list the get/set methods here
}
The "@MibObjectType" annotates a class property with MIB defination.
The "IfEntry" class is mapping to "iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1).interfaces(2).ifTable(2)" below,
IfEntry.java
import java.io.Serializable;
import net.sourceforge.snmphibernate.api.SmiType;
import net.sourceforge.snmphibernate.api.annotation.MibIndex;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType;
import net.sourceforge.snmphibernate.api.annotation.MibTable;
import net.sourceforge.snmphibernate.api.annotation.MibObjectType.Access;
@MibTable
public class IfEntry implements Serializable {
@MibIndex(no = 0, length = 1)
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.1", smiType = SmiType.INTEGER32, access = Access.READ)
private int ifIndex;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.2", smiType = SmiType.DISPLAY_STRING, access = Access.READ)
private String ifDescr;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.3", smiType = SmiType.INTEGER32, access = Access.READ)
private int ifType;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.4", smiType = SmiType.INTEGER32, access = Access.READ)
private int ifMtu;
@MibObjectType(oid = "1.3.6.1.2.1.2.2.1.5", smiType = SmiType.GAUGE32, access = Access.READ)
private long ifSpeed;
//don't list other properties.
}
"@MibTable" annotatation tags a class as a MIB table.
"@MibIndex" annotates a property as a MIB table index.
MibObjectType: Annotation for mapping a property to a Object-Type of MIB.
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD })
public @interface MibObjectType {
public enum Access { READ, WRITE, CREATE }
String oid();
SmiType smiType();
Access access();
}
MibTable: Annotation for mapping a class to a row of MIB table.
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.TYPE })
public @interface MibTable {
}
MibIndex:Annotation for mapping a property to an index of MIB table
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.FIELD })
public @interface MibIndex {
public static final int VARSTR_WITH_LENGTH = -1;
public static final int VARSTR_WITHOUT_LENGTH = -2;
int no(); // index no, 0 start.
int length(); // length of the index
}
RowStatus: Annotation for mapping the delete/create operations to RowStatus values.
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.TYPE })
public @interface RowStatus {
String oid();
int delete() default 6;
int create() default 4;
}
Released as OSGi bundle
For I used SnmpHibernate in our product as OSGi bundle, I put the OSGi "Manifest.MF" in the released jars and u could use them on OSGi platform directly. Sample code below introduce the usage on OSGi:
public Activate implements BundleActivator {
public void start(BundleContext context) throws Exception {
ServiceReference sRef= context.getServiceReference(ISnmpClientFacade.class.getName());
ISnmpClientFacade scFacade = context.getService(sRef);
// then u could inject the fadade to anywhere that need it.
}
public void stop(BundleContext context) throws Exception {
}
}
Advantages
Simplicity: Is it the most simple solution for MIB/Object mapping in the world?
Serializable: Serialize the Java Value Object to anywhere, for example, from Server to client.
To-Do List
Support XML/MIB mapping directly.
Feed new requirements from users.
Contribution
I hope someone could help me provide an implementation based on WestHawk SNMP protocol stack.
Contact
ery.lee@gmail.com