SnmpHibernate Developer Guide(1.0Beta)

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值