SNMP协议以及代码实现
主要是为了实现:Java通过SNMP协议和交换机进行交互
JAVA开发SNMP明细
第一步:
(1)首先安装SNMP服务。 (控制面板→添加与删除工具→添加与删除组件→管理和监视工具→详细信息→选择“简单网络管理协议”→确定)。
(2)启动snmp服务。
(3)下载snmp4j.jar
(4)新建项目,加如snmp4j.jar,编写代码
编写的代码中需要的内容:
(1)枚举网元类型(目前只有一种类型:摄像机类型)
(2)封装网元的基本属性(可操作属性、可返回属性等)
(3)封装target。(连接时网元的地址、端口、传输协议、共同体等)
(4)封装PDU数据包
(5)封装网元过滤规则。(通过一些表达式来限定处理网元的范围)
(6)检测中心。(包含重连操作和检测线程)
(7)心跳中心。(心跳检测线程)
(8)封装Get-Request。(命令发送和监听Response返回的线程)
(9)监听Trap报告。(监听162端口)
(10)封装Trap报告
(11)主线程。(入口,入则启动各项所需线程)
Java开发中SNMP的运行流程:
(1)程序入口在主线程,主线程启动后,在加载一些配置和启动其他的一些明细线程(心跳线程、检测中心线程、trap监听等)。
(2)Trap监听(同步到线程)运行后,会在工作站的162端口监听从网元发送来的告警信息,并将告警信息添加进告警列表内,同时
在Trap监听接口里实现清除告警方法。
(3)Get—Request接口里有向网元发送命令的方法和监听Response返回信息的线程。(发送命令关联Response监听)
(4)心跳线程运行后,会不断的验证当前连接正常的网元列表。(Get-Request和Trap的时候,成功交互会向正常网元列表添加网元)
[无重复添加],异常则移除,并在重连列表添加网元。
(5)重连检测中心线程运行起来后,会不断验证当前连接不正常的列表是否回复连接。(Get—Request和Trap的时候,成功交互会修改网元属性的连接状态为成功连接),
将依然断连的网元进行重连。
SNMP的具体部署:
代码实例;
//获取到交换机给的信息,发送不同的oid值,对应的消息不同
public class SnmpData {
//定义部分常量
public static final int DEFAULT_VARSION = SnmpConstants.version2c;
//采用的协议
public static final String DEFAULT_PROTOCOL = "udp";
//请求的端口号
public static final int DEFAULT_PORT = 161;
//请求超时的时间
public static final long DEFAULT_TIMEOUT = 3 * 1000L;
//失败之后请求次数
public static final int DEFAULT_RETRY = 3;
/*
* 创建对象communityTarget
*/
public static CommunityTarget createDefualt(String ip,String community){
//定义本机地址
Address address = GenericAddress.parse(DEFAULT_PROTOCOL+":"+ip+"/"+DEFAULT_PORT);
//设定CommunityTarget类
CommunityTarget target = new CommunityTarget();
//设置snmp共同体
target.setCommunity(new OctetString(community)); //获取到系统中的默认配置的属性,在服务中的安全下边可以进行配置
target.setAddress(address);
//设置超时重试次数
target.setRetries(DEFAULT_RETRY);
//设置超时的时间
target.setTimeout(DEFAULT_TIMEOUT);
//设置使用的snmp的版本
target.setVersion(DEFAULT_VARSION);
return target;
}
/*
* 获取单个oid对应的信息
*/
public static void snmpGet(String ip,String community,String oid){
//设定CommunityTarget类
CommunityTarget target = createDefualt(ip, community);
Snmp snmp = null;
try {
//创建请求的PDU 获取到MIB
PDU pdu = new PDU();
//通过调用add的方法来绑定要查询的OID
pdu.add(new VariableBinding(new OID(oid)));
//设定传输协议为UDP
DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
//创建snmp对象是为了的发送请求
snmp = new Snmp(transport);
//启动监听进程,接受消息
snmp.listen();
System.out.println("---------->发送PDU<------------");
//调用setType();方法来确定PDU的类型
pdu.setType(PDU.GET);
//snmp类调用send 将准备好的target 和 pdu 进行发送,返回一个ResponseEvent对象
ResponseEvent event = snmp.send(pdu, target);
System.out.println("PeerAddress:"+event.getPeerAddress());
//通过ResponseEvent对象来获取到回应的pdu ,event.getResponse()
PDU response = event.getResponse();
if(response == null){
System.out.println("response is null,request time out");
}else{
System.out.println("response pdu size is "+response.size());
for(int i = 0; i < response.size();i++){
//获取到的对象的的类型是VariableBinding,通过get(index)可以获取到MIB信息(之前绑定的OID的值)
VariableBinding vb = response.get(i);
System.out.println(vb.getOid()+" = "+vb.getVariable());
}
}
System.out.println("SNMP GET one OID value finished!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("SNMP GET EXCEPTION:"+e);
}finally{
if(snmp!=null){
try {
snmp.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
设置共用体的时候注意:private String community = “public”; //设定共用体
其中共用体是你在服务中进行配置的在本机电脑中的操作是:
①在服务中查找到SNMP Service,点击右键属性
②在列表头部中找到安全一栏,下方有接受的社区名称。
③添加相对应的社区名称即可。
SNMP4j的介绍
(1)是一个用Java来实现SNMP(简单网关协议)协议的开源项目,它支持命令行形式的管理与响应。
SNMP4j是纯面向对象涉及与SNMP++(用c++来实现)类似。
(2)特性: 注意其中全部均为PDU格式。
4.SNMP4j中重点类和接口
(1)SNMP类:
该类是SNMP4j中最为核心的类,负责snmp报文的接受和发送,提供了发送和接受PDU的方法,
所有类型的PDU都可以被同步或者异步被发送。
(2)PDU类和ScopePDU类:
该类是SNMP报文单元的抽象,其中PDU类适用于SNMPv1和SNMPv2c,ScopePDU类继承于PDU类,适用于SNMPv3;
(3)Target接口和CommunityTarget类以及UserTarget类
对应于SNMP代理的地址信息,包括IP地址和端口号(161)。其中Target接口适用于SNMPv1和SNMPv2c。CommunityTarget实现了Target接口,用于
SNMPv1和SNMPv2这两个版本,UserTarget类实现了Target接口,适用于SNMPv3。
(4)TransportMapping接口
该接口代表SNMP4j所使用的传输层协议。这也是SNMP4j一大特色的地方。按照RFC的规定;SNMP是只是用UDP作为传输层协议的。而SNMP4j支持管理端和代理
端使用UDP或者TCP进行传输。该接口有两个子接口。
(5)Snmp、Target、PDU三者的关系
Target代表远程设备或者远程实体、PDU代表端同Target通信的数据,Snmp就代表管理者管理功能(其实就是数据的收发)的具体执行者。
打个比方:Target是远程的交换机,PDU是一个存储两者之间进行交互的信封,SNMP是进行传递“信封”的“邮差”。
6.使用SNMP4J实现管理端的步骤
(1)第一步:初始化
①明确SNMP在传输层所使用的协议
一般情况下,我们都使用UDP协议作为SNMP在传输层的协议,所以我们需要实例化的对应是一个DefaultUdpTransportMapping接口对象。
②实例化一个snmp对象
在此过程中,我们需要将1中实例化的DefaultUdpTransportMapping接口的对象作为参数,穿snmp类的构造函数中。另外如果实现的SNMPv3协议,我们还需要设置安全
机制,添加安全用户等等。
③在此,我们可以调用刚刚实例化的DefaultUdpTransportMapping的接口对象的listen方法,让程序监听snmp消息。
(2)第二步:构造发送目标
如果实现的是SNMPv2c或者说是SNMPv1的报文,我们需要实例化一个CommunityTarget对象。如果实现的是SNMPv3的程序,我们则需要实例化一个UserTarget类的对象。
之后我们还需要对实例化的对象做一些设置。如果CommunityType的对象,则需要设置使用的SNMP的版本,重传时间和等待时延。如果是UserTarget对象我们
不仅仅是需要设置版本、重传时间、等待时延,还需要设置安全级别和安全名称。
(3)第三步:构造发送报文
如果实现的是SNMPv2c或者说是SNMPv1的报文,我们需要实例化一个PDU对象。如果发送的是SNMPv3的报文,我们则需要实例化一个ScopedPDU类的对象。
之后我们还需要生成一个OID的对象。其中包含了我们需要从获取SNMP对象在MIB库中的ID。然后我们需要将OID和之前生成的PDU对象或者是ScopedPDU对象绑定,
并且设置PDU的报文类型(五中SNMP报文类型之一)。
(4)第四步:构造响应监听对象(异步模式)
当使用异步模式的时候,我们需要实例化一个实现了ResponseListener接口的对象,作为响应消息的监听对象。在构造该对象的过程中,我们需要重写
ResponseListener的OnResponse函数,该函数是一个回调函数,用来处理程序收到响应后的一些操作。
(5)第五步:发送消息
当所有上述操作都设置完毕之后,就可以发送消息了。同步模式和一步模式发送消息调用的函数名字均为send,但是两个函数所需参数不一样。同步模式的参数
仅为4.2和4.3中构造函数的目标对象和报文对象,而异步模式还需要4.4中构造的监听对象。
同步模式发送消息后便等待响应的到达,到达之后会但会一个ResponseEvent对象,该对象中包含了响应的相应信息。
异步模式发送消息之后便会继续执行,当收到响应消息的时,便会调用监听对象的OnResponse函数。该函数中的语句便是我们对响应的处理。
7.使用SNMP4J实现管理端的编码实现
(1)设定远程实体
snmp4j中,用CommunityTarget对象来表示远程实体(要进行snmp消息通信的远程主机,使用snmp的v2版本)。
(2)指定远程实体的地址
snmp4j中使用Address接口对象来表示,Address对象需要通过实现该接口的类的对象向上转型来实例化。
(3)通过CommunityTarget以及其父类接口中提供的setXXX方法来设定远程实体的属性,
如设定远程实体的snmp共同体属性、远程实体的地址、超时时间、重传次数、snmp版本等
(4)设定使用的传输协议
snmp4j中,用TransportMapping接口的对象来表示传输协议(tcp/udp)
(5)调用TransportMapping中的Listener()方法,启动监听进程,接受消息,由于该监听是守护进程,最后应调用close()方法来释放该进程
(6)创建SNMP对象,用于发送请求PDU
a、创建请求pdu,即创建PDU类的对象,调用PDU类中的add()方法绑定要查询的OID,调用PDU中的setType()方法来确定该pdu的类型(与snmp中五中操作相对应)。
b、通过pdu的构造方法,public SNMP(TransportMapping transportMapping),或者其他构造方法来生成pdu,之后调用ResponseEvent send(PDU pdu,Target target)
发送pdu,该方法返回一个ResponseEvent对象。
(7)通过ResponseEvent对象来获得SNMP请求的应答pdu,方法:public PDU getResponse()
(8)通过应答pdu获得到MIB信息(之前绑定的OID的值)方法:VarbleBinding getResponse()
8.如何查看 一个端口号被占用并且关闭正在运行的程序
① cmd
② 在命令行中输入netstat -ano 回车
可以查看到本机中所有正在运行的进程,将本地地址后的最后一位记录下来 例如:本机地址为:0.0.0.49157
③ 查看被占用的端口号对应的PID值 输入命令: netstat -aon|findstr “49157” 回车 记录下来对应的PID值(2720)
④ tasklist|findstr “2720” 即可展示出正在使用端口号的程序。
⑤ 结束进程 taskkill /f /t /im 进程名 如:UDP.exe
具体代码逻辑
package com.ext.snmp;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.UnknownHostException;
import java.util.Vector;
import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
import com.ext.db.JDBC;
import com.ext.domain.AlcatelLucent;
import com.ext.domain.Avaya;
import com.ext.domain.Record;
import com.ext.domain.Siemens;
import com.ext.domain.Warn_info_send;
import com.ext.domain.Zte;
import com.ext.snmp.consts.AlcatelLucentSnmpConst;
import com.ext.snmp.consts.AvayaSnmpConst;
import com.ext.snmp.consts.RecordSnmpConst;
import com.ext.snmp.consts.SiemensSnmpConst;
import com.ext.snmp.consts.ZteSnmpConst;
import com.ext.snmp.utils.MessageEndpointUtils;
import com.ext.utils.Tools;
/**
* 本类用于监听代理进程的Trap信息
*/
public class SnmpTrapReceiver implements CommandResponder {
private static String ip = null;//客户端IP地址,不能是127.0.0.1
private static String port = null;//监听端口
private static String charset = null;//snmp编码集
/**
* 加载和snmp相关的属性信息
*/
static {
ip = Tools.getProperties("config/snmp.properties","client_ip");//获取到监听的IP地址
port = Tools.getProperties("config/snmp.properties", "client_port");//获取到监听的端口号
charset = Tools.getProperties("config/snmp.properties", "snmp_charset"); //获取到编码集
}
private MultiThreadedMessageDispatcher dispatcher;
private Snmp snmp = null;
private Address listenAddress;
private ThreadPool threadPool;
public SnmpTrapReceiver() {
// BasicConfigurator.configure();
}
/**
* 初始化snmp服务
* @throws UnknownHostException
* @throws IOException
*/
private void init() throws UnknownHostException, IOException {
threadPool = ThreadPool.create("Trap", 2);
dispatcher = new MultiThreadedMessageDispatcher(threadPool,
new MessageDispatcherImpl());
listenAddress = GenericAddress.parse(System.getProperty(
"snmp4j.listenAddress", "udp:" + ip + "/" + port)); // 本地IP与监听端口
TransportMapping transport;
// 对TCP与UDP协议进行处理
if (listenAddress instanceof UdpAddress) {
transport = new DefaultUdpTransportMapping(
(UdpAddress) listenAddress);
} else {
transport = new DefaultTcpTransportMapping(
(TcpAddress) listenAddress);
}
snmp = new Snmp(dispatcher, transport);
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());
snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());
USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
SecurityModels.getInstance().addSecurityModel(usm);
snmp.listen();
}
public void run() {
try {
init();
snmp.addCommandResponder(this);
System.out.println("SnmpTrap开始监听信息...");
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 实现CommandResponder的processPdu方法, 用于处理传入的请求、PDU等信息 当接收到trap时,会自动进入这个方法
* @param respEvnt
*/
// 解析Response
public void processPdu(CommandResponderEvent respEvnt) {
if (respEvnt != null && respEvnt.getPDU() != null) {
//记录日志需要的消息
//消息发送过来的IP地址和端口
String peerAddress = respEvnt.getPeerAddress().toString();
//trap信息中携带的变量信息
//String variableBindings = parStr(respEvnt.getPDU().getVariableBindings().toString());
String loginfo = "=== > 接收到的trap信息:[发送来源="+peerAddress+", 携带的变量= \"";
//获取到一个包含有全部oid值的对象
@SuppressWarnings("unchecked")
Vector<VariableBinding> recVBs = respEvnt.getPDU().getVariableBindings();
String message = null;
//目的是进行进行拼接日志信息,将十六进制进行表示的信息转化为汉字形式
for(VariableBinding rec:recVBs){
if(!"1.3.6.1.4.1.39871.6.100.1".equals(rec.getOid().toString())){ //录音系统的如果发送过来的是十六进制需要进行特殊处理
loginfo = loginfo +rec.getOid().toString() + " = "+parStr(rec.getVariable().toString()) + ";";
}else{
loginfo = loginfo +rec.getOid().toString() + " = "+ chageStr(rec.getVariable().toString()) + ";";
}
}
loginfo = loginfo +"\"] ";
//将对象中的所有的oid值全部都获取出来,与固定的字符串1.3.6.1.6.3.1.1.4.1.0进行对比,如果包含将该oid值对应的消息赋值给msg
boolean recordFlag = false;
for (int i = 0; i < recVBs.size(); i++) {
VariableBinding recVB = recVBs.elementAt(i);
//东航过来的SNMP消息标识位
if("1.3.6.1.6.3.1.1.4.1.0".equals(recVB.getOid().toString())){
message = parStr(recVB.getVariable().toString()).replace(" ", "");
recordFlag = true;
}else if("1.3.6.1.6.3.1.1.4.1.0".equals(recVB.getOid().toString())){
message = parStr(recVB.getVariable().toString());
break;
}
}
if(Tools.notEmpty(message)){
//告警信息初始化
Warn_info_send warn_info_send = new Warn_info_send();
//获取当前时间,到秒
String now = Tools.getDate();
//获取IP地址,不带端口号
String ipaddr = getIp(peerAddress);
//日期信息是否入库
boolean sendFlag = false;
int rSize = recVBs.size();
if("1.3.6.1.4.1.6889.2.73.9.0.4622".equals(message)
|| "1.3.6.1.4.1.6889.2.73.9.0.4992".equals(message)
|| "1.3.6.1.4.1.6889.2.73.9.0.5952".equals(message)
|| "1.3.6.1.4.1.6889.2.73.9.0.4972".equals(message)){
//AVAYA交换机
Avaya snmpContext = new Avaya();
//loginfo = "Avaya"+"=== > 接收到的trap信息:[发送来源="+respEvnt.getPeerAddress()+", 携带的变量="+parStr(respEvnt.getPDU().getVariableBindings().toString())+"] <=== \n";
loginfo = "Avaya " + loginfo;
for (int i = 0; i < rSize; i++) {
VariableBinding recVB = recVBs.elementAt(i);
AvayaSnmpConst.setFiledValue(snmpContext, recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
}
//告警信息初始化
warn_info_send.setWtitle(snmpContext.getAvCmMessagingAlarmWtitle());
String devType = "设备类型="+ Avaya.getWarnDevType(snmpContext.getAvCmMessagingAlarmEventName());
String devLoc = "告警位置=" + Avaya.getWarnDevLoc(snmpContext.getAvCmMessagingAlarmEventID());
String winfo = devType + "," +devLoc;
warn_info_send.setWinfo(winfo);
String level = changeColorMethod(snmpContext.getAvCmMessagingAlarmLevel());
warn_info_send.setWlevel(level);
//warn_info_send.setWlevel(snmpContext.getAvCmMessagingAlarmLevel());
warn_info_send.setWsysname("Avaya");
warn_info_send.setWsip(ipaddr);
warn_info_send.setSnmpinfo(loginfo);
//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
int flag = 0;
//将数据推送事找人平台
boolean flagdata = judgeAvaryLevelSend(snmpContext.getAvCmMessagingAlarmLevel());
if(flagdata){
String result = MessageEndpointUtils.send(snmpContext);
snmpContext.setResult(result);
flag = 3;
}
warn_info_send.setFlag(flag);
sendFlag = true;
}else if("1.3.6.1.4.1.637.64.0.10.1.2".equals(message)){
//阿尔卡特朗讯交换机
AlcatelLucent snmpContext = new AlcatelLucent();
snmpContext.setAlAlarmIpAddress(ipaddr);
//snmpContext.setAlAlarmDealWranLevel(alAlarmDealWranLevel);
loginfo = "AlcatelLucent "+loginfo;
for (int i = 0; i < rSize; i++) {
VariableBinding recVB = recVBs.elementAt(i);
//将获取的值放到对象对应的属性中
AlcatelLucentSnmpConst.setFiledValue(snmpContext, recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
}
//告警信息初始化
//warn_info_send.setWtitle(Tools.isNull(snmpContext.getAlAlarmSwitchBoradNetName()));
warn_info_send.setWtitle(Tools.isNull(snmpContext.getAlAlramExternal()));
warn_info_send.setWinfo(snmpContext.getContext());
String level = changeColorMethod(snmpContext.getAlAlarmDealWranLevel());
warn_info_send.setWlevel(level);
//warn_info_send.setWlevel(snmpContext.getAlAlarmDealWranLevel());
warn_info_send.setWsysname("阿朗");
warn_info_send.setWsip(ipaddr);
warn_info_send.setSnmpinfo(loginfo);
//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
int flag = 0;
//将数据推送事找人平台
boolean flagdata = judgeAlcateLucentLevelSend(snmpContext.getAlAlarmId());
if(flagdata){
String result = MessageEndpointUtils.send(snmpContext);
snmpContext.setResult(result);
flag = 3;
}
warn_info_send.setFlag(flag);
sendFlag = true;
}else if("1.3.6.1.4.1.4329.2.45.90.5".equals(message)){
//西门子的交换机
Siemens snmpContext = new Siemens();
loginfo = "Siemens "+loginfo;
for (int i = 0; i < rSize; i++) {
VariableBinding recVB = recVBs.elementAt(i);
SiemensSnmpConst.setFiledValue(snmpContext, recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
}
//告警信息初始化
warn_info_send.setWtitle(snmpContext.getSiemensAlarmWtitle());
warn_info_send.setWinfo(snmpContext.getSiemensAlarmExternal());
//String level = changeColorMethod(snmpContext.getSiemensAlarmLevel());
String level =snmpContext.getSiemensAlarmLevel();
warn_info_send.setWlevel(level);
//warn_info_send.setWlevel(snmpContext.getSiemensAlarmLevel());
warn_info_send.setWsysname("西门子");
warn_info_send.setWsip(ipaddr);
warn_info_send.setSnmpinfo(loginfo);
//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
int flag = 0;
//将数据推送事找人平台
boolean flagdata = judgeSiemensLevelSend(snmpContext.getSiemensAlarmLevel());
if(flagdata){
String result = MessageEndpointUtils.send(snmpContext);
snmpContext.setResult(result);
flag = 3;
}
warn_info_send.setFlag(flag);
sendFlag = true;
}else if("1.3.6.1.4.1.3902.701.1.1.50.4".equals(message)){
//中兴交换机
Zte snmpContext = new Zte();
loginfo = "Zte " + loginfo;
for (int i = 0; i < rSize; i++) {
VariableBinding recVB = recVBs.elementAt(i);
ZteSnmpConst.setFiledValue(snmpContext, recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
}
//告警信息初始化
warn_info_send.setWtitle(snmpContext.getZxEmsEventName());
//warn_info_send.setWinfo(snmpContext.getZxEmsEventDescription());
warn_info_send.setWinfo(snmpContext.getZxEmsEventName());
//String level = changeColorMethod(snmpContext.getZxEmsEventSeverity());
String level = snmpContext.getZxEmsEventSeverity();
warn_info_send.setWlevel(level);
//warn_info_send.setWlevel(snmpContext.getZxEmsEventSeverity());
warn_info_send.setWsysname("中兴");
warn_info_send.setWsip(snmpContext.getZxEmsEventserverIP());
warn_info_send.setSnmpinfo(loginfo);
//中兴交换机可以通过流水号判断告警事件唯一性,用于自动处理告警,将正在告警的告警如果已经恢复则自动处理
warn_info_send.setWcode(snmpContext.getZxEmsEventAid());
//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
int flag = 0;
//将数据推送事找人平台
boolean flagdata = judgeZetLevelSend(snmpContext.getZxEmsEventSeverity());
if(flagdata){
String result = MessageEndpointUtils.send(snmpContext);
snmpContext.setResult(result);
flag = 3;
}
warn_info_send.setFlag(flag);
sendFlag = true;
}else if(recordFlag){
//录音系统
Record snmpContext = new Record();
snmpContext.setAlarmInfo(message);
snmpContext.setAlarmType("INFO");
loginfo = "Record " + loginfo;
/**
for (int i = 0; i < rSize; i++) {
VariableBinding recVB = recVBs.elementAt(i);
RecordSnmpConst.setFiledValue(snmpContext,recVB.getOid().toString(), parStr(recVB.getVariable().toString()));
}
*/
warn_info_send.setWtitle(snmpContext.getAlarmInfo());
warn_info_send.setWinfo(snmpContext.getAlarmInfo());
//String level = changeColorMethod(snmpContext.getAlarmType());
warn_info_send.setWlevel("7");
//warn_info_send.setWlevel(snmpContext.getAlarmType());
warn_info_send.setWsysname("录音系统");
warn_info_send.setWsip(ipaddr);
warn_info_send.setSnmpinfo(loginfo);
//是否推送,0:告警入库,1:已恢复,2:忽略,3:已推送
int flag = 0;
//将数据推送事找人平台
boolean flagdata = judgeRecordLevelSend(snmpContext.getAlarmType());
if(flagdata){
String result = MessageEndpointUtils.send(snmpContext);
snmpContext.setResult(result);
flag = 3;
}
warn_info_send.setFlag(flag);
sendFlag = true;
}
if(sendFlag){
//JDBC连接数据库,将数据存储到数据库中
JDBC jdbc = new JDBC();
String wcode = warn_info_send.getWcode();
if(Tools.isEmpty(wcode)){
wcode = "";
}
String insertFiled = "insert into warn_info_send (wtitle,winfo,wlevel,wsysname,wdate,wsip,flag,wcode,snmpinfo)";
String insertValues = "values('"+warn_info_send.getWtitle()+"','"+warn_info_send.getWinfo()+"','"
+warn_info_send.getWlevel()+"','"+warn_info_send.getWsysname()
+"',to_timestamp('"+now+"','YYYY-MM-DD HH24:MI:SS'),'"
+warn_info_send.getWsip()+"',"+warn_info_send.getFlag()
+",'"+wcode+"','"+warn_info_send.getSnmpinfo()+"'"+")";
String sql = insertFiled + insertValues;
loginfo += ",JDBC UPDATE SQL=" + sql;
jdbc.update(sql);
jdbc.close();
}else{
loginfo = "未匹配到对应的交换机oid:" + loginfo;
}
}
//日志信息写入文件
extPrintLog(loginfo,"snmp");
}
}
/**
* 当录音系统的告警消息是十六进制的时候
*/
private String chageStr(String value) {
String infoMessage = "";
if(Tools.notEmpty(value)) {
String info = value;
String [] strs =Tools.str2StrArray(info, ":");
String str =info.substring(strs[0].length()+1,info.length());
infoMessage = parStr(str);
}
return infoMessage;
}
/**
* 打印日志信息
*/
public static void extPrintLog(String loginfo,String logFileName) {
String path = SnmpTrapReceiver.class.getResource("/").getPath();
path = path.substring(0, path.indexOf("WEB-INF"));
path = path + "/log/"+logFileName+".log";
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(path, true));
bw.write(Tools.getDate()+"\t");
bw.write(loginfo);
bw.newLine();
bw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bw!=null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 十六进制转中文
* @author lxd
* @param value
* @return
*/
public static String parStr(String value) {
String regex = "[0-9a-f]{2}(:[0-9a-f]{2})*";
if(value.matches(regex)) {
String[] strs = value.split(":");
byte[] bys = new byte[strs.length];
for (int i = 0; i < strs.length; i++) {
bys[i] = (byte) Integer.parseInt(strs[i], 16);
}
try {
value = new String(bys, charset);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return value;
}
/**
* 获取到ip地址
*/
public String getIp(String ip){
String ipAddress = null;
String[] ss = ip.split("/");
ipAddress = ss[0];
return ipAddress;
}
/**
* 交换机的等级变化
*/
public static String changeColorMethod(String colorNum){
String level = "";
String color = "colorNum";
if(color!=null&&!"".equals(color)){
if(colorNum.equalsIgnoreCase("Indeterminate")){
level = "0"; //不确定的
}else if(colorNum.equalsIgnoreCase("Critical")){
level = "1"; //关键的、严重的、极重要的
}else if(colorNum.equalsIgnoreCase("Error")){
level = "1";
}else if(colorNum.equalsIgnoreCase("Alarm")){
level = "1";
}else if(colorNum.equalsIgnoreCase("MAJ")){
level = "1";
}else if(colorNum.equalsIgnoreCase("Major")){
level = "2"; //重要的、主要的
}else if(colorNum.equalsIgnoreCase("Minor")){
level = "3"; //较小的
}else if(colorNum.equalsIgnoreCase("Warning")){
level = "4"; //一般警告
}else if(colorNum.equalsIgnoreCase("Warn")){
level = "4"; //警告
}else if(colorNum.equalsIgnoreCase("WRN")){
level = "4"; //警告
}else if(colorNum.equalsIgnoreCase("MIN")){
level = "4";
}else if(colorNum.equalsIgnoreCase("Restored")){
level = "5"; //修复、归还、交还、使恢复
}else if(colorNum.equals("cleared")||colorNum.equals("Cleared")){
level = "6"; //变明朗、明白
}else if(colorNum.equalsIgnoreCase("Normal")){
level = "6"; //正常
}else if(colorNum.equalsIgnoreCase("Notification")){
level = "7"; //通知、通知单、布告、公布
}else if(colorNum.equalsIgnoreCase("Info")){
level = "7";
}else if(colorNum.equalsIgnoreCase("Acknowledged")){
level = "8"; //告知已经收到
}else if(colorNum.equals("0")){
level = "0";
}else if(colorNum.equals("1")){
level = "1";
}else if(colorNum.equals("2")){
level = "2";
}else if(colorNum.equals("3")){
level = "3";
}else if(colorNum.equals("4")){
level = "4";
}else if(colorNum.equals("5")){
level = "5";
}else if(colorNum.equals("6")){
level = "6";
}else if(colorNum.equals("7")){
level = "7";
}else if(colorNum.equals("8")){
level = "8";
}else{
level = "6";
}
}else{
level = "6";
}
return level;
}
//改变中兴的告警等级
public boolean judgeZetLevelSend(String level){
boolean flag = false;
if(level!=null){
if(level.equalsIgnoreCase("0")){
flag = true;
}else if(level.equalsIgnoreCase("1")){
flag = true;
}else if(level.equalsIgnoreCase("2")){
flag = true;
}else if(level.equalsIgnoreCase("3")){
flag = true;
}else if(level.equalsIgnoreCase("5")){
flag = true;
}
}
return flag;
}
//改变西门子的告警等级
public boolean judgeSiemensLevelSend(String level){
boolean flag = false;
if(level!=null){
if(level.equalsIgnoreCase("0")){
flag = true;
}else if(level.equalsIgnoreCase("1")){
flag = true;
}else if(level.equalsIgnoreCase("2")){
flag = true;
}else if(level.equalsIgnoreCase("3")){
flag = true;
}
}
return flag;
}
//Avaya告警等级判断
public boolean judgeAvaryLevelSend(String level){
boolean flag = false;
if(level!=null){
if(level.equalsIgnoreCase("MAJ")){
flag = true;
}else if(level.equalsIgnoreCase("MIN")){
flag = true;
}else if(level.equalsIgnoreCase("major")){
flag = true;
}else if(level.equalsIgnoreCase("minor")){
flag = true;
}
}
return flag;
}
//阿郎
public boolean judgeAlcateLucentLevelSend(String alarmId){
boolean flag = false;
if(Tools.notEmpty(alarmId)){
/** 1125都是登录消息可以屏蔽,2018-10-25
if(alarmId.equals("1125")){
flag = true;
}else
*/
if(alarmId.equals("2826")){
flag = true;
}else if(alarmId.equals("2043")){
flag = true;
}else if(alarmId.equals("2042")){
flag = true;
}else if(alarmId.equals("4108")){
flag = true;
}else if(alarmId.equals("310")){
flag = true;
}else if(alarmId.equals("2168")){
flag = true;
}else if(alarmId.equals("2019")){ //增加2019 hzw 2019-01-14
flag = true;
}
}
return flag;
}
//录音系统
public boolean judgeRecordLevelSend(String level){
boolean flag = false;
if(level!=null){
if(level.equalsIgnoreCase("ALARM")){
flag = true;
}
}
return flag;
}
public static void main(String[] args) {
//
/*AlcateLucentTrapReceiver ar = new AlcateLucentTrapReceiver();
ar.run();*/
//String message = "1.3.6.1.4.1.637.64.0.10.1.2";
//String[] str = message.split("\\.");
//对小数点进行切割
//String[] strs = message.split("\\.");
//System.out.println(SnmpTrapReceiver.getIp("172.20.27.21/46931"));
//System.out.println(SnmpTrapReceiver.parStr("b3:ac:b3:a4:cd:a8:bb:b0:b8:e6:be:af:28:31:33:29"));
//SnmpTrapReceiver sr = new SnmpTrapReceiver();
//sr.run();
//System.out.println(SnmpTrapReceiver.changeColorMethod("Maan"));
//System.out.println(sr.judgeLevelSend("Indeterminate1"));
}
}
代码设计到的配置文件:
snmp.properties
#snmp配置
#本机的IP地址
client_ip=127.0.0.1
#snmp监听端口默认是162
client_port=162
#snmp字符集默认是gbk
snmp_charset=gbk