现在的位置: 首页 > 综合 > 正文

OpenNMS扩展–基于JoeSNMP/MIB数据访问实现

2014年12月03日 ⁄ 综合 ⁄ 共 4984字 ⁄ 字号 评论关闭

OpenNMS扩展基于JoeSNMP/MIB数据访问实现

1.     MIB访问流程及原理

JoeSNMPOpenNMS采用的SNMP API,已独立成为一个Open Source Framework,基于JoeSNMP可以对MIB网络数据进行相应的操作。JoeSNMP封装了多个对SNMP Get,Set等操作的处理。

l         Get:用于读取设备MIB信息库中实例对象的单个值,GetOID表示对象实例值,

l         Set:用于简单的设置MIB中可读写的对象实例值。

MIB访问的主流程图如下:

 

1. MIB访问的主流程图

首先根据自变量接收一个要访问的被管理对象主机名,并接收要查询的对象标识符的简略定义形式. 过程首先生成SNMP 报文,一旦报文生成,再把报文简单反转过来,发送出去.生成SNMP 报文后,建立代理地址,创建套接字连接,以便代理能将响应发回. 然后,SNMP 请求报文发给代理 ,等待一个响应的到来.因为SNMP 是工作在UDP 之上的,所以在SNMP 应用实体间通信时,无需先建立连接,这样虽降低了系统开销,UDP 传输是不可靠的,为此,网络管理站采取了相应的超时和重发策略. 系统在发出请求报文之后,启动超时计数器,等待响应的到来,并设置重发次数为3. 3 次之后仍没有收到响应,则关闭套接字,并返回一个接收失败错误代码. 反之,若确定收到一个响应,则调用一过程来把响应转换成为内部表示形式, 即对SNMP 报文进行译码. 再用已保存的Request-id与响应Request-id段进行比较,来验证这个报文是否是刚才发出的请求报文的响应. 若是,就调用另一个过程,把每段对象标识符的ASN.1表示形式转换成自己的内部形式,并显示其值

2.     Get-Request/Set-Request步骤

            实现SnmpHandler接口

写一个SnmpSet, SnmpGet, implement SnmpHandler,实现处理SNMP的方法:snmpReceivedPdu, snmpTimeoutErrortsnmpInternalError. 如:SnmpGet.java

 

public class SnmpGet implements SnmpHandler {

     /**

     * The log4j category used to log debug messsages and statements.

     */

    private static final String LOG4J_CATEGORY = "SureTech.NMS";

    

     public void snmpInternalError(SnmpSession session, int err, SnmpSyntax pdu) {

              System.out.println("InternalError");

              value ="Internal Error";

              synchronized (session) {

                       session.notify();

              }

     }

 

     public void snmpReceivedPdu(SnmpSession session, int command, SnmpPduPacket pdu) {

              ThreadCategory.setPrefix(LOG4J_CATEGORY);

         Category log = ThreadCategory.getInstance();

              SnmpVarBind varBind = pdu.getVarBindAt(0);

              value = varBind.getValue().toString();

              if(log.isDebugEnabled()){

                       log.debug("Received value: " + varBind.getName() + "="

                                 + varBind.getValue());

              }

              synchronized (session) {

                       session.notify();

              }

     }

 

     public void snmpTimeoutError(SnmpSession session, SnmpSyntax pdu) {

              System.out.println("SnmpTimeout");

              value ="Snmp Timeout";

              synchronized (session) {

                       session.notify();

              }

     }

}

 

2.2创建SnmpPeer对象

创建一个SnmpPeer对象,需定义:

l         AgentIP地址

l         port (defaults to 161)

l         retries (defaults to 3)

l         timeout (defaults to .8 seconds)

如下在方法snmpGet方法中的红色代码片段:

/**

     * The value of snmpget command.

     */

     public String snmpGet(String host, String oid) throws SocketException,

                       UnknownHostException {

              InetAddress remote = InetAddress.getByName(host);

              SnmpPeer peer = new SnmpPeer(remote);

              peer.setPort(161);

              peer.setTimeout(5000);

              peer.setRetries(1); // it is actually number of tries

 

              SnmpParameters parms = peer.getParameters();

              parms.setVersion(SnmpSMI.SNMPV2);

              parms.setReadCommunity("public");

 

              final SnmpSession session = new SnmpSession(peer);

              session.setDefaultHandler(new SnmpGet());

 

              SnmpVarBind[] vblist = { new SnmpVarBind(oid) };

              SnmpPduRequest pdu = new SnmpPduRequest(

                                 oid.endsWith(".0") ? SnmpPduPacket.GET : SnmpPduPacket.GETNEXT,

                                 vblist);

              pdu.setRequestId(1);

 

              try {

                       synchronized (session) {

                                 session.send(pdu);

                                 session.wait();

                       }

 

              } catch (InterruptedException e) {

                       // do nothing

              } finally {

                       session.close();

              }

              return value;

     }

2.3创建SnmpParameters对象

创建一个SnmpPeer对象,需定义:

l         read community string (defaults to public)

l         write community string (defaults to null)

l         SNMP version to use (defaults to SNMPV1)

l         AsnEncoder to use (defaults to BER)

SnmpParameters parms = peer.getParameters();

parms.setVersion(SnmpSMI.SNMPV2);

parms.setReadCommunity("public");

2.4创建SnmpSession对象,发送PDU

SnmpPeer创建一个SnmpSession对象,这样就创建一个“SnmpPortal”线程,此线程用来接受来自远程Agent的响应,也可以创建一个Quene来处理所有的SNMP请求。

final SnmpSession session = new SnmpSession(peer);

              session.setDefaultHandler(new SnmpGet());

 

              SnmpVarBind[] vblist = { new SnmpVarBind(oid) };

              SnmpPduRequest pdu = new SnmpPduRequest(

                                 oid.endsWith(".0") ? SnmpPduPacket.GET : SnmpPduPacket.GETNEXT,

                                 vblist);

              pdu.setRequestId(1);

 

              try {

                       synchronized (session) {

                                 session.send(pdu);

                                 session.wait();

                       }

              } catch (InterruptedException e) {

                       // do nothing

              } finally {

                       session.close();

              }

 

l         通过调用session.send(pdu)发送PDU请求到远程的Agent,开启一个新的线程发送请求和处理重试或超时。

l         调用session.wait()进行线程等待。

l         SNMP session线程收到来自Agent的响应后会调用snmpTimeoutError方法,如果Agent没有在超时时间内响应,SNMP session线程将调用snmpTimeoutError方法,如果是内部发生了问题,则调用snmpInternalError方法。

l         线程唤醒,并继续处理。

2.5关闭Session

session.close();

 

抱歉!评论已关闭.